Skip to content

Instantly share code, notes, and snippets.

@menzenski
Created November 23, 2024 13:38
Show Gist options
  • Save menzenski/7a86051eba729cf0292b0a2333a5187a to your computer and use it in GitHub Desktop.
Save menzenski/7a86051eba729cf0292b0a2333a5187a to your computer and use it in GitHub Desktop.
An attempt to allow a Python StrEnum member to be marked as deprecated
from enum import StrEnum
import warnings
class StrEnumWithDeprecationSupport(StrEnum):
"""String-based Enum with support for deprecation warnings."""
def __new__(cls, *values):
"""Values must already be of type `str`
We are overriding the `__new__` method of the standard library's `StrEnum` because it
only supports members whose values map to the `str` arguments (because they're passed
to `str` here:
https://github.com/python/cpython/blob/e33b6fccd3969dc2351f6a64d7b0362c36c2be96/Lib/enum.py#L1296).
This "works", in that it emits a DeprecationWarning, but it emits it at the time of enum
class creation, and not at time of member reference (which is what I actually want).
"""
if len(values) > 2:
raise TypeError("too many arguments for str(): %r" % (values,))
if len(values) == 1:
if not isinstance(values[0], str):
raise TypeError("%r is not a string" % (values[0],))
if len(values) == 2:
if not isinstance(values[1], dict):
raise TypeError("deprecation object must be a dict")
if "__deprecated__" not in values[1]:
raise TypeError("deprecation object must have a __deprecated__ key")
if not isinstance(values[1]["__deprecated__"], str):
raise TypeError("deprecation object must have a string value for the __deprecated__ key")
warnings.warn(values[1]["__deprecated__"], DeprecationWarning, 2)
# this is gross - we trust that our use cases don't need the other args that `str` supports,
# so we only pass the first value to `str` here, and we understand the second element in the
# member value to be a "deprecation configuration object", or something.
value = str(values[0])
member = str.__new__(cls, value)
member._value_ = value
if len(values) == 2:
member.__deprecated__ = values[1]["__deprecated__"]
return member
from enum import unique
from .enum_utilities import StrEnumWithDeprecationSupport
@unique
class Timezone(StrEnumWithDeprecationSupport):
US_CENTRAL = "US/Central", {"__deprecated__": "US_CENTRAL is deprecated. Use IANA standard AMERICA_CHICAGO instead."}
AMERICA_CHICAGO = "America/Chicago"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment