summaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Utility/CythonFunction.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/cython/Cython/Utility/CythonFunction.c')
-rw-r--r--contrib/tools/cython/Cython/Utility/CythonFunction.c147
1 files changed, 143 insertions, 4 deletions
diff --git a/contrib/tools/cython/Cython/Utility/CythonFunction.c b/contrib/tools/cython/Cython/Utility/CythonFunction.c
index 38e2f1cfc75..cbb7f743197 100644
--- a/contrib/tools/cython/Cython/Utility/CythonFunction.c
+++ b/contrib/tools/cython/Cython/Utility/CythonFunction.c
@@ -134,6 +134,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject
//@requires: ModuleSetupCode.c::IncludeStructmemberH
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: ObjectHandling.c::CachedMethodType
+//@requires: ObjectHandling.c::PyObjectCallOneArg
//@requires: ExtensionTypes.c::CallTypeTraverse
//@requires: Synchronization.c::CriticalSections
//@substitute: naming
@@ -461,6 +462,8 @@ __Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) {
return result;
}
+static int __Pyx_CyFunction_set_annotate_in_dict_if_exists(PyObject *op_in, PyObject *value); /*proto*/
+
static int
__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) {
CYTHON_UNUSED_VAR(context);
@@ -475,9 +478,59 @@ __Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, vo
__Pyx_BEGIN_CRITICAL_SECTION(op);
__Pyx_Py_XDECREF_SET(op->func_annotations, value);
__Pyx_END_CRITICAL_SECTION();
+ if (unlikely(__Pyx_CyFunction_set_annotate_in_dict_if_exists((PyObject*) op, Py_None) < 0)) return -1;
return 0;
}
+static int
+__Pyx_CyFunction_get_dict_if_exists(PyObject *op_in, PyObject **dict) {
+ /* Return 1 if the function dict exists, 0 otherwise. This cannot fail:
+ * _PyObject_GetDictPtr() may clear errors internally, but never reports them. */
+#if CYTHON_COMPILING_IN_PYPY
+ *dict = PyObject_GenericGetDict(op_in, NULL);
+#elif CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030C0000
+ *dict = ((__pyx_CyFunctionObject*) op_in)->func_dict;
+#else
+ PyObject **dictptr = _PyObject_GetDictPtr(op_in);
+ *dict = likely(dictptr) ? *dictptr : NULL;
+#endif
+ return *dict ? 1 : 0;
+}
+
+static int
+__Pyx_CyFunction_get_annotate_from_dict_if_exists(PyObject *op_in, PyObject **annotate) {
+ PyObject *dict;
+ int dict_found;
+ *annotate = NULL;
+ dict_found = __Pyx_CyFunction_get_dict_if_exists(op_in, &dict);
+ if (!dict_found) return 0;
+ return __Pyx_PyDict_GetItemRef(dict, PYIDENT("__annotate__"), annotate);
+}
+
+static int
+__Pyx_CyFunction_set_annotate_in_dict_if_exists(PyObject *op_in, PyObject *value) {
+ PyObject *dict;
+ int dict_found;
+ dict_found = __Pyx_CyFunction_get_dict_if_exists(op_in, &dict);
+ if (!dict_found) return 0;
+ return PyDict_SetItem(dict, PYIDENT("__annotate__"), value);
+}
+
+static int
+__Pyx_CyFunction_set_annotate_in_dict(PyObject *op_in, PyObject *value) {
+ PyObject *dict;
+ int result;
+#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000
+ dict = __Pyx_CyFunction_get_dict((__pyx_CyFunctionObject*) op_in, NULL);
+#else
+ dict = PyObject_GenericGetDict(op_in, NULL);
+#endif
+ if (unlikely(!dict)) return -1;
+ result = PyDict_SetItem(dict, PYIDENT("__annotate__"), value);
+ Py_DECREF(dict);
+ return result;
+}
+
static PyObject *
__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) {
PyObject* result = op->func_annotations;
@@ -491,15 +544,100 @@ __Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) {
}
static PyObject *
-__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) {
- PyObject *result;
+__Pyx_CyFunction_get_annotations(PyObject *op_in, void *context) {
+ PyObject *annotate = NULL;
+ PyObject *result = NULL;
+ __pyx_CyFunctionObject *op = (__pyx_CyFunctionObject*) op_in;
CYTHON_UNUSED_VAR(context);
- __Pyx_BEGIN_CRITICAL_SECTION(op);
- result = __Pyx_CyFunction_get_annotations_locked(op);
+ __Pyx_BEGIN_CRITICAL_SECTION(op_in);
+ result = __Pyx_XNewRef(op->func_annotations);
+ __Pyx_END_CRITICAL_SECTION();
+ if (result) return result;
+
+ if (unlikely(__Pyx_CyFunction_get_annotate_from_dict_if_exists(op_in, &annotate) < 0)) return NULL;
+ if (!annotate || annotate == Py_None) {
+ Py_XDECREF(annotate);
+ __Pyx_BEGIN_CRITICAL_SECTION(op_in);
+ result = __Pyx_CyFunction_get_annotations_locked(op);
+ __Pyx_END_CRITICAL_SECTION();
+ return result;
+ }
+
+ PyObject *format = PyLong_FromLong(1L); // annotationlib.Format.VALUE
+ if (likely(format)) {
+ result = __Pyx_PyObject_CallOneArg(annotate, format);
+ Py_DECREF(format);
+ }
+ Py_DECREF(annotate);
+ if (unlikely(!result)) return NULL;
+ if (unlikely(!PyDict_Check(result))) {
+ PyErr_SetString(PyExc_TypeError, "__annotate__ must return a dict");
+ Py_DECREF(result);
+ return NULL;
+ }
+ __Pyx_BEGIN_CRITICAL_SECTION(op_in);
+ __Pyx_Py_XDECREF_SET(op->func_annotations, __Pyx_NewRef(result));
__Pyx_END_CRITICAL_SECTION();
return result;
}
+static PyObject *__Pyx_CyFunction_annotate_impl(PyObject *self, PyObject *args) {
+ // The signature of this function is 0 or 1 args, where arg should be an int (if passed).
+ // However, for this basic placeholder implementation, we don't care and don't check it.
+ CYTHON_UNUSED_VAR(args);
+ if (unlikely(!self)) {
+ PyErr_SetString(PyExc_SystemError, "cython __annotate__ called without 'self' argument");
+ }
+ Py_XINCREF(self);
+ return self;
+}
+
+static PyMethodDef __Pyx_CyFunction_annotate_method = {
+ "__annotate__",
+ (PyCFunction)(void (*)(void))__Pyx_CyFunction_annotate_impl,
+ METH_VARARGS,
+ "Placeholder __annotate__ function to allow 'functools.wraps' to work "
+ "on Cython functions."
+};
+
+// We don't yet support PEP649 properly, so __annotate__ is
+// implemented in a minimal way, just so that functools.wraps works.
+static PyObject *
+__Pyx_CyFunction_get_annotate(PyObject *op_in, void *context) {
+ PyObject *annotate = NULL;
+ CYTHON_UNUSED_VAR(context);
+ if (unlikely(__Pyx_CyFunction_get_annotate_from_dict_if_exists(op_in, &annotate) < 0)) return NULL;
+ if (annotate) return annotate;
+
+ PyObject *annotations = __Pyx_CyFunction_get_annotations(op_in, NULL);
+ if (unlikely(!annotations)) return NULL;
+ PyObject *method = PyCFunction_New(
+ &__Pyx_CyFunction_annotate_method,
+ annotations);
+ Py_DECREF(annotations);
+ return method;
+}
+
+static int
+__Pyx_CyFunction_set_annotate(PyObject *op_in, PyObject* value, void *context) {
+ CYTHON_UNUSED_VAR(context);
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "__annotate__ cannot be deleted");
+ return -1;
+ }
+ if (unlikely(value != Py_None && !PyCallable_Check(value))) {
+ PyErr_SetString(PyExc_TypeError, "__annotate__ must be callable or None");
+ return -1;
+ }
+ if (value != Py_None) {
+ __pyx_CyFunctionObject *op = (__pyx_CyFunctionObject*) op_in;
+ __Pyx_BEGIN_CRITICAL_SECTION(op_in);
+ Py_CLEAR(op->func_annotations);
+ __Pyx_END_CRITICAL_SECTION();
+ }
+ return __Pyx_CyFunction_set_annotate_in_dict(op_in, value);
+}
+
static PyObject *
__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) {
int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE;
@@ -649,6 +787,7 @@ static PyGetSetDef __pyx_CyFunction_getsets[] = {
{"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
{"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
{"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {"__annotate__", (getter)__Pyx_CyFunction_get_annotate, (setter)__Pyx_CyFunction_set_annotate, 0, 0},
{"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0},
// {"__signature__", (getter)__Pyx_CyFunction_get_signature, 0, 0, 0},
#if CYTHON_COMPILING_IN_LIMITED_API