I have an enum for which some of the members are deprecated:
from enum import Enum
class Foo(Enum):
BAR = "bar"
BAZ = "baz" # deprecated
How do it get the following behavior:
- When somebody writes
Foo.BAR
, everything behaves normally - When somebody writes
Foo.BAZ
, aDeprecationWarning
is issued usingwarnings.warn("BAZ is deprecated", DeprecationWarning)
. Afterwards everything behaves normally. - The same behavior should apply when members are accessed in other ways, e.g.
Foo("baz")
andFoo["BAZ"]
should raise aDeprecationWarning
.
Things I have tried, but failed:
- Overwrite
_missing_
and don't defineBAZ
. Does not work, because in the end I still need to return an existing member for a while (until our DB is cleaned of the deprecated value). But I can not dynamically add members to an enum. If I define it,_missing_
is not called. - overwrite any of
__getattr__
,__getattribute__
. These are called when accessing attributes of a member, e.g.Foo.BAZ.boo
, not when accessingFoo.BAZ
. I guess this could work if I could overwrite__getattr__
ofEnumMeta
and then makeEnum
use the child meta class. However, I don't see how that can be done either - overwrite
__class_getitem__
: Reserved for static typing and not called anyways. - Abuse
_generate_next_value_
. This function is only called on class creation, so I can get a deprecation warning when the class is called once, regardless of whether the deprecated member is called or not. But that is not what I want. - Look at this question. It does not solve my problem, as the goal there is filtering of deprecated members during iteration.
TLDR: How can I detect and invoke a function when an enum member is accessed?
I am working with python 3.8, so new features are fine.