[Python-Dev] PEP 362: Signature objects

Jim Jewett jimjjewett at gmail.com
Fri Sep 7 23:43:59 CEST 2007


Brett Cannon wrote:

> A Signature object has the following structure attributes:

> * name : str
>     Name of the function.  This is not fully qualified because
>     function objects for methods do not know the class they are
>     contained within.  This makes functions and methods
>     indistinguishable from one another when passed to decorators,
>     preventing proper creation of a fully qualified name.

(1)  Would this change with the new static __class__ attribute used
for the new super?

(2)  What about functions without a name?  Do you want to say str or
NoneType, or is that assumed?

(3)  Is the Signature object live or frozen?  (name is writable ...
will the Signature object reflect the new name, or the name in use at
the time it was created?)

> * var_annotations: dict(str, object)
>     Dict that contains the annotations for the variable parameters.
>     The keys are of the variable parameter with values of the

Is there a special key for the "->" returns annotation, or is that
available as a separate property?

> 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 then a tuple of strings is used.

What is used for unnamed arguments (typically provided by C)?  I like
None, but I see the arguments for both "" and missing attribute.

> * position : int
>     The position of the parameter within the signature of the
>     function (zero-indexed).  For keyword-only parameters the position
>     value is arbitrary while not conflicting with positional
>     parameters.

Is this just a property/alias for signature.parameters.index(self) ?

What should a "parameter" object not associated with a specific
signature return?  -1, None, or missing attribute?

Is there a way to get the associated Signature, or is it "compiled
out" when the Signature and its child Parameters are first
constructed?  (I think the position property is the only attribute
that would use it, unless you want some of the other attributes --
like annotations -- to be live.)

...

I would also like to see a

 * value : object

attribute; this would be missing on most functions, but might be
filled in on a Signature representing a closure, or an execution
frame.


> When to construct the Signature object?
> ---------------------------------------

> The Signature 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.

Since most code doesn't need it, I would expect it to be optimized out
at least as often as docstrings are.

>  In the lazy situation, one would
> pass a function object to a function and that would generate the
> Signature object and store it to ``__signature__`` if
> needed, and then return the value of ``__signature__``.

Why store it?  Do you expect many use cases to need the signature more
than once (but not to save it themselves)?

If there is a __signature__ attribute on a object, you have to specify
whether it can be replaced, which parts of it are writable, how that
will affect the function's own behavior, etc.  I also suspect it might
become a source of heisenbugs, like the "reference leaks" that were
really DUMMY items in a dict.

If the Signature is just a snapshot no longer attached to the original
function, then people won't expect changes to the Signature to affect
the callable.

> Should ``Signature.bind`` return Parameter objects as keys?

(see above) If a Signature is a snapshot (rather than a live part of
the function), then it might make more sense to just add a value
attribute to Parameter objects.

> Provide a mapping of parameter name to Parameter object?
> --------------------------------------------------------

> While providing access to the parameters in order is handy, it might
> also be beneficial to provide a way to retrieve Parameter objects from
> a Signature object based on the parameter's name.  Which style of
> access (sequential/iteration or mapping) will influence how the
> parameters are stored internally and whether __getitem__ accepts
> strings or integers.

I think it should accept both.

What storage mechanism to use is an internal detail that should be
left to the implementation.  I wouldn't expect Signature inspection to
be inside a tight loop anyhow, unless it were part of a Generic
Function dispatch engine ... and those authors (just PJE?) can
optimize on what they actually need.

> Remove ``has_*`` attributes?
> ----------------------------

> If an EAFP approach to the API is taken,

Please leave them; it is difficult to catch Exceptions in a list comprehension.

> Have ``var_args`` and ``_var_kw_args`` default to ``None``?

Makes sense to me, particularly since it should probably be consistent
with function name, and that should probably be None.


-jJ


More information about the Python-Dev mailing list