← Back to index

annotations_typeexpr.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 15
FP: 0
FN: 0
Optional: 0 / 0
1"""
2Test for type expressions used in annotations.
3"""
4
5import abc
6import abc
7import types
8import types
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.
22class StrSub(str):
23 ...
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:
35 ...
38class AbstractBaseClass(abc.ABC):
39 @abc.abstractmethod
40 def abstract_method(self):
41 ...
44# The following parameter annotations should all be considered
45# valid and not generate errors.
46def valid_annotations(
47 p1: int,
48 p2: str,
49 p3: bytes,
50 p4: bytearray,
51 p5: memoryview,
52 p6: complex,
53 p7: float,
54 p8: bool,
55 p9: object,
56 p10: type,
57 p11: types.ModuleType,
58 p12: types.FunctionType,
59 p13: types.BuiltinFunctionType,
60 p14: UserDefinedClass,
61 p15: AbstractBaseClass,
62 p16: int,
63 p17: Union[int, str],
64 p18: None,
65 p19: list,
66 p20: list[int],
67 p21: tuple,
68 p22: Tuple[int, ...],
69 p23: Tuple[int, int, str],
70 p24: Callable[..., int],
71 p25: Callable[[int, str], None],
72 p26: Any,
73):
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.
82var1 = 3
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
89 p2: [int, str], # E
[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
90 p3: (int, str), # E
[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
92 p5: {}, # E
[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
94 p7: [int][0], # E
[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
96 p9: var1, # E
[invalid-type-form] Variable of type `Literal[3]` is not allowed in a type expression
97 p10: True, # E
[invalid-type-form] Boolean literals are not allowed in this context in a type expression
98 p11: 1, # E
[invalid-type-form] Int literals are not allowed in this context in a type expression
99 p12: -1, # E
[invalid-type-form] Unary operations are not allowed in type expressions
100 p13: int or str, # E
[invalid-type-form] Boolean operations are not allowed in type expressions
101 p14: f"int", # E
[fstring-type-annotation] Type expressions cannot use f-strings
102 p15: types, # E
[invalid-type-form] Module `types` is not valid in a type expression
103):
104 pass
107# > When used in a type hint, the expression None is considered equivalent to type(None).
110def takes_None(x: None) -> None:
111 ...
114assert_type(takes_None(None), None)