Skip to content
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-41341: Recursive evaluation of ForwardRef in get_type_hints #21553

Merged
merged 2 commits into from
Jul 22, 2020

Conversation

wyfo
Copy link
Contributor

@wyfo wyfo commented Jul 20, 2020

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.

https://bugs.python.org/issue41341

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
@the-knights-who-say-ni

This comment has been minimized.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@isidentical This might help moving https://bugs.python.org/issue38605 forward (make from __future__ import annotations the default).

@ambv Assuming we get this to work, what would you think of backporting it to 3.9, even though beta5 is already released? On the one hand it's awfully late for such a change (and experience with the bpo issue above suggests it's not painful). On the other hand getting the same behavior for forward refs in 3.9 with from __future__ import annotations as it will have in 3.10 (regardless of that import) seems useful.

@@ -2456,6 +2456,12 @@ def foo(a: tuple[ForwardRef('T')]):
self.assertEqual(get_type_hints(foo, globals(), locals()),
{'a': tuple[T]})

def test_double_forward(self):
def foo(a: 'List[\'int\']'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to approve this PR when I realized that we should make this work with list -- I tried and it doesn't currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right concerning the fact that it doesn't work with list, but I've found that it's not related to this PR; actually, I think there is a significant defect in current PEP 585 implementation. In fact:

from dataclasses import dataclass, field
from typing import get_type_hints, List, ForwardRef

@dataclass
class Node:
    children: list["Node"] = field(default_factory=list)
    children2: List["Node"] = field(default_factory=list)

assert get_type_hints(Node) == {"children": list["Node"], "children2": List[Node]}
assert List["Node"].__args__ == (ForwardRef("Node"),)
assert list["Node"].__args__ == ("Node",)  # No ForwardRef here, so no evaluation by get_type_hints

I will open an issue on bugs.python.org to discuss about this, because I think this PR is not the best place to do it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, you're right, thanks for the analysis. We probably will not ever support this: importing ForwardRef from the built-in generic alias code would be problematic, and once from __future__ import annotations is always on there's no need to quote the argument anyway. Sorry for the hiccup. I will now approve your PR.

@isidentical
Copy link
Sponsor Member

@isidentical This might help moving https://bugs.python.org/issue38605 forward (make from future import annotations the default).

I had my own implementations, but I think I am going to rebase because it was kind of a workaround.

@gvanrossum gvanrossum merged commit 653f420 into python:master Jul 22, 2020
@bedevere-bot
Copy link

@gvanrossum: Please replace # with GH- in the commit message next time. Thanks!

@gvanrossum
Copy link
Member

@ambv @pablogsal can I please have a decision on whether to backport this to 3.9? See my previous comment.

@pablogsal
Copy link
Member

@ambv @pablogsal can I please have a decision on whether to backport this to 3.9? See my previous comment.

I think it makes sense, but being this 3.9 this is @ambv's decision

@ambv ambv added the needs backport to 3.9 only security fixes label Jul 26, 2020
@miss-islington
Copy link
Contributor

Thanks @wyfo for the PR, and @gvanrossum for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jul 26, 2020
…onGH-21553)

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
(cherry picked from commit 653f420)

Co-authored-by: wyfo <joperez@hotmail.fr>
@bedevere-bot
Copy link

GH-21629 is a backport of this pull request to the 3.9 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Jul 26, 2020
miss-islington added a commit that referenced this pull request Jul 26, 2020
…1553)

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
(cherry picked from commit 653f420)

Co-authored-by: wyfo <joperez@hotmail.fr>
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Aug 4, 2020
…on#21553)

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Aug 20, 2020
…on#21553)

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
xzy3 pushed a commit to xzy3/cpython that referenced this pull request Oct 18, 2020
…on#21553)

The issue raised by recursive evaluation is infinite recursion with
recursive types. In that case, only the first recursive ForwardRef is
evaluated.
pdxjohnny added a commit to pdxjohnny/dffml that referenced this pull request Jun 2, 2022
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
pdxjohnny added a commit to pdxjohnny/dffml that referenced this pull request Jun 23, 2022
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
pdxjohnny added a commit to pdxjohnny/dffml that referenced this pull request Jun 23, 2022
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
pdxjohnny added a commit to intel/dffml that referenced this pull request Jul 7, 2022
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
pdxjohnny added a commit to intel/dffml that referenced this pull request Jul 7, 2022
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
hauntsaninja pushed a commit to python/typeshed that referenced this pull request Aug 24, 2022
pdxjohnny added a commit to pdxjohnny/dffml that referenced this pull request Jan 5, 2023
…f or str

Related: python/cpython#21553 (comment)
Signed-off-by: John Andersen <johnandersenpdx@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants