2

In Python 2 documentation of the random.seed() function I found a warning:

If a hashable object is given, deterministic results are only assured when PYTHONHASHSEED is disabled.

From https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED I infer that the -R switch of the interpreter may have similar effect as PYTHONHASHSEED.

I have verified empirically, that random numbers seeded with small integers seems to be reproducible. So do hashes of small integers.

However, int is hashable. Is it stated explicitly in any trusted source, that it is safe to use it as a seed for a reproducible sequence of random numbers?

In contrast to Reproducibility of python pseudo-random numbers across systems and versions?, reproducibility within same system and interpreter is enough.

Community
  • 1
  • 1
abukaj
  • 2,582
  • 1
  • 22
  • 45
  • I would consider that a documentation flaw; it should say that ints and longs are not hashed. In any case, the Python 2 implementation is unlikely to change at this point, and the [Python 3 documentation](https://docs.python.org/3/library/random.html#random.seed) mentions that ints (Python 2 longs) are used directly. – user2357112 Dec 19 '16 at 17:31

2 Answers2

3

Not a complete answer but the source code for random_seed (in C) would be relevent:

if (PyInt_Check(arg) || PyLong_Check(arg))
    n = PyNumber_Absolute(arg);
else {
    long hash = PyObject_Hash(arg);
    if (hash == -1)
        goto Done;
    n = PyLong_FromUnsignedLong((unsigned long)hash);
}

this would suggest that anything other then a long (int) directly uses the hash value as the seed, so as long as:

  1. hash(int) gives consistent results and
  2. You are using this implementation of seed (may not be the same for Jython etc.)

Then I'd expect seed(int) to yield consistent results.

That said I can't speak for either of those conditions staying constant so this doesn't really give a definitive answer unless someone else can verify them.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • 1
    That looks like the Python 3 source code. The [Python 2 code](https://hg.python.org/cpython/file/2.7/Modules/_randommodule.c#l231) would be more relevant. – user2357112 Dec 19 '16 at 17:37
  • @user2357112 ok but other then checking if it is an `int` or `long` instead of just `long` the relevant parts are pretty much the same no? – Tadhg McDonald-Jensen Dec 19 '16 at 22:04
  • @TadhgMcDonald-Jensen I agree with user2357112. It is not about `int`/`long` difference. The question was about Python 2 specifically, so Python 2.7 source code seems more appropriate – abukaj Dec 20 '16 at 10:42
0

The documentation confirms its safety in Python 2.6:

If x is not None or an int or long, hash(x) is used instead. If x is an int or long, x is used directly.

(from https://docs.python.org/2.6/library/random.html#random.seed)

[EDIT]

The documentation for 2.7 has been updated to:

If a is not None or an int or a long, then hash(a) is used instead. Note that the hash values for some types are nondeterministic when PYTHONHASHSEED is enabled.

abukaj
  • 2,582
  • 1
  • 22
  • 45