Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
Description
Bug report
Bug description:
According to the Python docs, annotate functions need to be actual functions. However, the C code doesn't enforce this, it enforces (using PyCallable_Check()) that the annotate 'function' is any callable:
Lines 865 to 888 in 9cb8c52
| staticint | |
| function___annotate___set_impl(PyFunctionObject*self, PyObject*value) | |
| /*[clinic end generated code: output=05b7dfc07ada66cd input=eb6225e358d97448]*/ | |
| { | |
| if (value==NULL){ | |
| PyErr_SetString(PyExc_TypeError, | |
| "__annotate__ cannot be deleted"); | |
| return-1; | |
| } | |
| if (Py_IsNone(value)){ | |
| Py_XSETREF(self->func_annotate, value); | |
| return0; | |
| } | |
| elseif (PyCallable_Check(value)){ | |
| Py_XSETREF(self->func_annotate, Py_XNewRef(value)); | |
| Py_CLEAR(self->func_annotations); | |
| return0; | |
| } | |
| else{ | |
| PyErr_SetString(PyExc_TypeError, | |
| "__annotate__ must be callable or None"); | |
| return-1; | |
| } | |
| } |
This initially seems fine, but leads to some weird bugs.
classC: def__call__(self, format, /): ifformat>2: raiseNotImplementedErrorreturn{'x': int} deff(x): ... f.__annotate__=C() fromannotationlibimportget_annotations, Formatget_annotations(f, format=Format.STRING) # AttributeError: 'C' object has no attribute '__closure__' ...And similar for get_annotations(f, format=Format.FORWARDREF), trying to find the annotation function's __builtins__, which only exists on functions (not arbitrary callables).
I'm happy to make a PR to replace the PyCallable_Check() with PyFunction_Check() in the relevant C code for setting __annotate__, but I guess this might be a breaking change? I'm not sure, so I thought I'd check first before making it. The other option would be checking for the presence of __closure__/__builtins__/etc. before accessing them in annotationlib.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux