-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-116040: [Enum] fix by-value calls when second value is falsey; e.g. Cardinal(1, 0) #116072
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,6 +162,13 @@ def _dedent(text): | |
lines[j] = l[i:] | ||
return '\n'.join(lines) | ||
|
||
class _not_given: | ||
def __repr__(self): | ||
return('<not given>') | ||
def __bool__(self): | ||
return False | ||
_not_given = _not_given() | ||
|
||
class _auto_null: | ||
def __repr__(self): | ||
return '_auto_null' | ||
|
@@ -680,7 +687,7 @@ def __bool__(cls): | |
""" | ||
return True | ||
|
||
def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None): | ||
def __call__(cls, value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None): | ||
""" | ||
Either returns an existing member, or creates a new enum class. | ||
|
||
|
@@ -709,18 +716,18 @@ def __call__(cls, value, names=None, *values, module=None, qualname=None, type=N | |
""" | ||
if cls._member_map_: | ||
# simple value lookup if members exist | ||
if names: | ||
if names is not _not_given: | ||
value = (value, names) + values | ||
return cls.__new__(cls, value) | ||
# otherwise, functional API: we're creating a new Enum type | ||
if names is None and type is None: | ||
if names is _not_given and type is None: | ||
# no body? no data-type? possibly wrong usage | ||
raise TypeError( | ||
f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum" | ||
) | ||
return cls._create_( | ||
class_name=value, | ||
names=names, | ||
names=names or None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add tests for something like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
module=module, | ||
qualname=qualname, | ||
type=type, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3409,6 +3409,15 @@ def __new__(cls, int_value, *value_aliases): | |
self.assertIs(Types(2), Types.NetList) | ||
self.assertIs(Types('nl'), Types.NetList) | ||
|
||
def test_second_tuple_item_is_falsey(self): | ||
class Cardinal(Enum): | ||
RIGHT = (1, 0) | ||
UP = (0, 1) | ||
LEFT = (-1, 0) | ||
DOWN = (0, -1) | ||
self.assertIs(Cardinal(1, 0), Cardinal.RIGHT) | ||
self.assertIs(Cardinal(-1, 0), Cardinal.LEFT) | ||
|
||
def test_no_members(self): | ||
with self.assertRaisesRegex( | ||
TypeError, | ||
|
@@ -3421,6 +3430,20 @@ def test_no_members(self): | |
): | ||
Flag(7) | ||
|
||
def test_empty_names(self): | ||
for nothing, e_type in ( | ||
('', None), | ||
('', int), | ||
([], None), | ||
([], int), | ||
({}, None), | ||
({}, int), | ||
): | ||
Comment on lines
+3434
to
+3441
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could perhaps be clearer with nested loops. for nothing in '', [], {}:
for e_type in None, int:
... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. |
||
empty_enum = Enum('empty_enum', nothing, type=e_type) | ||
self.assertEqual(len(empty_enum), 0) | ||
self.assertRaises(TypeError, 'has no members', empty_enum, 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It raises a TypeError because you try to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gah. Changed to |
||
|
||
|
||
class TestOrder(unittest.TestCase): | ||
"test usage of the `_order_` attribute" | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[Enum] fix by-value calls when second value is falsey; e.g. Cardinal(1, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, or the
or None
at line 730 will fail.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it should not take the boolean value there at first place, but use
is not _not_given
? I suspected that it can produce weird results if the second value is false andtype
is given.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean -- is "second value" the names parameter? If it's falsey and a type is given, a new empty enum is created (which is appropriate).