bpo-34572: change _pickle unpickling to use import rather than retrieving from sys.modules#9047
Conversation
|
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
Sorry, something went wrong.
c71f99f to
e47c5e1
Compare
September 5, 2018 03:06
|
Hi! Just wondering if there's something I can do to move this along - either that or be told that I'm completely wrong. We are using pure-python unpickling as a workaround for now, but I'd love to have some hope that we can switch back at some point in future. (I notice the same issue appears to be present in @pitrou/pickle5-backport - which I'm very keen to start using!) Thanks! |
Sorry, something went wrong.
|
@tjb900 I realize that this is a thread safety bug which is notoriously hard to test, but I generally find that pull requests that include tests are much easier to review, because it's easier to get a sense of what behavior it fixes and an assurance that there won't be regressions. |
Sorry, something went wrong.
|
@pganssle Thanks for checking it out. Test case was attached with the bug report, but I didn't include it in the PR - will look at that ASAP. |
Sorry, something went wrong.
|
Looks to me like @ericsnowcurrently added this line when adding It was added in several places, so I'm wondering if this thread safety bug is a problem for all the uses of |
Sorry, something went wrong.
|
Hmmm. Line 4160 in ca2d610 I'm still trying to identify at what point this became unsafe (have partially initialised modules always been present in |
Sorry, something went wrong.
|
It looks to me like the cpickle logic has always been unsafe, but prior to the introduction of per-module import locks for Python 3.3 in https://bugs.python.org/issue9260 it was likely much harder to hit. |
Sorry, something went wrong.
|
So if I understand this correctly, the current version of the code likely works the way it does for performance reasons, but unfortunately that comes at the cost of thread safety, in which case I think the current patch is likely the right approach (at least for now - maybe If it's possible to make a reliable but not terribly resource-intensive test for this, I think that would be a big help, but that may be a lot to ask. |
Sorry, something went wrong.
|
@tjb900 Thanks for adding that test. I've verified that this test consistently fails when run without the other changes in this PR, and it runs quickly whether or not it succeeds, so it's a +1 from me! One last nitpick, though is that I think it would be better to put it in with the other pickle tests so that people looking to add or change tests will be able to find it more easily (for example there are three or four different test modules where |
Sorry, something went wrong.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Sorry, something went wrong.
I agree with @pganssle in that this test should be placed with the rest of the pickle tests. |
Sorry, something went wrong.
|
I haven't tried adapting this to actually use pickle, but I can consistently get a failure due to partially initialized modules on the first try with this configuration. It does use |
Sorry, something went wrong.
|
This other case of
|
Sorry, something went wrong.
|
I have made the requested changes; please review again. Happy to backport to 3.6 and 3.7 also. |
Sorry, something went wrong.
|
Thanks for making the requested changes! @pablogsal: please review the changes made to this pull request. |
Sorry, something went wrong.
Please make that a separate issue on bugs.python.org. We'll have to discuss its performance implications separately. |
Sorry, something went wrong.
pitrou
left a comment
There was a problem hiding this comment.
LGTM.
Sorry, something went wrong.
|
@pablogsal, I think your comments have been addressed. Can you confirm? |
Sorry, something went wrong.
|
This addresses all my concerns! I like |
Sorry, something went wrong.
…ving from sys.modules (pythonGH-9047) Fix C implementation of pickle.loads to use importlib's locking mechanisms, and thereby avoid using partially-loaded modules. (cherry picked from commit 4371c0a) Co-authored-by: tjb900 <ozburgess@gmail.com>
import.cseems to contain a lot of protection to ensure that a partially-initialised module is not returned from import when in a multi-threaded environment.PyImport_Importenjoys these protections, butPyImport_GetModuledoes not.https://bugs.python.org/issue34572