Download - 20170131 python3 6 PEP526
![Page 1: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/1.jpg)
pep 526 and 周辺ツールについて2017/01/31 Python 3.6 Release Party @Yahoo!Japan
![Page 2: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/2.jpg)
自己紹介
@Masahito
github: masahitojp
株式会社ヌーラボ所属
主に Scala(be�er Java) とJSと少々のPythonでご飯を食べています
近頃はmypyとGrumPyがお気に入り
![Page 3: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/3.jpg)
![Page 4: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/4.jpg)
今日話すことPEP 526 - Syntax for Variable Annotations
typing module
周辺ツール、特にmypy
![Page 5: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/5.jpg)
PEP 526‐ Syntax for VariableAnnota�ons
![Page 6: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/6.jpg)
PEP 526はPEP484 の拡張です。
![Page 7: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/7.jpg)
PEP 484 ‐ Type Hint ご存知のかた?
![Page 8: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/8.jpg)
PEP 484についてPEP-484 Type Hint(en)
@t2y さんの日本語訳も提供されてます
PEP-484 Type Hint(ja)
![Page 9: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/9.jpg)
PEP484について軽く説明PEP 3107 Function Annotations ってのがPythonに入ってPythonの関数に、任意のメタデータを追加するための構文を導入する
def compile(source: "something compilable", filename: "where the compilable thing comes from", mode: "is this a single statement or a suite?"):
PEP3107 では特に意味づけがなかったものを Type Hint として使おうっていうのがPEP484です
def greeting(name: str) -> str: return 'Hello ' + name
![Page 10: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/10.jpg)
PEP484の目的としないものPython は依然として動的型付け言語のままです。 Python の作者たちは(たとえ規約としてであっても)型ヒントを必須とすることを望んではいません。
![Page 11: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/11.jpg)
この方針はPEP526でも同じです。
![Page 12: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/12.jpg)
じゃーなにが追加になったの?
![Page 13: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/13.jpg)
変数に対して型付けする構文が追加になった
from typing import List
# pep 484a = [1,2,3] # type: List[int]
# We should add *comments*path = None # type: Optional[str] # Path to module source
# pep 526a: List[int] = [1,2,3]path: Optional[str] = None # Path to module sourde
![Page 14: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/14.jpg)
値を指定しなくてもよい
# pep 484child # type: bool # これはゆるされない
# pep 526child: bool # こちらはokif age < 18: child = Trueelse: child = False
![Page 15: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/15.jpg)
これは全部同じ意味になる
# 3.6でもpep484スタイルを許す(後方互換性!hour = 24 # type: int
# 値を指定せずに定義して代入hour: int; hour = 24
hour: int = 24
![Page 16: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/16.jpg)
variable annota�on はどこに格納される?
__annotaitons__ に格納される
>>> answer:int = 42>>> __annotations__{'answer': <class 'int'>}
![Page 17: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/17.jpg)
クラス変数のみ格納される、インスタンス変数は無視される
>>> class Car:... stats: ClassVar[Dict[str, int]] = {}... def __init__(self) -> None:... self.seats = 4>>> c: Car = Car()>>> c.__annotations__{'stats': typing.ClassVar[typing.Dict[str, int]]}# only ClassVar!
![Page 18: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/18.jpg)
こんな書き方をしてもPythonとしてはゆるしてくれる
>>> alice: 'well done' = 'A+' # >>> bob: 'what a shame' = 'F-'>>> __annotations__{'alice': 'well done', 'bob': 'what a shame'}
けどPEP526ではType Hintとしてつかうことを推奨する
![Page 19: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/19.jpg)
typing
![Page 20: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/20.jpg)
typing moduleとはPython 3.5でPEP484が実装された時に入ったモジュール
DictとかTupleとかListみたいなbuild inのものはすでにこのモジュールで定義されている
from typing import Dict, Tuple, List
ConnectionOptions : Dict[str, str]Address : Tuple[str, int]Server : Tuple[Address, ConnectionOptions]
もちろんドキュメントも https://docs.python.org/3/library/typing.html
pip install typing python2でもつかえる, mypyのpy2modeを使うときに実は使います
![Page 21: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/21.jpg)
typing moduleの変更点
Collection
ContextManager
withで実行されるような型
class Context(object):
def __init__(self): print '__init__()'
def __enter__(self): print '__enter__()' return self def __exit__(self, exc_type, exc_val, exc_tb): print '__exit__()'
![Page 22: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/22.jpg)
NamedTuple
Point = namedtuple('Point', ['x', 'y'])p = Point(x=1, y=2)print(p.z) # Error: Point has no attribute 'z'
Python 3.6 で以下のようにかけるようになった
from typing import NamedTuple
class Point(NamedTuple): x: int y: int
![Page 23: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/23.jpg)
周辺ツール
![Page 24: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/24.jpg)
周辺ツール静的型チェッカー
っていうと難しく感じるかもですが要はコマンドです
mypy
pytype
IDE
PyCharm(今回は割愛
![Page 25: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/25.jpg)
pytypegoogleのリポジトリで開発されてる
Matthias Kramm(さんが一人でやってるっぽい
https://github.com/google/pytype
いまはPython2.7でのみ動く
けど、3.4/3.5モードで動かして型チェックすることも可能
pytype -V 3.5 program.py
PEP526のチェックもmasterブランチでは実装されてるが、いまのところ3.6モードはない
Magic Exceptionがでる
![Page 26: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/26.jpg)
mypypythonのレポジトリで開発されている
https://github.com/python/mypy
JukkaLさんが中心になって作成
今回は静的型チェッカーとしてのmypyについて話します
最近パッケージ名が変わった mypy-lang -> mypy
こちらはすでに3.6モードが実装済み
じつはcobertruaで吐き出すモードがあったりとCIにつっこむと嬉しいオプションもあります
![Page 27: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/27.jpg)
mypyfrom typing import Dict, NamedTuple
class Car: stats: Dict[str, int] = {} def __init__(self) -> None: self.seats = 4 class Employee(NamedTuple): name: str id: int
c: Car = Car()# print(c.__annotations__)employee = Employee(name='Guido', id='x')
mypy --fast-parser --python-version 3.6 example.pyexample.py:16: error: Argument 2 to "Employee" has incompatible type "str"; expected
![Page 28: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/28.jpg)
typeshed について軽く
TypeScriptでいうところのDe�nitely TypedのPython版
mypy/pytypeはこれを利用しています
つまりこれに対応していないモジュールは実行するとエラーになります
![Page 29: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/29.jpg)
現状(py36-mypy)~/s/p/try-pep526> cat collection.py
from typing import Collection
a: Collection[int] = [3,2,1]a.append(1)
(py36-mypy)~/s/p/try-pep526> mypy --fast-parser --python-version 3.6 collection.collection.py:2: error: Module 'typing' has no attribute 'Collection'
![Page 30: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/30.jpg)
typeshedとtypingモジュールの状況
typeshedのtypingモジュールは3.5までしか対応してません orz
そのため, いかのモジュールをimportすると定義されてないよエラーが
typing.ClassVar -> PEP526に書かれてるんだけどなぁ。。。。
https://github.com/python/typeshed/pull/889 無事近頃ttypeshedにはとりこまれた模様
typing.Collection -> Listとかで代用
typing.CotextManager -> ...
一応自分で定義(.ipr)をつくると行けそう
![Page 31: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/31.jpg)
mypy for Python 3.6構文追加系は動くのでぜひ使ってみるといいのではhttp://mypy.readthedocs.io/en/latest/python36.html
動く
PEP526対応済み(ただしClassVarはまだ
Underscores in numeric literals (PEP 515) e.g. million = 1_000_000
NamedTuple
未実装
Asynchronous generators (PEP 525)
Asynchronous comprehensions (PEP 530)
![Page 32: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/32.jpg)
mypy for Python3.6typeshedが対応すれば動くはず
typingで追加されたもの
![Page 33: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/33.jpg)
時間が余ったとき用
typingにはじつは _Protocol ってのが存在してる
Protocols (a.k.a. structural subtyping)要はこんな感じであるメソッドが実装されている型を新しくつくれるといいねっていう提案、mypy作者とGuido(!)を中心に議論
class Sized(Protocol): @abstractmethod def __len__(self) -> int: pass # __len__は特殊メソッド def hoge(l : Sized) -> int: return len(l) + 1
![Page 34: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/34.jpg)
PEP 526が入ったことでこういうのもProtocolっぽく動くよねっていう議論が
class Point(<some magical base class): x: float y: float z: float = 0
class MyPoint: # unrelated to Point def __init__(self, x: float, y: float): self.x, self.y = x, yp = MyPoint(1, 2)
とこんな感じでまだ固まってないので typing.Protocol が使えるのはまだ先のようです。(typingの内部では使われているので興味ある方は読んでみるとよいかと)
![Page 35: 20170131 python3 6 PEP526](https://reader034.vdocuments.net/reader034/viewer/2022052318/5899b72e1a28aba11e8b60f9/html5/thumbnails/35.jpg)
まとめ
PEP526で変数名にType Hintつけるのが楽になった
typingモジュールもだんだん進歩している
ぜひ mypy とかを使っていただいて、 みんなで typeshed を育てていきましょう