如何使 python 源代码的编译可重现
How to make the compilation of python source code reproducible
在我的机器上安装 jsonpickle 之后
(pip install jsonpickle==1.4.1 --no-compile),我注意到 ext
子文件夹中的 pandas.py
文件的编译并不总是可重现的。
在 ext
子文件夹中,我执行了以下 bash 代码以将所有 .py
文件编译为 .pyc
文件:
python -m compileall -d somereldir --invalidation-mode checked-hash
这在 __pycache__
子目录中创建了一个 pandas.cpython-37.pyc
文件。
然后在 __pycache__
子目录中执行:
xxd pandas.cpython-37.pyc > hex1.hex
如果我再次执行上述步骤并将 hexdump 写入 hex2.hex
,我注意到有两行不匹配。
diff hex1.hex hex2.hex
288,289c288,289
< 000011f0: 0029 013e 0200 0000 723f 0000 00da 056e .).>....r?.....n
< 00001200: 616d 6573 7213 0000 0029 0372 3300 0000 amesr....).r3...
---
> 000011f0: 0029 013e 0200 0000 da05 6e61 6d65 7372 .).>......namesr
> 00001200: 3f00 0000 7213 0000 0029 0372 3300 0000 ?...r....).r3...
我执行了几次,.pyc
文件似乎有两个“版本”,有时它们匹配,有时它们不匹配。
因此,我有几个问题:
- 为什么
.pyc
个文件不同?
- 如何确保编译后的
.pyc
文件始终相同。
- 我检查了其他一些 python 库,它们都生成了可重现的
.pyc
文件,那么这个 pandas.py
文件有什么不同?
将 pandas.py
文件拆分成更小的部分并进行编译后,我能够在第 135 行确定问题所在:
name_bundle = {k: v for k, v in meta.items() if k in {'name', 'names'}}
回答以下问题:
- 第 135 行包含一组 (
{'name','names'}
)。编译后不一定保留集合中元素的顺序。尽管 dictionaries preserve insertion order as of Python 3.7,但我找不到任何有关 Python 3.7. 集合中元素顺序保存的信息
- 将环境变量 PYTHONHASHSEED 设置为固定值。
- 这些库可能不包含任何集合。
在我的机器上安装 jsonpickle 之后
(pip install jsonpickle==1.4.1 --no-compile),我注意到 ext
子文件夹中的 pandas.py
文件的编译并不总是可重现的。
在 ext
子文件夹中,我执行了以下 bash 代码以将所有 .py
文件编译为 .pyc
文件:
python -m compileall -d somereldir --invalidation-mode checked-hash
这在 __pycache__
子目录中创建了一个 pandas.cpython-37.pyc
文件。
然后在 __pycache__
子目录中执行:
xxd pandas.cpython-37.pyc > hex1.hex
如果我再次执行上述步骤并将 hexdump 写入 hex2.hex
,我注意到有两行不匹配。
diff hex1.hex hex2.hex
288,289c288,289
< 000011f0: 0029 013e 0200 0000 723f 0000 00da 056e .).>....r?.....n
< 00001200: 616d 6573 7213 0000 0029 0372 3300 0000 amesr....).r3...
---
> 000011f0: 0029 013e 0200 0000 da05 6e61 6d65 7372 .).>......namesr
> 00001200: 3f00 0000 7213 0000 0029 0372 3300 0000 ?...r....).r3...
我执行了几次,.pyc
文件似乎有两个“版本”,有时它们匹配,有时它们不匹配。
因此,我有几个问题:
- 为什么
.pyc
个文件不同? - 如何确保编译后的
.pyc
文件始终相同。 - 我检查了其他一些 python 库,它们都生成了可重现的
.pyc
文件,那么这个pandas.py
文件有什么不同?
将 pandas.py
文件拆分成更小的部分并进行编译后,我能够在第 135 行确定问题所在:
name_bundle = {k: v for k, v in meta.items() if k in {'name', 'names'}}
回答以下问题:
- 第 135 行包含一组 (
{'name','names'}
)。编译后不一定保留集合中元素的顺序。尽管 dictionaries preserve insertion order as of Python 3.7,但我找不到任何有关 Python 3.7. 集合中元素顺序保存的信息
- 将环境变量 PYTHONHASHSEED 设置为固定值。
- 这些库可能不包含任何集合。