mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue 20691: Add follow_wrapped arg to inspect.signature/from_callable.
This commit is contained in:
parent
1f507a8140
commit
bcd4fc161a
5 changed files with 36 additions and 10 deletions
|
@ -431,7 +431,7 @@ The Signature object represents the call signature of a callable object and its
|
||||||
return annotation. To retrieve a Signature object, use the :func:`signature`
|
return annotation. To retrieve a Signature object, use the :func:`signature`
|
||||||
function.
|
function.
|
||||||
|
|
||||||
.. function:: signature(callable)
|
.. function:: signature(callable, \*, follow_wrapped=True)
|
||||||
|
|
||||||
Return a :class:`Signature` object for the given ``callable``::
|
Return a :class:`Signature` object for the given ``callable``::
|
||||||
|
|
||||||
|
@ -456,6 +456,11 @@ function.
|
||||||
Raises :exc:`ValueError` if no signature can be provided, and
|
Raises :exc:`ValueError` if no signature can be provided, and
|
||||||
:exc:`TypeError` if that type of object is not supported.
|
:exc:`TypeError` if that type of object is not supported.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
``follow_wrapped`` parameter. Pass ``False`` to get a signature of
|
||||||
|
``callable`` specifically (``callable.__wrapped__`` will not be used to
|
||||||
|
unwrap decorated callables.)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Some callables may not be introspectable in certain implementations of
|
Some callables may not be introspectable in certain implementations of
|
||||||
|
@ -528,12 +533,13 @@ function.
|
||||||
>>> str(new_sig)
|
>>> str(new_sig)
|
||||||
"(a, b) -> 'new return anno'"
|
"(a, b) -> 'new return anno'"
|
||||||
|
|
||||||
.. classmethod:: Signature.from_callable(obj)
|
.. classmethod:: Signature.from_callable(obj, \*, follow_wrapped=True)
|
||||||
|
|
||||||
Return a :class:`Signature` (or its subclass) object for a given callable
|
Return a :class:`Signature` (or its subclass) object for a given callable
|
||||||
``obj``. This method simplifies subclassing of :class:`Signature`:
|
``obj``. Pass ``follow_wrapped=False`` to get a signature of ``obj``
|
||||||
|
without unwrapping its ``__wrapped__`` chain.
|
||||||
|
|
||||||
::
|
This method simplifies subclassing of :class:`Signature`::
|
||||||
|
|
||||||
class MySignature(Signature):
|
class MySignature(Signature):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -430,6 +430,9 @@ inspect
|
||||||
subclassing of :class:`~inspect.Signature` easier. (Contributed
|
subclassing of :class:`~inspect.Signature` easier. (Contributed
|
||||||
by Yury Selivanov and Eric Snow in :issue:`17373`.)
|
by Yury Selivanov and Eric Snow in :issue:`17373`.)
|
||||||
|
|
||||||
|
* New argument ``follow_wrapped`` for :func:`inspect.signature`.
|
||||||
|
(Contributed by Yury Selivanov in :issue:`20691`.)
|
||||||
|
|
||||||
ipaddress
|
ipaddress
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
@ -2664,9 +2664,10 @@ class Signature:
|
||||||
return _signature_from_builtin(cls, func)
|
return _signature_from_builtin(cls, func)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_callable(cls, obj):
|
def from_callable(cls, obj, *, follow_wrapped=True):
|
||||||
"""Constructs Signature for the given callable object."""
|
"""Constructs Signature for the given callable object."""
|
||||||
return _signature_from_callable(obj, sigcls=cls)
|
return _signature_from_callable(obj, sigcls=cls,
|
||||||
|
follow_wrapper_chains=follow_wrapped)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
|
@ -2915,9 +2916,9 @@ class Signature:
|
||||||
return rendered
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
def signature(obj):
|
def signature(obj, *, follow_wrapped=True):
|
||||||
"""Get a signature object for the passed callable."""
|
"""Get a signature object for the passed callable."""
|
||||||
return Signature.from_callable(obj)
|
return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
|
||||||
|
|
||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
|
|
|
@ -1735,8 +1735,8 @@ class MyParameter(inspect.Parameter):
|
||||||
|
|
||||||
class TestSignatureObject(unittest.TestCase):
|
class TestSignatureObject(unittest.TestCase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def signature(func):
|
def signature(func, **kw):
|
||||||
sig = inspect.signature(func)
|
sig = inspect.signature(func, **kw)
|
||||||
return (tuple((param.name,
|
return (tuple((param.name,
|
||||||
(... if param.default is param.empty else param.default),
|
(... if param.default is param.empty else param.default),
|
||||||
(... if param.annotation is param.empty
|
(... if param.annotation is param.empty
|
||||||
|
@ -1956,6 +1956,11 @@ class TestSignatureObject(unittest.TestCase):
|
||||||
self.assertEqual(inspect.signature(func),
|
self.assertEqual(inspect.signature(func),
|
||||||
inspect.signature(decorated_func))
|
inspect.signature(decorated_func))
|
||||||
|
|
||||||
|
def wrapper_like(*args, **kwargs) -> int: pass
|
||||||
|
self.assertEqual(inspect.signature(decorated_func,
|
||||||
|
follow_wrapped=False),
|
||||||
|
inspect.signature(wrapper_like))
|
||||||
|
|
||||||
@cpython_only
|
@cpython_only
|
||||||
def test_signature_on_builtins_no_signature(self):
|
def test_signature_on_builtins_no_signature(self):
|
||||||
import _testcapi
|
import _testcapi
|
||||||
|
@ -2384,6 +2389,13 @@ class TestSignatureObject(unittest.TestCase):
|
||||||
('b', ..., ..., "positional_or_keyword")),
|
('b', ..., ..., "positional_or_keyword")),
|
||||||
...))
|
...))
|
||||||
|
|
||||||
|
self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
|
||||||
|
((('args', ..., ..., "var_positional"),
|
||||||
|
('kwargs', ..., ..., "var_keyword")),
|
||||||
|
...)) # functools.wraps will copy __annotations__
|
||||||
|
# from "func" to "wrapper", hence no
|
||||||
|
# return_annotation
|
||||||
|
|
||||||
# Test that we handle method wrappers correctly
|
# Test that we handle method wrappers correctly
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
|
|
|
@ -176,6 +176,10 @@ Library
|
||||||
- Issue 24190: Implement inspect.BoundArgument.apply_defaults() method.
|
- Issue 24190: Implement inspect.BoundArgument.apply_defaults() method.
|
||||||
Contributed by Yury Selivanov.
|
Contributed by Yury Selivanov.
|
||||||
|
|
||||||
|
- Issue 20691: Add 'follow_wrapped' argument to
|
||||||
|
inspect.Signature.from_callable() and inspect.signature().
|
||||||
|
Contributed by Yury Selivanov.
|
||||||
|
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue