Closed
Description
We have both type aliases and variables with types like Type[...]
, also there are module aliases and variables of type ModuleType
. I think we should document the difference in semantics and provide examples. (Also I think there are few minor things that should be fixed in mypy.) Here how I see things:
- Variables with type
Type[...]
should be created by assignments with an explicit type annotations:class A: ... tp: Type[A] = A
- Aliases are created by assignments without an explicit type:
class A: ... Alias = A
- The difference is that aliases are completely known statically and can be used in type context (annotations):
class A: ... class B: ... if random() > 0.5: Alias = A else: Alias = B # I think this should be prohibited (there are two TODOs in semanal.py) tp: Type[object] if random() > 0.5: tp = A else: tp = B # This is OK def fun1(x: Alias) -> None: ... # This is OK def fun2(x: tp) -> None: ... # Error
- There is similar distinction between module aliases and variables with type
types.ModuleType
:and alsoimport math, cmath from types import ModuleType mod: ModuleType = math # variable m = math # Alias mod.sin # Error. ModuleType has no attribute 'sin' m.sin # OK
if random() > 0.5: m = math else: m = cmath # Should be prohibited mod: ModuleType if random() > 0.5: mod = math else: mod = cmath # OK, note explicit annotation above
- For modules, we could add better support later (a particular module is a literal type as in Simple dependent types #3062 and binder can bind
mod
toUnion[Literal[math], Literal[cmath]]
after the above code).
@JukkaL Do we agree on semantics here? If yes, then I will make some minor changes in mypy and add this to documentation (maybe we also need to clarify this in PEP 484).