Skip to content

gh-111881: Import _sha2 lazily in random #111889

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions Lib/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
# 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
Expand All @@ -63,13 +62,6 @@
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",
Expand Down Expand Up @@ -105,6 +97,7 @@
BPF = 53 # Number of bits in a float
RECIP_BPF = 2 ** -BPF
_ONE = 1
_sha512 = None


class Random(_random.Random):
Expand Down Expand Up @@ -159,6 +152,16 @@ def seed(self, a=None, version=2):
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())
Expand Down Expand Up @@ -257,9 +260,10 @@ def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):

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
Expand Down