LoginSignup
1
2

More than 1 year has passed since last update.

PEP 657 (Include Fine Grained Error Locations in Tracebacks) を読んだよメモ

Posted at

先日、PEP 657 (Include Fine Grained Error Locations in Tracebacks)Final になったという PR を見かけました。
そして、cpython に実装が取り込まれていることが確認できたので、あらためて紹介しようと思います。

概要

  • 1行で複数の処理をしている箇所でエラーが発生した際に、どの処理でエラーが発生したのか表示する
  • 表示を改善するため、Python のバイトコード命令(bytecode instructions)に(行番号に加えて)オフセット情報を追加する
  • バイトコードのサイズが約 20% 増加する (標準ライブラリでの計測値)。.pyc ファイルと消費メモリに影響する
  • 環境変数 PYTHONNODEBUGRANGES やコマンドラインオプション -Xno_debug_ranges で無効化できる

アプローチ

以下の内容のスクリプトを用意しました。2行目では多段インデックスアクセスを行っていますが、値が入っていないので TypeError が発生します。

d = dict(x=None)
d['x']['y']['z'] = 1

このスクリプトを Python 3.9.5 で実行すると TypeError が発生し、以下のようなエラーが表示されます。

$ python -V
Python 3.9.5
$ python test.py
Traceback (most recent call last):
  File "/Users/tkomiya/test.py", line 2, in <module>
    d['x']['y']['z'] = 1
TypeError: 'NoneType' object is not subscriptable

同じスクリプトを Python 3.11.0 (開発版)で実行すると、エラーが発生した箇所にアンダーラインが表示されます。

$ python3.11 -V
Python 3.11.0a0
$ python3.11 test.py
Traceback (most recent call last):
  File "/Users/tkomiya/test.py", line 2, in <module>
    d['x']['y']['z'] = 1
    ~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

なお、Python を対話モードで起動した場合はこの機能は動かないようです。

$ python3.11
Python 3.11.0a0 (heads/main:919ad53, Jul 16 2021, 11:07:03) [Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> d = dict(x=None)
>>> d['x']['y']['z'] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable

感想

  • エラー表示がかっこよくなったのはめちゃくちゃ素敵。はやく 3.11 使いたい
  • この修正はバイトコードへの属性追加であるため、エラー以外にも用途が広がる可能性はありそうです。IDE、デバッガなどでも対応してくれるとよさそう
  • pytest が対応してくれるといいなあ
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2