[Python-3000] signature annotation in the function signature or a separate line

Nick Coghlan ncoghlan at gmail.com
Sat Aug 19 19:54:00 CEST 2006

Samuele Pedroni wrote:
> Guido van Rossum wrote:
>>> But maybe I'm misremembering the discussion, maybe decorators make it
>>> very difficult to visually scan for function definitions, and maybe
>>> people want all that garbage in their function signature.
>> They don't want it, but if they're forced to have it occasionally
>> they'll cope. I still think you're way overestimating the importance
>> of this use case.
> Given that the meaning of annotations is meant not be predefined,
> given that people are comining with arbitrarely verbose examples
> thereof, given the precedent of type inferenced languages
> that use a separate line for optional type information I think
> devising a way to have the annotation on a different line
> with a decorator like introduction instead of mixed with
> the function head would be saner:
> One possibility would be to have a syntax for signature expressions
> and then allow them as decorators with the obvious effect of attaching
> themself:
> @sig int,int -> int
> def f(a,b):
>      return a+b
> or with argument optional argument names:
> @sig a: int,b: int -> int
> def f(a,b):
>      return a+b
> sig expressions (possibly with parens) would be first class
> and be able to appear anywhere an expression is allowed,
> they would produce an object embedding the signature information.

What would a separate sig expression buy you over defining "->expr" as a 
special form of keyword argument that binds to the keyword name "return" in 
the dictionary for storing extra keyword arguments?

With the argument based approach, the two above examples would look like:

@sig(int, int, ->int)
def f(a,b):
      return a+b

@sig(a=int, b=int, ->int)
def f(a,b):
      return a+b

The implementation of sig might look something like:
   def sig(*args, **kwds):
       def annotator(f):
           # Assume bind() is defined to pass through any
           # 'return' binding into the returned mapping
           # Otherwise, it uses normal parameter binding
           notes = f.__signature__.bind(*args, **kwds)
           f.__signature__.annotations = notes
           return f
       return annotator

The longer this discussion goes on, the more convinced I become that making it 
easier to write decorator factories that produce decorators that map the 
factory's arguments to the decorated function's parameters is a better idea 
than adding function annotations directly to the function signature.


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

More information about the Python-3000 mailing list