Skip to content

Commit 13ffd4b

Browse files
authored
gh-116040: [Enum] fix by-value calls when second value is falsey; e.g. Cardinal(1, 0) (GH-116072)
1 parent b2d74cd commit 13ffd4b

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

Lib/enum.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@ def _dedent(text):
162162
lines[j] = l[i:]
163163
return '\n'.join(lines)
164164

165+
class _not_given:
166+
def __repr__(self):
167+
return('<not given>')
168+
def __bool__(self):
169+
return False
170+
_not_given = _not_given()
171+
165172
class _auto_null:
166173
def __repr__(self):
167174
return '_auto_null'
@@ -680,7 +687,7 @@ def __bool__(cls):
680687
"""
681688
return True
682689

683-
def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None):
690+
def __call__(cls, value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None):
684691
"""
685692
Either returns an existing member, or creates a new enum class.
686693
@@ -709,18 +716,18 @@ def __call__(cls, value, names=None, *values, module=None, qualname=None, type=N
709716
"""
710717
if cls._member_map_:
711718
# simple value lookup if members exist
712-
if names:
719+
if names is not _not_given:
713720
value = (value, names) + values
714721
return cls.__new__(cls, value)
715722
# otherwise, functional API: we're creating a new Enum type
716-
if names is None and type is None:
723+
if names is _not_given and type is None:
717724
# no body? no data-type? possibly wrong usage
718725
raise TypeError(
719726
f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum"
720727
)
721728
return cls._create_(
722729
class_name=value,
723-
names=names,
730+
names=names or None,
724731
module=module,
725732
qualname=qualname,
726733
type=type,

Lib/test/test_enum.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,6 +3409,15 @@ def __new__(cls, int_value, *value_aliases):
34093409
self.assertIs(Types(2), Types.NetList)
34103410
self.assertIs(Types('nl'), Types.NetList)
34113411

3412+
def test_second_tuple_item_is_falsey(self):
3413+
class Cardinal(Enum):
3414+
RIGHT = (1, 0)
3415+
UP = (0, 1)
3416+
LEFT = (-1, 0)
3417+
DOWN = (0, -1)
3418+
self.assertIs(Cardinal(1, 0), Cardinal.RIGHT)
3419+
self.assertIs(Cardinal(-1, 0), Cardinal.LEFT)
3420+
34123421
def test_no_members(self):
34133422
with self.assertRaisesRegex(
34143423
TypeError,
@@ -3421,6 +3430,20 @@ def test_no_members(self):
34213430
):
34223431
Flag(7)
34233432

3433+
def test_empty_names(self):
3434+
for nothing, e_type in (
3435+
('', None),
3436+
('', int),
3437+
([], None),
3438+
([], int),
3439+
({}, None),
3440+
({}, int),
3441+
):
3442+
empty_enum = Enum('empty_enum', nothing, type=e_type)
3443+
self.assertEqual(len(empty_enum), 0)
3444+
self.assertRaises(TypeError, 'has no members', empty_enum, 0)
3445+
3446+
34243447
class TestOrder(unittest.TestCase):
34253448
"test usage of the `_order_` attribute"
34263449

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[Enum] fix by-value calls when second value is falsey; e.g. Cardinal(1, 0)

0 commit comments

Comments
 (0)