Skip to content

Commit d771729

Browse files
authored
[3.12] gh-116040: [Enum] fix by-value calls when second value is falsey (GH-116072) (GH-116476)
e.g. Cardinal(1, 0) (cherry picked from commit 13ffd4b)
1 parent 4efd20e commit d771729

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

Lib/enum.py

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

169+
class _not_given:
170+
def __repr__(self):
171+
return('<not given>')
172+
def __bool__(self):
173+
return False
174+
_not_given = _not_given()
175+
169176
class _auto_null:
170177
def __repr__(self):
171178
return '_auto_null'
@@ -718,7 +725,7 @@ def __bool__(cls):
718725
"""
719726
return True
720727

721-
def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None):
728+
def __call__(cls, value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None):
722729
"""
723730
Either returns an existing member, or creates a new enum class.
724731
@@ -747,18 +754,18 @@ def __call__(cls, value, names=None, *values, module=None, qualname=None, type=N
747754
"""
748755
if cls._member_map_:
749756
# simple value lookup if members exist
750-
if names:
757+
if names is not _not_given:
751758
value = (value, names) + values
752759
return cls.__new__(cls, value)
753760
# otherwise, functional API: we're creating a new Enum type
754-
if names is None and type is None:
761+
if names is _not_given and type is None:
755762
# no body? no data-type? possibly wrong usage
756763
raise TypeError(
757764
f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum"
758765
)
759766
return cls._create_(
760767
class_name=value,
761-
names=names,
768+
names=names or None,
762769
module=module,
763770
qualname=qualname,
764771
type=type,

Lib/test/test_enum.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,6 +3312,40 @@ def __new__(cls, value):
33123312
member._value_ = Base(value)
33133313
return member
33143314

3315+
def test_second_tuple_item_is_falsey(self):
3316+
class Cardinal(Enum):
3317+
RIGHT = (1, 0)
3318+
UP = (0, 1)
3319+
LEFT = (-1, 0)
3320+
DOWN = (0, -1)
3321+
self.assertIs(Cardinal(1, 0), Cardinal.RIGHT)
3322+
self.assertIs(Cardinal(-1, 0), Cardinal.LEFT)
3323+
3324+
def test_no_members(self):
3325+
with self.assertRaisesRegex(
3326+
TypeError,
3327+
'has no members',
3328+
):
3329+
Enum(7)
3330+
with self.assertRaisesRegex(
3331+
TypeError,
3332+
'has no members',
3333+
):
3334+
Flag(7)
3335+
3336+
def test_empty_names(self):
3337+
for nothing, e_type in (
3338+
('', None),
3339+
('', int),
3340+
([], None),
3341+
([], int),
3342+
({}, None),
3343+
({}, int),
3344+
):
3345+
empty_enum = Enum('empty_enum', nothing, type=e_type)
3346+
self.assertEqual(len(empty_enum), 0)
3347+
self.assertRaises(TypeError, 'has no members', empty_enum, 0)
3348+
33153349

33163350
class TestOrder(unittest.TestCase):
33173351
"test usage of the `_order_` attribute"
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy