diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/tools/python3/src/Objects/descrobject.c | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Objects/descrobject.c')
-rw-r--r-- | contrib/tools/python3/src/Objects/descrobject.c | 930 |
1 files changed, 465 insertions, 465 deletions
diff --git a/contrib/tools/python3/src/Objects/descrobject.c b/contrib/tools/python3/src/Objects/descrobject.c index 075a92d408..833120df50 100644 --- a/contrib/tools/python3/src/Objects/descrobject.c +++ b/contrib/tools/python3/src/Objects/descrobject.c @@ -1,14 +1,14 @@ /* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h" -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "pycore_object.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tupleobject.h" -#include "structmember.h" // PyMemberDef - -_Py_IDENTIFIER(getattr); - +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_object.h" +#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_tupleobject.h" +#include "structmember.h" // PyMemberDef + +_Py_IDENTIFIER(getattr); + /*[clinic input] class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" class property "propertyobject *" "&PyProperty_Type" @@ -72,16 +72,16 @@ wrapperdescr_repr(PyWrapperDescrObject *descr) } static int -descr_check(PyDescrObject *descr, PyObject *obj) +descr_check(PyDescrObject *descr, PyObject *obj) { if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for '%.100s' objects " - "doesn't apply to a '%.100s' object", + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", descr_name((PyDescrObject *)descr), "?", descr->d_type->tp_name, - Py_TYPE(obj)->tp_name); - return -1; + Py_TYPE(obj)->tp_name); + return -1; } return 0; } @@ -92,11 +92,11 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) /* Ensure a valid type. Class methods ignore obj. */ if (type == NULL) { if (obj != NULL) - type = (PyObject *)Py_TYPE(obj); + type = (PyObject *)Py_TYPE(obj); else { /* Wot - no type?! */ PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%.100s' " + "descriptor '%V' for type '%.100s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name); @@ -105,85 +105,85 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) } if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%.100s' " - "needs a type, not a '%.100s' as arg 2", + "descriptor '%V' for type '%.100s' " + "needs a type, not a '%.100s' as arg 2", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, - Py_TYPE(type)->tp_name); + Py_TYPE(type)->tp_name); return NULL; } if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' requires a subtype of '%.100s' " - "but received '%.100s'", + "descriptor '%V' requires a subtype of '%.100s' " + "but received '%.100s'", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, ((PyTypeObject *)type)->tp_name); return NULL; } - PyTypeObject *cls = NULL; - if (descr->d_method->ml_flags & METH_METHOD) { - cls = descr->d_common.d_type; - } - return PyCMethod_New(descr->d_method, type, NULL, cls); + PyTypeObject *cls = NULL; + if (descr->d_method->ml_flags & METH_METHOD) { + cls = descr->d_common.d_type; + } + return PyCMethod_New(descr->d_method, type, NULL, cls); } static PyObject * method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) { - if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; - } - if (descr_check((PyDescrObject *)descr, obj) < 0) { - return NULL; - } - if (descr->d_method->ml_flags & METH_METHOD) { - if (PyType_Check(type)) { - return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type); - } else { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' needs a type, not '%s', as arg 2", - descr_name((PyDescrObject *)descr), - Py_TYPE(type)->tp_name); - return NULL; - } - } else { - return PyCFunction_NewEx(descr->d_method, obj, NULL); - } + if (obj == NULL) { + Py_INCREF(descr); + return (PyObject *)descr; + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } + if (descr->d_method->ml_flags & METH_METHOD) { + if (PyType_Check(type)) { + return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type); + } else { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' needs a type, not '%s', as arg 2", + descr_name((PyDescrObject *)descr), + Py_TYPE(type)->tp_name); + return NULL; + } + } else { + return PyCFunction_NewEx(descr->d_method, obj, NULL); + } } static PyObject * member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) { - if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; - } - if (descr_check((PyDescrObject *)descr, obj) < 0) { - return NULL; - } - - if (descr->d_member->flags & READ_RESTRICTED) { - if (PySys_Audit("object.__getattr__", "Os", - obj ? obj : Py_None, descr->d_member->name) < 0) { - return NULL; - } - } - + if (obj == NULL) { + Py_INCREF(descr); + return (PyObject *)descr; + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } + + if (descr->d_member->flags & READ_RESTRICTED) { + if (PySys_Audit("object.__getattr__", "Os", + obj ? obj : Py_None, descr->d_member->name) < 0) { + return NULL; + } + } + return PyMember_GetOne((char *)obj, descr->d_member); } static PyObject * getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) { - if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; - } - if (descr_check((PyDescrObject *)descr, obj) < 0) { - return NULL; - } + if (obj == NULL) { + Py_INCREF(descr); + return (PyObject *)descr; + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } if (descr->d_getset->get != NULL) return descr->d_getset->get(obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, @@ -196,28 +196,28 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) static PyObject * wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) { - if (obj == NULL) { - Py_INCREF(descr); - return (PyObject *)descr; - } - if (descr_check((PyDescrObject *)descr, obj) < 0) { - return NULL; - } + if (obj == NULL) { + Py_INCREF(descr); + return (PyObject *)descr; + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } return PyWrapper_New((PyObject *)descr, obj); } static int -descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value) +descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value) { assert(obj != NULL); if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for '%.100s' objects " - "doesn't apply to a '%.100s' object", + "doesn't apply to a '%.100s' object", descr_name(descr), "?", descr->d_type->tp_name, - Py_TYPE(obj)->tp_name); - return -1; + Py_TYPE(obj)->tp_name); + return -1; } return 0; } @@ -225,22 +225,22 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value) static int member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) { - if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { - return -1; - } + if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { + return -1; + } return PyMember_SetOne((char *)obj, descr->d_member, value); } static int getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) { - if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { - return -1; - } - if (descr->d_getset->set != NULL) { + if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { + return -1; + } + if (descr->d_getset->set != NULL) { return descr->d_getset->set(obj, value, descr->d_getset->closure); - } + } PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), "?", @@ -248,238 +248,238 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) return -1; } - -/* Vectorcall functions for each of the PyMethodDescr calling conventions. - * - * First, common helpers - */ -static inline int -method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) + +/* Vectorcall functions for each of the PyMethodDescr calling conventions. + * + * First, common helpers + */ +static inline int +method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - assert(!PyErr_Occurred()); + assert(!PyErr_Occurred()); if (nargs < 1) { - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - PyErr_Format(PyExc_TypeError, - "unbound method %U needs an argument", funcstr); - Py_DECREF(funcstr); - } - return -1; - } - PyObject *self = args[0]; - if (descr_check((PyDescrObject *)func, self) < 0) { - return -1; - } - if (kwnames && PyTuple_GET_SIZE(kwnames)) { - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - PyErr_Format(PyExc_TypeError, - "%U takes no keyword arguments", funcstr); - Py_DECREF(funcstr); - } - return -1; - } - return 0; -} - -typedef void (*funcptr)(void); - -static inline funcptr -method_enter_call(PyThreadState *tstate, PyObject *func) -{ - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { - return NULL; - } - return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; -} - -/* Now the actual vectorcall functions */ -static PyObject * -method_vectorcall_VARARGS( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, kwnames)) { - return NULL; - } - PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); - if (argstuple == NULL) { - return NULL; - } - PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); - if (meth == NULL) { - Py_DECREF(argstuple); - return NULL; - } - PyObject *result = meth(args[0], argstuple); - Py_DECREF(argstuple); - _Py_LeaveRecursiveCall(tstate); - return result; -} - -static PyObject * -method_vectorcall_VARARGS_KEYWORDS( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, NULL)) { - return NULL; - } - PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); - if (argstuple == NULL) { - return NULL; - } - PyObject *result = NULL; - /* Create a temporary dict for keyword arguments */ - PyObject *kwdict = NULL; - if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) { - kwdict = _PyStack_AsDict(args + nargs, kwnames); - if (kwdict == NULL) { - goto exit; - } - } - PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords) - method_enter_call(tstate, func); - if (meth == NULL) { - goto exit; - } - result = meth(args[0], argstuple, kwdict); - _Py_LeaveRecursiveCall(tstate); -exit: - Py_DECREF(argstuple); - Py_XDECREF(kwdict); - return result; -} - -static PyObject * -method_vectorcall_FASTCALL_KEYWORDS_METHOD( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, NULL)) { - return NULL; - } - PyCMethod meth = (PyCMethod) method_enter_call(tstate, func); - if (meth == NULL) { - return NULL; - } - PyObject *result = meth(args[0], - ((PyMethodDescrObject *)func)->d_common.d_type, - args+1, nargs-1, kwnames); - Py_LeaveRecursiveCall(); - return result; -} - -static PyObject * -method_vectorcall_FASTCALL( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, kwnames)) { - return NULL; - } - _PyCFunctionFast meth = (_PyCFunctionFast) - method_enter_call(tstate, func); - if (meth == NULL) { + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "unbound method %U needs an argument", funcstr); + Py_DECREF(funcstr); + } + return -1; + } + PyObject *self = args[0]; + if (descr_check((PyDescrObject *)func, self) < 0) { + return -1; + } + if (kwnames && PyTuple_GET_SIZE(kwnames)) { + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes no keyword arguments", funcstr); + Py_DECREF(funcstr); + } + return -1; + } + return 0; +} + +typedef void (*funcptr)(void); + +static inline funcptr +method_enter_call(PyThreadState *tstate, PyObject *func) +{ + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { return NULL; } - PyObject *result = meth(args[0], args+1, nargs-1); - _Py_LeaveRecursiveCall(tstate); + return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; +} + +/* Now the actual vectorcall functions */ +static PyObject * +method_vectorcall_VARARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); + if (meth == NULL) { + Py_DECREF(argstuple); + return NULL; + } + PyObject *result = meth(args[0], argstuple); + Py_DECREF(argstuple); + _Py_LeaveRecursiveCall(tstate); return result; } -static PyObject * -method_vectorcall_FASTCALL_KEYWORDS( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, NULL)) { +static PyObject * +method_vectorcall_VARARGS_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyObject *result = NULL; + /* Create a temporary dict for keyword arguments */ + PyObject *kwdict = NULL; + if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) { + kwdict = _PyStack_AsDict(args + nargs, kwnames); + if (kwdict == NULL) { + goto exit; + } + } + PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords) + method_enter_call(tstate, func); + if (meth == NULL) { + goto exit; + } + result = meth(args[0], argstuple, kwdict); + _Py_LeaveRecursiveCall(tstate); +exit: + Py_DECREF(argstuple); + Py_XDECREF(kwdict); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL_KEYWORDS_METHOD( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + PyCMethod meth = (PyCMethod) method_enter_call(tstate, func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], + ((PyMethodDescrObject *)func)->d_common.d_type, + args+1, nargs-1, kwnames); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + _PyCFunctionFast meth = (_PyCFunctionFast) + method_enter_call(tstate, func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1); + _Py_LeaveRecursiveCall(tstate); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) + method_enter_call(tstate, func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1, kwnames); + _Py_LeaveRecursiveCall(tstate); + return result; +} + +static PyObject * +method_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 1) { + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes no arguments (%zd given)", funcstr, nargs-1); + Py_DECREF(funcstr); + } return NULL; } - _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) - method_enter_call(tstate, func); - if (meth == NULL) { + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], NULL); + _Py_LeaveRecursiveCall(tstate); + return result; +} + +static PyObject * +method_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 2) { + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes exactly one argument (%zd given)", + funcstr, nargs-1); + Py_DECREF(funcstr); + } return NULL; } - PyObject *result = meth(args[0], args+1, nargs-1, kwnames); - _Py_LeaveRecursiveCall(tstate); + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args[1]); + _Py_LeaveRecursiveCall(tstate); return result; } -static PyObject * -method_vectorcall_NOARGS( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, kwnames)) { - return NULL; - } - if (nargs != 1) { - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - PyErr_Format(PyExc_TypeError, - "%U takes no arguments (%zd given)", funcstr, nargs-1); - Py_DECREF(funcstr); - } - return NULL; - } - PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); - if (meth == NULL) { - return NULL; - } - PyObject *result = meth(args[0], NULL); - _Py_LeaveRecursiveCall(tstate); - return result; -} - -static PyObject * -method_vectorcall_O( - PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (method_check_args(func, args, nargs, kwnames)) { - return NULL; - } - if (nargs != 2) { - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - PyErr_Format(PyExc_TypeError, - "%U takes exactly one argument (%zd given)", - funcstr, nargs-1); - Py_DECREF(funcstr); - } - return NULL; - } - PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); - if (meth == NULL) { - return NULL; - } - PyObject *result = meth(args[0], args[1]); - _Py_LeaveRecursiveCall(tstate); - return result; -} - - -/* Instances of classmethod_descriptor are unlikely to be called directly. - For one, the analogous class "classmethod" (for Python classes) is not - callable. Second, users are not likely to access a classmethod_descriptor - directly, since it means pulling it from the class __dict__. - - This is just an excuse to say that this doesn't need to be optimized: - we implement this simply by calling __get__ and then calling the result. -*/ + +/* Instances of classmethod_descriptor are unlikely to be called directly. + For one, the analogous class "classmethod" (for Python classes) is not + callable. Second, users are not likely to access a classmethod_descriptor + directly, since it means pulling it from the class __dict__. + + This is just an excuse to say that this doesn't need to be optimized: + we implement this simply by calling __get__ and then calling the result. +*/ static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) { - Py_ssize_t argc = PyTuple_GET_SIZE(args); + Py_ssize_t argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%V' of '%.100s' " @@ -488,15 +488,15 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyDescr_TYPE(descr)->tp_name); return NULL; } - PyObject *self = PyTuple_GET_ITEM(args, 0); - PyObject *bound = classmethod_get(descr, NULL, self); - if (bound == NULL) { + PyObject *self = PyTuple_GET_ITEM(args, 0); + PyObject *bound = classmethod_get(descr, NULL, self); + if (bound == NULL) { return NULL; } - PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1, - argc-1, kwds); - Py_DECREF(bound); - return res; + PyObject *res = PyObject_VectorcallDict(bound, _PyTuple_ITEMS(args)+1, + argc-1, kwds); + Py_DECREF(bound); + return res; } Py_LOCAL_INLINE(PyObject *) @@ -545,7 +545,7 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, - Py_TYPE(self)->tp_name); + Py_TYPE(self)->tp_name); return NULL; } @@ -610,7 +610,7 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) } static PyObject * -descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored)) +descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), PyDescr_TYPE(descr), PyDescr_NAME(descr)); @@ -697,23 +697,23 @@ PyTypeObject PyMethodDescr_Type = { sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */ + offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ - PyVectorcall_Call, /* tp_call */ + PyVectorcall_Call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_HAVE_VECTORCALL | - Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -737,10 +737,10 @@ PyTypeObject PyClassMethodDescr_Type = { sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -774,10 +774,10 @@ PyTypeObject PyMemberDescr_Type = { sizeof(PyMemberDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)member_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -811,10 +811,10 @@ PyTypeObject PyGetSetDescr_Type = { sizeof(PyGetSetDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)getset_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -848,10 +848,10 @@ PyTypeObject PyWrapperDescr_Type = { sizeof(PyWrapperDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)wrapperdescr_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -862,8 +862,8 @@ PyTypeObject PyWrapperDescr_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -904,46 +904,46 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) PyObject * PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) { - /* Figure out correct vectorcall function to use */ - vectorcallfunc vectorcall; - switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | - METH_O | METH_KEYWORDS | METH_METHOD)) - { - case METH_VARARGS: - vectorcall = method_vectorcall_VARARGS; - break; - case METH_VARARGS | METH_KEYWORDS: - vectorcall = method_vectorcall_VARARGS_KEYWORDS; - break; - case METH_FASTCALL: - vectorcall = method_vectorcall_FASTCALL; - break; - case METH_FASTCALL | METH_KEYWORDS: - vectorcall = method_vectorcall_FASTCALL_KEYWORDS; - break; - case METH_NOARGS: - vectorcall = method_vectorcall_NOARGS; - break; - case METH_O: - vectorcall = method_vectorcall_O; - break; - case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: - vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD; - break; - default: - PyErr_Format(PyExc_SystemError, - "%s() method: bad call flags", method->ml_name); - return NULL; - } - + /* Figure out correct vectorcall function to use */ + vectorcallfunc vectorcall; + switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | + METH_O | METH_KEYWORDS | METH_METHOD)) + { + case METH_VARARGS: + vectorcall = method_vectorcall_VARARGS; + break; + case METH_VARARGS | METH_KEYWORDS: + vectorcall = method_vectorcall_VARARGS_KEYWORDS; + break; + case METH_FASTCALL: + vectorcall = method_vectorcall_FASTCALL; + break; + case METH_FASTCALL | METH_KEYWORDS: + vectorcall = method_vectorcall_FASTCALL_KEYWORDS; + break; + case METH_NOARGS: + vectorcall = method_vectorcall_NOARGS; + break; + case METH_O: + vectorcall = method_vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + default: + PyErr_Format(PyExc_SystemError, + "%s() method: bad call flags", method->ml_name); + return NULL; + } + PyMethodDescrObject *descr; descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, type, method->ml_name); - if (descr != NULL) { + if (descr != NULL) { descr->d_method = method; - descr->vectorcall = vectorcall; - } + descr->vectorcall = vectorcall; + } return (PyObject *)descr; } @@ -1026,30 +1026,30 @@ static PyMappingMethods mappingproxy_as_mapping = { 0, /* mp_ass_subscript */ }; -static PyObject * -mappingproxy_or(PyObject *left, PyObject *right) -{ - if (PyObject_TypeCheck(left, &PyDictProxy_Type)) { - left = ((mappingproxyobject*)left)->mapping; - } - if (PyObject_TypeCheck(right, &PyDictProxy_Type)) { - right = ((mappingproxyobject*)right)->mapping; - } - return PyNumber_Or(left, right); -} - -static PyObject * -mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other)) -{ - return PyErr_Format(PyExc_TypeError, - "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name); -} - -static PyNumberMethods mappingproxy_as_number = { - .nb_or = mappingproxy_or, - .nb_inplace_or = mappingproxy_ior, -}; - +static PyObject * +mappingproxy_or(PyObject *left, PyObject *right) +{ + if (PyObject_TypeCheck(left, &PyDictProxy_Type)) { + left = ((mappingproxyobject*)left)->mapping; + } + if (PyObject_TypeCheck(right, &PyDictProxy_Type)) { + right = ((mappingproxyobject*)right)->mapping; + } + return PyNumber_Or(left, right); +} + +static PyObject * +mappingproxy_ior(PyObject *self, PyObject *Py_UNUSED(other)) +{ + return PyErr_Format(PyExc_TypeError, + "'|=' is not supported by %s; use '|' instead", Py_TYPE(self)->tp_name); +} + +static PyNumberMethods mappingproxy_as_number = { + .nb_or = mappingproxy_or, + .nb_inplace_or = mappingproxy_ior, +}; + static int mappingproxy_contains(mappingproxyobject *pp, PyObject *key) { @@ -1073,64 +1073,64 @@ static PySequenceMethods mappingproxy_as_sequence = { }; static PyObject * -mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs) +mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs) { - /* newargs: mapping, key, default=None */ - PyObject *newargs[3]; - newargs[0] = pp->mapping; - newargs[2] = Py_None; + /* newargs: mapping, key, default=None */ + PyObject *newargs[3]; + newargs[0] = pp->mapping; + newargs[2] = Py_None; - if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2, - &newargs[1], &newargs[2])) - { + if (!_PyArg_UnpackStack(args, nargs, "get", 1, 2, + &newargs[1], &newargs[2])) + { return NULL; - } - _Py_IDENTIFIER(get); - return _PyObject_VectorcallMethodId(&PyId_get, newargs, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, - NULL); + } + _Py_IDENTIFIER(get); + return _PyObject_VectorcallMethodId(&PyId_get, newargs, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, + NULL); } static PyObject * -mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(keys); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys); } static PyObject * -mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(values); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values); } static PyObject * -mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(items); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items); } static PyObject * -mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(copy); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy); -} - -static PyObject * -mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) -{ - _Py_IDENTIFIER(__reversed__); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId___reversed__); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy); } +static PyObject * +mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(__reversed__); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId___reversed__); +} + /* WARNING: mappingproxy methods must not give access to the underlying mapping */ static PyMethodDef mappingproxy_methods[] = { - {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL, + {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL, PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d." " d defaults to None.")}, {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS, @@ -1141,10 +1141,10 @@ static PyMethodDef mappingproxy_methods[] = { PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS, PyDoc_STR("D.copy() -> a shallow copy of D")}, - {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, - PyDoc_STR("See PEP 585")}, - {"__reversed__", (PyCFunction)mappingproxy_reversed, METH_NOARGS, - PyDoc_STR("D.__reversed__() -> reverse iterator")}, + {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, + PyDoc_STR("See PEP 585")}, + {"__reversed__", (PyCFunction)mappingproxy_reversed, METH_NOARGS, + PyDoc_STR("D.__reversed__() -> reverse iterator")}, {0} }; @@ -1257,51 +1257,51 @@ typedef struct { PyObject *self; } wrapperobject; -#define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type) +#define Wrapper_Check(v) Py_IS_TYPE(v, &_PyMethodWrapper_Type) static void wrapper_dealloc(wrapperobject *wp) { PyObject_GC_UnTrack(wp); - Py_TRASHCAN_BEGIN(wp, wrapper_dealloc) + Py_TRASHCAN_BEGIN(wp, wrapper_dealloc) Py_XDECREF(wp->descr); Py_XDECREF(wp->self); PyObject_GC_Del(wp); - Py_TRASHCAN_END + Py_TRASHCAN_END } static PyObject * wrapper_richcompare(PyObject *a, PyObject *b, int op) { - wrapperobject *wa, *wb; - int eq; + wrapperobject *wa, *wb; + int eq; assert(a != NULL && b != NULL); /* both arguments should be wrapperobjects */ - if ((op != Py_EQ && op != Py_NE) - || !Wrapper_Check(a) || !Wrapper_Check(b)) - { + if ((op != Py_EQ && op != Py_NE) + || !Wrapper_Check(a) || !Wrapper_Check(b)) + { Py_RETURN_NOTIMPLEMENTED; } - wa = (wrapperobject *)a; - wb = (wrapperobject *)b; - eq = (wa->descr == wb->descr && wa->self == wb->self); - if (eq == (op == Py_EQ)) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; + wa = (wrapperobject *)a; + wb = (wrapperobject *)b; + eq = (wa->descr == wb->descr && wa->self == wb->self); + if (eq == (op == Py_EQ)) { + Py_RETURN_TRUE; } + else { + Py_RETURN_FALSE; + } } static Py_hash_t wrapper_hash(wrapperobject *wp) { Py_hash_t x, y; - x = _Py_HashPointer(wp->self); - y = _Py_HashPointer(wp->descr); + x = _Py_HashPointer(wp->self); + y = _Py_HashPointer(wp->descr); x = x ^ y; if (x == -1) x = -2; @@ -1313,12 +1313,12 @@ wrapper_repr(wrapperobject *wp) { return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>", wp->descr->d_base->name, - Py_TYPE(wp->self)->tp_name, + Py_TYPE(wp->self)->tp_name, wp->self); } static PyObject * -wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored)) +wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored)) { return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), wp->self, PyDescr_NAME(wp->descr)); @@ -1400,10 +1400,10 @@ PyTypeObject _PyMethodWrapper_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)wrapper_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)wrapper_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1555,7 +1555,7 @@ property_dealloc(PyObject *self) Py_XDECREF(gs->prop_set); Py_XDECREF(gs->prop_del); Py_XDECREF(gs->prop_doc); - Py_TYPE(self)->tp_free(self); + Py_TYPE(self)->tp_free(self); } static PyObject * @@ -1565,14 +1565,14 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) Py_INCREF(self); return self; } - - propertyobject *gs = (propertyobject *)self; + + propertyobject *gs = (propertyobject *)self; if (gs->prop_get == NULL) { PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - - return PyObject_CallOneArg(gs->prop_get, obj); + + return PyObject_CallOneArg(gs->prop_get, obj); } static int @@ -1593,7 +1593,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) return -1; } if (value == NULL) - res = PyObject_CallOneArg(func, obj); + res = PyObject_CallOneArg(func, obj); else res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); if (res == NULL) @@ -1702,25 +1702,25 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, /* if no docstring given and the getter has one, use that one */ if ((doc == NULL || doc == Py_None) && fget != NULL) { _Py_IDENTIFIER(__doc__); - PyObject *get_doc; - int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc); - if (rc <= 0) { - return rc; + PyObject *get_doc; + int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc); + if (rc <= 0) { + return rc; } - if (Py_IS_TYPE(self, &PyProperty_Type)) { - Py_XSETREF(self->prop_doc, get_doc); + if (Py_IS_TYPE(self, &PyProperty_Type)) { + Py_XSETREF(self->prop_doc, get_doc); } else { - /* If this is a property subclass, put __doc__ - in dict of the subclass instance instead, - otherwise it gets shadowed by __doc__ in the - class's dict. */ - int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); - Py_DECREF(get_doc); - if (err < 0) - return -1; + /* If this is a property subclass, put __doc__ + in dict of the subclass instance instead, + otherwise it gets shadowed by __doc__ in the + class's dict. */ + int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); + Py_DECREF(get_doc); + if (err < 0) + return -1; } - self->getter_doc = 1; + self->getter_doc = 1; } return 0; @@ -1791,12 +1791,12 @@ PyTypeObject PyDictProxy_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mappingproxy_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ (reprfunc)mappingproxy_repr, /* tp_repr */ - &mappingproxy_as_number, /* tp_as_number */ + &mappingproxy_as_number, /* tp_as_number */ &mappingproxy_as_sequence, /* tp_as_sequence */ &mappingproxy_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ @@ -1833,10 +1833,10 @@ PyTypeObject PyProperty_Type = { 0, /* tp_itemsize */ /* methods */ property_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ |