mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
[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.
This commit is contained in:
parent
d9dafc790d
commit
65e43ca6d9
3 changed files with 25 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
||||||
import sys
|
import sys
|
||||||
import builtins as bltns
|
import builtins as bltns
|
||||||
|
from functools import partial
|
||||||
from types import MappingProxyType, DynamicClassAttribute
|
from types import MappingProxyType, DynamicClassAttribute
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ def _is_descriptor(obj):
|
||||||
"""
|
"""
|
||||||
Returns True if obj is a descriptor, False otherwise.
|
Returns True if obj is a descriptor, False otherwise.
|
||||||
"""
|
"""
|
||||||
return (
|
return not isinstance(obj, partial) and (
|
||||||
hasattr(obj, '__get__') or
|
hasattr(obj, '__get__') or
|
||||||
hasattr(obj, '__set__') or
|
hasattr(obj, '__set__') or
|
||||||
hasattr(obj, '__delete__')
|
hasattr(obj, '__delete__')
|
||||||
|
@ -402,6 +403,12 @@ class EnumDict(dict):
|
||||||
elif isinstance(value, nonmember):
|
elif isinstance(value, nonmember):
|
||||||
# unwrap value here; it won't be processed by the below `else`
|
# unwrap value here; it won't be processed by the below `else`
|
||||||
value = value.value
|
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):
|
elif _is_descriptor(value):
|
||||||
pass
|
pass
|
||||||
elif _is_internal_class(self._cls_name, value):
|
elif _is_internal_class(self._cls_name, value):
|
||||||
|
|
|
@ -11,6 +11,7 @@ import typing
|
||||||
import builtins as bltns
|
import builtins as bltns
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from functools import partial
|
||||||
from enum import Enum, EnumMeta, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto
|
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 STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum
|
||||||
from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum
|
from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum
|
||||||
|
@ -1537,6 +1538,19 @@ class TestSpecial(unittest.TestCase):
|
||||||
[Outer.a, Outer.b, Outer.Inner],
|
[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):
|
def test_enum_with_value_name(self):
|
||||||
class Huh(Enum):
|
class Huh(Enum):
|
||||||
name = 1
|
name = 1
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue