[Python-3000] Conventions for annotation consumers (was: Re: Draft pre-PEP: function annotations)

Paul Prescod paul at prescod.net
Tue Aug 15 17:18:31 CEST 2006


I totally do not understand the requirement for the dictionary and its extra
overhead.

On 8/15/06, Collin Winter <collinw at gmail.com> wrote:
>
>
> @typechecker
> def foo(a: {'type': Number},
>        b: {'type': Number}) -> {'type': Number}
>
>
> I'm going to raise the bar for future ideas on this subject: any
> proposals must be able to address the following use cases:
>
> 1) Static analysis tools (pychecker, optimising compilers, etc) must
> be able to use the annotations
> 2) Decorator-based annotation consumers must be able to use the
> annotations
> 3) Non-decorator-based annotation consumers (pydoc, etc) must be able
> to use the annotations


Consider the following syntax:

class MyType:
   def __init__(self, name):
        self.name = name

Number = MyType("Number")
Tuple = MyTime("Tuple")

def foo(a: tc(Number)) -> Tuple(Number, Number)

1. Static analysis tools can deal with this as much as with ANY truly
Pythonic syntax. Their ability to deal will depend (as in any syntax) on
their ability to do module or whole-program analysis. In your syntax, or
mine, "Number" could be defined dynamically. In either case, someone could
say "Number = None" and confuse everything.

2. A decorator based anaysis could look at __signatures__ and do what it
needs.

3. Similarly for non-decorator analyzers.

In fact, given that decorators are just syntactic sugar for function calls,
I don't see why they should require special consideration at all. If the
syntax works well for non-decorator consumers then decorators will be just a
special case. As far as static analysis tools: Python has never made major
concessions to them. Minor concessions, yes.

I'd ask that you add the following requirement:

 * must define how multiple annotation syntaxes can assign potentially
differing meanings to built-in types and objects, on the same parameter,
without actually conflicting

My full program (meeting all requirements) follows.

 Paul Prescod

====

def simulate_signature(sig):
    "simulates the signature feature of Pythn 3000"
    def _(func):
        func.__signature__ = sig
        return func
    return _

def my_print_signature(func):
    "a demo decorator that prints signatures."
    if hasattr(func, "__signature__"):
        sig = func.__signature__
        [my_print_arg(name, value) for name, value in sig.items()]
    return func

def my_print_arg(name, annotation):
    """print a single argument's
        declaration, skipping unknown anno types."""
    if isinstance(annotation, list):
        [my_print_arg(name, anno)
                for anno in annotation]
    elif conformsToInterface(annotation, MyType):
        print name
        annotation.print_arg()

def conformsToInterface(object, interface):
   "naive implemenation of interfaces"
   return isinstance(object, interface)

class MyType:
   def __init__(self, *children):
        self.children = children
   def print_arg(self):
        print self.children

#defined in your module. I have no knowledge of it
class YourType:
   def __init__(self, *stuff):
        pass

# a simple signature

# real syntax should be:
# def foo(bar: MyType(int))
@simulate_signature({"bar": MyType(int)})
def foo(bar):
        return (bar, bar)

# use print signature decorator

# real syntax should be:
# def foo2(bar: [MyType(int)...]) -> [MyType(...]
@my_print_signature
@simulate_signature({"bar": [MyType(int), YourType("int")],
                        "return": [MyType(tuple([int, int])),
                                   YourType("tuple of int,int")]})
def foo2(bar):
        return (bar, bar)

# can also be used as non-decorator
for name, val in vars().items():
    my_print_signature(val)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-3000/attachments/20060815/6cee76da/attachment.html 


More information about the Python-3000 mailing list