[Python-ideas] Conventions for Function Annotations
Mathias Panzenböck
grosser.meister.morti at gmx.net
Sun Aug 7 17:31:10 CEST 2011
On 08/07/2011 01:27 PM, dag.odenhall at gmail.com wrote:
> This isn't really a proposal for any sort of language/stdlib change,
> rather I felt like discussing the potential for informal standard
> conventions with annotations.
>
> Probably for the better, there is no special syntax for annotating
> raised exceptions or yields from a generator. In line with how the
> "->" syntax sets the 'return' key, I suggest an informal standard of
> representing keywords this way, for example in a decorator for
> raise/yield annotations:
>
> # third-party decorator
> @raises(ValueError)
> def foo():pass
>
> assert foo.__annotations__['raise'] == ValueError
>
I wrote something using the foo.__annotations__ convention a while back, but it wasn't received well
on this mailinglist. Here it is again now with an added `annotations` decorator:
"""
>>> @annotation
>>> def raises(*exceptions):
>>> return exceptions
>>>
>>> @raises(TypeError)
>>> def foo():
>>> pass
>>>
>>> getannot(foo,'raises')
(<type 'exceptions.TypeError'>,)
>>>
"""
from functools import wraps
def annotations(**annots):
def deco(obj):
if hasattr(obj,'__annotations__'):
obj.__annotations__.update(annots)
else:
obj.__annotations__ = annots
return obj
return deco
_NONE = object()
def getannot(obj, key, default=_NONE):
if hasattr(obj, '__annotations__'):
if default is _NONE:
return obj.__annotations__[key]
else:
return obj.__annotations__.get(key, default)
elif default is _NONE:
raise KeyError(key)
else:
return default
def setannot(obj, key, value):
if hasattr(obj, '__annotations__'):
obj.__annotations__[key] = value
else:
obj.__annotations__ = {key: value}
def hasannot(obj, key):
if hasattr(obj, '__annotations__'):
return key in obj.__annotations__
else:
return False
def annotation(annotfunc):
if hasattr(annotfunc, '__name__'):
key = annotfunc.__name__
else:
key = annotfunc.func_name
@wraps(annotfunc)
def params(*args,**kwargs):
def deco(obj):
setannot(obj, key, annotfunc(*args,**kwargs))
return obj
return deco
return params
More information about the Python-ideas
mailing list