diff --git a/enum_new.py b/replacement_new.py index 81a042b..321cd8a 100644 --- a/enum_new.py +++ b/replacement_new.py @@ -1,5 +1,12 @@ - def __new__(cls, value): +def _replacement__new__(cls, value): + """ Copied from python standard library enum.py class Enum. + Prevent cyclic references on ValueError during construction. + Local variable exc must be deleted, otherwise: + - ref to exc held by the frame + - ref to traceback held by exc + - ref to frame held by traceback + """ # all enum instances are actually created during class construction # without calling this method; this method is called by the metaclass' # __call__ (i.e. Color(3) ), and by pickle @@ -20,21 +27,23 @@ return member # still not found -- try _missing_ hook try: - exc = None result = cls._missing_(value) except Exception as e: - exc = e - result = None + e.__context__ = ValueError("%r is not a valid %s" % (value, cls.__name__)) + raise e + 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: + + with ValueError( + "%r is not a valid %s" % (value, cls.__name__) + ) as ve_exc: + if result is None: raise ve_exc - elif exc is None: - exc = TypeError( + + te_exc = TypeError( 'error in %s._missing_: returned %r instead of None or a valid member' % (cls.__name__, result) ) - exc.__context__ = ve_exc - raise exc + te_exc.__context__ = ve_exc + raise te_exc