[Python-Dev] Updated PEP 362 (Function Signature Object) (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Thu Jun 7 02:12:06 CEST 2012


On Thu, Jun 7, 2012 at 8:38 AM, Steven D'Aprano <steve at pearwood.info> wrote:

Brett Cannon wrote:

This is also Python, the language that assumes everyone is an consenting adult.

Exactly, which is why I'm not asking for signature to be immutable. Who knows, despite Larry's skepticism (and mine!), perhaps there is a use-case for signature being modified that we haven't thought of yet. But that's not really the point. It may be that nobody will be stupid enough to mangle signature, and inspect.getfullargspec becomes redundant.

I've presented use cases for doing this already. Please stop calling me stupid.

It will make sense to lie in signature any time there are constraints on a callable object that aren't accurately reflected in its Python level signature. The simplest example I can think of is a decorator that passes extra arguments in to the underlying function on every call. For example, here's a more elegant alternative to the default argument hack that relies on manipulating signature to avoid breaking introspection:

def shared_vars(*shared_args):
    """Decorator factory that defines shared variables that are

passed to every invocation of the function""" def decorator(f): @functools.wraps(f) # Sets wrapper.signature to Signature(f) def wrapper(*args, **kwds): full_args = shared_args + args return f(*full_args, **kwds) # When using this decorator, the public signature isn't the same as that # provided by the underlying function, as the first few positional # arguments are provided by the decorator sig = wrapper.signature for __ in shared_args: sig.popitem()

@shared_vars({})
def example(_state, arg1, arg2, arg3):
    # _state is for private communication between "shared_vars"

and the function # callers can't set it, and never see it (unless they dig into example.wrapped)

This has always been possible, but it's been a bad idea because of the way it breaks pydoc (including help(example)) and other automatic documentation tools. With a writable signature attribute it becomes possible to have our cake and eat it too.

If people really want to keep getullargspec() around then I want to at least add a note to the function that signature objects exist as an alternative (but not vice-versa). +1

Also +1, since inspect.getfullargspec() and inspect.signature() operate at different levels in order to answer different questions. The former asks "what is the actual signature", while the latter provides a way to ask "what is the effective signature".

That's why I see the PEP as more than just a way to more easily introspect function signatures: the ability to set a signature attribute and have the inspect module pay attention to it means it becomes possible to cleanly advertise the signature of callables that aren't actual functions, and also possible to derive a new signature from an existing one, without needing to care about the details of that existing signature (as in the example above, it's only necessary to know how the signature will change).

Cheers, Nick.

-- Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-Dev mailing list