https://github.com/python/cpython/commit/65e43ca6d936304622ec8b3cd2a9b264b3a3755b
commit: 65e43ca6d936304622ec8b3cd2a9b264b3a3755b
branch: 3.13
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-10-21T16:31:42+03:00
summary:

[3.13] gh-125316: Fix using partial() as Enum member (GH-125361)

A FutureWarning with suggestion to use enum.member() is now emitted
when the partial instance is used as an enum member.

files:
A Misc/NEWS.d/next/Library/2024-10-12-15-49-17.gh-issue-125316.t15RnJ.rst
M Lib/enum.py
M Lib/test/test_enum.py

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.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to