Created
November 23, 2024 13:38
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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