20170131 python3 6 pep526
Post on 07-Feb-2017
485 Views
Preview:
TRANSCRIPT
pep 526 and 周辺ツールについて2017/01/31 Python 3.6 Release Party @Yahoo!Japan
自己紹介
@Masahito
github: masahitojp
株式会社ヌーラボ所属
主に Scala(be�er Java) とJSと少々のPythonでご飯を食べています
近頃はmypyとGrumPyがお気に入り
今日話すことPEP 526 - Syntax for Variable Annotations
typing module
周辺ツール、特にmypy
PEP 526‐ Syntax for VariableAnnota�ons
PEP 526はPEP484 の拡張です。
PEP 484 ‐ Type Hint ご存知のかた?
PEP 484についてPEP-484 Type Hint(en)
@t2y さんの日本語訳も提供されてます
PEP-484 Type Hint(ja)
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
PEP484の目的としないものPython は依然として動的型付け言語のままです。 Python の作者たちは(たとえ規約としてであっても)型ヒントを必須とすることを望んではいません。
この方針は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
値を指定しなくてもよい
# pep 484child # type: bool # これはゆるされない
# pep 526child: bool # こちらはokif age < 18: child = Trueelse: child = False
これは全部同じ意味になる
# 3.6でもpep484スタイルを許す(後方互換性!hour = 24 # type: int
# 値を指定せずに定義して代入hour: int; hour = 24
hour: int = 24
variable annota�on はどこに格納される?
__annotaitons__ に格納される
>>> answer:int = 42>>> __annotations__{'answer': <class 'int'>}
クラス変数のみ格納される、インスタンス変数は無視される
>>> 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!
こんな書き方をしてもPythonとしてはゆるしてくれる
>>> alice: 'well done' = 'A+' # >>> bob: 'what a shame' = 'F-'>>> __annotations__{'alice': 'well done', 'bob': 'what a shame'}
けどPEP526ではType Hintとしてつかうことを推奨する
typing
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を使うときに実は使います
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__()'
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
周辺ツール
周辺ツール静的型チェッカー
っていうと難しく感じるかもですが要はコマンドです
mypy
pytype
IDE
PyCharm(今回は割愛
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がでる
mypypythonのレポジトリで開発されている
https://github.com/python/mypy
JukkaLさんが中心になって作成
今回は静的型チェッカーとしてのmypyについて話します
最近パッケージ名が変わった mypy-lang -> mypy
こちらはすでに3.6モードが実装済み
じつはcobertruaで吐き出すモードがあったりとCIにつっこむと嬉しいオプションもあります
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
typeshed について軽く
TypeScriptでいうところのDe�nitely TypedのPython版
mypy/pytypeはこれを利用しています
つまりこれに対応していないモジュールは実行するとエラーになります
現状(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'
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)をつくると行けそう
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)
mypy for Python3.6typeshedが対応すれば動くはず
typingで追加されたもの
時間が余ったとき用
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
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の内部では使われているので興味ある方は読んでみるとよいかと)
まとめ
PEP526で変数名にType Hintつけるのが楽になった
typingモジュールもだんだん進歩している
ぜひ mypy とかを使っていただいて、 みんなで typeshed を育てていきましょう
top related