Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a68742b

Browse files
committed
Split documentation into multiple subpages
1 parent 3bbba8c commit a68742b

15 files changed

Lines changed: 880 additions & 2 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Additional features
2+
-------------------
3+
4+
Several mypy features are not currently covered by this tutorial, including the following:
5+
6+
- inheritance between generic classes
7+
- compatibility and subtyping of generic types, including covariance of generic types
8+
- super()

docs/source/basics.rst

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
Basics
2+
======
3+
4+
Function Signatures
5+
*******************
6+
7+
A function without a type signature is dynamically typed. You can declare the signature of a function using the Python 3 annotation syntax This makes the function statically typed (the type checker reports type errors within the function):
8+
9+
.. code-block:: python
10+
11+
# Dynamically typed (identical to Python)
12+
13+
def greeting(name):
14+
return 'Hello, {}'.format(name)
15+
16+
.. code-block:: python
17+
18+
# Statically typed (still valid Python)
19+
20+
def greeting(name: str) -> str:
21+
return 'Hello, {}'.format(name)
22+
23+
A None return type indicates a function that does not explicitly return a value. Using a None result in a statically typed context results in a type check error:
24+
25+
.. code-block:: python
26+
27+
def p() -> None:
28+
print('hello')
29+
30+
a = p() # Type check error: p has None return value
31+
32+
The typing module
33+
*****************
34+
35+
We cheated a bit in the above examples: a module is type checked only if it imports the module typing. Here is a complete statically typed example from the previous section:
36+
37+
.. code-block:: python
38+
39+
import typing
40+
41+
def greeting(name: str) -> str:
42+
return 'Hello, {}'.format(name)
43+
44+
The typing module contains many definitions that are useful in statically typed code. You can also use from ... import to import them (we'll explain Iterable later in this document):
45+
46+
.. code-block:: python
47+
48+
from typing import Iterable
49+
50+
def greet_all(names: Iterable[str]) -> None:
51+
for name in names:
52+
print('Hello, {}'.format(name))
53+
54+
For brevity, we often omit the typing import in code examples, but you should always include it in modules that contain statically typed code.
55+
56+
You can still have dynamically typed functions in modules that import typing:
57+
58+
.. code-block:: python
59+
60+
import typing
61+
62+
def f():
63+
1 + 'x' # No static type error (dynamically typed)
64+
65+
def g() -> None:
66+
1 + 'x' # Type check error (statically typed)
67+
68+
Mixing dynamic and static typing within a single file is often useful. For example, if you are migrating existing Python code to static typing, it may be easiest to do this incrementally, such as by migrating a few functions at a time. Also, when prototyping a new feature, you may decide to first implement the relevant code using dynamic typing and only add type signatures later, when the code is more stable.
69+
70+
.. note::
71+
72+
Currently the type checker checks the top levels and annotated functions of all modules, even those that don't import typing. However, you should not rely on this, as this will change in the future.
73+
74+
Type checking and running programs
75+
**********************************
76+
77+
You can type check a program by using the mypy tool, which is basically a linter — it checks you program for errors without actually running it::
78+
79+
$ mypy program.py
80+
81+
You can always run a mypy program as a Python program, without type checking, even it it has type errors::
82+
83+
$ python3 program.py
84+
85+
All errors reported by mypy are essentially warnings that you are free to ignore, if you so wish.
86+
87+
The `README <https://github.com/JukkaL/mypy/blob/master/README.md>`_ explains how to download and install mypy.
88+
89+
.. note::
90+
91+
Depending on how mypy is configured, you may have to explicitly use the Python interpreter to run mypy. The mypy tool is an ordinary mypy (and so also Python) program.

docs/source/builtin_types.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Built-in types
2+
==============
3+
4+
These are examples of some of the most common built-in types:
5+
6+
.. code-block:: python
7+
8+
int # integer objects of arbitrary size
9+
float # floating point number
10+
bool # boolean value
11+
str # unicode string
12+
bytes # 8-bit string
13+
object # the common base class
14+
List[str] # list of str objects
15+
Dict[str, int] # dictionary from str to int
16+
Iterable[int] # iterable object containing ints
17+
Sequence[bool] # sequence of booleans
18+
Any # dynamically typed value
19+
20+
The type Any and type constructors List, Dict, Iterable and Sequence are defined in the typing module.
21+
22+
The type Dict is a *generic* class, signified by type arguments within [...]. For example, Dict[int, str] is a dictionary from integers to strings and and Dict[Any, Any] is a dictionary of dynamically typed (arbitrary) values and keys. List is another generic class. Dict and List are aliases for the built-ins dict and list, respectively.
23+
24+
Iterable and Sequence are generic abstract base classes that correspond to Python protocols. For example, a str object is valid when Iterable[str] or Sequence[str] is expected. Note that even though they are similar to abstract base classes defined in abc.collections (formerly collections), they are not identical, since the built-in collection type objects do not support indexing.

docs/source/casts.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Casts
2+
=====
3+
4+
Mypy supports type casts that are usually used to coerce a statically typed value to a subtype. Unlike languages such as Java or C#, however, mypy casts are only used as hints for the type checker when using Python semantics, and they have no runtime effect. Use the function cast to perform a cast:
5+
6+
.. code-block:: python
7+
8+
from typing import cast
9+
10+
o = [1] # type: object
11+
x = cast(List[int], o) # OK
12+
y = cast(List[str], o) # OK (cast performs no actual runtime check)
13+
14+
Supporting runtime checking of casts such as the above when using Python semantics would require emulating reified generics and this would be difficult to do and would likely degrade performance and make code more difficult to read. You should not rely in your programs on casts being checked at runtime. Use an assertion if you want to perform an actual runtime check. Casts are used to silence spurious type checker warnings.
15+
16+
You don't need a cast for expressions with type Any, of when assigning to a variable with type Any, as was explained earlier.
17+
18+
You can cast to a dynamically typed value by just calling Any:
19+
20+
.. code-block:: python
21+
22+
from typing import Any
23+
24+
def f(x: object) -> None:
25+
Any(x).foo() # OK

docs/source/class_basics.rst

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
Class basics
2+
============
3+
4+
Instance and class attributes
5+
*****************************
6+
7+
Mypy type checker detects if you are trying to access a missing attribute, which is a very common programming error. For this to work correctly, instance and class attributes must be defined or initialized within the class. Mypy infers the types of attributes:
8+
9+
.. code-block:: python
10+
11+
class A:
12+
def __init__(self, x: int) -> None:
13+
self.x = x # Attribute x of type int
14+
15+
a = A(1)
16+
a.x = 2 # OK
17+
a.y = 3 # Error: A has no attribute y
18+
19+
This is a bit like each class having an implicitly defined __slots__ attribute. In Python semantics this is only enforced during type checking: at runtime we use standard Python semantics. You can selectively define a class as *dynamic*; dynamic classes have Python-like compile-time semantics, and they allow you to assign to arbitrary attributes anywhere in a program without the type checker complaining:
20+
21+
.. code-block:: python
22+
23+
from typing import Dynamic
24+
25+
class A(Dynamic):
26+
pass
27+
28+
a = A()
29+
a.x = 2 # OK, no need to define x explicitly.
30+
31+
Mypy also lets you read arbitrary attributes of dynamic class instances. This limits type checking effectiveness, so you should only use dynamic classes when you really need them.
32+
33+
.. note::
34+
35+
Dynamic classes are not implemented in the current mypy version.
36+
37+
You can declare variables in the class body explicitly using Undefined or a type comment:
38+
39+
.. code-block:: python
40+
41+
class A:
42+
x = Undefined(List[int]) # Declare attribute y of type List[int]
43+
y = 0 # type: Any # Declare attribute x of type Any
44+
45+
a = A()
46+
a.x = [1] # OK
47+
48+
As in Python, a variable defined in the class body can used as a class or an instance variable.
49+
50+
Similarly, you can give explicit types to instance variables defined in a method:
51+
52+
.. code-block:: python
53+
54+
class A:
55+
def __init__(self) -> None:
56+
self.x = Undefined(List[int]) # OK
57+
58+
def f(self) -> None:
59+
self.y = 0 # type: Any # OK
60+
61+
You can only define an instance variable within a method if you assign to it explicitly using self:
62+
63+
.. code-block:: python
64+
65+
class A:
66+
def __init__(self) -> None:
67+
self.y = 1 # Define y
68+
a = self
69+
a.x = 1 # Error: x not defined
70+
71+
Overriding statically typed methods
72+
***********************************
73+
74+
When overriding a statically typed method, mypy checks that the override has a compatible signature:
75+
76+
.. code-block:: python
77+
78+
class A:
79+
def f(self, x: int) -> None:
80+
...
81+
82+
class B(A):
83+
def f(self, x: str) -> None: # Error: type of x incompatible
84+
...
85+
86+
class C(A):
87+
def f(self, x: int, y: int) -> None: # Error: too many arguments
88+
...
89+
90+
class D(A):
91+
def f(self, x: int) -> None: # OK
92+
...
93+
94+
.. note::
95+
96+
You can also vary return types **covariantly** in overriding. For example, you could override the return type 'object' with a subtype such as 'int'.
97+
98+
You can also override a statically typed method with a dynamically typed one. This allows dynamically typed code to override methods defined in library classes without worrying about their type signatures, similar to Python.
99+
100+
There is no runtime enforcement that the method override returns a value that is compatible with the original return type, since types are erased in the Python semantics:
101+
102+
.. code-block:: python
103+
104+
class A:
105+
def inc(self, x: int) -> int:
106+
return x + 1
107+
108+
class B(A):
109+
def inc(self, x): # Override, dynamically typed
110+
return 'hello'
111+
112+
b = B()
113+
print(b.inc(1)) # hello
114+
a = b # type: A
115+
print(a.inc(1)) # hello
116+
117+
Abstract base classes and multiple inheritance
118+
**********************************************
119+
120+
Mypy uses Python abstract base classes for protocol types. There are several built-in abstract base classes types (for example, Sequence, Iterable and Iterator). You can define abstract base classes using the abc.ABCMeta metaclass and the abc.abstractmethod function decorator.
121+
122+
.. code-block:: python
123+
124+
from abc import ABCMeta, abstractmethod
125+
import typing
126+
127+
class A(metaclass=ABCMeta):
128+
@abstractmethod
129+
def foo(self, x: int) -> None: pass
130+
131+
@abstractmethod
132+
def bar(self) -> str: pass
133+
134+
class B(A):
135+
def foo(self, x: int) -> None: ...
136+
def bar(self -> str:
137+
return 'x'
138+
139+
a = A() # Error: A is abstract
140+
b = B() # OK
141+
142+
Unlike most Python code, abstract base classes are likely to play a significant role in many complex mypy programs.
143+
144+
A class can inherit any number of classes, both abstract and concrete. As with normal overrides, a dynamically typed method can implement a statically typed abstract method defined in an abstract base class.
145+
146+
.. note::
147+
148+
There are also plans to support more Python-style "duck typing" in the type system. The details are still open.

docs/source/common_issues.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Common issues
2+
=============
3+
4+
Statically typed function bodies are often identical to normal Python code, but sometimes you need to do things slightly differently. This section introduces some of the most common cases which require different conventions in statically typed code.
5+
6+
First, you need to specify the type when creating an empty list or dict and when you assign to a new variable, as mentioned earlier:
7+
8+
.. code-block:: python
9+
10+
a = List[int]() # Explicit type required in statically typed code
11+
a = [] # Fine in a dynamically typed function, or if type
12+
# of a has been declared or inferred before
13+
14+
Sometimes you can avoid the explicit list item type by using a list comprehension. Here a type annotation is needed:
15+
16+
.. code-block:: python
17+
18+
l = List[int]()
19+
for i in range(n):
20+
l.append(i * i)
21+
22+
.. note::
23+
24+
A future mypy version may be able to deal with cases such as the above without type annotations.
25+
26+
No type annotation needed if using a list comprehension:
27+
28+
.. code-block:: python
29+
30+
l = [i * i for i in range(n)]
31+
32+
However, in more complex cases the explicit type annotation can improve the clarity of your code, whereas a complex list comprehension can make your code difficult to understand.
33+
34+
Second, each name within a function only has a single type. You can reuse for loop indices etc., but if you want to use a variable with multiple types within a single function, you may need to declare it with the Any type.
35+
36+
.. code-block:: python
37+
38+
def f() -> None:
39+
n = 1
40+
...
41+
n = x # Type error: n has type int
42+
43+
.. note::
44+
45+
This is another limitation that could be lifted in a future mypy version.
46+
47+
Third, sometimes the inferred type is a subtype of the desired type. The type inference uses the first assignment to infer the type of a name:
48+
49+
.. code-block:: python
50+
51+
# Assume Shape is the base class of both Circle and Triangle.
52+
shape = Circle() # Infer shape to be Circle
53+
...
54+
shape = Triangle() # Type error: Triangle is not a Circle
55+
56+
You can just give an explicit type for the variable in cases such the above example:
57+
58+
.. code-block:: python
59+
60+
shape = Circle() # type: Shape # The variable s can be any Shape,
61+
# not just Circle
62+
...
63+
shape = Triangle() # OK
64+
65+
Fourth, if you use isinstance tests or other kinds of runtime type tests, you may have to add casts (this is similar to instanceof tests in Java):
66+
67+
.. code-block:: python
68+
69+
def f(o: object) -> None:
70+
if isinstance(o, int):
71+
n = cast(int, o)
72+
n += 1 # o += 1 would be an error
73+
...
74+
75+
Note that the object type used in the above example is similar to Object in Java: it only supports operations defined for all objects, such as equality and isinstance(). The type Any, in contrast, supports all operations, even if they may fail at runtime. The cast above would have been unnecessary if the type of o was Any.
76+
77+
Some consider casual use of isinstance tests a sign of bad programming style. Often a method override or an overloaded function is a cleaner way of implementing functionality that depends on the runtime types of values. However, use whatever techniques that work for you. Sometimes isinstance tests *are* the cleanest way of implementing a piece of functionality.
78+
79+
Type inference in mypy is designed to work well in common cases, to be predictable and to let the type checker give useful error messages. More powerful type inference strategies often have complex and difficult-to-prefict failure modes and could result in very confusing error messages.

0 commit comments

Comments
 (0)