From cca0795a284f87e006adfcae79e11adfaf282d53 Mon Sep 17 00:00:00 2001 From: Wil Thieme Date: Mon, 11 Mar 2024 13:30:57 -0400 Subject: [PATCH 1/3] Fix: DeprecationWarning: Seeding based on hashing is deprecated since Python 3.9 and will be removed in a subsequent version. --- petl/util/random.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/petl/util/random.py b/petl/util/random.py index 94fa7588..d5fe9d7e 100644 --- a/petl/util/random.py +++ b/petl/util/random.py @@ -1,15 +1,24 @@ from __future__ import absolute_import, print_function, division - -import datetime +import hashlib import random import time from collections import OrderedDict from functools import partial + from petl.compat import xrange, text_type +from petl.util.base import Table -from petl.util.base import Table +def randomseed(): + """ + Obtain the hex digest of a sha256 hash of the + current epoch time in nanoseconds. + """ + + time_ns = str(time.time()).encode() + hash_time = hashlib.sha256(time_ns).hexdigest() + return hash_time def randomtable(numflds=5, numrows=100, wait=0, seed=None): @@ -36,9 +45,11 @@ def randomtable(numflds=5, numrows=100, wait=0, seed=None): | 0.026535969683863625 | 0.1988376506866485 | 0.6498844377795232 | +----------------------+----------------------+---------------------+ ... + Note that the data are generated on the fly and are not stored in memory, so this function can be used to simulate very large tables. + The only supported seed types are: None, int, float, str, bytes, and bytearray. """ @@ -52,7 +63,7 @@ def __init__(self, numflds=5, numrows=100, wait=0, seed=None): self.numrows = numrows self.wait = wait if seed is None: - self.seed = datetime.datetime.now() + self.seed = randomseed() else: self.seed = seed @@ -77,7 +88,7 @@ def __iter__(self): yield tuple(random.random() for n in range(nf)) def reseed(self): - self.seed = datetime.datetime.now() + self.seed = randomseed() def dummytable(numrows=100, @@ -108,6 +119,7 @@ def dummytable(numrows=100, | 4 | 'apples' | 0.09369523986159245 | +-----+----------+----------------------+ ... + >>> # customise fields ... import random @@ -132,12 +144,19 @@ def dummytable(numrows=100, | 0.4219218196852704 | 15 | 'chocolate' | +---------------------+-----+-------------+ ... + + + >>> table3_1 = etl.dummytable(50) + >>> table3_2 = etl.dummytable(100) + >>> table3_1[5] == table3_2[5] + False Data generation functions can be specified via the `fields` keyword argument. Note that the data are generated on the fly and are not stored in memory, so this function can be used to simulate very large tables. + The only supported seed types are: None, int, float, str, bytes, and bytearray. """ @@ -154,7 +173,7 @@ def __init__(self, numrows=100, fields=None, wait=0, seed=None): else: self.fields = OrderedDict(fields) if seed is None: - self.seed = datetime.datetime.now() + self.seed = randomseed() else: self.seed = seed @@ -181,4 +200,4 @@ def __iter__(self): yield tuple(fields[f]() for f in fields) def reseed(self): - self.seed = datetime.datetime.now() + self.seed = randomseed() From 906a8f87365ade62e5e787b86307e471b518d4f5 Mon Sep 17 00:00:00 2001 From: Wil Thieme Date: Mon, 11 Mar 2024 13:31:09 -0400 Subject: [PATCH 2/3] Add unit tests for randomtable, dummytable, and their supporting functions and classes. --- petl/test/util/test_random.py | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 petl/test/util/test_random.py diff --git a/petl/test/util/test_random.py b/petl/test/util/test_random.py new file mode 100644 index 00000000..18b55d56 --- /dev/null +++ b/petl/test/util/test_random.py @@ -0,0 +1,72 @@ +import random +from functools import partial + +from petl.util.random import randomseed, randomtable, RandomTable, dummytable, DummyTable + + +def test_randomseed(): + s = randomseed() + + assert isinstance(s, str) + assert s != "" + + +def test_randomtable(): + columns, rows = 3, 10 + table = randomtable(columns, rows) + + assert len(table[0]) == columns + assert len(table) == rows + 1 + + +def test_randomtable_class(): + columns, rows = 4, 60 + table = RandomTable(numflds=columns, numrows=rows) + + assert len(table[0]) == columns + assert len(table) == rows + 1 + + +def test_dummytable_custom_fields(): + columns = ( + ('count', partial(random.randint, 0, 100)), + ('pet', partial(random.choice, ('dog', 'cat', 'cow'))), + ('color', partial(random.choice, ('yellow', 'orange', 'brown'))), + ('value', random.random) + ) + rows = 35 + + table = dummytable( + numrows=rows, + fields=columns, + ) + assert len(table[0]) == 4 + assert len(table) == rows + 1 + + +def test_dummytable_no_seed(): + rows = 35 + + table = dummytable( + numrows=rows, + ) + assert len(table[0]) == 3 + assert len(table) == rows + 1 + + +def test_dummytable_int_seed(): + rows = 35 + + table = dummytable( + numrows=rows, + seed=42 + ) + assert len(table[0]) == 3 + assert len(table) == rows + 1 + + +def test_dummytable_class(): + rows = 70 + table = DummyTable(numrows=rows) + + assert len(table) == rows + 1 From 83c06404258ef29809c204840613d98828a9c319 Mon Sep 17 00:00:00 2001 From: Wil Thieme Date: Mon, 11 Mar 2024 13:31:22 -0400 Subject: [PATCH 3/3] document changes in changes.rst --- docs/changes.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/changes.rst b/docs/changes.rst index 3d83bfd2..5ff55eba 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,6 +1,15 @@ Changes ======= +Version 1.7.15 +-------------- + +* Add unit tests for randomtable, dummytable, and their supporting functions and classes. + By :user:`bmos`, :issue:`657`. + +* Fix: DeprecationWarning: Seeding based on hashing is deprecated since Python 3.9 and will be removed in a subsequent version. + By :user:`bmos`, :issue:`657`. + Version 1.7.14 --------------