-
-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support recursive and empty closure cells #443
Conversation
Yours is a pretty nice solution...
|
Unfortunately, the value of the cell would become the list instead of the element inside the list, but thank you for the suggestion. I was able to use it to make a solution that works for both Python 2 and Python 3 using the def _create_reference_cell():
contents = None
v = vars()
class Updater(object):
def __call__(self, value):
v['contents'] = value
contents = Updater()
return (lambda: contents).__closure__[0] Also, what are you plans with regards to compatibility? In Python 3.7+, |
I figured that either a list or a dict could serve as a stand-in for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, given the changes requested inline
Thank you for the help! I'll comb through the issues and see if there are new test cases I need to add. Will let you know when I am done. |
Alright. I did some playing around and found out that creating the pickling of the cell object the way I did does not actually work in Python 2. I just noticed that this issue only applies to Python 3 not Python 2. What I mean is that super is treated totally differently in both Python 2 and Python 3. In Python 3, it is treated as a cell object with a recursive value and in Python 2, it is set as special attributes of the >>> # Python 2.7
>>> import dill
>>> class A:
... def __init__(self):
... super(A, self).__init__()
...
>>> dill.copy(A)
<class __main__.A at 0x10bb4f7a0>
>>> A
<class __main__.A at 0x10bb4f6d0>
>>> dir(A.__init__)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'im_class', 'im_func', 'im_self']
>>> A.__init__.im_class
<class __main__.A at 0x10bb4f6d0> Because of this, we do not need a copy of |
I don't feel like there's anything else needed for this particular PR. Please follow up (with at least a comment) on each conversation above where you have been tagged... and let's get this merged. |
Alright. LGTM. |
Thanks for the follow up, the change looks good. Can you comment on these two dangling threads?
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
No problem. Feel free to merge. I'll open up a new ticket for 'explorations' on (1) above. |
Sounds good! I cannot merge the branch because I lack write access to the repo, but I think it is ready for you to merge. I have a couple of other PRs that I am opening now with more changes that were not related to this PR. |
Riiiiight. After this long PR, it feels like you should be able to merge. I'll do it now. |
@anivegesana: see interesting new failure case in f6f71f5 |
Yep. I thought that this particular recursion would be uncommon. I only handled the recursion that goes (function/class -> ... -> cell -> function/class). This recursion is (function/class -> ... -> list/dict/set -> function/class). This can be easily fixed by checking that no elements in the dictionary are recursive before picking the dictionary, and adding the dictionary to Will look into this later next week. Thanks for keeping me posted! |
Thanks for the follow-up. To me, placeholder elements are not a bad solution... I've used it several times in |
Also, @anivegesana, just FYI for the future -- intentionally removing functionality should involve an in-depth management decision. In a package with M/2 dl/day, uncommon cases are going to be encountered regularly. So, I want to be clear here, your PR is superb... and I'd also appreciate you not intentionally dropping corner cases without discussion. I guess there should be tests that fully cover the expected level of functionality, but there's obviously not if I generally run the |
This PR uses a better workaround for
super
objects. Instead of forcing_byref
toFalse
, this PR keeps track of what classes are in the process of being created. When a cell whose value is an incomplete class is encountered, it is saved to a list. Its initial value isNone
to prevent infinite recursion. Once a class is fully created, all of the cells that recursively reference the class are updated with the completed class.This PR adds generalized machinery to handle thunks by saving a list of postprocessing steps for each potentially recursive object, like changing the value of a cell. The
_postproc
can be used for other operations, like registering ABCs and updating the__globals__
and__dict__
of recursive functions and enum classes.This PR also adds a
_shims
module to handle version incompatibilities in Python and dill more seamlessly.Fixes #229, fixes #239, fixes #300, fixes #344, fixes #399, fixes #211