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

Recursive type aliases tracker #7904

Closed
5 tasks done
srittau opened this issue May 21, 2022 · 8 comments
Closed
5 tasks done

Recursive type aliases tracker #7904

srittau opened this issue May 21, 2022 · 8 comments
Labels
project: feature tracker Tracks whether a typing feature can be used in typeshed stubs

Comments

@srittau
Copy link
Collaborator

srittau commented May 21, 2022

Test case:

from typing import TypeAlias

Recursive: TypeAlias = str | list["Recursive"]

def foo(r: Recursive) -> None:
    if not isinstance(r, str):
        foo(r[0])
    if not isinstance(r, list):
        r.casefold()

foo("")
foo(list(""))
foo(list(list(""), ""))
@srittau srittau added the project: feature tracker Tracks whether a typing feature can be used in typeshed stubs label May 21, 2022
@rchen152
Copy link
Collaborator

rchen152 commented Jun 7, 2022

Recursive types should work with pytype. We don't support the X | Y syntax for union types yet, so the test case has to be modified a bit, but pytype accept this:

from typing import TypeAlias, Union

Recursive: TypeAlias = Union[str, list["Recursive"]]

def foo(r: Recursive) -> None:
  if not isinstance(r, str):
    foo(r[0])
  if not isinstance(r, list):
    r.casefold()

foo("")
foo(list(""))
foo(list((list(""), "")))

(I also changed the list[...]s to list(..) in the last two lines; I assume that was a typo.)

@ilevkivskyi
Copy link
Member

FWIW mypy version in master supports this under a flag (expect it fails on the last line because of an unrelated bug in special-casing tuple literals, should be a 1-line fix).

@ilevkivskyi
Copy link
Member

In general, I guess we will discover a bunch of inconsistencies in type inference in mypy (currently it is a bit arbitrary in some situations, while it should be quite consistent for recursive types, especially if invariant collections are involved, e.g. this test passes if I use Sequence)

@al-yakubovich

This comment was marked as off-topic.

@AlexWaygood
Copy link
Member

Seems like we're all done here! We have our first recursive types successfully added to typeshed: #9134

Thanks @ilevkivskyi for all the incredible work on mypy recently to enable this!

@jleonard-r7
Copy link

These are not working for me:

WorkerResult: TypeAlias = Result[str, str] | Result[object, str]
Worker: TypeAlias = Callable[[], WorkerResult | Worker]

gives:

Traceback (most recent call last):
  File "/app/src/app/main.py", line 17, in <module>
    Worker: TypeAlias = Callable[[], WorkerResult | Worker]
                                                    ^^^^^^
NameError: name 'Worker' is not defined

@jleonard-r7
Copy link

Python version 3.11.2 (which should include whatever work happened in Nov 2022 on mypy).

@JelleZijlstra
Copy link
Member

This issue is about support in type checkers, not at runtime. To prevent the runtime NameError you'll (still) have to enclose the name in quotes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project: feature tracker Tracks whether a typing feature can be used in typeshed stubs
Projects
None yet
Development

No branches or pull requests

7 participants