Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
gh-90562: Improve zero argument support forsuper()
in dataclasses whenslots=True
#124692
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
gh-90562: Improve zero argument support forsuper()
in dataclasses whenslots=True
#124692
Conversation
ghost commentedSep 27, 2024 • edited by ghost
Loading Uh oh!
There was an error while loading.Please reload this page.
edited by ghost
Uh oh!
There was an error while loading.Please reload this page.
2e0ca01
to3b65acf
CompareLib/dataclasses.py Outdated
return True | ||
return False | ||
def _find_inner_functions(obj, _seen=None, _depth=0): |
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 the leading underscores on_seen
and_depth
?
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.
This should indicate that these arguments are only used within the function (in recursive calls) and not outside of the function body.
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 that the whole function is private, so it can only be used inside CPython by us :)
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.
Well, you've got a point. Removed the underscores.
Lib/dataclasses.py Outdated
_seen.add(id(obj)) | ||
_depth += 1 | ||
if _depth > 2: |
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 are depth 1 and 2 special? What is this test (and_depth
in general) trying to accomplish? Please add comments explaining what's going on here, it's not at all clear from the code.
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.
Added an explanation and few test cases for this behaviour. Caught two bugs in the process \o/
Lib/dataclasses.py Outdated
): | ||
# we don't want to inspect custom descriptors just yet | ||
# there's still a chance we'll encounter a pure function | ||
# or a property |
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.
Please add a comment explaining why encountering a pure function or property means we don't have to inspect custom descriptors.
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.
Hmm, there's already an explanation above:
Lines 1336 to 1339 in3b65acf
# original class. We can break out of this loop as soon as we | |
# make an update, since all closures for a class will share a | |
# given cell. First we try to find a pure function/properties, | |
# and then fallback to inspecting custom descriptors. |
Would you like me to add clarification for this case specifically?
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.
Ah, you're right. Maybe change the comment to "... fallback to inspecting custom descriptors if no pure function or property is found".
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.
Makes sense. I've added clarification in both places to be extra clear.
Uh oh!
There was an error while loading.Please reload this page.
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.
Great find, thanks a lot for your work! 👍
Lib/dataclasses.py Outdated
return True | ||
return False | ||
def _find_inner_functions(obj, _seen=None, _depth=0): |
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 that the whole function is private, so it can only be used inside CPython by us :)
Uh oh!
There was an error while loading.Please reload this page.
Lib/dataclasses.py Outdated
return None | ||
for attr in dir(obj): | ||
value = getattr(obj, attr, None) |
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.
This case is always complex, sincegetattr
can evaluate properties and other objects. There are two ways of hanling this case:
- Allow all exceptions to raise
- Hide all exceptions from user here
I am not quite sure which one is better here.
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.
Thanks for bringing this to my attention!
After some hacking, I've decided to go with the third option: removing any possibility of user defined code execution.
Uh oh!
There was an error while loading.Please reload this page.
Co-authored-by: sobolevn <mail@sobolevn.me>
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.
This looks OK to me; I'll let@ericvsmith give it final approval/merge.
I don't love that we've opened the door to an infinite fractal of complexity here; at some point it would probably be better to bite the bullet and introduce a__classcell__
attribute on classes that allows reliably finding this cell in O(1) time.
Uh oh!
There was an error while loading.Please reload this page.
I agree that the complexity is unfortunate. |
This uses builtins.dir, which will trigger custom __getattibute__ if any, and will trigger __get__ on __dict__ descriptor.
Good idea. I've changed the implementation to use |
@carljm, friendly ping :) |
As I mentioned above, I would rather have@ericvsmith approve/merge this, since it was his review comments you addressed. |
I've been busy, but it's on my list of things to do. |
Uh oh!
There was an error while loading.Please reload this page.
Added two tests for two cases that weren't covered in original PR: