diff --git a/Lib/enum.py b/Lib/enum.py index 0c2135f9040bac..78df81d24a9adf 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1,5 +1,6 @@ import sys import builtins as bltns +from functools import partial from types import MappingProxyType, DynamicClassAttribute @@ -37,7 +38,7 @@ def _is_descriptor(obj): """ Returns True if obj is a descriptor, False otherwise. """ - return ( + return not isinstance(obj, partial) and ( hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__') @@ -402,6 +403,12 @@ def __setitem__(self, key, value): elif isinstance(value, nonmember): # unwrap value here; it won't be processed by the below `else` value = value.value + elif isinstance(value, partial): + import warnings + warnings.warn('functools.partial will be a method descriptor ' + 'in future Python versions; wrap it in ' + 'enum.member() if you want to preserve the ' + 'old behavior', FutureWarning, stacklevel=2) elif _is_descriptor(value): pass elif _is_internal_class(self._cls_name, value): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 5b4a8070526fcf..46f57b2d9b641a 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -11,6 +11,7 @@ import builtins as bltns from collections import OrderedDict from datetime import date +from functools import partial from enum import Enum, EnumMeta, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto from enum import STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum @@ -1537,6 +1538,19 @@ class Inner(Enum): [Outer.a, Outer.b, Outer.Inner], ) + def test_partial(self): + def func(a, b=5): + return a, b + with self.assertWarnsRegex(FutureWarning, r'partial.*enum\.member') as cm: + class E(Enum): + a = 1 + b = partial(func) + self.assertEqual(cm.filename, __file__) + self.assertIsInstance(E.b, partial) + self.assertEqual(E.b(2), (2, 5)) + with self.assertWarnsRegex(FutureWarning, 'partial'): + self.assertEqual(E.a.b(2), (2, 5)) + def test_enum_with_value_name(self): class Huh(Enum): name = 1 diff --git a/Misc/NEWS.d/next/Library/2024-10-12-15-49-17.gh-issue-125316.t15RnJ.rst b/Misc/NEWS.d/next/Library/2024-10-12-15-49-17.gh-issue-125316.t15RnJ.rst new file mode 100644 index 00000000000000..07b642d69995d5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-12-15-49-17.gh-issue-125316.t15RnJ.rst @@ -0,0 +1,3 @@ +Fix using :func:`functools.partial` as :class:`enum.Enum` member. A +FutureWarning with suggestion to use :func:`enum.member` is now emitted when +the ``partial`` instance is used as an enum member.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: