Note that PEP 563 semantics allows more efficient implementation. Annotation is just a single constant tuple, not a dict. We already have the efficient implementation for Python 3.10. The efficient implementation in 3.10 can share tuples. If there are hundreds of methods with the same signature, annotation is just a single tuple, not hundreds of tuples. This is very efficient for auto generated codebase. I think this PEP can share the code objects for same signature by removing co_firstlineno information too.
That's very clever! My co_annotations repo was branched from
before this feature was added, and I haven't pulled and merged
recently. So I hadn't seen it.
Additionally, we should include the cost for loading annotations from PYC files, because most annotations are "load once, set once". Loading "simple code object" from pyc files is not so cheap. It may affect importing time of large annotated codebase and memory footprints.
I did some analysis in a separate message. The summary is, the
code object for a single annotation costs us 232 bytes; that
includes the code object itself, the bytestring for the bytecode,
and the bytestring for the lnotab. This grows slowly as you add
new parameters; the code object for ten parameters is 360 bytes.
It seems possible to create a hybrid of these two approaches!
Here's my idea: instead of the compiler storing a code object as
the annotations argument to MAKE_FUNCTION, store a tuple
containing the fields you'd need to recreate the code
object at runtime--bytecode, lnotab, names, consts, etc.
func_get_annotations would create the code object from that, bind
it to a function object, call it, and return the result. These
code-object-tuples would then be automatically shared in the .pyc
file and at runtime the same way that 3.10 shares the tuples of
stringized annotations today.
That said, I suggest PEP 649's memory consumption isn't an urgent consideration in choosing to accept or reject it. PEP 649 is competitive in terms of startup time and memory usage with PEP 563, and PEP 563 was accepted and shipped with several versions of Python.
Cheers,
/arry