Slide 1

Slide 1 text

mypyの10年、pyrightの5年 tyの挑戦 - 型チェッカー進化論 - Recustomer株式会社 Misato Maeda

Slide 2

Slide 2 text

本⽇お話しすること 型

Slide 3

Slide 3 text

本⽇お話しすること 人類の叡智

Slide 4

Slide 4 text

本⽇お話しすること 型は 色んなことから我々を 守ってくれます

Slide 5

Slide 5 text

1 そもそもなぜ型チェッカーが 必要なのか?

Slide 6

Slide 6 text

型チェッカーの需要 ● リファクタリングの安全性担保 ● ⾃動補完やリントの精度向上 ● テストの補完 ● 設計の明⽂化

Slide 7

Slide 7 text

2 型チェッカー誕⽣の背景

Slide 8

Slide 8 text

需要 Python が科学計算や Web開発で広く使われ始 める →コードが⼤規模化 “動的型付けでは可読性 が低く、リファクタリン グも怖い” 思想 動的⾔語の利便性を保 ちながら、静的型付け の安全性を必要な部分 にだけ導⼊する 「gradual typing」 の実験 出来事 Jukka Lehtosalo が博 ⼠研究の⼀環で mypy を開発開始 2012: mypy の誕⽣

Slide 9

Slide 9 text

需要 Python が科学計算や Web開発で広く使われ始 める →コードが⼤規模化 “動的型付けでは可読性 が低く、リファクタリン グも怖い” 思想 動的⾔語の利便性を保 ちながら、静的型付け の安全性を必要な部分 にだけ導⼊する 「gradual typing」 の実験 出来事 Jukka Lehtosalo が博 ⼠研究の⼀環で mypy を開発開始 2012: mypy の誕⽣

Slide 10

Slide 10 text

需要 Python が科学計算や Web開発で広く使われ始 める →コードが⼤規模化 “動的型付けでは可読性 が低く、リファクタリン グも怖い” 思想 動的⾔語の利便性を保 ちながら、静的型付け の安全性を必要な部分 にだけ導⼊する 「gradual typing」 の実験 出来事 Jukka Lehtosalo⽒が 博⼠研究の⼀環で mypy を開発開始 2012: mypy の誕⽣

Slide 11

Slide 11 text

需要 mypyの他にも多数の”独 ⾃チェッカー”や”独⾃表 記”が誕⽣ エコシステム全体の整合 を取るため、Python ⾔ 語⾃体に共通記法が必要 思想 静的解析(IDE補完‧ リファクタリング‧CI ⾃動検査)を最優先 型注釈はオプションと して段階的導⼊可能に 出来事 PEP 484(Type Hints) が採択される Python 3.5 に typing モジュールが追加され た 2014‒2015: 型ヒント標準化

Slide 12

Slide 12 text

需要 mypyの他にも多数の”独 ⾃チェッカー”や”独⾃表 記”が誕⽣ エコシステム全体の整合 を取るため、Python ⾔ 語⾃体に共通記法が必要 思想 静的解析(IDE補完‧ リファクタリング‧CI ⾃動検査)を最優先 型注釈はオプションと して段階的導⼊可能に 出来事 PEP 484(Type Hints) が採択される Python 3.5 に typing モジュールが追加され た 2014‒2015: 型ヒント標準化

Slide 13

Slide 13 text

需要 mypyの他にも多数の”独 ⾃チェッカー”や”独⾃表 記”が誕⽣ エコシステム全体の整合 を取るため、Python ⾔ 語⾃体に共通記法が必要 思想 静的解析(IDE補完‧ リファクタリング‧CI ⾃動検査)を最優先 型注釈はオプションと して段階的導⼊可能に 出来事 PEP 484(Type Hints) が採択される Python 3.5 に typing モジュールが追加され た 2014‒2015: 型ヒント標準化

Slide 14

Slide 14 text

時系列 2015年 typingモジュール 追加 mypy 2012年頃

Slide 15

Slide 15 text

2015年 mypyは バージョン0.2

Slide 16

Slide 16 text

2015年は Pythonの型元年ですね

Slide 17

Slide 17 text

実は Python の型の誕⽣よりも mypy のほうが古いのです

Slide 18

Slide 18 text

型元年 Python 3.5 ● typing モジュールが追加 ○ 例えば次のようなものが追加されました ■ List[T] ■ Dict[T] ■ Optional[T] ■ Union[X, Y] ■ Callable[X, Y] 今の Python では利⽤されなくなったものが 多いものの 初期には必要でした ● List[T] → list[T] ● Optional[T] → T | None ● typing.Callable → collections.abc.Callable など

Slide 19

Slide 19 text

型元年 Python 3.5 ● typing モジュールが追加 ○ NewType の追加 このように、実体は intだが、int と違う型をつくることで、意味もわかりやすく、別の型 を間違っていれるようなことも少なくなりました def create_order(order_id: OrderId) -> None OrderId = NewType(“OrderId”, int)

Slide 20

Slide 20 text

型元年 Python 3.5 ● typing モジュールが追加 ○ NewType の追加 このように、実体は intだが、int と違う型をつくることで、意味もわかりやすく、別の型 を間違っていれるようなことも少なくなりました def create_order(order_id: OrderId) -> None OrderId = NewType(“OrderId”, int) ❌ create_order(Order(1)) ✅ create_order(OrderId(1))

Slide 21

Slide 21 text

需要 外部ライブラリが型を持 たない →型チェッカーが正しく 働かない 思想 標準ライブラリや有名 パッケージの 型スタブ(.pyi)を 集約して共通利⽤ (=typeshed) 出来事 typeshed プロジェク ト誕⽣ Dropbox が 400万⾏規 模のコードに mypy を 導⼊ →リファクタリングの 安全性‧可読性向上を 実証 2015‒2019: ⼤規模利⽤と typeshed

Slide 22

Slide 22 text

需要 外部ライブラリが型を持 たない →型チェッカーが正しく 働かない 思想 標準ライブラリや有名 パッケージの 型スタブ(.pyi)を 集約して共通利⽤ (=typeshed) 出来事 typeshed プロジェク ト誕⽣ Dropbox が 400万⾏規 模のコードに mypy を 導⼊ →リファクタリングの 安全性‧可読性向上を 実証 2015‒2019: ⼤規模利⽤と typeshed

Slide 23

Slide 23 text

需要 外部ライブラリが型を持 たない →型チェッカーが正しく 働かない 思想 標準ライブラリや有名 パッケージの 型スタブ(.pyi)を 集約して共通利⽤ (=typeshed) 出来事 typeshed プロジェク ト誕⽣ Dropbox が 400万⾏規 模のコードに mypy を 導⼊ →リファクタリングの 安全性‧可読性向上を 実証 2015‒2019: ⼤規模利⽤と typeshed

Slide 24

Slide 24 text

typeshed とは? ● mypy同様に Python.org で管理されているリポジトリ ● 標準ライブラリや⼀部サードパーティ⽤の「型スタブ(.pyi)の共同保管庫」 ● ここにあるものは pip install requests-stub などとパッケージインストール できるようになっている python/typeshed には たくさんのライブラリに関する 型情報が集まっている!

Slide 25

Slide 25 text

需要 VS Code + Python拡張が 広く使われるように。 mypyをIDEに直接統合す ると”保存のたびに数⼗ 秒待たされる”ケースが 発⽣ 思想 軽量‧⾼速な解析器を 作り、⾔語サーバプロ トコル(LSP)経由で IDE と密結合 出来事 Microsoft が Pyright を公開し、VS Code の Pylance 拡張に統合。 ユーザーは設定不要で 即型検査の恩恵を受け る 2019‒2020: Pyright と IDE 即時性

Slide 26

Slide 26 text

需要 VS Code + Python拡張が 広く使われるように。 mypyをIDEに直接統合す ると”保存のたびに数⼗ 秒待たされる”ケースが 発⽣ 思想 軽量‧⾼速な解析器を 作り、⾔語サーバプロ トコル(LSP)経由で IDE と密結合 出来事 Microsoft が Pyright を公開し、VS Code の Pylance 拡張に統合。 ユーザーは設定不要で 即型検査の恩恵を受け る 2019‒2020: Pyright と IDE 即時性

Slide 27

Slide 27 text

需要 VS Code + Python拡張が 広く使われるように。 mypyをIDEに直接統合す ると”保存のたびに数⼗ 秒待たされる”ケースが 発⽣ 思想 軽量‧⾼速な解析器を 作り、⾔語サーバプロ トコル(LSP)経由で IDE と密結合 出来事 Microsoft が Pyright を公開し、VS Code の Pylance 拡張に統合。 ユーザーは設定不要で 即型検査の恩恵を受け る 2019‒2020: Pyright と IDE 即時性

Slide 28

Slide 28 text

Pyright の登場 ● 時代は VSCode 大ブーム ● Pyright は Pylance という VSCode プラグインで使われている 弊社Recustomerは VSCodeユーザーも多いこともあり Pyright と mypy の両⽅のチェック が通ることを確認しています

Slide 29

Slide 29 text

時系列 2015年 typingモジュール 追加 mypy 2012年頃 29 Pyright (Microsoft) 2019年頃

Slide 30

Slide 30 text

需要 型ヒントが冗⻑で読みに くい Union 型や Generics の 表記が複雑 思想 Python 的な書き⼼地 を保ちつつ、表現⼒を 増す 出来事 PEP 585:組込み型の ジェネリクス PEP 604: X | Y 記法 PEP 544: Protocol= 静的ダックタイピング が採⽤される 2020‒2023: 表現⼒と書き⼼地の進化

Slide 31

Slide 31 text

需要 型ヒントが冗⻑で読みに くい Union 型や Generics の 表記が複雑 思想 Python 的な書き⼼地 を保ちつつ、表現⼒を 増す 出来事 PEP 585:組込み型の ジェネリクス PEP 604: X | Y 記法 PEP 544: Protocol= 静的ダックタイピング が採⽤される 2020‒2023: 表現⼒と書き⼼地の進化

Slide 32

Slide 32 text

需要 型ヒントが冗⻑で読みに くい Union 型や Generics の 表記が複雑 思想 Python 的な書き⼼地 を保ちつつ、表現⼒を 増す 出来事 PEP 585:組込み型の ジェネリクス PEP 604: X | Y 記法 PEP 544: Protocol= 静的ダックタイピング が採⽤される 2020‒2023: 表現⼒と書き⼼地の進化

Slide 33

Slide 33 text

需要 モノレポ級の巨⼤コード でも CI と IDE でストレ スなく型チェッカーを動 作させたい 思想 Rust によるゼロから の再実装で、速度と安 全性を両⽴ 出来事 Astral が ty をプレ ビュー公開 (「Ruff/uv」の流れ を継ぐコミュニティ主 導型) 2024‒2025 Rust 実装と超⾼速化

Slide 34

Slide 34 text

需要 モノレポ級の巨⼤コード でも CI と IDE でストレ スなく型チェッカーを動 作させたい 思想 Rust によるゼロから の再実装で、速度と安 全性を両⽴ 出来事 Astral が ty をプレ ビュー公開 (「Ruff/uv」の流れ を継ぐコミュニティ主 導型) 2024‒2025 Rust 実装と超⾼速化

Slide 35

Slide 35 text

需要 モノレポ級の巨⼤コード でも CI と IDE でストレ スなく型チェッカーを動 作させたい 思想 Rust によるゼロから の再実装で、速度と安 全性を両⽴ 出来事 Astral が ty をプレ ビュー公開 (「Ruff/uv」の流れ を継ぐコミュニティ主 導型) 2024‒2025 Rust 実装と超⾼速化

Slide 36

Slide 36 text

● Rustで書かれているという「⾼速性」 ● 期待の⼤きい型チェックツール ○ しかしながら、0.0.1-alpha ○ まだ全然安定していない ty の登場

Slide 37

Slide 37 text

uv を世に届け Rustツールにより時代を変化させた Astral社がリリースした という期待 それでもtyが期待される理由

Slide 38

Slide 38 text

uv がもたらした変化 (Recustomer社⾃社の使⽤ツールの変化) 昔 近頃 Python本体管理 pyenv uv パッケージマネージャー pip, poetry uv Rustツールによる 圧倒的高速と 何でもできる強み

Slide 39

Slide 39 text

今日では88%の開発者が型チェックを 「常に」または「頻繁に」 使用している 型チェッカーの現在地 出典: https://engineering.fb.com/2024/12/09/developer-tools/typed-python-2024-survey-meta/

Slide 40

Slide 40 text

型チェッカーの現在地 型検査機構として 今尚mypyが 第一線を走っている状況

Slide 41

Slide 41 text

3 速度⽐較

Slide 42

Slide 42 text

● Python 3.12.7環境 ● timeコマンドによる実⾏時間計測 ● mypy 1.15.0, pyright 1.1.398, ty 0.0.1a19 検証環境

Slide 43

Slide 43 text

⼩規模ファイルで実験 100⾏未満の

Slide 44

Slide 44 text

mypy pyright ty 実⾏時間 0.53s 0.492 s 0.071s CPU使⽤率 98% 119% (並列処理) 83% ⼩規模ファイル実験結果 ≒ >

Slide 45

Slide 45 text

⼤規模ファイルで実験 10,000⾏を超えるファイルならどうか?

Slide 46

Slide 46 text

mypy pyright ty 実⾏時間 21.839s 3.652s 0.204s CPU使⽤率 97% 245% (並列処理) 371% (並列処理) ⼤規模ファイル実験結果 (26ファイル、13,795行 での結果)

Slide 47

Slide 47 text

mypy pyright ty 実⾏時間 21.839s 3.652s 0.204s CPU使⽤率 97% 245% (並列処理) 371% (並列処理) ⼤規模ファイル実験結果 ⼤規模ファイルで ⼒を発揮 圧倒的速さ

Slide 48

Slide 48 text

4 エラー表⽰⽐較

Slide 49

Slide 49 text

テストコード def calculate_price(base: float, tax_rate: float) -> int: """税込み価格を計算""" total = base * (1 + tax_rate) return total # エラー: float を int として返している

Slide 50

Slide 50 text

mypy

Slide 51

Slide 51 text

mypy ● 出⼒はシンプル ● 型の不⼀致だけを伝える

Slide 52

Slide 52 text

mypy 補⾜ % makers mypy --pretty [cargo-make] INFO - makers 0.37.15 [cargo-make] INFO - Build File: Makefile.toml [cargo-make] INFO - Task: mypy [cargo-make] INFO - Profile: development [cargo-make] INFO - Execute Command: "uv" "run" "mypy" "." "--pretty" zlatan/services/utils.py:18: error: Incompatible return value type (got "str", expected "int") [return-value] return token ^~~~~ Found 1 error in 1 file (checked 569 source files) Error while executing command, exit code: 1

Slide 53

Slide 53 text

mypy 補⾜ % makers mypy --pretty [cargo-make] INFO - makers 0.37.15 [cargo-make] INFO - Build File: Makefile.toml [cargo-make] INFO - Task: mypy [cargo-make] INFO - Profile: development [cargo-make] INFO - Execute Command: "uv" "run" "mypy" "." "--pretty" zlatan/services/utils.py:18: error: Incompatible return value type (got "str", expected "int") [return-value] return token ^~~~~ Found 1 error in 1 file (checked 569 source files) Error while executing command, exit code: 1 ● —prettty optionを使えば⼀応視覚的に表⽰可能

Slide 54

Slide 54 text

pyright

Slide 55

Slide 55 text

pyright ● 説明の粒度はmypyよりも具体的 ● コードのどこか(ファイル名と⾏番号)を指すが、⽮印や コードの抜粋は出さない

Slide 56

Slide 56 text

ty

Slide 57

Slide 57 text

ty ● 該当コードを抜粋して表⽰し、⽮印(^^^^^)で問題箇所 を⽰す ● Rust コンパイラ⾵のより視覚的にわかりやすい表現

Slide 58

Slide 58 text

5 型推論能⼒⽐較

Slide 59

Slide 59 text

ここまでtyの感動を お届けしてきましたが

Slide 60

Slide 60 text

現バージョンの tyは 全然動きません

Slide 61

Slide 61 text

mypy pyright いつものプロジェクトで 型チェック実⾏結果 ● ともにstrictモードで実⾏ ● ✅エラー無し

Slide 62

Slide 62 text

strictモード ● mypy ○ 型アノテーションのない関数定義を禁⽌ など →型アノテーション必須化してAnyを減らす ● pyright ○ 型が不明, 誤⽤ならエラーにする など →Unknown を許さず推論漏れを検出

Slide 63

Slide 63 text

ty いつものプロジェクトで 型チェック実⾏結果 ● ⚠ 49ものエラーが誤検出

Slide 64

Slide 64 text

例えば ● 複雑な外部型定義ファイルのオーバーロード解析 ができない ○ オーバーロードのパターンマッチングができずに誤検知 ● tyの環境認識バグ ○ ライブラリは正しくインストールされていて、実際にインポー トも成功するが、tyが認識できていない

Slide 65

Slide 65 text

mypy pyright おまけ Python typing (PEP) の仕様に忠実 特殊なライブラリに対 するプラグインが利⽤ できる (ex Django) 型推論が強⼒で、暗黙的な Any や None ミスに厳しい mypyが発⾒できないエ ラーを検出することもある

Slide 66

Slide 66 text

6 結論

Slide 67

Slide 67 text

結論 (現時点では) mypyの利⽤が最もおすすめ

Slide 68

Slide 68 text

結論 (余裕があれば) pyrightの併⽤を推奨

Slide 69

Slide 69 text

結論 まだまだこれからなtyを 引き続き⾒守っていきましょう!

Slide 70

Slide 70 text

私は知っているかのように 喋りましたが ところで…

Slide 71

Slide 71 text

実はPython歴1年です

Slide 72

Slide 72 text

このような知識が学べる 会社Recustomer ご興味ありましたら 是非入社してください!