![](https://secure.gravatar.com/avatar/7b647ef007327af1dfe4d14c9e56789b.jpg?s=120&d=mm&r=g)
Hi! To help automatic document generators and static type checkers reason more about the code, the possible side-effects and raised exceptions could also be annotated in a standardized way. I'll let some example code talk on my behalf. Here's a simple decorator for annotating exceptions: In [1]: import typing as t In [2]: def raises(exc: Exception) -> t.Callable: ...: def decorator(fn: t.Callable) -> t.Callable: ...: fn.__annotations__["__raises__"] = exc ...: return fn ...: return decorator ...: In [3]: @raises(ValueError) ...: def hello_if_5(x: int) -> None: ...: if x != 5: ...: raise ValueError("number other than 5 given") ...: print("Hello!") ...: In [4]: hello_if_5.__annotations__ Out[4]: {'x': int, 'return': None, '__raises__': ValueError} In [5]: hello_if_5(1) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-5-7fb1d79ce3f4> in <module> ----> 1 hello_if_5(1) <ipython-input-3-1084d197ce1b> in hello_if_5(x) 2 def hello_if_5(x: int) -> None: 3 if x != 5: ----> 4 raise ValueError("number other than 5 given") 5 print("Hello!") 6 ValueError: number other than 5 given In [6]: hello_if_5(5) Hello! In [7]: and here's a simple decorator for annotating side-effects: In [1]: import typing as t In [2]: def side_effect(has_side_effect: bool) -> t.Callable: ...: def decorator(fn: t.Callable) -> t.Callable: ...: fn.__annotations__["__side_effect__"] = has_side_effect ...: return fn ...: return decorator ...: In [3]: a = 10 In [4]: @side_effect(True) ...: def change_a(val: int) -> None: ...: global a ...: a = val ...: In [5]: change_a.__annotations__ Out[5]: {'val': int, 'return': None, '__side_effect__': True} In [6]: change_a(100) In [7]: a Out[7]: 100 In [8]: @side_effect(True) ...: def mutate_list(items: t.List) -> None: ...: items.append("new item") ...: In [9]: mutate_list.__annotations__ Out[9]: {'items': typing.List, 'return': None, '__side_effect__': True} In [10]: l = ["old item"] In [11]: mutate_list(l) In [12]: l Out[12]: ['old item', 'new item'] In [13]: The example implementations have some obvious limitations, such as only allowing one error type. What do you think of the idea in general? Do you feel this is something that could be included in Python? typing would probably be a good module to store such decorators, I guess… Miikka Salminen miikka.salminen@gmail.com