summaryrefslogtreecommitdiffstats
path: root/Lib/random.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-11-09 22:10:21 (GMT)
committerGitHub <noreply@github.com>2023-11-09 22:10:21 (GMT)
commitb9f814ce6fdc2fd636bb01e60c60f3ed708a245f (patch)
tree16c86ad269d4d818f30205f615352a0686a374f8 /Lib/random.py
parent0802fd6c8ee0cacb3ab555dd86e235a5dfab7618 (diff)
downloadcpython-b9f814ce6fdc2fd636bb01e60c60f3ed708a245f.zip
cpython-b9f814ce6fdc2fd636bb01e60c60f3ed708a245f.tar.gz
cpython-b9f814ce6fdc2fd636bb01e60c60f3ed708a245f.tar.bz2
gh-111881: Import _sha2 lazily in random (#111889)
The random module now imports the _sha2 module lazily in the Random.seed() method for str, bytes and bytearray seeds. It also imports lazily the warnings module in the _randbelow() method for classes without getrandbits(). Lazy import makes Python startup faster and reduces the number of imported modules at startup.
Diffstat (limited to 'Lib/random.py')
-rw-r--r--Lib/random.py26
1 files changed, 15 insertions, 11 deletions
diff --git a/Lib/random.py b/Lib/random.py
index 3f7bfd2..875beb2 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -50,7 +50,6 @@ General notes on the underlying Mersenne Twister core generator:
# Adrian Baddeley. Adapted by Raymond Hettinger for use with
# the Mersenne Twister and os.urandom() core generators.
-from warnings import warn as _warn
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from math import tau as TWOPI, floor as _floor, isfinite as _isfinite
@@ -63,13 +62,6 @@ from bisect import bisect as _bisect
import os as _os
import _random
-try:
- # hashlib is pretty heavy to load, try lean internal module first
- from _sha2 import sha512 as _sha512
-except ImportError:
- # fallback to official implementation
- from hashlib import sha512 as _sha512
-
__all__ = [
"Random",
"SystemRandom",
@@ -105,6 +97,7 @@ SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53 # Number of bits in a float
RECIP_BPF = 2 ** -BPF
_ONE = 1
+_sha512 = None
class Random(_random.Random):
@@ -159,6 +152,16 @@ class Random(_random.Random):
a = -2 if x == -1 else x
elif version == 2 and isinstance(a, (str, bytes, bytearray)):
+ global _sha512
+ if _sha512 is None:
+ try:
+ # hashlib is pretty heavy to load, try lean internal
+ # module first
+ from _sha2 import sha512 as _sha512
+ except ImportError:
+ # fallback to official implementation
+ from hashlib import sha512 as _sha512
+
if isinstance(a, str):
a = a.encode()
a = int.from_bytes(a + _sha512(a).digest())
@@ -257,9 +260,10 @@ class Random(_random.Random):
random = self.random
if n >= maxsize:
- _warn("Underlying random() generator does not supply \n"
- "enough bits to choose from a population range this large.\n"
- "To remove the range limitation, add a getrandbits() method.")
+ from warnings import warn
+ warn("Underlying random() generator does not supply \n"
+ "enough bits to choose from a population range this large.\n"
+ "To remove the range limitation, add a getrandbits() method.")
return _floor(random() * n)
rem = maxsize % n
limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0