20170131 python3 6 pep526

35
pep 526 and 周辺ツールについて 2017/01/31 Python 3.6 Release Party @Yahoo!Japan

Upload: masahitojp

Post on 07-Feb-2017

484 views

Category:

Engineering


5 download

TRANSCRIPT

Page 1: 20170131 python3 6 PEP526

pep 526 and 周辺ツールについて2017/01/31 Python 3.6 Release Party @Yahoo!Japan

Page 2: 20170131 python3 6 PEP526

自己紹介

@Masahito

github: masahitojp

株式会社ヌーラボ所属

主に Scala(be�er Java) とJSと少々のPythonでご飯を食べています

近頃はmypyとGrumPyがお気に入り

Page 3: 20170131 python3 6 PEP526
Page 4: 20170131 python3 6 PEP526

今日話すことPEP 526 - Syntax for Variable Annotations

typing module

周辺ツール、特にmypy

Page 5: 20170131 python3 6 PEP526

PEP 526‐ Syntax for VariableAnnota�ons

Page 6: 20170131 python3 6 PEP526

PEP 526はPEP484 の拡張です。

Page 7: 20170131 python3 6 PEP526

PEP 484 ‐ Type Hint ご存知のかた?

Page 8: 20170131 python3 6 PEP526

PEP 484についてPEP-484 Type Hint(en)

@t2y さんの日本語訳も提供されてます

PEP-484 Type Hint(ja)

Page 9: 20170131 python3 6 PEP526

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

PEP484の目的としないものPython は依然として動的型付け言語のままです。 Python の作者たちは(たとえ規約としてであっても)型ヒントを必須とすることを望んではいません。

Page 11: 20170131 python3 6 PEP526

この方針はPEP526でも同じです。

Page 12: 20170131 python3 6 PEP526

じゃーなにが追加になったの?

Page 13: 20170131 python3 6 PEP526

変数に対して型付けする構文が追加になった

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

値を指定しなくてもよい

# pep 484child # type: bool # これはゆるされない

# pep 526child: bool # こちらはokif age < 18: child = Trueelse: child = False

Page 15: 20170131 python3 6 PEP526

これは全部同じ意味になる

# 3.6でもpep484スタイルを許す(後方互換性!hour = 24 # type: int

# 値を指定せずに定義して代入hour: int; hour = 24

hour: int = 24

Page 16: 20170131 python3 6 PEP526

variable annota�on はどこに格納される?

__annotaitons__ に格納される

>>> answer:int = 42>>> __annotations__{'answer': <class 'int'>}

Page 17: 20170131 python3 6 PEP526

クラス変数のみ格納される、インスタンス変数は無視される

>>> 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

こんな書き方をしても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

typing

Page 20: 20170131 python3 6 PEP526

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

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

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

周辺ツール

Page 24: 20170131 python3 6 PEP526

周辺ツール静的型チェッカー

っていうと難しく感じるかもですが要はコマンドです

mypy

pytype

IDE

PyCharm(今回は割愛

Page 25: 20170131 python3 6 PEP526

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

mypypythonのレポジトリで開発されている

https://github.com/python/mypy

JukkaLさんが中心になって作成

今回は静的型チェッカーとしてのmypyについて話します

最近パッケージ名が変わった  mypy-lang -> mypy

こちらはすでに3.6モードが実装済み

じつはcobertruaで吐き出すモードがあったりとCIにつっこむと嬉しいオプションもあります

Page 27: 20170131 python3 6 PEP526

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

typeshed について軽く

TypeScriptでいうところのDe�nitely TypedのPython版

mypy/pytypeはこれを利用しています

つまりこれに対応していないモジュールは実行するとエラーになります

Page 29: 20170131 python3 6 PEP526

現状(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

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

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

mypy for Python3.6typeshedが対応すれば動くはず

typingで追加されたもの

Page 33: 20170131 python3 6 PEP526

時間が余ったとき用

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

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

まとめ

PEP526で変数名にType Hintつけるのが楽になった

typingモジュールもだんだん進歩している

ぜひ mypy とかを使っていただいて、  みんなで typeshed を育てていきましょう