On Jan 4, 2016, at 19:08, Emanuel Barry firstname.lastname@example.org wrote:
Output from both 3.4.1 and 3.5.0:
def foo(): pass foo.__annotations__
Probably an oversight. I'm also not a C expert, but func_get_annotations (line 396 and onwards in funcobject.c) explicitely returns a new, empty dict if the function doesn't have any annotations (unlike all the other slots, like __defaults__ or __kwdefaults__, which merely return None if they're not present).
But that code implies if you just create a new function object and never check its __annotations__, it's not wasting any space for them. Otherwise, it wouldn't have to check for NULL there.
We can't test this _directly_ from Python, but with a bit of ctypes hackery and funcobject.h, we can define a PyFunctionObject(Structure)... or, keeping things a bit more concise but a lot more hacky for the purposes of email:
def func(): pass pf = cast(id(func), POINTER(c_voidp)) assert pf == id(func.__code__) assert not pf f.__annotations__ assert pf
So it is indeed NULL until you check it, and then it becomes something (an empty dict).