2Test for type expressions used in annotations.
9from typing import Any, Callable, Tuple, Union, assert_type
11# https://typing.readthedocs.io/en/latest/spec/annotations.html#valid-type-expression-forms
14def greeting(name: str) -> str:
15 return "Hello " + name
18assert_type(greeting("Monty"), str)
21# > Expressions whose type is a subtype of a specific argument type are also accepted for that argument.
26assert_type(greeting(StrSub("Monty")), str)
29# > Type hints may be built-in classes (including those defined in standard library or third-party
30# > extension modules), abstract base classes, types available in the types module, and user-defined
31# > classes (including those defined in the standard library or third-party modules).
34class UserDefinedClass:
38class AbstractBaseClass(abc.ABC):
40 def abstract_method(self):
44# The following parameter annotations should all be considered
45# valid and not generate errors.
57 p11: types.ModuleType,
58 p12: types.FunctionType,
59 p13: types.BuiltinFunctionType,
60 p14: UserDefinedClass,
61 p15: AbstractBaseClass,
69 p23: Tuple[int, int, str],
70 p24: Callable[..., int],
71 p25: Callable[[int, str], None],
74 assert_type(p17, int | str)
75 assert_type(p19, list[Any])
76 assert_type(p20, list[int])
77 assert_type(p21, tuple[Any, ...])
80# > Annotations should be kept simple or static analysis tools may not be able to interpret the values.
85# The following parameter annotations should all be considered
86# invalid and generate errors.
87def invalid_annotations(
88 p1: eval("".join(map(chr, [105, 110, 116]))), # E
[invalid-type-form] Function calls are not allowed in type expressions
[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
91 p4: [int for i in range(1)], # E
[invalid-type-form] List comprehensions are not allowed in type expressions
[invalid-type-form] Dict literals are not allowed in type expressions
93 p6: (lambda: int)(), # E
[invalid-type-form] Function calls are not allowed in type expressions
[invalid-type-form] Invalid subscript of object of type `list[Unknown | <class 'int'>]` in type expression
[invalid-type-form] Int literals are not allowed in this context in a type expression
95 p8: int if 1 < 3 else str, # E
[invalid-type-form] `if` expressions are not allowed in type expressions
[invalid-type-form] Variable of type `Literal[3]` is not allowed in a type expression
[invalid-type-form] Boolean literals are not allowed in this context in a type expression
[invalid-type-form] Int literals are not allowed in this context in a type expression
[invalid-type-form] Unary operations are not allowed in type expressions
[invalid-type-form] Boolean operations are not allowed in type expressions
[fstring-type-annotation] Type expressions cannot use f-strings
[invalid-type-form] Module `types` is not valid in a type expression
107# > When used in a type hint, the expression None is considered equivalent to type(None).
110def takes_None(x: None) -> None:
114assert_type(takes_None(None), None)