Prevent Recursion Errors with django_q2 Tasks #287
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It appears that using the
inventreepython library with functions that require pickling - likedjango_q2background jobs - can fail in some cases. I'll admit that it's unclear to me exactly what conditions lead to it failing, because thusfar I've only noticed it on thisProjectCodecase but have definitely used it elsewhere with no issues.The following is a simplified version of some code I have in a different Django site of mine.
Traceback is provided below
Which points to this block in
base.pySpecifically, the call to
self._dataappears to be problematic during pickling (according to the_ForkingPickler.loads(res)line in traceback). Pickling is not a process I fully understand, but it seems like there is an intermediate state where the object is not fully "initialized." Asking for the._dataproperty, which doesn't exist yet in this "uninitialized state", attempts a lookup ofname in self._data.keys(), which self references and causes the infinite recursion.Additionally, I believe the call to
super().__getattribute__(name)is unnecessary. I see the intent here.... it's to fall back on the normal attributes when the attribute we ask for is not in the_datadictionary. However, python's behavior means that we never even reach the__getattr__function call if the "normal" attribute already exists.I therefore suggest we update this
__getattr__function to instead beTo prove this works, here is a minimal example: