GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — bpo-28411: Support other mappings in PyInterpreterState.modules. by ericsnowcurrently · Pull Request #3593 · python/cpython Conversation
|
| if (PyErr_ExceptionMatches(PyExc_KeyError)) { | ||
| PyErr_Clear(); | ||
| } | ||
| return mod; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This is missing the Py_XDECREF to return a borrowed reference instead of a new one.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Gah! The docs for PyDict_GetItemWithError() before 3.7 don't mention it returning a borrowed reference. Thanks for catching that. I was looking for that refleak!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Looks like that wasn't the refleak I was looking for. :/ Back I go.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I was just pattern matching with the code above based on the assumption that PyDict_GetItem and PyDict_GetItemWithError exposed the same refcount semantics :)
However, it now occurs to me that these access patterns are thoroughly dubious if you genuinely want to allow dict subclasses and arbitrary mappings, as those may return dynamic references (e.g. from __missing__ methods) , in which case the Py_XDECREF() line may invalidate the reference entirely.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Good call. I'll fix that.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if (PyErr_Occurred()) { | ||
| PyErr_Clear(); | ||
| } | ||
| Py_XDECREF(mod); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This could do with a second comment saying "Return a borrowed reference instead of a new one"
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Will do.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
FYI, I'm hunting down a refleak (probably in import.c): test_pickle hits it too. Once I track it down and fix it I'm planning on merging. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I suspect your reference leaks are coming from the iterators.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| i = 0; | ||
| while (PyDict_Next(modules_dict, &i, &module_name, &module)) { | ||
| PyObject *iterator = PyObject_GetIter(modules); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Where does this iterator get cleaned up?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I would have found it eventually but you just saved me a bunch of time!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| } | ||
| else { | ||
| PyObject *iterator = PyObject_GetIter(modules); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This iterator doesn't appear to get cleaned up either.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.