Skip to content

Commit

Permalink
pythongh-116110: remove extra processing for the __signature__ attrib…
Browse files Browse the repository at this point in the history
…ute (pythonGH-116234)

This is an alternative to pythonGH-100168.
  • Loading branch information
skirpichev authored and efimov-mikhail committed Oct 9, 2024
1 parent 7a4b55c commit 3b823fd
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 48 deletions.
22 changes: 15 additions & 7 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,21 @@ def _add_member_(cls, name, member):
# now add to _member_map_ (even aliases)
cls._member_map_[name] = member

@property
def __signature__(cls):
from inspect import Parameter, Signature
if cls._member_names_:
return Signature([Parameter('values', Parameter.VAR_POSITIONAL)])
else:
return Signature([Parameter('new_class_name', Parameter.POSITIONAL_ONLY),
Parameter('names', Parameter.POSITIONAL_OR_KEYWORD),
Parameter('module', Parameter.KEYWORD_ONLY, default=None),
Parameter('qualname', Parameter.KEYWORD_ONLY, default=None),
Parameter('type', Parameter.KEYWORD_ONLY, default=None),
Parameter('start', Parameter.KEYWORD_ONLY, default=1),
Parameter('boundary', Parameter.KEYWORD_ONLY, default=None)])


EnumMeta = EnumType # keep EnumMeta name for backwards compatibility


Expand Down Expand Up @@ -1135,13 +1150,6 @@ class Enum(metaclass=EnumType):
attributes -- see the documentation for details.
"""

@classmethod
def __signature__(cls):
if cls._member_names_:
return '(*values)'
else:
return '(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)'

def __new__(cls, value):
# all enum instances are actually created during class construction
# without calling this method; this method is called by the metaclass'
Expand Down
10 changes: 1 addition & 9 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2424,18 +2424,10 @@ def _signature_from_callable(obj, *,
pass
else:
if sig is not None:
# since __text_signature__ is not writable on classes, __signature__
# may contain text (or be a callable that returns text);
# if so, convert it
o_sig = sig
if not isinstance(sig, (Signature, str)) and callable(sig):
sig = sig()
if isinstance(sig, str):
sig = _signature_fromstr(sigcls, obj, sig)
if not isinstance(sig, Signature):
raise TypeError(
'unexpected object {!r} in __signature__ '
'attribute'.format(o_sig))
'attribute'.format(sig))
return sig

try:
Expand Down
32 changes: 0 additions & 32 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4879,38 +4879,6 @@ def foo(): pass
self.assertEqual(signature_func(foo), inspect.Signature())
self.assertEqual(inspect.get_annotations(foo), {})

def test_signature_as_str(self):
self.maxDiff = None
class S:
__signature__ = '(a, b=2)'

self.assertEqual(self.signature(S),
((('a', ..., ..., 'positional_or_keyword'),
('b', 2, ..., 'positional_or_keyword')),
...))

def test_signature_as_callable(self):
# __signature__ should be either a staticmethod or a bound classmethod
class S:
@classmethod
def __signature__(cls):
return '(a, b=2)'

self.assertEqual(self.signature(S),
((('a', ..., ..., 'positional_or_keyword'),
('b', 2, ..., 'positional_or_keyword')),
...))

class S:
@staticmethod
def __signature__():
return '(a, b=2)'

self.assertEqual(self.signature(S),
((('a', ..., ..., 'positional_or_keyword'),
('b', 2, ..., 'positional_or_keyword')),
...))

def test_signature_on_derived_classes(self):
# gh-105080: Make sure that signatures are consistent on derived classes

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Removed extra preprocessing for the ``__signature__`` attribute: the code
just check if it's a :class:`inspect.Signature` instance. Patch by Sergey B
Kirpichev.

0 comments on commit 3b823fd

Please sign in to comment.