Pythonのdefで関数を定義するところを、hogeで関数を定義できるようにCPythonを変更しました。

同じようにPythonを改造しようと思われている方の参考になればと思い、流れを以下にまとめます。

変更前

def test():
    print('ok')
  
test() # okと出力される

変更後

hoge test():
    print('ok')
  
test() # okと出力される

私の開発環境

- macOS Sequoia 15.5
- Clang 17.0.0
- CPython v3.10.7
- Editor: nano

Clangはmacに元々入っているもので何も触っていません。

バージョン3.10.7を使って、手順を紹介します。

エディタはターミナルでnanoを使用しました。

注意事項

コードの修正はターミナルで行ってください。

私はnanoを使用しました。VSCodeではじめはコードを編集していたのですが、ビルド(ソースコードをコンピュータが実行できる形に変換する一連の作業)の際にエラーが出ていました。

ターミナルで編集するようになってからそのエラーがなくなりました。

パスの影響かと思うのですが、余計なエラーを無くすためにターミナルを使ってください。

手順① 必要なツールの準備

Xcode Command Line Tools
Cコンパイラやmakeなど、Pythonをビルドするための基本ツール。

# ターミナルでのインストール方法
xcode-select --install

Homebrew
追加のライブラリやツールを管理するツール。
以下のサイトからインストールできます。
https://brew.sh/

ライブラリ
homebrewでCPythonをソースからビルドするために必要なもの。
PythonはC言語で書かれているため、Pythonを実装しているC言語のコードをCPythonと言います。

# インストール方法
# zlib → 圧縮・解凍に必要
# xz → .xz ファイルを扱うのに必
# readline → インタラクティブシェルの編集機能
brew install zlib xz readline

手順② フォルダを作る

ソースコードをダウンロードするためのフォルダを作成します。

ここでは例としてホームディレクトリにpythonというフォルダを作成します。

作成したら、そのフォルダの中に移動します。

mkdir ~/python
cd ~/python

手順③ Python 3.10.7 をダウンロード

②で作成したpythonフォルダの中で以下を実行します。

# Python 3.10.7をダウンロード
curl -O https://www.python.org/ftp/python/3.10.7/Python-3.10.7.tgz

# 圧縮フォルダを解凍
tar xzf Python-3.10.7.tgz

# 解凍したフォルダに移動
cd Python-3.10.7

これで「Python-3.10.7」というフォルダの中にPythonのソースコードが入ります。

手順④ 改造専用フォルダにインストール

ソースコードをビルドとインストールして、Python 3.10.7を使えるようにします。

# ./configureはビルドの際に使うコマンド
# どこにインストールしたフォルダを置くかを決める
# インストール後にpythonフォルダの中にpython-buildという別のフォルダが作られる
./configure --prefix=$HOME/python/python-build

# makeはビルド自動化ツール
# make -j4 は4コアを使って並列コンパイルし、CPUを有効活用できる
make -j4
make install

これで、Python 3.10.7が使用できるようになりました。

macに元々入っているPythonとは関係がないので、こちらの改造に専念できます。

試しに、Python 3.10.7が使用できるかを確認します。

ターミナルで以下を入力し、シェル(>>>で入力ができる状態)に表示が変わるか確認してください。

シェルから抜けるためにはctrl + Dを使用します。

~/python/python-build/bin/python3.10

手順⑤ ソースコードの変更

この手順がコードの改造の肝となる部分です。

変更するファイルは一つだけで、Grammarフォルダの中にあるpython.gramというファイルです。

以下を入力して、nanoでpython.gramを編集できるようにします。

現在は~/python/Python-3.10.7のフォルダにいるものとします。

nano Grammar/python.gram

ソースコードが表示されると思います。

これから二つのコードを変更していきます。

まず一つ目は、以下のコードを検索してください。

検索はctrl + Wです。

‘ ‘ もつけてください。

'def'

全部で四ヶ所ヒットすると思います。

その部分を以下のように ‘def’ の横に ‘hoge’ を追加します。

( )と | と ‘hoge’ を追加する以外は何も触っていません。

これで、hoge でも関数とみなされるようにします。

# 一ヶ所目
&('def' | 'hoge' | '@' | ASYNC) function_def
# 二ヶ所目と三ヶ所目
function_def_raw[stmt_ty]:
    | invalid_def_raw  
    | ('def'| 'hoge') n=NAME '(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
        _PyAST_FunctionDef(n->v.Name.id,
                        (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
                        b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA) }
    | ASYNC ('def'| 'hoge') n=NAME '(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
        CHECK_VERSION(
            stmt_ty,
            5,  
            "Async functions are",
            _PyAST_AsyncFunctionDef(n->v.Name.id,
                            (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
                            b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA)
        ) }
# 四ヶ所目
invalid_def_raw:
    | [ASYNC] a=('def' | 'hoge') NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
        RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", ((Token*)a)->lineno) }

このままだとビルドの際にエラーが出てしまうので、二つ目に以下の部分を変更します。

検索のctrl + Wで以下を検索してください。

a->lineno

全部で14ヶ所あると思います。

それを以下のように変更してください。

((Token*)a)->lineno

これでソースコードの変更は以上です。

手順⑥ 改造したソースコードを再度ビルドしてインストール

④と重複する部分がありますが、変更したソースコードでPython3.10.7を実行できるようにします。

# python.gramの変更を反映させるコマンド
make regen-pegen

# ビルドを初期状態に戻す
make clean

# ビルドしてインストール
make -j4
make install

これで終了です。

最後に、hogeで関数を実行できるかシェルを起動し確かめてみてください。

# シェルを起動
~/python/python-build/bin/python3.10

皆様の参考になれば幸いです。

参考文献

Changing CPython’s grammar

https://github.com/python/cpython/blob/main/InternalDocs/changing_grammar.md

日経ソフトウェア

https://info.nikkeibp.co.jp/media/NSW/atcl/mag/112000051