残念ながら、コンパイルされたバイトコードは列オフセットを失いました。バイトコード インデックスから行番号へのマッピングは、co_lnotab
行番号テーブルに含まれています。dis
モジュールは、バイトコードを見て解釈する良い方法ですco_lnotab
:
>>> dis.dis(compile('a, b, c', '', 'eval'))
1 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 LOAD_NAME 2 (c)
9 BUILD_TUPLE 3
12 RETURN_VALUE
^-- line number
ただし、行番号をいじるのを止めるものは何もありません。
>>> a = ast.parse('a, b, c', mode='eval')
>>> for n in ast.walk(a):
... if hasattr(n, 'col_offset'):
... n.lineno = n.lineno * 1000 + n.col_offset
>>> dis.dis(compile(a, '', 'eval'))
1000 0 LOAD_NAME 0 (a)
1003 3 LOAD_NAME 1 (b)
1006 6 LOAD_NAME 2 (c)
9 BUILD_TUPLE 3
12 RETURN_VALUE
コードを直接コンパイルすることは、 を介してコンパイルすることと同じであるべきであり、行番号をast.parse
いじっても、生成されたバイトコード ( .co_lnotab
- ソースファイルを見つける
- で解析します
ast.parse
- ast の行番号を変更して、列のオフセットを含めます
- astをコンパイルする
- を使用し
tb_lasti
てマンジドを検索しますco_lnotab
- 変更された行番号を (行番号、列オフセット) に戻す