-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Description
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:
Lines 842 to 845 in 781cc68
| 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