【问题标题】:Reproducible builds in pythonpython中的可重现构建
【发布时间】:2016-09-13 13:59:11
【问题描述】:

我需要发布一个 Python 脚本的编译版本,并且能够证明(使用哈希)编译后的文件确实与原始文件相同。

到目前为止,我们使用的是一个简单的:

find . -name "*.py" -print0 | xargs -0 python2 -m py_compile

问题在于这是不可重现的(不确定波动因素是什么,但 2 次执行不会为同一个 python 文件提供相同的 .pyc)并迫使我们始终发布相同的编译版本而不是能够只需将构建脚本提供给任何人以生成新的编译版本。

有没有办法做到这一点?

谢谢

【问题讨论】:

  • 编译的字节级波动是可以预料的。发布编译版本有什么问题?
  • 1) 操作系统细节 2) 精确的 python 版本 3) 时间相关的波动
  • 我们需要在服务器/驱动器上存储一个包含已编译版本的 zip 文件,维护每个版本的副本,以及在使用 git 进行代码托管和构建时想要避免的那种头痛脚本。如果我可以在特定版本中签出,重新构建并检查它是否相同,那会更容易。
  • 您可以将版本存储在您的服务器、S3 或任何其他存储上。我认为与编译器的这场战斗不值得......
  • 如果您希望创建可重现的 zip,即使使用散列源 .pycs,您仍然必须与 zip 包含文件权限、文件顺序和文件修改时间戳作斗争。请参阅github.com/bboe/deterministic_zipBarriers to deterministic, reproducible zip files by Mark Rushakoff (2014) 了解更多详情。

标签: python binary-reproducibility


【解决方案1】:

编译后的 Python 文件包括一个四字节幻数和四字节编译日期时间。这可能是您看到的差异的原因。

如果您在校验和过程中省略字节 5-8,那么您应该会看到给定 Python 版本的常量校验和。

.pyc 文件的格式由 Ned Batchelder 在this blog post 中给出。

【讨论】:

    【解决方案2】:

    2019 / python3.7+ 更新:自PEP 552

    python -m compileall -f --invalidation-mode=checked-hash [file|dir]
    # or
    export SOURCE_DATE_EPOCH=1 # set py_compile to use 
    python -m py_compile       # pycompile.PycInvalidationMode.CHECKED_HASH
    

    将创建.pycs,在其源代码更改之前不会更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多