bpo-32554: Deprecate hashing arbitrary types in random.seed() (GH-15382)

This commit is contained in:
Raymond Hettinger 2019-08-22 09:19:36 -07:00 committed by GitHub
parent 4109263a7e
commit d0cdeaab76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 2 deletions

View File

@ -86,6 +86,11 @@ Bookkeeping functions
.. versionchanged:: 3.2
Moved to the version 2 scheme which uses all of the bits in a string seed.
.. deprecated:: 3.9
In the future, the *seed* must be one of the following types:
*NoneType*, :class:`int`, :class:`float`, :class:`str`,
:class:`bytes`, or :class:`bytearray`.
.. function:: getstate()
Return an object capturing the current internal state of the generator. This
@ -316,6 +321,11 @@ Alternative Generator
Class that implements the default pseudo-random number generator used by the
:mod:`random` module.
.. deprecated:: 3.9
In the future, the *seed* must be one of the following types:
:class:`NoneType`, :class:`int`, :class:`float`, :class:`str`,
:class:`bytes`, or :class:`bytearray`.
.. class:: SystemRandom([seed])
Class that uses the :func:`os.urandom` function for generating random numbers

View File

@ -169,6 +169,12 @@ Deprecated
of Python. For the majority of use cases users can leverage the Abstract Syntax
Tree (AST) generation and compilation stage, using the :mod:`ast` module.
* The :mod:`random` module currently accepts any hashable type as a
possible seed value. Unfortunately, some of those types are not
guaranteed to have a deterministic hash value. After Python 3.9,
the module will restrict its seeds to *None*, :class:`int`,
:class:`float`, :class:`str`, :class:`bytes`, and :class:`bytearray`.
Removed
=======

View File

@ -121,7 +121,10 @@ class Random(_random.Random):
break
def seed(self, a=None, version=2):
"""Initialize internal state from hashable object.
"""Initialize internal state from a seed.
The only supported seed types are None, int, float,
str, bytes, and bytearray.
None or no argument seeds from current time or from an operating
system specific randomness source if available.
@ -143,12 +146,20 @@ class Random(_random.Random):
x ^= len(a)
a = -2 if x == -1 else x
if version == 2 and isinstance(a, (str, bytes, bytearray)):
elif version == 2 and isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode()
a += _sha512(a).digest()
a = int.from_bytes(a, 'big')
elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
_warn('Seeding based on hashing is deprecated\n'
'since Python 3.9 and will be removed in a subsequent '
'version. The only \n'
'supported seed types are: None, '
'int, float, str, bytes, and bytearray.',
DeprecationWarning, 2)
super().seed(a)
self.gauss_next = None

View File

@ -0,0 +1 @@
Deprecate having random.seed() call hash on arbitrary types.