2006-08-21 19:54:07 -04:00
|
|
|
|
PEP: 362
|
|
|
|
|
Title: Function Signature Object
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
|
|
|
|
Author: Brett Cannon <brett@python.org>
|
|
|
|
|
Jiwon Seo <seojiwon@gmail.com>
|
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Python-Version: 2.6
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 21-Aug-2006
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
Python has always supported powerful introspection capabilities,
|
|
|
|
|
including that for functions. Taking a function object, you can fully
|
|
|
|
|
reconstruct the function signature using ``func_defaults``,
|
|
|
|
|
``func_code.co_argcount``, ``func_code.co_flags``, and
|
|
|
|
|
``func_code.co_varnames``. Unfortunately this is a little unruly
|
|
|
|
|
having to look at four different attributes to pull together complete
|
|
|
|
|
information for a function's signature.
|
|
|
|
|
|
|
|
|
|
This PEP proposes an object representation for function signatures.
|
|
|
|
|
This should help facilitate introspection on functions. It also helps
|
|
|
|
|
for introspection for decorators that wrap the function they are
|
|
|
|
|
applied to by allowing the wrapped function's signature object be set
|
|
|
|
|
for the wrapping function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Signature Object
|
|
|
|
|
================
|
|
|
|
|
|
|
|
|
|
The overall signature of an object is represented by the Signature
|
|
|
|
|
object. This object is to store Parameter objects (discussed later)
|
|
|
|
|
along with any information about the function itself and any
|
|
|
|
|
parameters that are highly unique (.e.g, ``*args``).
|
|
|
|
|
|
|
|
|
|
A Signature object has the following structure attributes:
|
|
|
|
|
|
|
|
|
|
* name:str
|
|
|
|
|
Name of the function.
|
|
|
|
|
* var_args:str
|
|
|
|
|
Name of the ``*args`` parameter, if present, else the empty
|
|
|
|
|
string.
|
|
|
|
|
* var_kw_args:str
|
|
|
|
|
Name of the ``**kwargs`` parameter, if present, else the empty
|
|
|
|
|
string.
|
|
|
|
|
* parameters:list(Parameter)
|
|
|
|
|
List of the parameters of the function are represented by
|
|
|
|
|
Parameter objects (see `Parameter Object`_ for their
|
|
|
|
|
description).
|
|
|
|
|
|
|
|
|
|
The Signature object is stored in the ``__signature__`` attribute of
|
|
|
|
|
the function. When it is to be created is an `Open Issues`_.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parameter Object
|
|
|
|
|
================
|
|
|
|
|
|
|
|
|
|
A function's signature is partially made up of several parameters.
|
|
|
|
|
Python's different kinds of parameters is quite large and rich and
|
|
|
|
|
continues to grow. This means that Parameter objects require they
|
|
|
|
|
represent any possible parameter.
|
|
|
|
|
|
|
|
|
|
Originally the plan was to represent parameters using a list of
|
|
|
|
|
parameter names on the Signature object along with various dicts keyed
|
|
|
|
|
on parameter names to disseminate the various possible pieces of
|
|
|
|
|
information one can know about a parameter. But the decision was made
|
|
|
|
|
to incorporate all information about a parameter in a single argument
|
|
|
|
|
so as to make extending the information easier. This was originally
|
|
|
|
|
put forth by Talin and the preferred form of Guido (as discussed at
|
|
|
|
|
the 2006 Google Sprint).
|
|
|
|
|
|
|
|
|
|
The structure of the Parameter object is:
|
|
|
|
|
|
|
|
|
|
* name:(str | tuple(str))
|
|
|
|
|
The name of the parameter as a string if it is not a tuple. If
|
|
|
|
|
the argument is a tuple, use a tuple of strings where each item is
|
|
|
|
|
the name of the parameter contained within the tuple.
|
|
|
|
|
* position:int
|
|
|
|
|
The position of the parameter within the signature of the
|
|
|
|
|
function (zero-indexed).
|
|
|
|
|
* has_default:bool
|
|
|
|
|
True if the parameter has a default value, else False.
|
|
|
|
|
* default_value:object
|
|
|
|
|
The default value for the parameter, if present, else the
|
|
|
|
|
attribute does not exist. This is done so that the attribute is
|
|
|
|
|
not accidentally used if no default value is set as any default
|
|
|
|
|
value could be a legitimate default value itself.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Implementation
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
An implementation is forthcoming for experimentation purposes based on
|
|
|
|
|
the 'inspect' module [#inspect-module]_. The classes will be exposed
|
|
|
|
|
in the 'inspect' module as well. This PEP has been posted without
|
|
|
|
|
implementation so as to not be a hinderance to another PEP that is
|
|
|
|
|
under development by another author.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Relation With Other PEPs
|
|
|
|
|
========================
|
|
|
|
|
|
|
|
|
|
"Keyword-Only Arguments [#pep-3102]_
|
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
|
|
If keyword-only parameters come into existence, the Parameter object
|
|
|
|
|
will require modification. A ``keyword_only`` attribute will be added
|
|
|
|
|
that holds a boolean representing whether the parameter is
|
|
|
|
|
keyword-only or not.
|
|
|
|
|
|
2006-08-22 13:30:16 -04:00
|
|
|
|
Nick Coghlan suggested to set 'position' to None to signal that the
|
|
|
|
|
argument is keyword-only and thus remove the need for the new
|
|
|
|
|
attribute. But that would cause different types to be used in the
|
|
|
|
|
attribute that are in no way compatible. It also removes the ability
|
|
|
|
|
to know the position number within the signature from the Paramter
|
|
|
|
|
object itself. Plus Guido preferred the original approach over this
|
|
|
|
|
alternative.
|
2006-08-21 19:54:07 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Open Issues
|
|
|
|
|
===========
|
|
|
|
|
|
|
|
|
|
When to construct the Parameter object?
|
|
|
|
|
---------------------------------------
|
|
|
|
|
|
|
|
|
|
The Parameter object can either be created in an eager or lazy
|
|
|
|
|
fashion. In the eager situation, the object can be created during
|
|
|
|
|
creation of the function object. In the lazy situation, one would
|
|
|
|
|
pass a function object to ``inspect.signature()`` and that would
|
|
|
|
|
generate the Signature object and store it to ``__signature__`` if
|
|
|
|
|
needed, and then return the value of ``__signature__``.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
.. [#inspect-module] ``inspect`` -- Inspect live objects
|
|
|
|
|
(http://docs.python.org/lib/module-inspect.html)
|
|
|
|
|
|
|
|
|
|
.. [#pep-3102] Keyword-Only Arguments
|
|
|
|
|
(http://www.python.org/dev/peps/pep-3102/)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|