🐕
Pythonのインデント = ブロックを決めている実装を追う
はじめに
Pythonのコードブロックはインデント4つなどで決めていますが、実装はどうなっているのでしょうか?気になったので調べてみました。
準備
cpythonは下記のgithubリポジトリで公開されています。
今回は、ローカルでファイルを確認したいためクローンします。
cpythonをクローン
git clone https://github.com/python/cpython.git
cd cpython
調査
対象ファイル
確認
tok_get_normal_mode - Parser/lexer/lexer.c:501
- インデントレベルの変化検出とINDENT/DEDENTトークン生成の中核処理
-
lexer.c:514-607: インデントレベル計算・比較ロジック- 515行:
if (tok->atbol)で行頭チェック - 516-546行: スペース・タブ文字をカウントしてインデントレベルを計算
- 571-606行: 現在のインデントと前回のインデントを比較し、INDENT/DEDENT生成を決定
- 515行:
-
lexer.c:613-631: INDENT/DEDENTトークン生成- 614行:
if (tok->pendin != 0)でペンディングトークンをチェック - 615-621行:
tok->pendin < 0の場合DEDENTトークン生成(621行) - 623-630行:
tok->pendin > 0の場合INDENTトークン生成(629行)
- 614行:
- インデントレベルの一貫性を検証
- 571-575行: 現在レベルと一致する場合のaltindstackチェック
- 584-585行: INDENT時のaltcolチェック
- 598-601行: DEDENT時の不整合チェック(E_DEDENT設定)
- 603-605行: DEDENT時のaltindstackチェック
- インデント状態管理
-
int indent(87行): 現在のインデントレベルインデックス -
int indstack[MAXINDENT](88行): インデントレベルスタック -
int atbol(89行): 行頭フラグ -
int pendin(90行): ペンディングINDENT/DEDENT数
フロー図
まとめ
PEP8でインデントは空白4つなど、準拠すべきルールが定められていますがインデントは4で固定でないことやそのアルゴリズムがわかりました。皆さんの学習の補助に使っていただけると幸いです。
Discussion