Kaydet (Commit) 0f2fc8be authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) Ethan Furman

bpo-34536: raise error for invalid _missing_ results (GH-9147) (GH-9978)

* raise exception if _missing_ returns None or invalid type
üst 2a6cf446
......@@ -540,7 +540,25 @@ class Enum(metaclass=EnumMeta):
if member._value_ == value:
return member
# still not found -- try _missing_ hook
return cls._missing_(value)
try:
exc = None
result = cls._missing_(value)
except Exception as e:
exc = e
result = None
if isinstance(result, cls):
return result
else:
ve_exc = ValueError("%r is not a valid %s" % (value, cls.__name__))
if result is None and exc is None:
raise ve_exc
elif exc is None:
exc = TypeError(
'error in %s._missing_: returned %r instead of None or a valid member'
% (cls.__name__, result)
)
exc.__context__ = ve_exc
raise exc
def _generate_next_value_(name, start, count, last_values):
for last_value in reversed(last_values):
......
......@@ -1717,6 +1717,38 @@ class TestEnum(unittest.TestCase):
third = auto()
self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
def test_missing(self):
class Color(Enum):
red = 1
green = 2
blue = 3
@classmethod
def _missing_(cls, item):
if item == 'three':
return cls.blue
elif item == 'bad return':
# trigger internal error
return 5
elif item == 'error out':
raise ZeroDivisionError
else:
# trigger not found
return None
self.assertIs(Color('three'), Color.blue)
self.assertRaises(ValueError, Color, 7)
try:
Color('bad return')
except TypeError as exc:
self.assertTrue(isinstance(exc.__context__, ValueError))
else:
raise Exception('Exception not raised.')
try:
Color('error out')
except ZeroDivisionError as exc:
self.assertTrue(isinstance(exc.__context__, ValueError))
else:
raise Exception('Exception not raised.')
def test_multiple_mixin(self):
class MaxMixin:
@classproperty
......
`Enum._missing_`: raise `ValueError` if None returned and `TypeError` if
non-member is returned.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment