[Python-checkins] gh-99248: [Enum] fix negative number infinite loop (GH-99256)
miss-islington
webhook-mailer at python.org
Tue Nov 8 15:33:27 EST 2022
https://github.com/python/cpython/commit/4f31171e3fcef0a81b3d9186b28cd0596aaff771
commit: 4f31171e3fcef0a81b3d9186b28cd0596aaff771
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-11-08T12:33:21-08:00
summary:
gh-99248: [Enum] fix negative number infinite loop (GH-99256)
[Enum] fix negative number infinite loop
- _iter_bits_lsb() now raises a ValueError if a negative number
is passed in
- verify() now skips checking negative numbers for named flags
(cherry picked from commit 0b4ffb08ccdc21fc07ce90d3f78b58a25e1af653)
Co-authored-by: Ethan Furman <ethan at stoneleaf.us>
files:
A Misc/NEWS.d/next/Library/2022-11-08-11-15-37.gh-issue-99248.1vt8xI.rst
M Lib/enum.py
M Lib/test/test_enum.py
diff --git a/Lib/enum.py b/Lib/enum.py
index ec3ebde28686..62d6e25cecce 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -114,9 +114,12 @@ def _break_on_call_reduce(self, proto):
setattr(obj, '__module__', '<unknown>')
def _iter_bits_lsb(num):
- # num must be an integer
+ # num must be a positive integer
+ original = num
if isinstance(num, Enum):
num = num.value
+ if num < 0:
+ raise ValueError('%r is not a positive integer' % original)
while num:
b = num & (~num + 1)
yield b
@@ -1856,6 +1859,9 @@ def __call__(self, enumeration):
if name in member_names:
# not an alias
continue
+ if alias.value < 0:
+ # negative numbers are not checked
+ continue
values = list(_iter_bits_lsb(alias.value))
missed = [v for v in values if v not in member_values]
if missed:
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index d2b3a918d3ae..a9b80ad0d3db 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -14,7 +14,7 @@
from enum import Enum, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto
from enum import STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum
from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum
-from enum import member, nonmember
+from enum import member, nonmember, _iter_bits_lsb
from io import StringIO
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
from test import support
@@ -174,6 +174,10 @@ def test_is_private(self):
for name in self.sunder_names + self.dunder_names + self.random_names:
self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?')
+ def test_iter_bits_lsb(self):
+ self.assertEqual(list(_iter_bits_lsb(7)), [1, 2, 4])
+ self.assertRaisesRegex(ValueError, '-8 is not a positive integer', list, _iter_bits_lsb(-8))
+
# for subclassing tests
@@ -3965,6 +3969,16 @@ class Sillier(IntEnum):
triple = 3
value = 4
+ def test_negative_alias(self):
+ @verify(NAMED_FLAGS)
+ class Color(Flag):
+ RED = 1
+ GREEN = 2
+ BLUE = 4
+ WHITE = -1
+ # no error means success
+
+
class TestInternals(unittest.TestCase):
sunder_names = '_bad_', '_good_', '_what_ho_'
diff --git a/Misc/NEWS.d/next/Library/2022-11-08-11-15-37.gh-issue-99248.1vt8xI.rst b/Misc/NEWS.d/next/Library/2022-11-08-11-15-37.gh-issue-99248.1vt8xI.rst
new file mode 100644
index 000000000000..99bf1d5d08ba
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-11-08-11-15-37.gh-issue-99248.1vt8xI.rst
@@ -0,0 +1 @@
+fix negative numbers failing in verify()
More information about the Python-checkins
mailing list