-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Check scope's __dict__ instead of using hasattr when registering classes and exceptions #2335
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
Merged
YannickJadoul
merged 4 commits into
pybind:master
from
YannickJadoul:fix-derived-class-scope
Oct 8, 2020
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
95342d9
Check scope's __dict__ instead of using hasattr when registering clas…
YannickJadoul 1eaacb7
Extend test_base_and_derived_nested_scope test
YannickJadoul 8368c76
Add tests on error being thrown registering duplicate classes
YannickJadoul 0f66572
Circumvent bug with combination of test_class.py::test_register_dupli…
YannickJadoul File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
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.
Potentially, we could drop
hasattr(rec.scope, "__dict__")
, if we're happy throwing an exception when the user tries to use a scope that doesn't have a__dict__
attribute?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.
The idea of throwing an exception in this situation worries me, a lot.
I'm surprised to see the strong runtime performance concerns from both Yannick and Boris. Is it correct that this code only runs when a pybind11 module is imported? Is that so slow that people complain already? What's the incremental extra runtime overhead? My first guess is it's no measurable, given all the other things happening at import time (files are opened, dlls loaded), but maybe I'm overlooking something?
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.
It's not really a concern. It is only run once at import time, so it hardly matter.
I wasn't measuring
import whatever
, but rather this specific patch in isolation.Again, this is executed exactly once. It really shouldn't be a concern. I just wanted to satisfy my own curiosity.
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.
Not too worried about it, either! Just want to point it out.
The reasoning is/was, if
hasattr(rec.scope, "__dict__")
fails, most likely the laterscope.attr(name) = *this;
will also fail/throw an exception?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 think I misunderstood this code initially (github is helpfully hiding the next line...). Would this be logically equivalent?
Now suspecting: the existing
hasattr
returns true, but we want to raise an error only if we find that the attribute is defined in__dict__
?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.
Not sure how to solve this, though. Checking
hasattr
/getattr
is too wide (i.e., checks base classes), while__dict__
is too strict (would miss the crazy case where__getattr__
/__setattr__
, or__getattribute__
/__setattribute__
, would be overwritten).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.
Maybe we shouldn't fix it? If it's this hard to do it right, perhaps we shouldn't "fix" it and break things that currently work.
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.
Interesting suggestion, yes. I must say the current situation feels wrong, though, where it matters in which order you register a class first in the base class or first in a derived class.
And the above shouldn't break too much. there's a thing where, if
getattr
andsetattr
are overwritten, things might already be broken anyway. In any case, thescope
should be a class or a module, no?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.
Do you want the good news or the bad news? The bad news?
The good news is that using functions as scopes isn't allowed with pybind. I tried. I really really tried to make pybind accept a function object as a scope.
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'm indeed not sure if this is good or bad news :-/