Skip to content

Commit bdddeaf

Browse files
committed
clinic getset methods which is not performance critical
1 parent 92c52fd commit bdddeaf

File tree

2 files changed

+253
-39
lines changed

2 files changed

+253
-39
lines changed

Objects/clinic/funcobject.c.h

Lines changed: 173 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: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,13 @@ static PyMemberDef func_memberlist[] = {
636636
{NULL} /* Sentinel */
637637
};
638638

639+
/*[clinic input]
640+
class function "PyFunctionObject *" "&PyFunction_Type"
641+
[clinic start generated code]*/
642+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/
643+
644+
#include "clinic/funcobject.c.h"
645+
639646
static PyObject *
640647
func_get_code(PyObject *self, void *Py_UNUSED(ignored))
641648
{
@@ -825,32 +832,46 @@ func_set_kwdefaults(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
825832
return 0;
826833
}
827834

835+
/*[clinic input]
836+
@critical_section
837+
@getter
838+
function.__annotate__
839+
840+
Get the code object for a function.
841+
[clinic start generated code]*/
842+
828843
static PyObject *
829-
func_get_annotate(PyObject *self, void *Py_UNUSED(ignored))
844+
function___annotate___get_impl(PyFunctionObject *self)
845+
/*[clinic end generated code: output=5ec7219ff2bda9e6 input=7f3db11e3c3329f3]*/
830846
{
831-
PyFunctionObject *op = _PyFunction_CAST(self);
832-
if (op->func_annotate == NULL) {
847+
if (self->func_annotate == NULL) {
833848
Py_RETURN_NONE;
834849
}
835-
return Py_NewRef(op->func_annotate);
850+
return Py_NewRef(self->func_annotate);
836851
}
837852

853+
/*[clinic input]
854+
@critical_section
855+
@setter
856+
function.__annotate__
857+
[clinic start generated code]*/
858+
838859
static int
839-
func_set_annotate(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
860+
function___annotate___set_impl(PyFunctionObject *self, PyObject *value)
861+
/*[clinic end generated code: output=05b7dfc07ada66cd input=eb6225e358d97448]*/
840862
{
841-
PyFunctionObject *op = _PyFunction_CAST(self);
842863
if (value == NULL) {
843864
PyErr_SetString(PyExc_TypeError,
844865
"__annotate__ cannot be deleted");
845866
return -1;
846867
}
847868
if (Py_IsNone(value)) {
848-
Py_XSETREF(op->func_annotate, value);
869+
Py_XSETREF(self->func_annotate, value);
849870
return 0;
850871
}
851872
else if (PyCallable_Check(value)) {
852-
Py_XSETREF(op->func_annotate, Py_XNewRef(value));
853-
Py_CLEAR(op->func_annotations);
873+
Py_XSETREF(self->func_annotate, Py_XNewRef(value));
874+
Py_CLEAR(self->func_annotations);
854875
return 0;
855876
}
856877
else {
@@ -860,27 +881,41 @@ func_set_annotate(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
860881
}
861882
}
862883

884+
/*[clinic input]
885+
@critical_section
886+
@getter
887+
function.__annotations__
888+
889+
Dict of annotations in a function object.
890+
[clinic start generated code]*/
891+
863892
static PyObject *
864-
func_get_annotations(PyObject *self, void *Py_UNUSED(ignored))
893+
function___annotations___get_impl(PyFunctionObject *self)
894+
/*[clinic end generated code: output=a4cf4c884c934cbb input=92643d7186c1ad0c]*/
865895
{
866-
PyFunctionObject *op = _PyFunction_CAST(self);
867896
PyObject *d = NULL;
868897
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)
898+
if (self->func_annotations == NULL &&
899+
(self->func_annotate == NULL || !PyCallable_Check(self->func_annotate))) {
900+
self->func_annotations = PyDict_New();
901+
if (self->func_annotations == NULL)
873902
return NULL;
874903
}
875-
d = func_get_annotation_dict(op);
904+
d = func_get_annotation_dict(self);
876905
Py_END_CRITICAL_SECTION();
877906
return Py_XNewRef(d);
878907
}
879908

909+
/*[clinic input]
910+
@critical_section
911+
@setter
912+
function.__annotations__
913+
[clinic start generated code]*/
914+
880915
static int
881-
func_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
916+
function___annotations___set_impl(PyFunctionObject *self, PyObject *value)
917+
/*[clinic end generated code: output=a61795d4a95eede4 input=5302641f686f0463]*/
882918
{
883-
PyFunctionObject *op = _PyFunction_CAST(self);
884919
if (value == Py_None)
885920
value = NULL;
886921
/* Legal to del f.func_annotations.
@@ -892,36 +927,50 @@ func_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
892927
return -1;
893928
}
894929
Py_BEGIN_CRITICAL_SECTION(self);
895-
Py_XSETREF(op->func_annotations, Py_XNewRef(value));
896-
Py_CLEAR(op->func_annotate);
930+
Py_XSETREF(self->func_annotations, Py_XNewRef(value));
931+
Py_CLEAR(self->func_annotate);
897932
Py_END_CRITICAL_SECTION();
898933
return 0;
899934
}
900935

936+
/*[clinic input]
937+
@critical_section
938+
@getter
939+
function.__type_params__
940+
941+
Get the declared type parameters for a function.
942+
[clinic start generated code]*/
943+
901944
static PyObject *
902-
func_get_type_params(PyObject *self, void *Py_UNUSED(ignored))
945+
function___type_params___get_impl(PyFunctionObject *self)
946+
/*[clinic end generated code: output=eb844d7ffca517a8 input=0864721484293724]*/
903947
{
904-
PyFunctionObject *op = _PyFunction_CAST(self);
905-
if (op->func_typeparams == NULL) {
948+
if (self->func_typeparams == NULL) {
906949
return PyTuple_New(0);
907950
}
908951

909-
assert(PyTuple_Check(op->func_typeparams));
910-
return Py_NewRef(op->func_typeparams);
952+
assert(PyTuple_Check(self->func_typeparams));
953+
return Py_NewRef(self->func_typeparams);
911954
}
912955

956+
/*[clinic input]
957+
@critical_section
958+
@setter
959+
function.__type_params__
960+
[clinic start generated code]*/
961+
913962
static int
914-
func_set_type_params(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
963+
function___type_params___set_impl(PyFunctionObject *self, PyObject *value)
964+
/*[clinic end generated code: output=038b4cda220e56fb input=3862fbd4db2b70e8]*/
915965
{
916966
/* Not legal to del f.__type_params__ or to set it to anything
917967
* other than a tuple object. */
918-
PyFunctionObject *op = _PyFunction_CAST(self);
919968
if (value == NULL || !PyTuple_Check(value)) {
920969
PyErr_SetString(PyExc_TypeError,
921970
"__type_params__ must be set to a tuple");
922971
return -1;
923972
}
924-
Py_XSETREF(op->func_typeparams, Py_NewRef(value));
973+
Py_XSETREF(self->func_typeparams, Py_NewRef(value));
925974
return 0;
926975
}
927976

@@ -940,22 +989,15 @@ static PyGetSetDef func_getsetlist[] = {
940989
{"__code__", func_get_code, func_set_code},
941990
{"__defaults__", func_get_defaults, func_set_defaults},
942991
{"__kwdefaults__", func_get_kwdefaults, func_set_kwdefaults},
943-
{"__annotations__", func_get_annotations, func_set_annotations},
944-
{"__annotate__", func_get_annotate, func_set_annotate},
992+
FUNCTION___ANNOTATIONS___GETSETDEF
993+
FUNCTION___ANNOTATE___GETSETDEF
945994
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
946995
{"__name__", func_get_name, func_set_name},
947996
{"__qualname__", func_get_qualname, func_set_qualname},
948-
{"__type_params__", func_get_type_params, func_set_type_params},
997+
FUNCTION___TYPE_PARAMS___GETSETDEF
949998
{NULL} /* Sentinel */
950999
};
9511000

952-
/*[clinic input]
953-
class function "PyFunctionObject *" "&PyFunction_Type"
954-
[clinic start generated code]*/
955-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/
956-
957-
#include "clinic/funcobject.c.h"
958-
9591001
/* function.__new__() maintains the following invariants for closures.
9601002
The closure must correspond to the free variables of the code object.
9611003

0 commit comments

Comments
 (0)