-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Force the builtin module key to be the correct type. #2814
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
Conversation
Previously it was always going to be a std::string which converted into unicode. Python 2 appears to want module keys to be normal str types, so this was breaking code that expected plain string types in the builtins.keys() data structure
We discussed this on Gitter. I agree that it makes sense that a module's Fun thing, this is actually not breaking the ABI, and (probably) not even stopping different pybind11 libraries from interacting, since: Python 2.7.17 (default, Sep 30 2020, 13:38:04)
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {}
>>> d[u'answer'] = 42
>>> d[u'answer']
42
>>> d['answer']
42
>>> type(u'answer')
<type 'unicode'>
>>> type('answer')
<type 'str'>
>>> Do you mind checking this, @crimsoncor, whether a pybind11 library from our current |
Did some very basic testing of this (source code in the attached zip). I built one module with a pre-patch pybind11 and the other with post-patch (and then also flipped the order). In all cases, both modules were able to access the same internals block. What I did notice was that which one was loaded first determined the type of the argument in the builtin dict:
But even with that said, regardless of the type of the key, it still worked for both modules. Also double checked to make sure there was ever only a single entry in the map (despite it being str vs unicode)
And that looks like it also was correct |
@henryiii, I'm going to say it's your call on whether we've already stopped accepting PRs for 2.6.2 :-P |
If we can get another global testing run (which I think we will, @rwgk ?), maybe over the weekend, and release Monday, perhaps? |
OK, np, I'll include this PR in the next run. |
@crimsoncor if you could add a minimal test that would be great. |
What sort of test do you think would be applicable? The existing tests that exercise internals being shared across multiple modules continue to function fine, which shows that changing the type of the key in python 2.7 has not caused any regression. The only other test that seems like it might be applicable would be testing a module built with an older version and a module built with the new code (like I did manually) and I'm not sure how to add that in any sane fashion in the pybind11 test suite. |
@crimsoncor, what about just adding a single test that checks |
done |
Awesome, thanks! |
if hasattr(__builtins__, "keys"): | ||
keys = __builtins__.keys() | ||
else: # this is to make pypy happy since builtins is different there. | ||
keys = __builtins__.__dict__.keys() |
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.
Why not simply always go through __builtins__.__dict__.keys()
? It works in CPython and PyPy.
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.
answered in gitter, but I'll add here as well. Python 2 has the following amazing feature
In module __main__:
__builtins__ is a reference to module __builtin__.
__builtin__ only exists if you import it.
In any other module:
__builtins__ is a reference to module __builtin__'s __dict__.
__builtin__ only exists if you import it.
so we need to handle both cases.
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.
sigh
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.
I ran this through our global testing and found no issues.
Thanks for creating this PR, @crimsoncor / @jesse-sony! |
Previously it was always going to be a std::string which converted into
unicode. Python 2 appears to want module keys to be normal str types, so
this was breaking code that expected plain string types in the
builtins.keys() data structure
Description
Suggested changelog entry: