Skip to content

Commit b9f814c

Browse files
authored
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.
1 parent 0802fd6 commit b9f814c

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

Lib/random.py

+15-11
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
# Adrian Baddeley. Adapted by Raymond Hettinger for use with
5151
# the Mersenne Twister and os.urandom() core generators.
5252

53-
from warnings import warn as _warn
5453
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
5554
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
5655
from math import tau as TWOPI, floor as _floor, isfinite as _isfinite
@@ -63,13 +62,6 @@
6362
import os as _os
6463
import _random
6564

66-
try:
67-
# hashlib is pretty heavy to load, try lean internal module first
68-
from _sha2 import sha512 as _sha512
69-
except ImportError:
70-
# fallback to official implementation
71-
from hashlib import sha512 as _sha512
72-
7365
__all__ = [
7466
"Random",
7567
"SystemRandom",
@@ -105,6 +97,7 @@
10597
BPF = 53 # Number of bits in a float
10698
RECIP_BPF = 2 ** -BPF
10799
_ONE = 1
100+
_sha512 = None
108101

109102

110103
class Random(_random.Random):
@@ -159,6 +152,16 @@ def seed(self, a=None, version=2):
159152
a = -2 if x == -1 else x
160153

161154
elif version == 2 and isinstance(a, (str, bytes, bytearray)):
155+
global _sha512
156+
if _sha512 is None:
157+
try:
158+
# hashlib is pretty heavy to load, try lean internal
159+
# module first
160+
from _sha2 import sha512 as _sha512
161+
except ImportError:
162+
# fallback to official implementation
163+
from hashlib import sha512 as _sha512
164+
162165
if isinstance(a, str):
163166
a = a.encode()
164167
a = int.from_bytes(a + _sha512(a).digest())
@@ -257,9 +260,10 @@ def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
257260

258261
random = self.random
259262
if n >= maxsize:
260-
_warn("Underlying random() generator does not supply \n"
261-
"enough bits to choose from a population range this large.\n"
262-
"To remove the range limitation, add a getrandbits() method.")
263+
from warnings import warn
264+
warn("Underlying random() generator does not supply \n"
265+
"enough bits to choose from a population range this large.\n"
266+
"To remove the range limitation, add a getrandbits() method.")
263267
return _floor(random() * n)
264268
rem = maxsize % n
265269
limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0

0 commit comments

Comments
 (0)