Skip to content

annotationlib: Simplify __closure__ and __code__.co_freevars access in annotationlib._build_closure #141489

@dr-carlos

Description

@dr-carlos

Feature or enhancement

Proposal:

Currently, every time annotationlib runs a function in a fake globals namespace, it builds a closure with _build_closure(). This function iterates over the closure variables in func.__closure__ and names them in __code__.co_freevars, defaulting to "cell" if the variable is unnamed:

if i < len(freevars):
name = freevars[i]
else:
name = "__cell__"

This default process is fine, but as far as I can tell, it is unnecessary and cannot be tested (as in #141174)

A function's __closure__ attribute is read-only, and is always generated with the same length as __code__.co_freevars by the compiler. __code__ itself is writable, but can only be set to a code object, which cannot be subclassed. Furthermore, when assigning a function's __code__ attribute, its co_freevars is enforced as being the same length as the __closure__.

A non-function could be passed as an 'annotate function' with custom __code__ and __closure__ attributes - except when the function is run in a fake globals namespace, it is re-created through the types.FunctionType constructor, which enforces its __code__ being an actual code object.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions