11. mypy command
$ time mypy --no-incremental sphinx
real 0m21.968s
user 0m20.986s
sys 0m0.769s
$ time mypy --follow-imports=error sphinx
sphinx/events.py: note: In member "disconnect" of class "EventManager":
sphinx/events.py:71:5: error: Missing return statement
real 0m16.784s
user 0m16.366s
sys 0m0.361s
12. mypy daemon
$ dmypy start -- --follow-imports=error
Daemon started
$ ps ax|grep dmypy
59452 ?? S 0:00.00 path/to/dmypy start -- --follow-imports=error
$ time dmypy check sphinx
real 0m20.714s
user 0m0.116s
sys 0m0.035s
$ time dmypy check sphinx
Daemon crashed!
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'type_vars'
エラーになって計測できなかった。。。
18. NamedTuple(2)
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(x=1, y=2)
print(p.z) # Error: Point has no attribute 'z'
from typing import NamedTuple
Point = NamedTuple('Point', [('x', int), ('y', int)])
p = Point(x=1, y='x')
# Error: Argument has incompatible type "str"; expected "int"
19. NamedTuple(3)
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
p = Point(x=1, y='x')
# Error: Argument has incompatible type "str"; expected "int"
3.6 からクラス構文でも定義できる
NamedTuple の型定義は継承できない
21. NewType(2)
class UserId(int):
pass
def name_by_id(user_id: UserId) -> str:
...
from typing import NewType
UserId = NewType('UserId', int)
UserId('user')
# error: Argument 1 to "UserId" has incompatible type "str"; expected "int"
name_by_id(42)
# error: Argument 1 to "name_by_id" has incompatible type "int"; expected "UserId"
name_by_id(UserId(42)) # OK
num = UserId(5) + 1 # type: int
22. NewType の実装
def NewType(name, tp):
"""NewType creates simple unique types with almost zero
runtime overhead. NewType(name, tp) is considered a subtype of tp
by static type checkers. At runtime, NewType(name, tp) returns
a dummy function that simply returns its argument. Usage::
"""
def new_type(x):
return x
new_type.__name__ = name
new_type.__supertype__ = tp
return new_type
23. ソースファイルのオーバーロード
●
当初 PEP 484 では @overload デコレーターは
スタブファイルのみでのサポートと記述されて
いたが、その制約は見直された
– Relax constraints on @overload. It may occur in
modules if followed by a non-@overload version.
●
ソースコードにも記述して mypy で型チェック
できるようになった
●
Union 型では厳密に定義できないときがある
●
mypy 0.510 でサポート
24. リストの添字アクセス (Union)
from typing import Sequence, TypeVar, Union
T = TypeVar('T')
class MyList(Sequence[T]):
def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]:
if isinstance(index, int):
... # Return a T here
elif isinstance(index, slice):
... # Return a sequence of Ts here
else:
raise TypeError(...)
リストの添字アクセス
- インデックス値かスライスを指定したら T か Sequence[T] を返す
25. リストの添字アクセス (overload)
リストの添字アクセス
- インデックス値を指定したら T を返す
- スライスを指定したら Sequence[T] を返す
from typing import overload, Sequence, TypeVar, Union
T = TypeVar('T')
class MyList(Sequence[T]):
@overload
def __getitem__(self, index: int) -> T:
pass # Don't put code here
@overload
def __getitem__(self, index: slice) -> Sequence[T]:
pass # Don't put code here
35. 前方参照のコード例
class A:
def f(self):
return B()
b = B() # NameError: name 'B' is not defined
def f():
b = B()
f() # NameError: name 'B' is not defined
a = A()
a.f() # NameError: name 'B' is not defined
class B:
pass
36. 前方参照の型アノテーション
( 型アノテーションのみサポート )
from __future__ import annotations
class C:
field = 'c_field'
def method(self) -> C.field:... # this is OK
def method(self) -> field:... # this is OK
def method(self) -> C.D:... # this is OK
def method(self) -> D:... # this is OK
class D:
field2 = 'd_field'
def method(self) -> C.D.field2:... # this is OK
def method(self) -> D.field2:... # this is OK
def method(self) -> field2:... # this is OK
def method(self) -> field:... # this FAILS, class D doesn't
# see C's attributes, This was
# already true before this PEP.
70. 型ヒント
●
What is Gradual Typing: 漸進的型付けとは何か
●
PEP
– [翻訳] PEP 0484 -- 型ヒント (Type Hints)
●
Python と型ヒント (Type Hints) と #pyconjp
– PEP 526 -- Syntax for Variable Annotations
– PEP 544 -- Protocols: Structural subtyping (static duck typing)
– PEP 560 -- Core support for typing module and generic types
– PEP 561 -- Distributing and Packaging Type Information
– PEP 563 -- Postponed Evaluation of Annotations
●
[翻訳] Python の静的型、すごい mypy!