summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-13 14:10:28 (GMT)
committerAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-13 14:10:28 (GMT)
commit4e48bf929b9d43afcd6567d69a4b384959775ca9 (patch)
tree72be4dbb60ea1ce16cbdbed6290a113ed0e54509
parent4e9e9c1c44309c90d167ab1e2a3e85582f1a52f8 (diff)
downloadcpython-4e48bf929b9d43afcd6567d69a4b384959775ca9.zip
cpython-4e48bf929b9d43afcd6567d69a4b384959775ca9.tar.gz
cpython-4e48bf929b9d43afcd6567d69a4b384959775ca9.tar.bz2
Issue #15151: PEP 362 — document signature and related classes for inspect.py
Initial patch by Yury Selivanov
-rw-r--r--Doc/library/inspect.rst268
1 files changed, 268 insertions, 0 deletions
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 3ec17d6..e5010c8 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -395,6 +395,267 @@ Retrieving source code
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:
Classes and functions
@@ -443,6 +704,10 @@ Classes and functions
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)
@@ -505,6 +770,9 @@ Classes and functions
.. versionadded:: 3.2
+ .. note::
+ Consider using the new :meth:`Signature.bind` instead.
+
.. function:: getclosurevars(func)