![](https://secure.gravatar.com/avatar/d264e9dd3768e50e27aa3364cdfe3b6d.jpg?s=120&d=mm&r=g)
On 08/07/2011 01:27 PM, dag.odenhall@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