TypeAlias cannot be indirectly imported?

Dear all,

I received plenty of interesting comments regarding my previous question, so that I indulge myself in another one.

In file a.py, you import TypeAlias from module typing

from typing import TypeAlias

In file b.py, you import all of module a and use TypeAlias

from a import *
t:TypeAlias = int

Then Pyright raises an error:

error: Expression of type "Type[int]" cannot be assigned to declared type "TypeAlias"
    "Type[type]" is incompatible with "Type[TypeAlias]"

However, if I import TypeAlias direcly in module b, it works!

# from a import *
from typing import TypeAlias
t:TypeAlias = int

It also works if I use the extended name of TypeAlias, that is, typing.TypeAlias

# from a import *
import typing
t:typing.TypeAlias = int

In the typing.py source code, it is mentioned that TypeAlias is not a type-as-usual, but kind of a “Special marker”. It is emphasized that its use is strictly restricted to the form above, but nothing is specified about importation.

The official doc refers to PEP613, but I am not sure to understand all of it. At least, word “import” does not appear in the document.

Could anybody explain how it should be used properly?

Best regards,

Luc.

That looks like it might be a bug in pyright. I’d recommend filing a bug report at the issue tracker here, and seeing what Eric Traut thinks: Issues · microsoft/pyright · GitHub

Thanks, Alex. Will do. Luc

1 Like

Here is Eric Traut’s answer. He confirms that it is a design feature. I agree with him that the real solution is a specific syntax for type declaration, as proposed in his PEP 695.

Luc.

Copied from Pyright Issue #3941

You appear to be re-exporting a symbol called TypeAlias from your own module. TypeAlias is a special form that requires special-case handling in static type checkers. In all other languages that I know of, type alias declarations have their own syntax and keyword, but Python is a bit backward in this regard. I’ve authored PEP 695, which proposes to add such a facility to Python 3.12.

Pyright process the TypeAlias symbol in its “binder”, which runs prior to any type analysis. That explains the limitation you are seeing here.

Is there a reason you don’t want to import TypeAlias directly from typing or typing_extensions? I’ve never seen this done before.

The obvious workaround is to avoid doing this and import TypeAlias from typing directly.

1 Like

“from foo import *” is usually best avoided.