Commit 4e48bf92 authored by Andrew Svetlov's avatar Andrew Svetlov

Issue #15151: PEP 362 — document signature and related classes for inspect.py

Initial patch by Yury Selivanov
parent 4e9e9c1c
...@@ -395,6 +395,267 @@ Retrieving source code ...@@ -395,6 +395,267 @@ Retrieving source code
onwards is removed. Also, all tabs are expanded to spaces. onwards is removed. Also, all tabs are expanded to spaces.
.. _inspect-signature-object:
Introspecting callables with Signature Object
---------------------------------------------
Signature object represents the call signature of a callable object and its
return annotation. To get a Signature object use the :func:`signature`
function.
.. versionadded:: 3.3
.. seealso::
:pep:`362` - Function Signature Object.
The detailed specification, implementation details and examples.
.. function:: signature(callable)
Returns a :class:`Signature` object for the given ``callable``::
>>> from inspect import signature
>>> def foo(a, *, b:int, **kwargs):
... pass
>>> sig = signature(foo)
>>> str(sig)
'(a, *, b:int, **kwargs)'
>>> str(sig.parameters['b'])
'b:int'
>>> sig.parameters['b'].annotation
<class 'int'>
Accepts a wide range of python callables, from plain functions and classes
to :func:`functools.partial` objects.
.. note::
Some callables may not be introspectable in certain implementations
of Python. For example, in CPython, built-in functions defined in C
provide no metadata about their arguments.
.. class:: Signature
A Signature object represents the call signature of a function and its
return annotation. For each parameter accepted by the function it
stores a :class:`Parameter` object in its :attr:`parameters` collection.
Signature objects are *immutable*. Use :meth:`Signature.replace` to make
a modified copy.
.. attribute:: Signature.empty
A special class-level marker to specify absence of a return annotation.
.. attribute:: Signature.parameters
An ordered mapping of parameters' names to the corresponding
:class:`Parameter` objects.
.. attribute:: Signature.return_annotation
The "return" annotation for the callable. If the callable has
no "return" annotation, this attribute is set to
:attr:`Signature.empty`.
.. method:: Signature.bind(*args, **kwargs)
Creates a mapping from positional and keyword arguments to parameters.
Returns :class:`BoundArguments` if ``*args`` and ``**kwargs`` match
the signature, or raises a :exc:`TypeError`.
.. method:: Signature.bind_partial(*args, **kwargs)
Works the same way as :meth:`Signature.bind`, but allows the
omission of some required arguments (mimics :func:`functools.partial`
behavior.) Returns :class:`BoundArguments`, or raises a :exc:`TypeError`
if the passed arguments do not match the signature.
.. method:: Signature.replace([parameters], *, [return_annotation])
Creates a new Signature instance based on the instance replace was
invoked on. It is possible to pass different ``parameters`` and/or
``return_annotation`` to override the corresponding properties of
the base signature. To remove return_annotation from the copied
Signature, pass in :attr:`Signature.empty`.
::
>>> def test(a, b):
... pass
>>> sig = signature(test)
>>> new_sig = sig.replace(return_annotation="new return anno")
>>> str(new_sig)
"(a, b) -> 'new return anno'"
.. class:: Parameter
Parameter objects are *immutable*. Instead of modifying a Parameter object,
you can use :meth:`Parameter.replace` to create a modified copy.
.. attribute:: Parameter.empty
A special class-level marker to specify absence of default
values and annotations.
.. attribute:: Parameter.name
The name of the parameter as a string. Must be a valid python identifier
name (with the exception of ``POSITIONAL_ONLY`` parameters, which can
have it set to ``None``.)
.. attribute:: Parameter.default
The default value for the parameter. If the parameter has no default
value, this attribute is set to :attr:`Parameter.empty`.
.. attribute:: Parameter.annotation
The annotation for the parameter. If the parameter has no annotation,
this attribute is set to :attr:`Parameter.empty`.
.. attribute:: Parameter.kind
Describes how argument values are bound to the parameter.
Possible values (accessible via :class:`Parameter`, like
``Parameter.KEYWORD_ONLY``):
+------------------------+----------------------------------------------+
| Name | Meaning |
+========================+==============================================+
| *POSITIONAL_ONLY* | Value must be supplied as a positional |
| | argument. |
| | |
| | Python has no explicit syntax for defining |
| | positional-only parameters, but many built-in|
| | and extension module functions (especially |
| | those that accept only one or two parameters)|
| | accept them. |
+------------------------+----------------------------------------------+
| *POSITIONAL_OR_KEYWORD*| Value may be supplied as either a keyword or |
| | positional argument (this is the standard |
| | binding behaviour for functions implemented |
| | in Python.) |
+------------------------+----------------------------------------------+
| *VAR_POSITIONAL* | A tuple of positional arguments that aren't |
| | bound to any other parameter. This |
| | corresponds to a ``*args`` parameter in a |
| | Python function definition. |
+------------------------+----------------------------------------------+
| *KEYWORD_ONLY* | Value must be supplied as a keyword argument.|
| | Keyword only parameters are those which |
| | appear after a ``*`` or ``*args`` entry in a |
| | Python function definition. |
+------------------------+----------------------------------------------+
| *VAR_KEYWORD* | A dict of keyword arguments that aren't bound|
| | to any other parameter. This corresponds to a|
| | ``**kwargs`` parameter in a Python function |
| | definition. |
+------------------------+----------------------------------------------+
Print all keyword-only arguments without default values::
>>> def foo(a, b, *, c, d=10):
... pass
>>> sig = signature(foo)
>>> for param in sig.parameters.values():
... if (param.kind == param.KEYWORD_ONLY and
... param.default is param.empty):
... print('Parameter:', param)
Parameter: c
.. method:: Parameter.replace(*, [name], [kind], [default], [annotation])
Creates a new Parameter instance based on the instance replaced was
invoked on. To override a :class:`Parameter` attribute, pass the
corresponding argument. To remove a default value or/and an annotation
from a Parameter, pass :attr:`Parameter.empty`.
::
>>> from inspect import Parameter
>>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42)
>>> str(param)
'foo=42'
>>> str(param.replace()) # Will create a shallow copy of 'param'
'foo=42'
>>> str(param.replace(default=Parameter.empty, annotation='spam'))
"foo:'spam'"
.. class:: BoundArguments
Result of a :meth:`Signature.bind` or :meth:`Signature.bind_partial` call.
Holds the mapping of arguments to the function's parameters.
.. attribute:: BoundArguments.arguments
An ordered, mutable mapping (:class:`collections.OrderedDict`) of
parameters' names to arguments' values. Contains only explicitly
bound arguments. Changes in :attr:`arguments` will reflect in
:attr:`args` and :attr:`kwargs`.
Should be used in conjunction with :attr:`Signature.parameters` for
any arguments processing purposes.
.. note::
Arguments for which :meth:`Signature.bind` or
:meth:`Signature.bind_partial` relied on a default value are skipped.
However, if needed, it's easy to include them
::
>>> def foo(a, b=10):
... pass
>>> sig = signature(foo)
>>> ba = sig.bind(5)
>>> ba.args, ba.kwargs
((5,), {})
>>> for param in sig.parameters.values():
... if param.name not in ba.arguments:
... ba.arguments[param.name] = param.default
>>> ba.args, ba.kwargs
((5, 10), {})
.. attribute:: BoundArguments.args
Tuple of positional arguments values. Dynamically computed
from the :attr:`arguments` attribute.
.. attribute:: BoundArguments.kwargs
Dict of keyword arguments values. Dynamically computed
from the :attr:`arguments` attribute.
:attr:`args` and :attr:`kwargs` properties can be used to invoke functions::
def test(a, *, b):
...
sig = signature(test)
ba = sig.bind(10, b=20)
test(*ba.args, **ba.kwargs)
.. _inspect-classes-functions: .. _inspect-classes-functions:
Classes and functions Classes and functions
...@@ -443,6 +704,10 @@ Classes and functions ...@@ -443,6 +704,10 @@ Classes and functions
The first four items in the tuple correspond to :func:`getargspec`. The first four items in the tuple correspond to :func:`getargspec`.
.. note::
Consider using the new :ref:`Signature Object <inspect-signature-object>`
interface, which provides a better way of introspecting functions.
.. function:: getargvalues(frame) .. function:: getargvalues(frame)
...@@ -505,6 +770,9 @@ Classes and functions ...@@ -505,6 +770,9 @@ Classes and functions
.. versionadded:: 3.2 .. versionadded:: 3.2
.. note::
Consider using the new :meth:`Signature.bind` instead.
.. function:: getclosurevars(func) .. function:: getclosurevars(func)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment