等效于影响整数哈希的 python 的 -R 选项



我们有大量的python代码收集一些输入并产生一些输出。

我们要保证,鉴于相同的输入,无论Python版本或本地环境如何,我们都会产生相同的输出。(例如,代码是在Windows,Mac还是Linux上运行的32位还是64位(

,我们一直在使用和不使用-R选项运行我们的程序来实施自动测试套件,以python和比较输出,假设这会摆脱任何景点,而我们的输出意外在dict上意外限制了依赖迭代的位置。(我们代码中最常见的非确定性来源(

但是,由于最近我们调整了代码以支持Python 3,因此我们发现了一个地方,我们的输出部分取决于dict上使用int S作为密钥的迭代。与Python2相比,该迭代顺序在Python3中发生了变化,并且使我们的产出不同。我们现有的测试(全部在Python 2.7上(没有注意到这一点。(因为-R不会影响int s的哈希(,一旦找到,它就很容易修复,但是我们希望早些发现它。

是否有任何方法可以进一步强调我们的代码,并让我们有信心,我们将最终取决于在Python版本/环境中可能会有所不同的所有地方掩盖了所有地方?我认为,应用于数字以及strbytesdatetime对象的-RPYTHONHASHSEED之类的东西可以起作用,但我对其他方法开放。但是,如果可能的话,我希望我们的自动测试机只需要安装一个Python版本。

另一种可接受的替代方法将是某种方法可以通过pypy调整我们的代码,以便在迭代 dict中迭代项目时使用不同的顺序;我 think 我们的代码在PYPY上运行,尽管这不是我们明确支持的。但是,如果某些PYPY专家为我们提供了一种在不同运行中调整字典迭代顺序的方法,那么这是我们将要努力的事情。

使用pypy并不是这里的最佳选择,因为它始终保留插入顺序(使用使dicts使用 sill 内存的方法(。当然,我们可以更改命令的命令,但它打败了重点。

相反,我建议您用cpython源代码进行黑客攻击,以更改dictObject.c中的哈希使用方式。例如,在每个hash = PyObject_Hash(key); if (hash == -1) { ..error.. };之后,您可以添加hash ^= HASH_TWEAK;并编译具有HASH_TWEAK值不同的CPYTHON的不同版本。(我在某一时刻做了这样的事情,但是我再也找不到了。

最新更新