-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-46333: Honor module
parameter in ForwardRef
#30536
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
bpo-46333: Honor module
parameter in ForwardRef
#30536
Conversation
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have same name. This affects __eq__, __repr__ and __hash__ and methods.
This comment was marked as resolved.
This comment was marked as resolved.
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.
Welcome to CPython! You can add a NEWS entry to your PR using https://blurb-it.herokuapp.com/ :)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Since this is your first contribution, you should also feel free to add your name to https://github.com/python/cpython/blob/main/Misc/ACKS (this is entirely optional, only if you'd like to). |
@Fidget-Spinner I hope you can review and merge this PR? |
@gvanrossum Sure. Leave it to 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.
Great work! We're almost ready to merge, I just have some minor concerns.
Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst
Outdated
Show resolved
Hide resolved
@@ -2611,6 +2611,10 @@ def test_forward_equality(self): | |||
fr = typing.ForwardRef('int') | |||
self.assertEqual(fr, typing.ForwardRef('int')) | |||
self.assertNotEqual(List['int'], List[int]) | |||
self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__)) |
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, I wonder if this test is run directly, will __name__
be `main``? Wouldn't that make the test pass incorrectly? (Throwing this question out there because I'm not too sure myself). Maybe we should be safe and give it a distinct name?
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 test is to ensure that ForwardRef
with module
set is different from ForwardRef
with module
not set (That was previsously not the case). The actual value of module
(or __name__
) is not relevant. Under the hood the comparison is None
vs str
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.
My bad, thanks for pointing that out. I mistakenly assumed it would grab a default value from the current scope to populate module
in things like ClassVar['int']
due to the _type_check
/_type_convert
function (I'm now shocked that it doesn't and only does that for TypedDict
).
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.
Yes, unfortunately the current module is not captured automatically.
The current scope/module is typicallly obtained by get_type_hints
because a class knows its module (and so all ForwardRefs in member annotations can be correctly resolved. But each forward Ref does originally not know its module).
However for type aliases this does not work, and there one needs the explicit module.
For example
Json = Union[ List['Json'], Dict[str,'Json'], int, float, bool, None ]
cannot be exported (and expect to work) unless one sets the module
for each forward ref.
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
@Fidget-Spinner, do you see this one as more of a bugfix that should be backported, or more of an enhancement/behaviour change? (This is just for my clarification, @aha79 — I'm fairly new to the triage team 🙂) |
@AlexWaygood this is a grey area. On one hand, generally, anything dealing with However, this specific I'm inclined to accept the PR without the |
Thanks, that's really clarifying! It might be worth noting that @sobolevn proposes in #29158 (not yet merged) to use the |
Btw @aha79 — could I ask if you've signed the CLA? For legal reasons, it may be difficult for CPython to merge a PR from you if you haven't 🙂 |
Yes, sorry. I completely understand that. I clarify with my organization (This will be ok, but may take a few more days) |
Of course! No rush :) |
@AlexWaygood The CLA is now signed. Sorry that it took a while. |
Thanks, no worries!
To me it makes sense to split off the Fidget-Spinner is currently on a break from open source — @JelleZijlstra, if you've got the time, do you have any thoughts on this PR? |
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
There were already tests for |
Sorry, I think I was unclear — my bad :) We now have two test methods for testing cpython/Lib/test/test_typing.py Line 2648 in 9dd2f8f
Could you move the new tests for |
I didn't mean to imply otherwise! |
Sorry I misunderstood. I move/adapted the tests to the right place |
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.
Looks good to me. Feel free to open a new PR for the __repr__
changes (you can link to the same BPO issue).
@gvanrossum could we possibly get the full test suite run on this PR, please? :) |
@AlexWaygood / @JelleZijlstra Is this ready to merge? |
Looks that way to me :) |
Yes I think it's good. It can wait though, hopefully I can merge it myself next week :) |
Thanks @aha79 for the PR, and @JelleZijlstra for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9, 3.10. |
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <andreas.hangauer@siemens.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <34090357+aha79@users.noreply.github.com>
GH-31379 is a backport of this pull request to the 3.10 branch. |
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <andreas.hangauer@siemens.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <34090357+aha79@users.noreply.github.com>
GH-31380 is a backport of this pull request to the 3.9 branch. |
…H-31379) The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <andreas.hangauer@siemens.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <34090357+aha79@users.noreply.github.com> Automerge-Triggered-By: GH:JelleZijlstra
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <andreas.hangauer@siemens.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <34090357+aha79@users.noreply.github.com>
The `module` parameter carries semantic information about the forward ref. Forward refs are different if they refer to different module even if they have the same name. This affects the `__eq__`, `__repr__` and `__hash__` methods. Co-authored-by: Andreas Hangauer <andreas.hangauer@siemens.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> (cherry picked from commit 6e7b813) Co-authored-by: aha79 <34090357+aha79@users.noreply.github.com>
The
module
parameter carries semantic information about the forward ref.Forward refs are different if they refer to different module even if they
have same name. This affects eq, repr and hash and methods,
which were previously not honoring the
module
parameter.https://bugs.python.org/issue46333