Skip to content

Commit 3d7d16b

Browse files
committed
clinicize func object __annotations__ getter/setter
1 parent 117dcee commit 3d7d16b

File tree

2 files changed

+121
-52
lines changed

2 files changed

+121
-52
lines changed

Objects/clinic/funcobject.c.h

Lines changed: 59 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/funcobject.c

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -860,44 +860,6 @@ func_set_annotate(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
860860
}
861861
}
862862

863-
static PyObject *
864-
func_get_annotations(PyObject *self, void *Py_UNUSED(ignored))
865-
{
866-
PyFunctionObject *op = _PyFunction_CAST(self);
867-
PyObject *d = NULL;
868-
Py_BEGIN_CRITICAL_SECTION(self);
869-
if (op->func_annotations == NULL &&
870-
(op->func_annotate == NULL || !PyCallable_Check(op->func_annotate))) {
871-
op->func_annotations = PyDict_New();
872-
if (op->func_annotations == NULL)
873-
return NULL;
874-
}
875-
d = func_get_annotation_dict(op);
876-
Py_END_CRITICAL_SECTION();
877-
return Py_XNewRef(d);
878-
}
879-
880-
static int
881-
func_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
882-
{
883-
PyFunctionObject *op = _PyFunction_CAST(self);
884-
if (value == Py_None)
885-
value = NULL;
886-
/* Legal to del f.func_annotations.
887-
* Can only set func_annotations to NULL (through C api)
888-
* or a dict. */
889-
if (value != NULL && !PyDict_Check(value)) {
890-
PyErr_SetString(PyExc_TypeError,
891-
"__annotations__ must be set to a dict object");
892-
return -1;
893-
}
894-
Py_BEGIN_CRITICAL_SECTION(self);
895-
Py_XSETREF(op->func_annotations, Py_XNewRef(value));
896-
Py_CLEAR(op->func_annotate);
897-
Py_END_CRITICAL_SECTION();
898-
return 0;
899-
}
900-
901863
static PyObject *
902864
func_get_type_params(PyObject *self, void *Py_UNUSED(ignored))
903865
{
@@ -936,19 +898,6 @@ _Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func,
936898
return Py_NewRef(func);
937899
}
938900

939-
static PyGetSetDef func_getsetlist[] = {
940-
{"__code__", func_get_code, func_set_code},
941-
{"__defaults__", func_get_defaults, func_set_defaults},
942-
{"__kwdefaults__", func_get_kwdefaults, func_set_kwdefaults},
943-
{"__annotations__", func_get_annotations, func_set_annotations},
944-
{"__annotate__", func_get_annotate, func_set_annotate},
945-
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
946-
{"__name__", func_get_name, func_set_name},
947-
{"__qualname__", func_get_qualname, func_set_qualname},
948-
{"__type_params__", func_get_type_params, func_set_type_params},
949-
{NULL} /* Sentinel */
950-
};
951-
952901
/*[clinic input]
953902
class function "PyFunctionObject *" "&PyFunction_Type"
954903
[clinic start generated code]*/
@@ -1064,6 +1013,68 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
10641013
return (PyObject *)newfunc;
10651014
}
10661015

1016+
/*[clinic input]
1017+
@critical_section
1018+
@getter
1019+
function.__annotations__
1020+
1021+
Dict of annotations in a function object.
1022+
[clinic start generated code]*/
1023+
1024+
static PyObject *
1025+
function___annotations___get_impl(PyFunctionObject *self)
1026+
/*[clinic end generated code: output=a4cf4c884c934cbb input=ae1caef917be9bb2]*/
1027+
{
1028+
PyObject *d = NULL;
1029+
if (self->func_annotations == NULL &&
1030+
(self->func_annotate == NULL || !PyCallable_Check(self->func_annotate))) {
1031+
self->func_annotations = PyDict_New();
1032+
if (self->func_annotations == NULL)
1033+
return NULL;
1034+
}
1035+
d = func_get_annotation_dict(self);
1036+
return Py_XNewRef(d);
1037+
}
1038+
1039+
/*[clinic input]
1040+
@critical_section
1041+
@setter
1042+
function.__annotations__
1043+
[clinic start generated code]*/
1044+
1045+
static int
1046+
function___annotations___set_impl(PyFunctionObject *self, PyObject *value)
1047+
/*[clinic end generated code: output=a61795d4a95eede4 input=5302641f686f0463]*/
1048+
{
1049+
if (value == Py_None)
1050+
value = NULL;
1051+
/* Legal to del f.func_annotations.
1052+
* Can only set func_annotations to NULL (through C api)
1053+
* or a dict. */
1054+
if (value != NULL && !PyDict_Check(value)) {
1055+
PyErr_SetString(PyExc_TypeError,
1056+
"__annotations__ must be set to a dict object");
1057+
return -1;
1058+
}
1059+
Py_XSETREF(self->func_annotations, Py_XNewRef(value));
1060+
Py_CLEAR(self->func_annotate);
1061+
return 0;
1062+
}
1063+
1064+
static PyGetSetDef func_getsetlist[] = {
1065+
{"__code__", func_get_code, func_set_code},
1066+
{"__defaults__", func_get_defaults, func_set_defaults},
1067+
{"__kwdefaults__", func_get_kwdefaults, func_set_kwdefaults},
1068+
FUNCTION___ANNOTATIONS___GETSETDEF
1069+
{"__annotate__", func_get_annotate, func_set_annotate},
1070+
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1071+
{"__name__", func_get_name, func_set_name},
1072+
{"__qualname__", func_get_qualname, func_set_qualname},
1073+
{"__type_params__", func_get_type_params, func_set_type_params},
1074+
{NULL} /* Sentinel */
1075+
};
1076+
1077+
10671078
static int
10681079
func_clear(PyObject *self)
10691080
{

0 commit comments

Comments
 (0)