diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/random.py | 54 | ||||
-rw-r--r-- | Lib/test/test_random.py | 20 |
2 files changed, 63 insertions, 11 deletions
diff --git a/Lib/random.py b/Lib/random.py index 66433baa8c..a4128c28fb 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -51,6 +51,7 @@ 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 from os import urandom as _urandom from _collections_abc import Set as _Set, Sequence as _Sequence +from operator import index as _index from itertools import accumulate as _accumulate, repeat as _repeat from bisect import bisect as _bisect import os as _os @@ -297,28 +298,59 @@ class Random(_random.Random): # This code is a bit messy to make it fast for the # common case while still doing adequate error checking. - istart = int(start) - if istart != start: - raise ValueError("non-integer arg 1 for randrange()") + try: + istart = _index(start) + except TypeError: + if int(start) == start: + istart = int(start) + _warn('Float arguments to randrange() have been deprecated\n' + 'since Python 3.10 and will be removed in a subsequent ' + 'version.', + DeprecationWarning, 2) + else: + _warn('randrange() will raise TypeError in the future', + DeprecationWarning, 2) + raise ValueError("non-integer arg 1 for randrange()") if stop is None: if istart > 0: return self._randbelow(istart) raise ValueError("empty range for randrange()") # stop argument supplied. - istop = int(stop) - if istop != stop: - raise ValueError("non-integer stop for randrange()") + try: + istop = _index(stop) + except TypeError: + if int(stop) == stop: + istop = int(stop) + _warn('Float arguments to randrange() have been deprecated\n' + 'since Python 3.10 and will be removed in a subsequent ' + 'version.', + DeprecationWarning, 2) + else: + _warn('randrange() will raise TypeError in the future', + DeprecationWarning, 2) + raise ValueError("non-integer stop for randrange()") + + try: + istep = _index(step) + except TypeError: + if int(step) == step: + istep = int(step) + _warn('Float arguments to randrange() have been deprecated\n' + 'since Python 3.10 and will be removed in a subsequent ' + 'version.', + DeprecationWarning, 2) + else: + _warn('randrange() will raise TypeError in the future', + DeprecationWarning, 2) + raise ValueError("non-integer step for randrange()") width = istop - istart - if step == 1 and width > 0: + if istep == 1 and width > 0: return istart + self._randbelow(width) - if step == 1: + if istep == 1: raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) # Non-unit step argument supplied. - istep = int(step) - if istep != step: - raise ValueError("non-integer step for randrange()") if istep > 0: n = (width + istep - 1) // istep elif istep < 0: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index e7f911d128..436f3c98e6 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -542,6 +542,26 @@ class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase): raises(0, 42, 0) raises(0, 42, 3.14159) + def test_randrange_argument_handling(self): + randrange = self.gen.randrange + with self.assertWarns(DeprecationWarning): + randrange(10.0, 20, 2) + with self.assertWarns(DeprecationWarning): + randrange(10, 20.0, 2) + with self.assertWarns(DeprecationWarning): + randrange(10, 20, 1.0) + with self.assertWarns(DeprecationWarning): + randrange(10, 20, 2.0) + with self.assertWarns(DeprecationWarning): + with self.assertRaises(ValueError): + randrange(10.5) + with self.assertWarns(DeprecationWarning): + with self.assertRaises(ValueError): + randrange(10, 20.5) + with self.assertWarns(DeprecationWarning): + with self.assertRaises(ValueError): + randrange(10, 20, 1.5) + def test_randbelow_logic(self, _log=log, int=int): # check bitcount transition points: 2**i and 2**(i+1)-1 # show that: k = int(1.001 + _log(n, 2)) |