Skip to content

Commit 1cd2b9f

Browse files
committed
Detect and warn about non-deterministic random seeds.
1 parent 1010431 commit 1cd2b9f

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ v2.0.0
88

99
Unreleased
1010
------------------
11+
Deprecated
12+
- The Random class will now warn if the seed it's given will not used
13+
deterministically. It will no longer accept non-integer seeds in the future.
14+
1115
Changed
1216
- Now bundles SDL 2.0.14 for MacOS.
1317
- `tcod.event` can now detect and will warn about uninitialized tile

tcod/random.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
However, you will need to use these generators to get deterministic results
66
from the :any:`Noise` and :any:`BSP` classes.
77
"""
8+
import os
89
import random
10+
import warnings
911
from typing import Any, Hashable, Optional
1012

1113
import tcod.constants
@@ -31,6 +33,11 @@ class Random(object):
3133
Attributes:
3234
random_c (CData): A cffi pointer to a TCOD_random_t object.
3335
36+
.. warning::
37+
A non-integer seed is only deterministic if the environment variable
38+
``PYTHONHASHSEED`` is set. In the future this function will only
39+
accept `int`'s as a seed.
40+
3441
.. versionchanged:: 9.1
3542
Added `tcod.random.MULTIPLY_WITH_CARRY` constant.
3643
`algorithm` parameter now defaults to `tcod.random.MERSENNE_TWISTER`.
@@ -44,12 +51,30 @@ def __init__(
4451
"""Create a new instance using this algorithm and seed."""
4552
if seed is None:
4653
seed = random.getrandbits(32)
54+
elif not isinstance(seed, int):
55+
warnings.warn(
56+
"In the future this class will only accept integer seeds.",
57+
DeprecationWarning,
58+
stacklevel=2,
59+
)
60+
if __debug__ and "PYTHONHASHSEED" not in os.environ:
61+
warnings.warn(
62+
"Python's hash algorithm is not configured to be"
63+
" deterministic so this non-integer seed will not be"
64+
" deterministic."
65+
"\nYou should do one of the following to fix this error:"
66+
"\n* Use an integer as a seed instead (recommended.)"
67+
"\n* Set the PYTHONHASHSEED environment variable before"
68+
" starting Python.",
69+
RuntimeWarning,
70+
stacklevel=2,
71+
)
72+
seed = hash(seed)
73+
4774
self.random_c = ffi.gc(
4875
ffi.cast(
4976
"mersenne_data_t*",
50-
lib.TCOD_random_new_from_seed(
51-
algorithm, hash(seed) % (1 << 32)
52-
),
77+
lib.TCOD_random_new_from_seed(algorithm, seed & 0xFFFFFFFF),
5378
),
5479
lib.TCOD_random_delete,
5580
)

0 commit comments

Comments
 (0)