らんだむな記憶

blogというものを体験してみようか!的なー

Python の関数コール

https://github.com/python/cpython/blob/master/Objects/call.c
の下に関数コールの仕組みやデフォルト引数の扱いの秘密が隠れてそうには思うものの default で検索しても出てこないし、すぐには分からんなぁ・・・

根性入れて compile して print デバッグをするなら、Your Guide to the CPython Source Code – Real Python とかかなぁ・・・。と思ったけど、公式 1. Getting Started — Python Developer's Guide を参考に以下のような感じで:

FROM ubuntu:18.04

ENV DEBIAN_FRONTEND noninteractive

RUN perl -pi -e 's/# deb-src/deb-src/' /etc/apt/sources.list && \
    apt update && apt build-dep -y python3.8

WORKDIR /workdir

VOLUME ["/workdir"]

CMD ["bash"]

これくらいの Dockerfile でビルド環境はできるような気がする。(3.9 にするとダメだった。20.04 にすればいけることは確認した)

git clone https://github.com/python/cpython.git

して

$ cpython
$ du -h
476M	.

だったのでまだマシ・・・。

git checkout v3.8.8
docker run -it --rm -v $PWD:/workdir derwind/python-build bash

で一応は準備ができちゃう的な・・・。

./configure --with-pydebug
make

でビルドは開始する。どれくらいかかるんかな?・・・と思ったら 5 分もかからなかった。すごっ。ビルドに使ったマシンのスペックもあるだろうけど、意外とはやい。*1

https://github.com/python/cpython/blob/v3.8.8/Objects/classobject.c#L106
この辺にログを入れて空の .py を実行させるとめっちゃログが出る。標準モジュールのせいかな?

https://github.com/python/cpython/blob/v3.8.8/Modules/timemodule.c#L68
この辺にログを入れると以下のようになる。一応動いているな・・・

>>> import time
>>> time.time()
time_time is called
1617383621.7431877

次回以降で CPython インタープリタの中からデフォルト引数の流れを追いかける。但し、断片的に追いかけるので一部推測を交えて手短にやる・・・。

一応のゴールは「デフォルト引数に mutable なオブジェクトを渡すことが嫌われる」ことの裏舞台を下回りから追跡して理解を深めることにある。

*1:Why does cpython use -O3? - Ideas - Discussions on Python.org にあるようにデフォルトでは最適化として -O3 が適用されている。Python 3.8.0b3 からPGOビルドが速くなる - QiitaUbuntuでPythonをソースからインストール - Qiita で触れられている --enable-optimizations を指定していなくてもである。Issue 38350: ./configure --with-pydebug should use -O0 rather than -Og - Python tracker によると、--with-pydebug を configure に渡すと -Og でのビルドに切り替わる。