@@ -26,102 +26,102 @@ No errors reported for obviously wrong code
26
26
There are several common reasons why obviously wrong code is not
27
27
flagged as an error.
28
28
29
- - **The function containing the error is not annotated. ** Functions that
30
- do not have any annotations (neither for any argument nor for the
31
- return type) are not type-checked, and even the most blatant type
32
- errors (e.g. ``2 + 'a' ``) pass silently. The solution is to add
33
- annotations. Where that isn't possible, functions without annotations
34
- can be checked using :option: `--check-untyped-defs <mypy --check-untyped-defs> `.
29
+ **The function containing the error is not annotated. ** Functions that
30
+ do not have any annotations (neither for any argument nor for the
31
+ return type) are not type-checked, and even the most blatant type
32
+ errors (e.g. ``2 + 'a' ``) pass silently. The solution is to add
33
+ annotations. Where that isn't possible, functions without annotations
34
+ can be checked using :option: `--check-untyped-defs <mypy --check-untyped-defs> `.
35
35
36
- Example:
36
+ Example:
37
37
38
- .. code-block :: python
38
+ .. code-block :: python
39
39
40
- def foo (a ):
41
- return ' (' + a.split() + ' )' # No error!
40
+ def foo (a ):
41
+ return ' (' + a.split() + ' )' # No error!
42
42
43
- This gives no error even though ``a.split() `` is "obviously" a list
44
- (the author probably meant ``a.strip() ``). The error is reported
45
- once you add annotations:
43
+ This gives no error even though ``a.split() `` is "obviously" a list
44
+ (the author probably meant ``a.strip() ``). The error is reported
45
+ once you add annotations:
46
46
47
- .. code-block :: python
47
+ .. code-block :: python
48
48
49
- def foo (a : str ) -> str :
50
- return ' (' + a.split() + ' )'
51
- # error: Unsupported operand types for + ("str" and List[str])
49
+ def foo (a : str ) -> str :
50
+ return ' (' + a.split() + ' )'
51
+ # error: Unsupported operand types for + ("str" and List[str])
52
52
53
- If you don't know what types to add, you can use ``Any ``, but beware:
53
+ If you don't know what types to add, you can use ``Any ``, but beware:
54
54
55
- - **One of the values involved has type 'Any'. ** Extending the above
56
- example, if we were to leave out the annotation for ``a ``, we'd get
57
- no error:
55
+ **One of the values involved has type 'Any'. ** Extending the above
56
+ example, if we were to leave out the annotation for ``a ``, we'd get
57
+ no error:
58
58
59
- .. code-block :: python
59
+ .. code-block :: python
60
60
61
- def foo (a ) -> str :
62
- return ' (' + a.split() + ' )' # No error!
61
+ def foo (a ) -> str :
62
+ return ' (' + a.split() + ' )' # No error!
63
63
64
- The reason is that if the type of ``a `` is unknown, the type of
65
- ``a.split() `` is also unknown, so it is inferred as having type
66
- ``Any ``, and it is no error to add a string to an ``Any ``.
64
+ The reason is that if the type of ``a `` is unknown, the type of
65
+ ``a.split() `` is also unknown, so it is inferred as having type
66
+ ``Any ``, and it is no error to add a string to an ``Any ``.
67
67
68
- If you're having trouble debugging such situations,
69
- :ref: `reveal_type() <reveal-type >` might come in handy.
68
+ If you're having trouble debugging such situations,
69
+ :ref: `reveal_type() <reveal-type >` might come in handy.
70
70
71
- Note that sometimes library stubs have imprecise type information,
72
- e.g. the :py:func: `pow ` builtin returns ``Any `` (see `typeshed issue 285
73
- <https://github.com/python/typeshed/issues/285> `_ for the reason).
71
+ Note that sometimes library stubs have imprecise type information,
72
+ e.g. the :py:func: `pow ` builtin returns ``Any `` (see `typeshed issue 285
73
+ <https://github.com/python/typeshed/issues/285> `_ for the reason).
74
74
75
- - :py:meth: `__init__ <object.__init__> ` **method has no annotated
76
- arguments or return type annotation. ** :py:meth: `__init__ <object.__init__> `
77
- is considered fully-annotated **if at least one argument is annotated **,
78
- while mypy will infer the return type as ``None ``.
79
- The implication is that, for a :py:meth: `__init__ <object.__init__> ` method
80
- that has no argument, you'll have to explicitly annotate the return type
81
- as ``None `` to type-check this :py:meth: `__init__ <object.__init__> ` method:
75
+ :py:meth: `__init__ <object.__init__> ` **method has no annotated
76
+ arguments or return type annotation. ** :py:meth: `__init__ <object.__init__> `
77
+ is considered fully-annotated **if at least one argument is annotated **,
78
+ while mypy will infer the return type as ``None ``.
79
+ The implication is that, for a :py:meth: `__init__ <object.__init__> ` method
80
+ that has no argument, you'll have to explicitly annotate the return type
81
+ as ``None `` to type-check this :py:meth: `__init__ <object.__init__> ` method:
82
82
83
- .. code-block :: python
83
+ .. code-block :: python
84
84
85
- def foo (s : str ) -> str :
86
- return s
87
-
88
- class A ():
89
- def __init__ (self , value : str ): # Return type inferred as None, considered as typed method
90
- self .value = value
91
- foo(1 ) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"
92
-
93
- class B ():
94
- def __init__ (self ): # No argument is annotated, considered as untyped method
95
- foo(1 ) # No error!
96
-
97
- class C ():
98
- def __init__ (self ) -> None : # Must specify return type to type-check
99
- foo(1 ) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"
100
-
101
- - **Some imports may be silently ignored **. Another source of
102
- unexpected ``Any `` values are the :option: `--ignore-missing-imports
103
- <mypy --ignore-missing-imports> ` and :option: `--follow-imports=skip
104
- <mypy --follow-imports> ` flags. When you use :option: `--ignore-missing-imports <mypy --ignore-missing-imports> `,
105
- any imported module that cannot be found is silently replaced with
106
- ``Any ``. When using :option: `--follow-imports=skip <mypy --follow-imports> ` the same is true for
107
- modules for which a ``.py `` file is found but that are not specified
108
- on the command line. (If a ``.pyi `` stub is found it is always
109
- processed normally, regardless of the value of
110
- :option: `--follow-imports <mypy --follow-imports> `.) To help debug the former situation (no
111
- module found at all) leave out :option: `--ignore-missing-imports <mypy --ignore-missing-imports> `; to get
112
- clarity about the latter use :option: `--follow-imports=error <mypy --follow-imports> `. You can
113
- read up about these and other useful flags in :ref: `command-line `.
114
-
115
- - **A function annotated as returning a non-optional type returns 'None'
116
- and mypy doesn't complain **.
85
+ def foo (s : str ) -> str :
86
+ return s
87
+
88
+ class A ():
89
+ def __init__ (self , value : str ): # Return type inferred as None, considered as typed method
90
+ self .value = value
91
+ foo(1 ) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"
92
+
93
+ class B ():
94
+ def __init__ (self ): # No argument is annotated, considered as untyped method
95
+ foo(1 ) # No error!
96
+
97
+ class C ():
98
+ def __init__ (self ) -> None : # Must specify return type to type-check
99
+ foo(1 ) # error: Argument 1 to "foo" has incompatible type "int"; expected "str"
100
+
101
+ **Some imports may be silently ignored **. Another source of
102
+ unexpected ``Any `` values are the :option: `--ignore-missing-imports
103
+ <mypy --ignore-missing-imports> ` and :option: `--follow-imports=skip
104
+ <mypy --follow-imports> ` flags. When you use :option: `--ignore-missing-imports <mypy --ignore-missing-imports> `,
105
+ any imported module that cannot be found is silently replaced with
106
+ ``Any ``. When using :option: `--follow-imports=skip <mypy --follow-imports> ` the same is true for
107
+ modules for which a ``.py `` file is found but that are not specified
108
+ on the command line. (If a ``.pyi `` stub is found it is always
109
+ processed normally, regardless of the value of
110
+ :option: `--follow-imports <mypy --follow-imports> `.) To help debug the former situation (no
111
+ module found at all) leave out :option: `--ignore-missing-imports <mypy --ignore-missing-imports> `; to get
112
+ clarity about the latter use :option: `--follow-imports=error <mypy --follow-imports> `. You can
113
+ read up about these and other useful flags in :ref: `command-line `.
114
+
115
+ **A function annotated as returning a non-optional type returns 'None'
116
+ and mypy doesn't complain **.
117
117
118
- .. code-block :: python
118
+ .. code-block :: python
119
119
120
- def foo () -> str :
121
- return None # No error!
120
+ def foo () -> str :
121
+ return None # No error!
122
122
123
- You may have disabled strict optional checking (see
124
- :ref: `no_strict_optional ` for more).
123
+ You may have disabled strict optional checking (see
124
+ :ref: `no_strict_optional ` for more).
125
125
126
126
.. _silencing_checker :
127
127
@@ -383,10 +383,10 @@ explicit type cast:
383
383
if index < 0 :
384
384
raise ValueError (' No str found' )
385
385
386
- found = a[index] # Has `object` type, despite the fact that we know it is ` str`
387
- return cast(str , found) # So, we need an explicit cast to make mypy happy
386
+ found = a[index] # Has type "object" , despite the fact that we know it is " str"
387
+ return cast(str , found) # We need an explicit cast to make mypy happy
388
388
389
- Alternatively, you can use ``assert `` statement together with some
389
+ Alternatively, you can use an ``assert `` statement together with some
390
390
of the supported type inference techniques:
391
391
392
392
.. code-block :: python
@@ -396,9 +396,9 @@ of the supported type inference techniques:
396
396
if index < 0 :
397
397
raise ValueError (' No str found' )
398
398
399
- found = a[index] # Has `object` type, despite the fact that we know it is ` str`
400
- assert isinstance (found, str ) # Now, ` found` will be narrowed to ` str` subtype
401
- return found # No need for the explicit ` cast()` anymore
399
+ found = a[index] # Has type "object" , despite the fact that we know it is " str"
400
+ assert isinstance (found, str ) # Now, " found" will be narrowed to " str"
401
+ return found # No need for the explicit " cast()" anymore
402
402
403
403
.. note ::
404
404
@@ -411,7 +411,7 @@ of the supported type inference techniques:
411
411
412
412
.. note ::
413
413
414
- You can read more about type narrowing techniques here.
414
+ You can read more about type narrowing techniques :ref: ` here < type-narrowing >` .
415
415
416
416
Type inference in Mypy is designed to work well in common cases, to be
417
417
predictable and to let the type checker give useful error
@@ -634,32 +634,41 @@ You can install the latest development version of mypy from source. Clone the
634
634
Variables vs type aliases
635
635
-------------------------
636
636
637
- Mypy has both type aliases and variables with types like ``Type[...] `` and it is important to know their difference.
637
+ Mypy has both *type aliases * and variables with types like ``Type[...] ``. These are
638
+ subtly different, and it's important to understand how they differ to avoid pitfalls.
638
639
639
- 1. Variables with type ``Type[...] `` should be created by assignments with an explicit type annotations:
640
+ 1. A variable with type ``Type[...] `` is defined using an assignment with an
641
+ explicit type annotation:
640
642
641
643
.. code-block :: python
642
644
643
645
class A : ...
644
646
tp: Type[A] = A
645
647
646
- 2. Aliases are created by assignments without an explicit type.
648
+ 2. You can define a type alias using an assignment without an explicit type annotation
649
+ at the top level of a module:
647
650
648
651
.. code-block :: python
649
652
650
653
class A : ...
651
654
Alias = A
652
655
653
- Or you can also use :pep: `613 ` and explicit type aliases :
656
+ You can also use `` TypeAlias `` ( :pep: `613 `) to define an * explicit type alias * :
654
657
655
658
.. code-block :: python
656
-
657
- from typing import TypeAlias # or ` from typing_extensions` before `python3.10`
658
-
659
+
660
+ from typing import TypeAlias # " from typing_extensions" in Python 3.9 and earlier
661
+
659
662
class A : ...
660
663
Alias: TypeAlias = A
661
664
662
- 3. The difference is that aliases are completely known statically and can be used in type context (annotations):
665
+ You should always use ``TypeAlias `` to define a type alias in a class body or
666
+ inside a function.
667
+
668
+ The main difference is that the target of an alias is precisely known statically, and this
669
+ means that they can be used in type annotations and other *type contexts *. Type aliases
670
+ can't be defined conditionally (unless using
671
+ :ref: `supported Python version and platform checks <version_and_platform_checks >`):
663
672
664
673
.. code-block :: python
665
674
@@ -669,17 +678,18 @@ Mypy has both type aliases and variables with types like ``Type[...]`` and it is
669
678
if random() > 0.5 :
670
679
Alias = A
671
680
else :
672
- Alias = B # error: Cannot assign multiple types to name "Alias" without an explicit "Type[...]" annotation \
673
- # error: Incompatible types in assignment (expression has type "Type[B]", variable has type "Type[A]")
681
+ # error: Cannot assign multiple types to name "Alias" without an
682
+ # explicit "Type[...]" annotation
683
+ Alias = B
674
684
675
- tp: Type[object ] # tp is a type variable
685
+ tp: Type[object ] # "tp" is a variable with a type object value
676
686
if random() > 0.5 :
677
687
tp = A
678
688
else :
679
689
tp = B # This is OK
680
690
681
- def fun1 (x : Alias) -> None : ... # This is OK
682
- def fun2 (x : tp) -> None : ... # error: Variable "__main__. tp" is not valid as a type
691
+ def fun1 (x : Alias) -> None : ... # OK
692
+ def fun2 (x : tp) -> None : ... # Error: " tp" is not valid as a type
683
693
684
694
Incompatible overrides
685
695
----------------------
0 commit comments