Commit f38e7941 authored by Kirill Smelkov's avatar Kirill Smelkov

test/gen_testdata: Switch to random2 for PRNG

Python3 changed behaviour of random module compared to its previous
behaviour under Python2:

    $ python2
    Python 2.7.18 (default, Jul 14 2021, 08:11:37)
    [GCC 10.2.1 20210110] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import random
    >>> random.seed(0)
    >>> for _ in range(5): print(random.randint(0,99))
    ...
    84
    75
    42
    25
    51

    $ python3
    Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import random
    >>> random.seed(0)
    >>> for _ in range(5): print(random.randint(0,99))
    ...
    49
    97
    53
    5
    33

Since gen_testdata.py uses PRNG heavily it means that with PRNG based on
builtin random module of current python, generated output will differ
strongly in between py2 and py3 versions.

However we want generated outputs to be close to each other for py2 and
py3 so that it is easier to analyze what is essential difference in
generated databases.

-> Make sure py2/py3 databases will be logically the same by explicitly
using random2 and asserting that PRNG behaviour is stable independently
of current python.

No change in generated files as behaviour of random2 is by definition
exactly the same as behaviour of builtin random on py2:

https://pypi.org/project/random2/
parent 1118ba3a
......@@ -23,7 +23,7 @@ setup(
install_requires = ['ZODB', 'zodburi', 'zope.interface', 'pygolang >= 0.0.0.dev6', 'six', 'dateparser'],
extras_require = {
'test': ['pytest', 'freezegun', 'pytz', 'mock;python_version<="2.7"'],
'test': ['pytest', 'freezegun', 'pytz', 'mock;python_version<="2.7"', 'random2'],
},
entry_points= {'console_scripts': ['zodb = zodbtools.zodb:main']},
......
......@@ -49,7 +49,7 @@ import glob
import sys
import struct
import time
import random
import random2
import logging
# convert numeric oid to/from str
......@@ -102,8 +102,20 @@ class Object(Persistent):
# rand is our private PRNG.
# It is made independent to stay predictable even if third-party code uses random as well.
rand = random.Random()
del random
# It also provides the same behaviour for both py2 and py3 so that generated
# test data closely match each other where possible on all python versions.
rand = random2.Random()
del random2
def _(): # assert that rand behaviour is predictable
rand.seed(0)
R = lambda: rand.randint(0, 99)
v = list(R() for _ in range(10))
assert v == [84, 75, 42, 25, 51, 40, 78, 30, 47, 58], v
rand.shuffle(v)
assert v == [84, 47, 30, 78, 75, 25, 40, 42, 51, 58], v
y = list(rand.choice(v) for _ in v)
assert y == [58, 78, 42, 51, 40, 75, 47, 75, 40, 58], y
_()
# keys returns list of obj.keys() in predictable order independent of python version.
def keys(obj):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment