17db96d56Sopenharmony_ci/* Abstract Object Interface (many thanks to Jim Fulton) */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#include "Python.h" 47db96d56Sopenharmony_ci#include "pycore_abstract.h" // _PyIndex_Check() 57db96d56Sopenharmony_ci#include "pycore_call.h" // _PyObject_CallNoArgs() 67db96d56Sopenharmony_ci#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() 77db96d56Sopenharmony_ci#include "pycore_object.h" // _Py_CheckSlotResult() 87db96d56Sopenharmony_ci#include "pycore_pyerrors.h" // _PyErr_Occurred() 97db96d56Sopenharmony_ci#include "pycore_pystate.h" // _PyThreadState_GET() 107db96d56Sopenharmony_ci#include "pycore_unionobject.h" // _PyUnion_Check() 117db96d56Sopenharmony_ci#include <ctype.h> 127db96d56Sopenharmony_ci#include <stddef.h> // offsetof() 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci/* Shorthands to return certain errors */ 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_cistatic PyObject * 197db96d56Sopenharmony_citype_error(const char *msg, PyObject *obj) 207db96d56Sopenharmony_ci{ 217db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, msg, Py_TYPE(obj)->tp_name); 227db96d56Sopenharmony_ci return NULL; 237db96d56Sopenharmony_ci} 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_cistatic PyObject * 267db96d56Sopenharmony_cinull_error(void) 277db96d56Sopenharmony_ci{ 287db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 297db96d56Sopenharmony_ci if (!_PyErr_Occurred(tstate)) { 307db96d56Sopenharmony_ci _PyErr_SetString(tstate, PyExc_SystemError, 317db96d56Sopenharmony_ci "null argument to internal routine"); 327db96d56Sopenharmony_ci } 337db96d56Sopenharmony_ci return NULL; 347db96d56Sopenharmony_ci} 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci/* Operations on any object */ 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ciPyObject * 397db96d56Sopenharmony_ciPyObject_Type(PyObject *o) 407db96d56Sopenharmony_ci{ 417db96d56Sopenharmony_ci PyObject *v; 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci if (o == NULL) { 447db96d56Sopenharmony_ci return null_error(); 457db96d56Sopenharmony_ci } 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci v = (PyObject *)Py_TYPE(o); 487db96d56Sopenharmony_ci Py_INCREF(v); 497db96d56Sopenharmony_ci return v; 507db96d56Sopenharmony_ci} 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ciPy_ssize_t 537db96d56Sopenharmony_ciPyObject_Size(PyObject *o) 547db96d56Sopenharmony_ci{ 557db96d56Sopenharmony_ci if (o == NULL) { 567db96d56Sopenharmony_ci null_error(); 577db96d56Sopenharmony_ci return -1; 587db96d56Sopenharmony_ci } 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; 617db96d56Sopenharmony_ci if (m && m->sq_length) { 627db96d56Sopenharmony_ci Py_ssize_t len = m->sq_length(o); 637db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); 647db96d56Sopenharmony_ci return len; 657db96d56Sopenharmony_ci } 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci return PyMapping_Size(o); 687db96d56Sopenharmony_ci} 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci#undef PyObject_Length 717db96d56Sopenharmony_ciPy_ssize_t 727db96d56Sopenharmony_ciPyObject_Length(PyObject *o) 737db96d56Sopenharmony_ci{ 747db96d56Sopenharmony_ci return PyObject_Size(o); 757db96d56Sopenharmony_ci} 767db96d56Sopenharmony_ci#define PyObject_Length PyObject_Size 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ciint 797db96d56Sopenharmony_ci_PyObject_HasLen(PyObject *o) { 807db96d56Sopenharmony_ci return (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) || 817db96d56Sopenharmony_ci (Py_TYPE(o)->tp_as_mapping && Py_TYPE(o)->tp_as_mapping->mp_length); 827db96d56Sopenharmony_ci} 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci/* The length hint function returns a non-negative value from o.__len__() 857db96d56Sopenharmony_ci or o.__length_hint__(). If those methods aren't found the defaultvalue is 867db96d56Sopenharmony_ci returned. If one of the calls fails with an exception other than TypeError 877db96d56Sopenharmony_ci this function returns -1. 887db96d56Sopenharmony_ci*/ 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ciPy_ssize_t 917db96d56Sopenharmony_ciPyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) 927db96d56Sopenharmony_ci{ 937db96d56Sopenharmony_ci PyObject *hint, *result; 947db96d56Sopenharmony_ci Py_ssize_t res; 957db96d56Sopenharmony_ci if (_PyObject_HasLen(o)) { 967db96d56Sopenharmony_ci res = PyObject_Length(o); 977db96d56Sopenharmony_ci if (res < 0) { 987db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 997db96d56Sopenharmony_ci assert(_PyErr_Occurred(tstate)); 1007db96d56Sopenharmony_ci if (!_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { 1017db96d56Sopenharmony_ci return -1; 1027db96d56Sopenharmony_ci } 1037db96d56Sopenharmony_ci _PyErr_Clear(tstate); 1047db96d56Sopenharmony_ci } 1057db96d56Sopenharmony_ci else { 1067db96d56Sopenharmony_ci return res; 1077db96d56Sopenharmony_ci } 1087db96d56Sopenharmony_ci } 1097db96d56Sopenharmony_ci hint = _PyObject_LookupSpecial(o, &_Py_ID(__length_hint__)); 1107db96d56Sopenharmony_ci if (hint == NULL) { 1117db96d56Sopenharmony_ci if (PyErr_Occurred()) { 1127db96d56Sopenharmony_ci return -1; 1137db96d56Sopenharmony_ci } 1147db96d56Sopenharmony_ci return defaultvalue; 1157db96d56Sopenharmony_ci } 1167db96d56Sopenharmony_ci result = _PyObject_CallNoArgs(hint); 1177db96d56Sopenharmony_ci Py_DECREF(hint); 1187db96d56Sopenharmony_ci if (result == NULL) { 1197db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 1207db96d56Sopenharmony_ci if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { 1217db96d56Sopenharmony_ci _PyErr_Clear(tstate); 1227db96d56Sopenharmony_ci return defaultvalue; 1237db96d56Sopenharmony_ci } 1247db96d56Sopenharmony_ci return -1; 1257db96d56Sopenharmony_ci } 1267db96d56Sopenharmony_ci else if (result == Py_NotImplemented) { 1277db96d56Sopenharmony_ci Py_DECREF(result); 1287db96d56Sopenharmony_ci return defaultvalue; 1297db96d56Sopenharmony_ci } 1307db96d56Sopenharmony_ci if (!PyLong_Check(result)) { 1317db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "__length_hint__ must be an integer, not %.100s", 1327db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 1337db96d56Sopenharmony_ci Py_DECREF(result); 1347db96d56Sopenharmony_ci return -1; 1357db96d56Sopenharmony_ci } 1367db96d56Sopenharmony_ci res = PyLong_AsSsize_t(result); 1377db96d56Sopenharmony_ci Py_DECREF(result); 1387db96d56Sopenharmony_ci if (res < 0 && PyErr_Occurred()) { 1397db96d56Sopenharmony_ci return -1; 1407db96d56Sopenharmony_ci } 1417db96d56Sopenharmony_ci if (res < 0) { 1427db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0"); 1437db96d56Sopenharmony_ci return -1; 1447db96d56Sopenharmony_ci } 1457db96d56Sopenharmony_ci return res; 1467db96d56Sopenharmony_ci} 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ciPyObject * 1497db96d56Sopenharmony_ciPyObject_GetItem(PyObject *o, PyObject *key) 1507db96d56Sopenharmony_ci{ 1517db96d56Sopenharmony_ci if (o == NULL || key == NULL) { 1527db96d56Sopenharmony_ci return null_error(); 1537db96d56Sopenharmony_ci } 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; 1567db96d56Sopenharmony_ci if (m && m->mp_subscript) { 1577db96d56Sopenharmony_ci PyObject *item = m->mp_subscript(o, key); 1587db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__getitem__", item != NULL)); 1597db96d56Sopenharmony_ci return item; 1607db96d56Sopenharmony_ci } 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci PySequenceMethods *ms = Py_TYPE(o)->tp_as_sequence; 1637db96d56Sopenharmony_ci if (ms && ms->sq_item) { 1647db96d56Sopenharmony_ci if (_PyIndex_Check(key)) { 1657db96d56Sopenharmony_ci Py_ssize_t key_value; 1667db96d56Sopenharmony_ci key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); 1677db96d56Sopenharmony_ci if (key_value == -1 && PyErr_Occurred()) 1687db96d56Sopenharmony_ci return NULL; 1697db96d56Sopenharmony_ci return PySequence_GetItem(o, key_value); 1707db96d56Sopenharmony_ci } 1717db96d56Sopenharmony_ci else { 1727db96d56Sopenharmony_ci return type_error("sequence index must " 1737db96d56Sopenharmony_ci "be integer, not '%.200s'", key); 1747db96d56Sopenharmony_ci } 1757db96d56Sopenharmony_ci } 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci if (PyType_Check(o)) { 1787db96d56Sopenharmony_ci PyObject *meth, *result; 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci // Special case type[int], but disallow other types so str[int] fails 1817db96d56Sopenharmony_ci if ((PyTypeObject*)o == &PyType_Type) { 1827db96d56Sopenharmony_ci return Py_GenericAlias(o, key); 1837db96d56Sopenharmony_ci } 1847db96d56Sopenharmony_ci 1857db96d56Sopenharmony_ci if (_PyObject_LookupAttr(o, &_Py_ID(__class_getitem__), &meth) < 0) { 1867db96d56Sopenharmony_ci return NULL; 1877db96d56Sopenharmony_ci } 1887db96d56Sopenharmony_ci if (meth && meth != Py_None) { 1897db96d56Sopenharmony_ci result = PyObject_CallOneArg(meth, key); 1907db96d56Sopenharmony_ci Py_DECREF(meth); 1917db96d56Sopenharmony_ci return result; 1927db96d56Sopenharmony_ci } 1937db96d56Sopenharmony_ci Py_XDECREF(meth); 1947db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "type '%.200s' is not subscriptable", 1957db96d56Sopenharmony_ci ((PyTypeObject *)o)->tp_name); 1967db96d56Sopenharmony_ci return NULL; 1977db96d56Sopenharmony_ci } 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci return type_error("'%.200s' object is not subscriptable", o); 2007db96d56Sopenharmony_ci} 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ciint 2037db96d56Sopenharmony_ciPyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) 2047db96d56Sopenharmony_ci{ 2057db96d56Sopenharmony_ci if (o == NULL || key == NULL || value == NULL) { 2067db96d56Sopenharmony_ci null_error(); 2077db96d56Sopenharmony_ci return -1; 2087db96d56Sopenharmony_ci } 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; 2117db96d56Sopenharmony_ci if (m && m->mp_ass_subscript) { 2127db96d56Sopenharmony_ci int res = m->mp_ass_subscript(o, key, value); 2137db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__setitem__", res >= 0)); 2147db96d56Sopenharmony_ci return res; 2157db96d56Sopenharmony_ci } 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci if (Py_TYPE(o)->tp_as_sequence) { 2187db96d56Sopenharmony_ci if (_PyIndex_Check(key)) { 2197db96d56Sopenharmony_ci Py_ssize_t key_value; 2207db96d56Sopenharmony_ci key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); 2217db96d56Sopenharmony_ci if (key_value == -1 && PyErr_Occurred()) 2227db96d56Sopenharmony_ci return -1; 2237db96d56Sopenharmony_ci return PySequence_SetItem(o, key_value, value); 2247db96d56Sopenharmony_ci } 2257db96d56Sopenharmony_ci else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { 2267db96d56Sopenharmony_ci type_error("sequence index must be " 2277db96d56Sopenharmony_ci "integer, not '%.200s'", key); 2287db96d56Sopenharmony_ci return -1; 2297db96d56Sopenharmony_ci } 2307db96d56Sopenharmony_ci } 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci type_error("'%.200s' object does not support item assignment", o); 2337db96d56Sopenharmony_ci return -1; 2347db96d56Sopenharmony_ci} 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ciint 2377db96d56Sopenharmony_ciPyObject_DelItem(PyObject *o, PyObject *key) 2387db96d56Sopenharmony_ci{ 2397db96d56Sopenharmony_ci if (o == NULL || key == NULL) { 2407db96d56Sopenharmony_ci null_error(); 2417db96d56Sopenharmony_ci return -1; 2427db96d56Sopenharmony_ci } 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; 2457db96d56Sopenharmony_ci if (m && m->mp_ass_subscript) { 2467db96d56Sopenharmony_ci int res = m->mp_ass_subscript(o, key, (PyObject*)NULL); 2477db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__delitem__", res >= 0)); 2487db96d56Sopenharmony_ci return res; 2497db96d56Sopenharmony_ci } 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ci if (Py_TYPE(o)->tp_as_sequence) { 2527db96d56Sopenharmony_ci if (_PyIndex_Check(key)) { 2537db96d56Sopenharmony_ci Py_ssize_t key_value; 2547db96d56Sopenharmony_ci key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); 2557db96d56Sopenharmony_ci if (key_value == -1 && PyErr_Occurred()) 2567db96d56Sopenharmony_ci return -1; 2577db96d56Sopenharmony_ci return PySequence_DelItem(o, key_value); 2587db96d56Sopenharmony_ci } 2597db96d56Sopenharmony_ci else if (Py_TYPE(o)->tp_as_sequence->sq_ass_item) { 2607db96d56Sopenharmony_ci type_error("sequence index must be " 2617db96d56Sopenharmony_ci "integer, not '%.200s'", key); 2627db96d56Sopenharmony_ci return -1; 2637db96d56Sopenharmony_ci } 2647db96d56Sopenharmony_ci } 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci type_error("'%.200s' object does not support item deletion", o); 2677db96d56Sopenharmony_ci return -1; 2687db96d56Sopenharmony_ci} 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_ciint 2717db96d56Sopenharmony_ciPyObject_DelItemString(PyObject *o, const char *key) 2727db96d56Sopenharmony_ci{ 2737db96d56Sopenharmony_ci PyObject *okey; 2747db96d56Sopenharmony_ci int ret; 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci if (o == NULL || key == NULL) { 2777db96d56Sopenharmony_ci null_error(); 2787db96d56Sopenharmony_ci return -1; 2797db96d56Sopenharmony_ci } 2807db96d56Sopenharmony_ci okey = PyUnicode_FromString(key); 2817db96d56Sopenharmony_ci if (okey == NULL) 2827db96d56Sopenharmony_ci return -1; 2837db96d56Sopenharmony_ci ret = PyObject_DelItem(o, okey); 2847db96d56Sopenharmony_ci Py_DECREF(okey); 2857db96d56Sopenharmony_ci return ret; 2867db96d56Sopenharmony_ci} 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci/* Return 1 if the getbuffer function is available, otherwise return 0. */ 2907db96d56Sopenharmony_ciint 2917db96d56Sopenharmony_ciPyObject_CheckBuffer(PyObject *obj) 2927db96d56Sopenharmony_ci{ 2937db96d56Sopenharmony_ci PyBufferProcs *tp_as_buffer = Py_TYPE(obj)->tp_as_buffer; 2947db96d56Sopenharmony_ci return (tp_as_buffer != NULL && tp_as_buffer->bf_getbuffer != NULL); 2957db96d56Sopenharmony_ci} 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci/* We release the buffer right after use of this function which could 2997db96d56Sopenharmony_ci cause issues later on. Don't use these functions in new code. 3007db96d56Sopenharmony_ci */ 3017db96d56Sopenharmony_ciint 3027db96d56Sopenharmony_ciPyObject_CheckReadBuffer(PyObject *obj) 3037db96d56Sopenharmony_ci{ 3047db96d56Sopenharmony_ci PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; 3057db96d56Sopenharmony_ci Py_buffer view; 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci if (pb == NULL || 3087db96d56Sopenharmony_ci pb->bf_getbuffer == NULL) 3097db96d56Sopenharmony_ci return 0; 3107db96d56Sopenharmony_ci if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { 3117db96d56Sopenharmony_ci PyErr_Clear(); 3127db96d56Sopenharmony_ci return 0; 3137db96d56Sopenharmony_ci } 3147db96d56Sopenharmony_ci PyBuffer_Release(&view); 3157db96d56Sopenharmony_ci return 1; 3167db96d56Sopenharmony_ci} 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_cistatic int 3197db96d56Sopenharmony_cias_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) 3207db96d56Sopenharmony_ci{ 3217db96d56Sopenharmony_ci Py_buffer view; 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci if (obj == NULL || buffer == NULL || buffer_len == NULL) { 3247db96d56Sopenharmony_ci null_error(); 3257db96d56Sopenharmony_ci return -1; 3267db96d56Sopenharmony_ci } 3277db96d56Sopenharmony_ci if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) 3287db96d56Sopenharmony_ci return -1; 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci *buffer = view.buf; 3317db96d56Sopenharmony_ci *buffer_len = view.len; 3327db96d56Sopenharmony_ci PyBuffer_Release(&view); 3337db96d56Sopenharmony_ci return 0; 3347db96d56Sopenharmony_ci} 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ciint 3377db96d56Sopenharmony_ciPyObject_AsCharBuffer(PyObject *obj, 3387db96d56Sopenharmony_ci const char **buffer, 3397db96d56Sopenharmony_ci Py_ssize_t *buffer_len) 3407db96d56Sopenharmony_ci{ 3417db96d56Sopenharmony_ci return as_read_buffer(obj, (const void **)buffer, buffer_len); 3427db96d56Sopenharmony_ci} 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ciint PyObject_AsReadBuffer(PyObject *obj, 3457db96d56Sopenharmony_ci const void **buffer, 3467db96d56Sopenharmony_ci Py_ssize_t *buffer_len) 3477db96d56Sopenharmony_ci{ 3487db96d56Sopenharmony_ci return as_read_buffer(obj, buffer, buffer_len); 3497db96d56Sopenharmony_ci} 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ciint PyObject_AsWriteBuffer(PyObject *obj, 3527db96d56Sopenharmony_ci void **buffer, 3537db96d56Sopenharmony_ci Py_ssize_t *buffer_len) 3547db96d56Sopenharmony_ci{ 3557db96d56Sopenharmony_ci PyBufferProcs *pb; 3567db96d56Sopenharmony_ci Py_buffer view; 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci if (obj == NULL || buffer == NULL || buffer_len == NULL) { 3597db96d56Sopenharmony_ci null_error(); 3607db96d56Sopenharmony_ci return -1; 3617db96d56Sopenharmony_ci } 3627db96d56Sopenharmony_ci pb = Py_TYPE(obj)->tp_as_buffer; 3637db96d56Sopenharmony_ci if (pb == NULL || 3647db96d56Sopenharmony_ci pb->bf_getbuffer == NULL || 3657db96d56Sopenharmony_ci ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { 3667db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 3677db96d56Sopenharmony_ci "expected a writable bytes-like object"); 3687db96d56Sopenharmony_ci return -1; 3697db96d56Sopenharmony_ci } 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci *buffer = view.buf; 3727db96d56Sopenharmony_ci *buffer_len = view.len; 3737db96d56Sopenharmony_ci PyBuffer_Release(&view); 3747db96d56Sopenharmony_ci return 0; 3757db96d56Sopenharmony_ci} 3767db96d56Sopenharmony_ci 3777db96d56Sopenharmony_ci/* Buffer C-API for Python 3.0 */ 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ciint 3807db96d56Sopenharmony_ciPyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) 3817db96d56Sopenharmony_ci{ 3827db96d56Sopenharmony_ci PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; 3837db96d56Sopenharmony_ci 3847db96d56Sopenharmony_ci if (pb == NULL || pb->bf_getbuffer == NULL) { 3857db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 3867db96d56Sopenharmony_ci "a bytes-like object is required, not '%.100s'", 3877db96d56Sopenharmony_ci Py_TYPE(obj)->tp_name); 3887db96d56Sopenharmony_ci return -1; 3897db96d56Sopenharmony_ci } 3907db96d56Sopenharmony_ci int res = (*pb->bf_getbuffer)(obj, view, flags); 3917db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(obj, "getbuffer", res >= 0)); 3927db96d56Sopenharmony_ci return res; 3937db96d56Sopenharmony_ci} 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_cistatic int 3967db96d56Sopenharmony_ci_IsFortranContiguous(const Py_buffer *view) 3977db96d56Sopenharmony_ci{ 3987db96d56Sopenharmony_ci Py_ssize_t sd, dim; 3997db96d56Sopenharmony_ci int i; 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci /* 1) len = product(shape) * itemsize 4027db96d56Sopenharmony_ci 2) itemsize > 0 4037db96d56Sopenharmony_ci 3) len = 0 <==> exists i: shape[i] = 0 */ 4047db96d56Sopenharmony_ci if (view->len == 0) return 1; 4057db96d56Sopenharmony_ci if (view->strides == NULL) { /* C-contiguous by definition */ 4067db96d56Sopenharmony_ci /* Trivially F-contiguous */ 4077db96d56Sopenharmony_ci if (view->ndim <= 1) return 1; 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_ci /* ndim > 1 implies shape != NULL */ 4107db96d56Sopenharmony_ci assert(view->shape != NULL); 4117db96d56Sopenharmony_ci 4127db96d56Sopenharmony_ci /* Effectively 1-d */ 4137db96d56Sopenharmony_ci sd = 0; 4147db96d56Sopenharmony_ci for (i=0; i<view->ndim; i++) { 4157db96d56Sopenharmony_ci if (view->shape[i] > 1) sd += 1; 4167db96d56Sopenharmony_ci } 4177db96d56Sopenharmony_ci return sd <= 1; 4187db96d56Sopenharmony_ci } 4197db96d56Sopenharmony_ci 4207db96d56Sopenharmony_ci /* strides != NULL implies both of these */ 4217db96d56Sopenharmony_ci assert(view->ndim > 0); 4227db96d56Sopenharmony_ci assert(view->shape != NULL); 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci sd = view->itemsize; 4257db96d56Sopenharmony_ci for (i=0; i<view->ndim; i++) { 4267db96d56Sopenharmony_ci dim = view->shape[i]; 4277db96d56Sopenharmony_ci if (dim > 1 && view->strides[i] != sd) { 4287db96d56Sopenharmony_ci return 0; 4297db96d56Sopenharmony_ci } 4307db96d56Sopenharmony_ci sd *= dim; 4317db96d56Sopenharmony_ci } 4327db96d56Sopenharmony_ci return 1; 4337db96d56Sopenharmony_ci} 4347db96d56Sopenharmony_ci 4357db96d56Sopenharmony_cistatic int 4367db96d56Sopenharmony_ci_IsCContiguous(const Py_buffer *view) 4377db96d56Sopenharmony_ci{ 4387db96d56Sopenharmony_ci Py_ssize_t sd, dim; 4397db96d56Sopenharmony_ci int i; 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_ci /* 1) len = product(shape) * itemsize 4427db96d56Sopenharmony_ci 2) itemsize > 0 4437db96d56Sopenharmony_ci 3) len = 0 <==> exists i: shape[i] = 0 */ 4447db96d56Sopenharmony_ci if (view->len == 0) return 1; 4457db96d56Sopenharmony_ci if (view->strides == NULL) return 1; /* C-contiguous by definition */ 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci /* strides != NULL implies both of these */ 4487db96d56Sopenharmony_ci assert(view->ndim > 0); 4497db96d56Sopenharmony_ci assert(view->shape != NULL); 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_ci sd = view->itemsize; 4527db96d56Sopenharmony_ci for (i=view->ndim-1; i>=0; i--) { 4537db96d56Sopenharmony_ci dim = view->shape[i]; 4547db96d56Sopenharmony_ci if (dim > 1 && view->strides[i] != sd) { 4557db96d56Sopenharmony_ci return 0; 4567db96d56Sopenharmony_ci } 4577db96d56Sopenharmony_ci sd *= dim; 4587db96d56Sopenharmony_ci } 4597db96d56Sopenharmony_ci return 1; 4607db96d56Sopenharmony_ci} 4617db96d56Sopenharmony_ci 4627db96d56Sopenharmony_ciint 4637db96d56Sopenharmony_ciPyBuffer_IsContiguous(const Py_buffer *view, char order) 4647db96d56Sopenharmony_ci{ 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci if (view->suboffsets != NULL) return 0; 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci if (order == 'C') 4697db96d56Sopenharmony_ci return _IsCContiguous(view); 4707db96d56Sopenharmony_ci else if (order == 'F') 4717db96d56Sopenharmony_ci return _IsFortranContiguous(view); 4727db96d56Sopenharmony_ci else if (order == 'A') 4737db96d56Sopenharmony_ci return (_IsCContiguous(view) || _IsFortranContiguous(view)); 4747db96d56Sopenharmony_ci return 0; 4757db96d56Sopenharmony_ci} 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci 4787db96d56Sopenharmony_civoid* 4797db96d56Sopenharmony_ciPyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices) 4807db96d56Sopenharmony_ci{ 4817db96d56Sopenharmony_ci char* pointer; 4827db96d56Sopenharmony_ci int i; 4837db96d56Sopenharmony_ci pointer = (char *)view->buf; 4847db96d56Sopenharmony_ci for (i = 0; i < view->ndim; i++) { 4857db96d56Sopenharmony_ci pointer += view->strides[i]*indices[i]; 4867db96d56Sopenharmony_ci if ((view->suboffsets != NULL) && (view->suboffsets[i] >= 0)) { 4877db96d56Sopenharmony_ci pointer = *((char**)pointer) + view->suboffsets[i]; 4887db96d56Sopenharmony_ci } 4897db96d56Sopenharmony_ci } 4907db96d56Sopenharmony_ci return (void*)pointer; 4917db96d56Sopenharmony_ci} 4927db96d56Sopenharmony_ci 4937db96d56Sopenharmony_ci 4947db96d56Sopenharmony_civoid 4957db96d56Sopenharmony_ci_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape) 4967db96d56Sopenharmony_ci{ 4977db96d56Sopenharmony_ci int k; 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci for (k=0; k<nd; k++) { 5007db96d56Sopenharmony_ci if (index[k] < shape[k]-1) { 5017db96d56Sopenharmony_ci index[k]++; 5027db96d56Sopenharmony_ci break; 5037db96d56Sopenharmony_ci } 5047db96d56Sopenharmony_ci else { 5057db96d56Sopenharmony_ci index[k] = 0; 5067db96d56Sopenharmony_ci } 5077db96d56Sopenharmony_ci } 5087db96d56Sopenharmony_ci} 5097db96d56Sopenharmony_ci 5107db96d56Sopenharmony_civoid 5117db96d56Sopenharmony_ci_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) 5127db96d56Sopenharmony_ci{ 5137db96d56Sopenharmony_ci int k; 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci for (k=nd-1; k>=0; k--) { 5167db96d56Sopenharmony_ci if (index[k] < shape[k]-1) { 5177db96d56Sopenharmony_ci index[k]++; 5187db96d56Sopenharmony_ci break; 5197db96d56Sopenharmony_ci } 5207db96d56Sopenharmony_ci else { 5217db96d56Sopenharmony_ci index[k] = 0; 5227db96d56Sopenharmony_ci } 5237db96d56Sopenharmony_ci } 5247db96d56Sopenharmony_ci} 5257db96d56Sopenharmony_ci 5267db96d56Sopenharmony_ciPy_ssize_t 5277db96d56Sopenharmony_ciPyBuffer_SizeFromFormat(const char *format) 5287db96d56Sopenharmony_ci{ 5297db96d56Sopenharmony_ci PyObject *structmodule = NULL; 5307db96d56Sopenharmony_ci PyObject *calcsize = NULL; 5317db96d56Sopenharmony_ci PyObject *res = NULL; 5327db96d56Sopenharmony_ci PyObject *fmt = NULL; 5337db96d56Sopenharmony_ci Py_ssize_t itemsize = -1; 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_ci structmodule = PyImport_ImportModule("struct"); 5367db96d56Sopenharmony_ci if (structmodule == NULL) { 5377db96d56Sopenharmony_ci return itemsize; 5387db96d56Sopenharmony_ci } 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ci calcsize = PyObject_GetAttrString(structmodule, "calcsize"); 5417db96d56Sopenharmony_ci if (calcsize == NULL) { 5427db96d56Sopenharmony_ci goto done; 5437db96d56Sopenharmony_ci } 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci fmt = PyUnicode_FromString(format); 5467db96d56Sopenharmony_ci if (fmt == NULL) { 5477db96d56Sopenharmony_ci goto done; 5487db96d56Sopenharmony_ci } 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci res = PyObject_CallFunctionObjArgs(calcsize, fmt, NULL); 5517db96d56Sopenharmony_ci if (res == NULL) { 5527db96d56Sopenharmony_ci goto done; 5537db96d56Sopenharmony_ci } 5547db96d56Sopenharmony_ci 5557db96d56Sopenharmony_ci itemsize = PyLong_AsSsize_t(res); 5567db96d56Sopenharmony_ci if (itemsize < 0) { 5577db96d56Sopenharmony_ci goto done; 5587db96d56Sopenharmony_ci } 5597db96d56Sopenharmony_ci 5607db96d56Sopenharmony_cidone: 5617db96d56Sopenharmony_ci Py_DECREF(structmodule); 5627db96d56Sopenharmony_ci Py_XDECREF(calcsize); 5637db96d56Sopenharmony_ci Py_XDECREF(fmt); 5647db96d56Sopenharmony_ci Py_XDECREF(res); 5657db96d56Sopenharmony_ci return itemsize; 5667db96d56Sopenharmony_ci} 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_ciint 5697db96d56Sopenharmony_ciPyBuffer_FromContiguous(const Py_buffer *view, const void *buf, Py_ssize_t len, char fort) 5707db96d56Sopenharmony_ci{ 5717db96d56Sopenharmony_ci int k; 5727db96d56Sopenharmony_ci void (*addone)(int, Py_ssize_t *, const Py_ssize_t *); 5737db96d56Sopenharmony_ci Py_ssize_t *indices, elements; 5747db96d56Sopenharmony_ci char *ptr; 5757db96d56Sopenharmony_ci const char *src; 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci if (len > view->len) { 5787db96d56Sopenharmony_ci len = view->len; 5797db96d56Sopenharmony_ci } 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ci if (PyBuffer_IsContiguous(view, fort)) { 5827db96d56Sopenharmony_ci /* simplest copy is all that is needed */ 5837db96d56Sopenharmony_ci memcpy(view->buf, buf, len); 5847db96d56Sopenharmony_ci return 0; 5857db96d56Sopenharmony_ci } 5867db96d56Sopenharmony_ci 5877db96d56Sopenharmony_ci /* Otherwise a more elaborate scheme is needed */ 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ci /* view->ndim <= 64 */ 5907db96d56Sopenharmony_ci indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); 5917db96d56Sopenharmony_ci if (indices == NULL) { 5927db96d56Sopenharmony_ci PyErr_NoMemory(); 5937db96d56Sopenharmony_ci return -1; 5947db96d56Sopenharmony_ci } 5957db96d56Sopenharmony_ci for (k=0; k<view->ndim;k++) { 5967db96d56Sopenharmony_ci indices[k] = 0; 5977db96d56Sopenharmony_ci } 5987db96d56Sopenharmony_ci 5997db96d56Sopenharmony_ci if (fort == 'F') { 6007db96d56Sopenharmony_ci addone = _Py_add_one_to_index_F; 6017db96d56Sopenharmony_ci } 6027db96d56Sopenharmony_ci else { 6037db96d56Sopenharmony_ci addone = _Py_add_one_to_index_C; 6047db96d56Sopenharmony_ci } 6057db96d56Sopenharmony_ci src = buf; 6067db96d56Sopenharmony_ci /* XXX : This is not going to be the fastest code in the world 6077db96d56Sopenharmony_ci several optimizations are possible. 6087db96d56Sopenharmony_ci */ 6097db96d56Sopenharmony_ci elements = len / view->itemsize; 6107db96d56Sopenharmony_ci while (elements--) { 6117db96d56Sopenharmony_ci ptr = PyBuffer_GetPointer(view, indices); 6127db96d56Sopenharmony_ci memcpy(ptr, src, view->itemsize); 6137db96d56Sopenharmony_ci src += view->itemsize; 6147db96d56Sopenharmony_ci addone(view->ndim, indices, view->shape); 6157db96d56Sopenharmony_ci } 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ci PyMem_Free(indices); 6187db96d56Sopenharmony_ci return 0; 6197db96d56Sopenharmony_ci} 6207db96d56Sopenharmony_ci 6217db96d56Sopenharmony_ciint PyObject_CopyData(PyObject *dest, PyObject *src) 6227db96d56Sopenharmony_ci{ 6237db96d56Sopenharmony_ci Py_buffer view_dest, view_src; 6247db96d56Sopenharmony_ci int k; 6257db96d56Sopenharmony_ci Py_ssize_t *indices, elements; 6267db96d56Sopenharmony_ci char *dptr, *sptr; 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci if (!PyObject_CheckBuffer(dest) || 6297db96d56Sopenharmony_ci !PyObject_CheckBuffer(src)) { 6307db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6317db96d56Sopenharmony_ci "both destination and source must be "\ 6327db96d56Sopenharmony_ci "bytes-like objects"); 6337db96d56Sopenharmony_ci return -1; 6347db96d56Sopenharmony_ci } 6357db96d56Sopenharmony_ci 6367db96d56Sopenharmony_ci if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1; 6377db96d56Sopenharmony_ci if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) { 6387db96d56Sopenharmony_ci PyBuffer_Release(&view_dest); 6397db96d56Sopenharmony_ci return -1; 6407db96d56Sopenharmony_ci } 6417db96d56Sopenharmony_ci 6427db96d56Sopenharmony_ci if (view_dest.len < view_src.len) { 6437db96d56Sopenharmony_ci PyErr_SetString(PyExc_BufferError, 6447db96d56Sopenharmony_ci "destination is too small to receive data from source"); 6457db96d56Sopenharmony_ci PyBuffer_Release(&view_dest); 6467db96d56Sopenharmony_ci PyBuffer_Release(&view_src); 6477db96d56Sopenharmony_ci return -1; 6487db96d56Sopenharmony_ci } 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci if ((PyBuffer_IsContiguous(&view_dest, 'C') && 6517db96d56Sopenharmony_ci PyBuffer_IsContiguous(&view_src, 'C')) || 6527db96d56Sopenharmony_ci (PyBuffer_IsContiguous(&view_dest, 'F') && 6537db96d56Sopenharmony_ci PyBuffer_IsContiguous(&view_src, 'F'))) { 6547db96d56Sopenharmony_ci /* simplest copy is all that is needed */ 6557db96d56Sopenharmony_ci memcpy(view_dest.buf, view_src.buf, view_src.len); 6567db96d56Sopenharmony_ci PyBuffer_Release(&view_dest); 6577db96d56Sopenharmony_ci PyBuffer_Release(&view_src); 6587db96d56Sopenharmony_ci return 0; 6597db96d56Sopenharmony_ci } 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci /* Otherwise a more elaborate copy scheme is needed */ 6627db96d56Sopenharmony_ci 6637db96d56Sopenharmony_ci /* XXX(nnorwitz): need to check for overflow! */ 6647db96d56Sopenharmony_ci indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim); 6657db96d56Sopenharmony_ci if (indices == NULL) { 6667db96d56Sopenharmony_ci PyErr_NoMemory(); 6677db96d56Sopenharmony_ci PyBuffer_Release(&view_dest); 6687db96d56Sopenharmony_ci PyBuffer_Release(&view_src); 6697db96d56Sopenharmony_ci return -1; 6707db96d56Sopenharmony_ci } 6717db96d56Sopenharmony_ci for (k=0; k<view_src.ndim;k++) { 6727db96d56Sopenharmony_ci indices[k] = 0; 6737db96d56Sopenharmony_ci } 6747db96d56Sopenharmony_ci elements = 1; 6757db96d56Sopenharmony_ci for (k=0; k<view_src.ndim; k++) { 6767db96d56Sopenharmony_ci /* XXX(nnorwitz): can this overflow? */ 6777db96d56Sopenharmony_ci elements *= view_src.shape[k]; 6787db96d56Sopenharmony_ci } 6797db96d56Sopenharmony_ci while (elements--) { 6807db96d56Sopenharmony_ci _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape); 6817db96d56Sopenharmony_ci dptr = PyBuffer_GetPointer(&view_dest, indices); 6827db96d56Sopenharmony_ci sptr = PyBuffer_GetPointer(&view_src, indices); 6837db96d56Sopenharmony_ci memcpy(dptr, sptr, view_src.itemsize); 6847db96d56Sopenharmony_ci } 6857db96d56Sopenharmony_ci PyMem_Free(indices); 6867db96d56Sopenharmony_ci PyBuffer_Release(&view_dest); 6877db96d56Sopenharmony_ci PyBuffer_Release(&view_src); 6887db96d56Sopenharmony_ci return 0; 6897db96d56Sopenharmony_ci} 6907db96d56Sopenharmony_ci 6917db96d56Sopenharmony_civoid 6927db96d56Sopenharmony_ciPyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape, 6937db96d56Sopenharmony_ci Py_ssize_t *strides, int itemsize, 6947db96d56Sopenharmony_ci char fort) 6957db96d56Sopenharmony_ci{ 6967db96d56Sopenharmony_ci int k; 6977db96d56Sopenharmony_ci Py_ssize_t sd; 6987db96d56Sopenharmony_ci 6997db96d56Sopenharmony_ci sd = itemsize; 7007db96d56Sopenharmony_ci if (fort == 'F') { 7017db96d56Sopenharmony_ci for (k=0; k<nd; k++) { 7027db96d56Sopenharmony_ci strides[k] = sd; 7037db96d56Sopenharmony_ci sd *= shape[k]; 7047db96d56Sopenharmony_ci } 7057db96d56Sopenharmony_ci } 7067db96d56Sopenharmony_ci else { 7077db96d56Sopenharmony_ci for (k=nd-1; k>=0; k--) { 7087db96d56Sopenharmony_ci strides[k] = sd; 7097db96d56Sopenharmony_ci sd *= shape[k]; 7107db96d56Sopenharmony_ci } 7117db96d56Sopenharmony_ci } 7127db96d56Sopenharmony_ci return; 7137db96d56Sopenharmony_ci} 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_ciint 7167db96d56Sopenharmony_ciPyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, 7177db96d56Sopenharmony_ci int readonly, int flags) 7187db96d56Sopenharmony_ci{ 7197db96d56Sopenharmony_ci if (view == NULL) { 7207db96d56Sopenharmony_ci PyErr_SetString(PyExc_BufferError, 7217db96d56Sopenharmony_ci "PyBuffer_FillInfo: view==NULL argument is obsolete"); 7227db96d56Sopenharmony_ci return -1; 7237db96d56Sopenharmony_ci } 7247db96d56Sopenharmony_ci 7257db96d56Sopenharmony_ci if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && 7267db96d56Sopenharmony_ci (readonly == 1)) { 7277db96d56Sopenharmony_ci PyErr_SetString(PyExc_BufferError, 7287db96d56Sopenharmony_ci "Object is not writable."); 7297db96d56Sopenharmony_ci return -1; 7307db96d56Sopenharmony_ci } 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci view->obj = obj; 7337db96d56Sopenharmony_ci if (obj) 7347db96d56Sopenharmony_ci Py_INCREF(obj); 7357db96d56Sopenharmony_ci view->buf = buf; 7367db96d56Sopenharmony_ci view->len = len; 7377db96d56Sopenharmony_ci view->readonly = readonly; 7387db96d56Sopenharmony_ci view->itemsize = 1; 7397db96d56Sopenharmony_ci view->format = NULL; 7407db96d56Sopenharmony_ci if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) 7417db96d56Sopenharmony_ci view->format = "B"; 7427db96d56Sopenharmony_ci view->ndim = 1; 7437db96d56Sopenharmony_ci view->shape = NULL; 7447db96d56Sopenharmony_ci if ((flags & PyBUF_ND) == PyBUF_ND) 7457db96d56Sopenharmony_ci view->shape = &(view->len); 7467db96d56Sopenharmony_ci view->strides = NULL; 7477db96d56Sopenharmony_ci if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) 7487db96d56Sopenharmony_ci view->strides = &(view->itemsize); 7497db96d56Sopenharmony_ci view->suboffsets = NULL; 7507db96d56Sopenharmony_ci view->internal = NULL; 7517db96d56Sopenharmony_ci return 0; 7527db96d56Sopenharmony_ci} 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_civoid 7557db96d56Sopenharmony_ciPyBuffer_Release(Py_buffer *view) 7567db96d56Sopenharmony_ci{ 7577db96d56Sopenharmony_ci PyObject *obj = view->obj; 7587db96d56Sopenharmony_ci PyBufferProcs *pb; 7597db96d56Sopenharmony_ci if (obj == NULL) 7607db96d56Sopenharmony_ci return; 7617db96d56Sopenharmony_ci pb = Py_TYPE(obj)->tp_as_buffer; 7627db96d56Sopenharmony_ci if (pb && pb->bf_releasebuffer) { 7637db96d56Sopenharmony_ci pb->bf_releasebuffer(obj, view); 7647db96d56Sopenharmony_ci } 7657db96d56Sopenharmony_ci view->obj = NULL; 7667db96d56Sopenharmony_ci Py_DECREF(obj); 7677db96d56Sopenharmony_ci} 7687db96d56Sopenharmony_ci 7697db96d56Sopenharmony_ciPyObject * 7707db96d56Sopenharmony_ciPyObject_Format(PyObject *obj, PyObject *format_spec) 7717db96d56Sopenharmony_ci{ 7727db96d56Sopenharmony_ci PyObject *meth; 7737db96d56Sopenharmony_ci PyObject *empty = NULL; 7747db96d56Sopenharmony_ci PyObject *result = NULL; 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci if (format_spec != NULL && !PyUnicode_Check(format_spec)) { 7777db96d56Sopenharmony_ci PyErr_Format(PyExc_SystemError, 7787db96d56Sopenharmony_ci "Format specifier must be a string, not %.200s", 7797db96d56Sopenharmony_ci Py_TYPE(format_spec)->tp_name); 7807db96d56Sopenharmony_ci return NULL; 7817db96d56Sopenharmony_ci } 7827db96d56Sopenharmony_ci 7837db96d56Sopenharmony_ci /* Fast path for common types. */ 7847db96d56Sopenharmony_ci if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { 7857db96d56Sopenharmony_ci if (PyUnicode_CheckExact(obj)) { 7867db96d56Sopenharmony_ci Py_INCREF(obj); 7877db96d56Sopenharmony_ci return obj; 7887db96d56Sopenharmony_ci } 7897db96d56Sopenharmony_ci if (PyLong_CheckExact(obj)) { 7907db96d56Sopenharmony_ci return PyObject_Str(obj); 7917db96d56Sopenharmony_ci } 7927db96d56Sopenharmony_ci } 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ci /* If no format_spec is provided, use an empty string */ 7957db96d56Sopenharmony_ci if (format_spec == NULL) { 7967db96d56Sopenharmony_ci empty = PyUnicode_New(0, 0); 7977db96d56Sopenharmony_ci format_spec = empty; 7987db96d56Sopenharmony_ci } 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci /* Find the (unbound!) __format__ method */ 8017db96d56Sopenharmony_ci meth = _PyObject_LookupSpecial(obj, &_Py_ID(__format__)); 8027db96d56Sopenharmony_ci if (meth == NULL) { 8037db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 8047db96d56Sopenharmony_ci if (!_PyErr_Occurred(tstate)) { 8057db96d56Sopenharmony_ci _PyErr_Format(tstate, PyExc_TypeError, 8067db96d56Sopenharmony_ci "Type %.100s doesn't define __format__", 8077db96d56Sopenharmony_ci Py_TYPE(obj)->tp_name); 8087db96d56Sopenharmony_ci } 8097db96d56Sopenharmony_ci goto done; 8107db96d56Sopenharmony_ci } 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci /* And call it. */ 8137db96d56Sopenharmony_ci result = PyObject_CallOneArg(meth, format_spec); 8147db96d56Sopenharmony_ci Py_DECREF(meth); 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ci if (result && !PyUnicode_Check(result)) { 8177db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 8187db96d56Sopenharmony_ci "__format__ must return a str, not %.200s", 8197db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 8207db96d56Sopenharmony_ci Py_DECREF(result); 8217db96d56Sopenharmony_ci result = NULL; 8227db96d56Sopenharmony_ci goto done; 8237db96d56Sopenharmony_ci } 8247db96d56Sopenharmony_ci 8257db96d56Sopenharmony_cidone: 8267db96d56Sopenharmony_ci Py_XDECREF(empty); 8277db96d56Sopenharmony_ci return result; 8287db96d56Sopenharmony_ci} 8297db96d56Sopenharmony_ci/* Operations on numbers */ 8307db96d56Sopenharmony_ci 8317db96d56Sopenharmony_ciint 8327db96d56Sopenharmony_ciPyNumber_Check(PyObject *o) 8337db96d56Sopenharmony_ci{ 8347db96d56Sopenharmony_ci if (o == NULL) 8357db96d56Sopenharmony_ci return 0; 8367db96d56Sopenharmony_ci PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; 8377db96d56Sopenharmony_ci return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); 8387db96d56Sopenharmony_ci} 8397db96d56Sopenharmony_ci 8407db96d56Sopenharmony_ci/* Binary operators */ 8417db96d56Sopenharmony_ci 8427db96d56Sopenharmony_ci#define NB_SLOT(x) offsetof(PyNumberMethods, x) 8437db96d56Sopenharmony_ci#define NB_BINOP(nb_methods, slot) \ 8447db96d56Sopenharmony_ci (*(binaryfunc*)(& ((char*)nb_methods)[slot])) 8457db96d56Sopenharmony_ci#define NB_TERNOP(nb_methods, slot) \ 8467db96d56Sopenharmony_ci (*(ternaryfunc*)(& ((char*)nb_methods)[slot])) 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_ci/* 8497db96d56Sopenharmony_ci Calling scheme used for binary operations: 8507db96d56Sopenharmony_ci 8517db96d56Sopenharmony_ci Order operations are tried until either a valid result or error: 8527db96d56Sopenharmony_ci w.op(v,w)[*], v.op(v,w), w.op(v,w) 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci [*] only when Py_TYPE(v) != Py_TYPE(w) && Py_TYPE(w) is a subclass of 8557db96d56Sopenharmony_ci Py_TYPE(v) 8567db96d56Sopenharmony_ci */ 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_cistatic PyObject * 8597db96d56Sopenharmony_cibinary_op1(PyObject *v, PyObject *w, const int op_slot 8607db96d56Sopenharmony_ci#ifndef NDEBUG 8617db96d56Sopenharmony_ci , const char *op_name 8627db96d56Sopenharmony_ci#endif 8637db96d56Sopenharmony_ci ) 8647db96d56Sopenharmony_ci{ 8657db96d56Sopenharmony_ci binaryfunc slotv; 8667db96d56Sopenharmony_ci if (Py_TYPE(v)->tp_as_number != NULL) { 8677db96d56Sopenharmony_ci slotv = NB_BINOP(Py_TYPE(v)->tp_as_number, op_slot); 8687db96d56Sopenharmony_ci } 8697db96d56Sopenharmony_ci else { 8707db96d56Sopenharmony_ci slotv = NULL; 8717db96d56Sopenharmony_ci } 8727db96d56Sopenharmony_ci 8737db96d56Sopenharmony_ci binaryfunc slotw; 8747db96d56Sopenharmony_ci if (!Py_IS_TYPE(w, Py_TYPE(v)) && Py_TYPE(w)->tp_as_number != NULL) { 8757db96d56Sopenharmony_ci slotw = NB_BINOP(Py_TYPE(w)->tp_as_number, op_slot); 8767db96d56Sopenharmony_ci if (slotw == slotv) { 8777db96d56Sopenharmony_ci slotw = NULL; 8787db96d56Sopenharmony_ci } 8797db96d56Sopenharmony_ci } 8807db96d56Sopenharmony_ci else { 8817db96d56Sopenharmony_ci slotw = NULL; 8827db96d56Sopenharmony_ci } 8837db96d56Sopenharmony_ci 8847db96d56Sopenharmony_ci if (slotv) { 8857db96d56Sopenharmony_ci PyObject *x; 8867db96d56Sopenharmony_ci if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { 8877db96d56Sopenharmony_ci x = slotw(v, w); 8887db96d56Sopenharmony_ci if (x != Py_NotImplemented) 8897db96d56Sopenharmony_ci return x; 8907db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 8917db96d56Sopenharmony_ci slotw = NULL; 8927db96d56Sopenharmony_ci } 8937db96d56Sopenharmony_ci x = slotv(v, w); 8947db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(v, op_name, x != NULL)); 8957db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 8967db96d56Sopenharmony_ci return x; 8977db96d56Sopenharmony_ci } 8987db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 8997db96d56Sopenharmony_ci } 9007db96d56Sopenharmony_ci if (slotw) { 9017db96d56Sopenharmony_ci PyObject *x = slotw(v, w); 9027db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(w, op_name, x != NULL)); 9037db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 9047db96d56Sopenharmony_ci return x; 9057db96d56Sopenharmony_ci } 9067db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 9077db96d56Sopenharmony_ci } 9087db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 9097db96d56Sopenharmony_ci} 9107db96d56Sopenharmony_ci 9117db96d56Sopenharmony_ci#ifdef NDEBUG 9127db96d56Sopenharmony_ci# define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot) 9137db96d56Sopenharmony_ci#else 9147db96d56Sopenharmony_ci# define BINARY_OP1(v, w, op_slot, op_name) binary_op1(v, w, op_slot, op_name) 9157db96d56Sopenharmony_ci#endif 9167db96d56Sopenharmony_ci 9177db96d56Sopenharmony_cistatic PyObject * 9187db96d56Sopenharmony_cibinop_type_error(PyObject *v, PyObject *w, const char *op_name) 9197db96d56Sopenharmony_ci{ 9207db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 9217db96d56Sopenharmony_ci "unsupported operand type(s) for %.100s: " 9227db96d56Sopenharmony_ci "'%.100s' and '%.100s'", 9237db96d56Sopenharmony_ci op_name, 9247db96d56Sopenharmony_ci Py_TYPE(v)->tp_name, 9257db96d56Sopenharmony_ci Py_TYPE(w)->tp_name); 9267db96d56Sopenharmony_ci return NULL; 9277db96d56Sopenharmony_ci} 9287db96d56Sopenharmony_ci 9297db96d56Sopenharmony_cistatic PyObject * 9307db96d56Sopenharmony_cibinary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) 9317db96d56Sopenharmony_ci{ 9327db96d56Sopenharmony_ci PyObject *result = BINARY_OP1(v, w, op_slot, op_name); 9337db96d56Sopenharmony_ci if (result == Py_NotImplemented) { 9347db96d56Sopenharmony_ci Py_DECREF(result); 9357db96d56Sopenharmony_ci 9367db96d56Sopenharmony_ci if (op_slot == NB_SLOT(nb_rshift) && 9377db96d56Sopenharmony_ci PyCFunction_CheckExact(v) && 9387db96d56Sopenharmony_ci strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0) 9397db96d56Sopenharmony_ci { 9407db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 9417db96d56Sopenharmony_ci "unsupported operand type(s) for %.100s: " 9427db96d56Sopenharmony_ci "'%.100s' and '%.100s'. Did you mean \"print(<message>, " 9437db96d56Sopenharmony_ci "file=<output_stream>)\"?", 9447db96d56Sopenharmony_ci op_name, 9457db96d56Sopenharmony_ci Py_TYPE(v)->tp_name, 9467db96d56Sopenharmony_ci Py_TYPE(w)->tp_name); 9477db96d56Sopenharmony_ci return NULL; 9487db96d56Sopenharmony_ci } 9497db96d56Sopenharmony_ci return binop_type_error(v, w, op_name); 9507db96d56Sopenharmony_ci } 9517db96d56Sopenharmony_ci return result; 9527db96d56Sopenharmony_ci} 9537db96d56Sopenharmony_ci 9547db96d56Sopenharmony_ci 9557db96d56Sopenharmony_ci/* 9567db96d56Sopenharmony_ci Calling scheme used for ternary operations: 9577db96d56Sopenharmony_ci 9587db96d56Sopenharmony_ci Order operations are tried until either a valid result or error: 9597db96d56Sopenharmony_ci v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) 9607db96d56Sopenharmony_ci */ 9617db96d56Sopenharmony_ci 9627db96d56Sopenharmony_cistatic PyObject * 9637db96d56Sopenharmony_citernary_op(PyObject *v, 9647db96d56Sopenharmony_ci PyObject *w, 9657db96d56Sopenharmony_ci PyObject *z, 9667db96d56Sopenharmony_ci const int op_slot, 9677db96d56Sopenharmony_ci const char *op_name 9687db96d56Sopenharmony_ci ) 9697db96d56Sopenharmony_ci{ 9707db96d56Sopenharmony_ci PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; 9717db96d56Sopenharmony_ci PyNumberMethods *mw = Py_TYPE(w)->tp_as_number; 9727db96d56Sopenharmony_ci 9737db96d56Sopenharmony_ci ternaryfunc slotv; 9747db96d56Sopenharmony_ci if (mv != NULL) { 9757db96d56Sopenharmony_ci slotv = NB_TERNOP(mv, op_slot); 9767db96d56Sopenharmony_ci } 9777db96d56Sopenharmony_ci else { 9787db96d56Sopenharmony_ci slotv = NULL; 9797db96d56Sopenharmony_ci } 9807db96d56Sopenharmony_ci 9817db96d56Sopenharmony_ci ternaryfunc slotw; 9827db96d56Sopenharmony_ci if (!Py_IS_TYPE(w, Py_TYPE(v)) && mw != NULL) { 9837db96d56Sopenharmony_ci slotw = NB_TERNOP(mw, op_slot); 9847db96d56Sopenharmony_ci if (slotw == slotv) { 9857db96d56Sopenharmony_ci slotw = NULL; 9867db96d56Sopenharmony_ci } 9877db96d56Sopenharmony_ci } 9887db96d56Sopenharmony_ci else { 9897db96d56Sopenharmony_ci slotw = NULL; 9907db96d56Sopenharmony_ci } 9917db96d56Sopenharmony_ci 9927db96d56Sopenharmony_ci if (slotv) { 9937db96d56Sopenharmony_ci PyObject *x; 9947db96d56Sopenharmony_ci if (slotw && PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v))) { 9957db96d56Sopenharmony_ci x = slotw(v, w, z); 9967db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 9977db96d56Sopenharmony_ci return x; 9987db96d56Sopenharmony_ci } 9997db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 10007db96d56Sopenharmony_ci slotw = NULL; 10017db96d56Sopenharmony_ci } 10027db96d56Sopenharmony_ci x = slotv(v, w, z); 10037db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(v, op_name, x != NULL)); 10047db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 10057db96d56Sopenharmony_ci return x; 10067db96d56Sopenharmony_ci } 10077db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 10087db96d56Sopenharmony_ci } 10097db96d56Sopenharmony_ci if (slotw) { 10107db96d56Sopenharmony_ci PyObject *x = slotw(v, w, z); 10117db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(w, op_name, x != NULL)); 10127db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 10137db96d56Sopenharmony_ci return x; 10147db96d56Sopenharmony_ci } 10157db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 10167db96d56Sopenharmony_ci } 10177db96d56Sopenharmony_ci 10187db96d56Sopenharmony_ci PyNumberMethods *mz = Py_TYPE(z)->tp_as_number; 10197db96d56Sopenharmony_ci if (mz != NULL) { 10207db96d56Sopenharmony_ci ternaryfunc slotz = NB_TERNOP(mz, op_slot); 10217db96d56Sopenharmony_ci if (slotz == slotv || slotz == slotw) { 10227db96d56Sopenharmony_ci slotz = NULL; 10237db96d56Sopenharmony_ci } 10247db96d56Sopenharmony_ci if (slotz) { 10257db96d56Sopenharmony_ci PyObject *x = slotz(v, w, z); 10267db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(z, op_name, x != NULL)); 10277db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 10287db96d56Sopenharmony_ci return x; 10297db96d56Sopenharmony_ci } 10307db96d56Sopenharmony_ci Py_DECREF(x); /* can't do it */ 10317db96d56Sopenharmony_ci } 10327db96d56Sopenharmony_ci } 10337db96d56Sopenharmony_ci 10347db96d56Sopenharmony_ci if (z == Py_None) { 10357db96d56Sopenharmony_ci PyErr_Format( 10367db96d56Sopenharmony_ci PyExc_TypeError, 10377db96d56Sopenharmony_ci "unsupported operand type(s) for %.100s: " 10387db96d56Sopenharmony_ci "'%.100s' and '%.100s'", 10397db96d56Sopenharmony_ci op_name, 10407db96d56Sopenharmony_ci Py_TYPE(v)->tp_name, 10417db96d56Sopenharmony_ci Py_TYPE(w)->tp_name); 10427db96d56Sopenharmony_ci } 10437db96d56Sopenharmony_ci else { 10447db96d56Sopenharmony_ci PyErr_Format( 10457db96d56Sopenharmony_ci PyExc_TypeError, 10467db96d56Sopenharmony_ci "unsupported operand type(s) for %.100s: " 10477db96d56Sopenharmony_ci "'%.100s', '%.100s', '%.100s'", 10487db96d56Sopenharmony_ci op_name, 10497db96d56Sopenharmony_ci Py_TYPE(v)->tp_name, 10507db96d56Sopenharmony_ci Py_TYPE(w)->tp_name, 10517db96d56Sopenharmony_ci Py_TYPE(z)->tp_name); 10527db96d56Sopenharmony_ci } 10537db96d56Sopenharmony_ci return NULL; 10547db96d56Sopenharmony_ci} 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_ci#define BINARY_FUNC(func, op, op_name) \ 10577db96d56Sopenharmony_ci PyObject * \ 10587db96d56Sopenharmony_ci func(PyObject *v, PyObject *w) { \ 10597db96d56Sopenharmony_ci return binary_op(v, w, NB_SLOT(op), op_name); \ 10607db96d56Sopenharmony_ci } 10617db96d56Sopenharmony_ci 10627db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Or, nb_or, "|") 10637db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Xor, nb_xor, "^") 10647db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_And, nb_and, "&") 10657db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<") 10667db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>") 10677db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Subtract, nb_subtract, "-") 10687db96d56Sopenharmony_ciBINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()") 10697db96d56Sopenharmony_ci 10707db96d56Sopenharmony_ciPyObject * 10717db96d56Sopenharmony_ciPyNumber_Add(PyObject *v, PyObject *w) 10727db96d56Sopenharmony_ci{ 10737db96d56Sopenharmony_ci PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_add), "+"); 10747db96d56Sopenharmony_ci if (result != Py_NotImplemented) { 10757db96d56Sopenharmony_ci return result; 10767db96d56Sopenharmony_ci } 10777db96d56Sopenharmony_ci Py_DECREF(result); 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; 10807db96d56Sopenharmony_ci if (m && m->sq_concat) { 10817db96d56Sopenharmony_ci result = (*m->sq_concat)(v, w); 10827db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(v, "+", result != NULL)); 10837db96d56Sopenharmony_ci return result; 10847db96d56Sopenharmony_ci } 10857db96d56Sopenharmony_ci 10867db96d56Sopenharmony_ci return binop_type_error(v, w, "+"); 10877db96d56Sopenharmony_ci} 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_cistatic PyObject * 10907db96d56Sopenharmony_cisequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) 10917db96d56Sopenharmony_ci{ 10927db96d56Sopenharmony_ci Py_ssize_t count; 10937db96d56Sopenharmony_ci if (_PyIndex_Check(n)) { 10947db96d56Sopenharmony_ci count = PyNumber_AsSsize_t(n, PyExc_OverflowError); 10957db96d56Sopenharmony_ci if (count == -1 && PyErr_Occurred()) { 10967db96d56Sopenharmony_ci return NULL; 10977db96d56Sopenharmony_ci } 10987db96d56Sopenharmony_ci } 10997db96d56Sopenharmony_ci else { 11007db96d56Sopenharmony_ci return type_error("can't multiply sequence by " 11017db96d56Sopenharmony_ci "non-int of type '%.200s'", n); 11027db96d56Sopenharmony_ci } 11037db96d56Sopenharmony_ci PyObject *res = (*repeatfunc)(seq, count); 11047db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(seq, "*", res != NULL)); 11057db96d56Sopenharmony_ci return res; 11067db96d56Sopenharmony_ci} 11077db96d56Sopenharmony_ci 11087db96d56Sopenharmony_ciPyObject * 11097db96d56Sopenharmony_ciPyNumber_Multiply(PyObject *v, PyObject *w) 11107db96d56Sopenharmony_ci{ 11117db96d56Sopenharmony_ci PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_multiply), "*"); 11127db96d56Sopenharmony_ci if (result == Py_NotImplemented) { 11137db96d56Sopenharmony_ci PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; 11147db96d56Sopenharmony_ci PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; 11157db96d56Sopenharmony_ci Py_DECREF(result); 11167db96d56Sopenharmony_ci if (mv && mv->sq_repeat) { 11177db96d56Sopenharmony_ci return sequence_repeat(mv->sq_repeat, v, w); 11187db96d56Sopenharmony_ci } 11197db96d56Sopenharmony_ci else if (mw && mw->sq_repeat) { 11207db96d56Sopenharmony_ci return sequence_repeat(mw->sq_repeat, w, v); 11217db96d56Sopenharmony_ci } 11227db96d56Sopenharmony_ci result = binop_type_error(v, w, "*"); 11237db96d56Sopenharmony_ci } 11247db96d56Sopenharmony_ci return result; 11257db96d56Sopenharmony_ci} 11267db96d56Sopenharmony_ci 11277db96d56Sopenharmony_ciPyObject * 11287db96d56Sopenharmony_ciPyNumber_MatrixMultiply(PyObject *v, PyObject *w) 11297db96d56Sopenharmony_ci{ 11307db96d56Sopenharmony_ci return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@"); 11317db96d56Sopenharmony_ci} 11327db96d56Sopenharmony_ci 11337db96d56Sopenharmony_ciPyObject * 11347db96d56Sopenharmony_ciPyNumber_FloorDivide(PyObject *v, PyObject *w) 11357db96d56Sopenharmony_ci{ 11367db96d56Sopenharmony_ci return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); 11377db96d56Sopenharmony_ci} 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ciPyObject * 11407db96d56Sopenharmony_ciPyNumber_TrueDivide(PyObject *v, PyObject *w) 11417db96d56Sopenharmony_ci{ 11427db96d56Sopenharmony_ci return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); 11437db96d56Sopenharmony_ci} 11447db96d56Sopenharmony_ci 11457db96d56Sopenharmony_ciPyObject * 11467db96d56Sopenharmony_ciPyNumber_Remainder(PyObject *v, PyObject *w) 11477db96d56Sopenharmony_ci{ 11487db96d56Sopenharmony_ci return binary_op(v, w, NB_SLOT(nb_remainder), "%"); 11497db96d56Sopenharmony_ci} 11507db96d56Sopenharmony_ci 11517db96d56Sopenharmony_ciPyObject * 11527db96d56Sopenharmony_ciPyNumber_Power(PyObject *v, PyObject *w, PyObject *z) 11537db96d56Sopenharmony_ci{ 11547db96d56Sopenharmony_ci return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()"); 11557db96d56Sopenharmony_ci} 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ciPyObject * 11587db96d56Sopenharmony_ci_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs) 11597db96d56Sopenharmony_ci{ 11607db96d56Sopenharmony_ci return PyNumber_Power(lhs, rhs, Py_None); 11617db96d56Sopenharmony_ci} 11627db96d56Sopenharmony_ci 11637db96d56Sopenharmony_ci/* Binary in-place operators */ 11647db96d56Sopenharmony_ci 11657db96d56Sopenharmony_ci/* The in-place operators are defined to fall back to the 'normal', 11667db96d56Sopenharmony_ci non in-place operations, if the in-place methods are not in place. 11677db96d56Sopenharmony_ci 11687db96d56Sopenharmony_ci - If the left hand object has the appropriate struct members, and 11697db96d56Sopenharmony_ci they are filled, call the appropriate function and return the 11707db96d56Sopenharmony_ci result. No coercion is done on the arguments; the left-hand object 11717db96d56Sopenharmony_ci is the one the operation is performed on, and it's up to the 11727db96d56Sopenharmony_ci function to deal with the right-hand object. 11737db96d56Sopenharmony_ci 11747db96d56Sopenharmony_ci - Otherwise, in-place modification is not supported. Handle it exactly as 11757db96d56Sopenharmony_ci a non in-place operation of the same kind. 11767db96d56Sopenharmony_ci 11777db96d56Sopenharmony_ci */ 11787db96d56Sopenharmony_ci 11797db96d56Sopenharmony_cistatic PyObject * 11807db96d56Sopenharmony_cibinary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot 11817db96d56Sopenharmony_ci#ifndef NDEBUG 11827db96d56Sopenharmony_ci , const char *op_name 11837db96d56Sopenharmony_ci#endif 11847db96d56Sopenharmony_ci ) 11857db96d56Sopenharmony_ci{ 11867db96d56Sopenharmony_ci PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; 11877db96d56Sopenharmony_ci if (mv != NULL) { 11887db96d56Sopenharmony_ci binaryfunc slot = NB_BINOP(mv, iop_slot); 11897db96d56Sopenharmony_ci if (slot) { 11907db96d56Sopenharmony_ci PyObject *x = (slot)(v, w); 11917db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(v, op_name, x != NULL)); 11927db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 11937db96d56Sopenharmony_ci return x; 11947db96d56Sopenharmony_ci } 11957db96d56Sopenharmony_ci Py_DECREF(x); 11967db96d56Sopenharmony_ci } 11977db96d56Sopenharmony_ci } 11987db96d56Sopenharmony_ci#ifdef NDEBUG 11997db96d56Sopenharmony_ci return binary_op1(v, w, op_slot); 12007db96d56Sopenharmony_ci#else 12017db96d56Sopenharmony_ci return binary_op1(v, w, op_slot, op_name); 12027db96d56Sopenharmony_ci#endif 12037db96d56Sopenharmony_ci} 12047db96d56Sopenharmony_ci 12057db96d56Sopenharmony_ci#ifdef NDEBUG 12067db96d56Sopenharmony_ci# define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot) 12077db96d56Sopenharmony_ci#else 12087db96d56Sopenharmony_ci# define BINARY_IOP1(v, w, iop_slot, op_slot, op_name) binary_iop1(v, w, iop_slot, op_slot, op_name) 12097db96d56Sopenharmony_ci#endif 12107db96d56Sopenharmony_ci 12117db96d56Sopenharmony_cistatic PyObject * 12127db96d56Sopenharmony_cibinary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot, 12137db96d56Sopenharmony_ci const char *op_name) 12147db96d56Sopenharmony_ci{ 12157db96d56Sopenharmony_ci PyObject *result = BINARY_IOP1(v, w, iop_slot, op_slot, op_name); 12167db96d56Sopenharmony_ci if (result == Py_NotImplemented) { 12177db96d56Sopenharmony_ci Py_DECREF(result); 12187db96d56Sopenharmony_ci return binop_type_error(v, w, op_name); 12197db96d56Sopenharmony_ci } 12207db96d56Sopenharmony_ci return result; 12217db96d56Sopenharmony_ci} 12227db96d56Sopenharmony_ci 12237db96d56Sopenharmony_cistatic PyObject * 12247db96d56Sopenharmony_citernary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int op_slot, 12257db96d56Sopenharmony_ci const char *op_name) 12267db96d56Sopenharmony_ci{ 12277db96d56Sopenharmony_ci PyNumberMethods *mv = Py_TYPE(v)->tp_as_number; 12287db96d56Sopenharmony_ci if (mv != NULL) { 12297db96d56Sopenharmony_ci ternaryfunc slot = NB_TERNOP(mv, iop_slot); 12307db96d56Sopenharmony_ci if (slot) { 12317db96d56Sopenharmony_ci PyObject *x = (slot)(v, w, z); 12327db96d56Sopenharmony_ci if (x != Py_NotImplemented) { 12337db96d56Sopenharmony_ci return x; 12347db96d56Sopenharmony_ci } 12357db96d56Sopenharmony_ci Py_DECREF(x); 12367db96d56Sopenharmony_ci } 12377db96d56Sopenharmony_ci } 12387db96d56Sopenharmony_ci return ternary_op(v, w, z, op_slot, op_name); 12397db96d56Sopenharmony_ci} 12407db96d56Sopenharmony_ci 12417db96d56Sopenharmony_ci#define INPLACE_BINOP(func, iop, op, op_name) \ 12427db96d56Sopenharmony_ci PyObject * \ 12437db96d56Sopenharmony_ci func(PyObject *v, PyObject *w) { \ 12447db96d56Sopenharmony_ci return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \ 12457db96d56Sopenharmony_ci } 12467db96d56Sopenharmony_ci 12477db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=") 12487db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=") 12497db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=") 12507db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=") 12517db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=") 12527db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") 12537db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=") 12547db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceFloorDivide, nb_inplace_floor_divide, nb_floor_divide, "//=") 12557db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceTrueDivide, nb_inplace_true_divide, nb_true_divide, "/=") 12567db96d56Sopenharmony_ciINPLACE_BINOP(PyNumber_InPlaceRemainder, nb_inplace_remainder, nb_remainder, "%=") 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ciPyObject * 12597db96d56Sopenharmony_ciPyNumber_InPlaceAdd(PyObject *v, PyObject *w) 12607db96d56Sopenharmony_ci{ 12617db96d56Sopenharmony_ci PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_add), 12627db96d56Sopenharmony_ci NB_SLOT(nb_add), "+="); 12637db96d56Sopenharmony_ci if (result == Py_NotImplemented) { 12647db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; 12657db96d56Sopenharmony_ci Py_DECREF(result); 12667db96d56Sopenharmony_ci if (m != NULL) { 12677db96d56Sopenharmony_ci binaryfunc func = m->sq_inplace_concat; 12687db96d56Sopenharmony_ci if (func == NULL) 12697db96d56Sopenharmony_ci func = m->sq_concat; 12707db96d56Sopenharmony_ci if (func != NULL) { 12717db96d56Sopenharmony_ci result = func(v, w); 12727db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(v, "+=", result != NULL)); 12737db96d56Sopenharmony_ci return result; 12747db96d56Sopenharmony_ci } 12757db96d56Sopenharmony_ci } 12767db96d56Sopenharmony_ci result = binop_type_error(v, w, "+="); 12777db96d56Sopenharmony_ci } 12787db96d56Sopenharmony_ci return result; 12797db96d56Sopenharmony_ci} 12807db96d56Sopenharmony_ci 12817db96d56Sopenharmony_ciPyObject * 12827db96d56Sopenharmony_ciPyNumber_InPlaceMultiply(PyObject *v, PyObject *w) 12837db96d56Sopenharmony_ci{ 12847db96d56Sopenharmony_ci PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_multiply), 12857db96d56Sopenharmony_ci NB_SLOT(nb_multiply), "*="); 12867db96d56Sopenharmony_ci if (result == Py_NotImplemented) { 12877db96d56Sopenharmony_ci ssizeargfunc f = NULL; 12887db96d56Sopenharmony_ci PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; 12897db96d56Sopenharmony_ci PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; 12907db96d56Sopenharmony_ci Py_DECREF(result); 12917db96d56Sopenharmony_ci if (mv != NULL) { 12927db96d56Sopenharmony_ci f = mv->sq_inplace_repeat; 12937db96d56Sopenharmony_ci if (f == NULL) 12947db96d56Sopenharmony_ci f = mv->sq_repeat; 12957db96d56Sopenharmony_ci if (f != NULL) 12967db96d56Sopenharmony_ci return sequence_repeat(f, v, w); 12977db96d56Sopenharmony_ci } 12987db96d56Sopenharmony_ci else if (mw != NULL) { 12997db96d56Sopenharmony_ci /* Note that the right hand operand should not be 13007db96d56Sopenharmony_ci * mutated in this case so sq_inplace_repeat is not 13017db96d56Sopenharmony_ci * used. */ 13027db96d56Sopenharmony_ci if (mw->sq_repeat) 13037db96d56Sopenharmony_ci return sequence_repeat(mw->sq_repeat, w, v); 13047db96d56Sopenharmony_ci } 13057db96d56Sopenharmony_ci result = binop_type_error(v, w, "*="); 13067db96d56Sopenharmony_ci } 13077db96d56Sopenharmony_ci return result; 13087db96d56Sopenharmony_ci} 13097db96d56Sopenharmony_ci 13107db96d56Sopenharmony_ciPyObject * 13117db96d56Sopenharmony_ciPyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) 13127db96d56Sopenharmony_ci{ 13137db96d56Sopenharmony_ci return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power), 13147db96d56Sopenharmony_ci NB_SLOT(nb_power), "**="); 13157db96d56Sopenharmony_ci} 13167db96d56Sopenharmony_ci 13177db96d56Sopenharmony_ciPyObject * 13187db96d56Sopenharmony_ci_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs) 13197db96d56Sopenharmony_ci{ 13207db96d56Sopenharmony_ci return PyNumber_InPlacePower(lhs, rhs, Py_None); 13217db96d56Sopenharmony_ci} 13227db96d56Sopenharmony_ci 13237db96d56Sopenharmony_ci 13247db96d56Sopenharmony_ci/* Unary operators and functions */ 13257db96d56Sopenharmony_ci 13267db96d56Sopenharmony_ciPyObject * 13277db96d56Sopenharmony_ciPyNumber_Negative(PyObject *o) 13287db96d56Sopenharmony_ci{ 13297db96d56Sopenharmony_ci if (o == NULL) { 13307db96d56Sopenharmony_ci return null_error(); 13317db96d56Sopenharmony_ci } 13327db96d56Sopenharmony_ci 13337db96d56Sopenharmony_ci PyNumberMethods *m = Py_TYPE(o)->tp_as_number; 13347db96d56Sopenharmony_ci if (m && m->nb_negative) { 13357db96d56Sopenharmony_ci PyObject *res = (*m->nb_negative)(o); 13367db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__neg__", res != NULL)); 13377db96d56Sopenharmony_ci return res; 13387db96d56Sopenharmony_ci } 13397db96d56Sopenharmony_ci 13407db96d56Sopenharmony_ci return type_error("bad operand type for unary -: '%.200s'", o); 13417db96d56Sopenharmony_ci} 13427db96d56Sopenharmony_ci 13437db96d56Sopenharmony_ciPyObject * 13447db96d56Sopenharmony_ciPyNumber_Positive(PyObject *o) 13457db96d56Sopenharmony_ci{ 13467db96d56Sopenharmony_ci if (o == NULL) { 13477db96d56Sopenharmony_ci return null_error(); 13487db96d56Sopenharmony_ci } 13497db96d56Sopenharmony_ci 13507db96d56Sopenharmony_ci PyNumberMethods *m = Py_TYPE(o)->tp_as_number; 13517db96d56Sopenharmony_ci if (m && m->nb_positive) { 13527db96d56Sopenharmony_ci PyObject *res = (*m->nb_positive)(o); 13537db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__pos__", res != NULL)); 13547db96d56Sopenharmony_ci return res; 13557db96d56Sopenharmony_ci } 13567db96d56Sopenharmony_ci 13577db96d56Sopenharmony_ci return type_error("bad operand type for unary +: '%.200s'", o); 13587db96d56Sopenharmony_ci} 13597db96d56Sopenharmony_ci 13607db96d56Sopenharmony_ciPyObject * 13617db96d56Sopenharmony_ciPyNumber_Invert(PyObject *o) 13627db96d56Sopenharmony_ci{ 13637db96d56Sopenharmony_ci if (o == NULL) { 13647db96d56Sopenharmony_ci return null_error(); 13657db96d56Sopenharmony_ci } 13667db96d56Sopenharmony_ci 13677db96d56Sopenharmony_ci PyNumberMethods *m = Py_TYPE(o)->tp_as_number; 13687db96d56Sopenharmony_ci if (m && m->nb_invert) { 13697db96d56Sopenharmony_ci PyObject *res = (*m->nb_invert)(o); 13707db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__invert__", res != NULL)); 13717db96d56Sopenharmony_ci return res; 13727db96d56Sopenharmony_ci } 13737db96d56Sopenharmony_ci 13747db96d56Sopenharmony_ci return type_error("bad operand type for unary ~: '%.200s'", o); 13757db96d56Sopenharmony_ci} 13767db96d56Sopenharmony_ci 13777db96d56Sopenharmony_ciPyObject * 13787db96d56Sopenharmony_ciPyNumber_Absolute(PyObject *o) 13797db96d56Sopenharmony_ci{ 13807db96d56Sopenharmony_ci if (o == NULL) { 13817db96d56Sopenharmony_ci return null_error(); 13827db96d56Sopenharmony_ci } 13837db96d56Sopenharmony_ci 13847db96d56Sopenharmony_ci PyNumberMethods *m = Py_TYPE(o)->tp_as_number; 13857db96d56Sopenharmony_ci if (m && m->nb_absolute) { 13867db96d56Sopenharmony_ci PyObject *res = m->nb_absolute(o); 13877db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__abs__", res != NULL)); 13887db96d56Sopenharmony_ci return res; 13897db96d56Sopenharmony_ci } 13907db96d56Sopenharmony_ci 13917db96d56Sopenharmony_ci return type_error("bad operand type for abs(): '%.200s'", o); 13927db96d56Sopenharmony_ci} 13937db96d56Sopenharmony_ci 13947db96d56Sopenharmony_ci 13957db96d56Sopenharmony_ciint 13967db96d56Sopenharmony_ciPyIndex_Check(PyObject *obj) 13977db96d56Sopenharmony_ci{ 13987db96d56Sopenharmony_ci return _PyIndex_Check(obj); 13997db96d56Sopenharmony_ci} 14007db96d56Sopenharmony_ci 14017db96d56Sopenharmony_ci 14027db96d56Sopenharmony_ci/* Return a Python int from the object item. 14037db96d56Sopenharmony_ci Can return an instance of int subclass. 14047db96d56Sopenharmony_ci Raise TypeError if the result is not an int 14057db96d56Sopenharmony_ci or if the object cannot be interpreted as an index. 14067db96d56Sopenharmony_ci*/ 14077db96d56Sopenharmony_ciPyObject * 14087db96d56Sopenharmony_ci_PyNumber_Index(PyObject *item) 14097db96d56Sopenharmony_ci{ 14107db96d56Sopenharmony_ci if (item == NULL) { 14117db96d56Sopenharmony_ci return null_error(); 14127db96d56Sopenharmony_ci } 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ci if (PyLong_Check(item)) { 14157db96d56Sopenharmony_ci Py_INCREF(item); 14167db96d56Sopenharmony_ci return item; 14177db96d56Sopenharmony_ci } 14187db96d56Sopenharmony_ci if (!_PyIndex_Check(item)) { 14197db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 14207db96d56Sopenharmony_ci "'%.200s' object cannot be interpreted " 14217db96d56Sopenharmony_ci "as an integer", Py_TYPE(item)->tp_name); 14227db96d56Sopenharmony_ci return NULL; 14237db96d56Sopenharmony_ci } 14247db96d56Sopenharmony_ci 14257db96d56Sopenharmony_ci PyObject *result = Py_TYPE(item)->tp_as_number->nb_index(item); 14267db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(item, "__index__", result != NULL)); 14277db96d56Sopenharmony_ci if (!result || PyLong_CheckExact(result)) { 14287db96d56Sopenharmony_ci return result; 14297db96d56Sopenharmony_ci } 14307db96d56Sopenharmony_ci 14317db96d56Sopenharmony_ci if (!PyLong_Check(result)) { 14327db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 14337db96d56Sopenharmony_ci "__index__ returned non-int (type %.200s)", 14347db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 14357db96d56Sopenharmony_ci Py_DECREF(result); 14367db96d56Sopenharmony_ci return NULL; 14377db96d56Sopenharmony_ci } 14387db96d56Sopenharmony_ci /* Issue #17576: warn if 'result' not of exact type int. */ 14397db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 14407db96d56Sopenharmony_ci "__index__ returned non-int (type %.200s). " 14417db96d56Sopenharmony_ci "The ability to return an instance of a strict subclass of int " 14427db96d56Sopenharmony_ci "is deprecated, and may be removed in a future version of Python.", 14437db96d56Sopenharmony_ci Py_TYPE(result)->tp_name)) { 14447db96d56Sopenharmony_ci Py_DECREF(result); 14457db96d56Sopenharmony_ci return NULL; 14467db96d56Sopenharmony_ci } 14477db96d56Sopenharmony_ci return result; 14487db96d56Sopenharmony_ci} 14497db96d56Sopenharmony_ci 14507db96d56Sopenharmony_ci/* Return an exact Python int from the object item. 14517db96d56Sopenharmony_ci Raise TypeError if the result is not an int 14527db96d56Sopenharmony_ci or if the object cannot be interpreted as an index. 14537db96d56Sopenharmony_ci*/ 14547db96d56Sopenharmony_ciPyObject * 14557db96d56Sopenharmony_ciPyNumber_Index(PyObject *item) 14567db96d56Sopenharmony_ci{ 14577db96d56Sopenharmony_ci PyObject *result = _PyNumber_Index(item); 14587db96d56Sopenharmony_ci if (result != NULL && !PyLong_CheckExact(result)) { 14597db96d56Sopenharmony_ci Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); 14607db96d56Sopenharmony_ci } 14617db96d56Sopenharmony_ci return result; 14627db96d56Sopenharmony_ci} 14637db96d56Sopenharmony_ci 14647db96d56Sopenharmony_ci/* Return an error on Overflow only if err is not NULL*/ 14657db96d56Sopenharmony_ci 14667db96d56Sopenharmony_ciPy_ssize_t 14677db96d56Sopenharmony_ciPyNumber_AsSsize_t(PyObject *item, PyObject *err) 14687db96d56Sopenharmony_ci{ 14697db96d56Sopenharmony_ci Py_ssize_t result; 14707db96d56Sopenharmony_ci PyObject *runerr; 14717db96d56Sopenharmony_ci PyObject *value = _PyNumber_Index(item); 14727db96d56Sopenharmony_ci if (value == NULL) 14737db96d56Sopenharmony_ci return -1; 14747db96d56Sopenharmony_ci 14757db96d56Sopenharmony_ci /* We're done if PyLong_AsSsize_t() returns without error. */ 14767db96d56Sopenharmony_ci result = PyLong_AsSsize_t(value); 14777db96d56Sopenharmony_ci if (result != -1) 14787db96d56Sopenharmony_ci goto finish; 14797db96d56Sopenharmony_ci 14807db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 14817db96d56Sopenharmony_ci runerr = _PyErr_Occurred(tstate); 14827db96d56Sopenharmony_ci if (!runerr) { 14837db96d56Sopenharmony_ci goto finish; 14847db96d56Sopenharmony_ci } 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ci /* Error handling code -- only manage OverflowError differently */ 14877db96d56Sopenharmony_ci if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { 14887db96d56Sopenharmony_ci goto finish; 14897db96d56Sopenharmony_ci } 14907db96d56Sopenharmony_ci _PyErr_Clear(tstate); 14917db96d56Sopenharmony_ci 14927db96d56Sopenharmony_ci /* If no error-handling desired then the default clipping 14937db96d56Sopenharmony_ci is sufficient. */ 14947db96d56Sopenharmony_ci if (!err) { 14957db96d56Sopenharmony_ci assert(PyLong_Check(value)); 14967db96d56Sopenharmony_ci /* Whether or not it is less than or equal to 14977db96d56Sopenharmony_ci zero is determined by the sign of ob_size 14987db96d56Sopenharmony_ci */ 14997db96d56Sopenharmony_ci if (_PyLong_Sign(value) < 0) 15007db96d56Sopenharmony_ci result = PY_SSIZE_T_MIN; 15017db96d56Sopenharmony_ci else 15027db96d56Sopenharmony_ci result = PY_SSIZE_T_MAX; 15037db96d56Sopenharmony_ci } 15047db96d56Sopenharmony_ci else { 15057db96d56Sopenharmony_ci /* Otherwise replace the error with caller's error object. */ 15067db96d56Sopenharmony_ci _PyErr_Format(tstate, err, 15077db96d56Sopenharmony_ci "cannot fit '%.200s' into an index-sized integer", 15087db96d56Sopenharmony_ci Py_TYPE(item)->tp_name); 15097db96d56Sopenharmony_ci } 15107db96d56Sopenharmony_ci 15117db96d56Sopenharmony_ci finish: 15127db96d56Sopenharmony_ci Py_DECREF(value); 15137db96d56Sopenharmony_ci return result; 15147db96d56Sopenharmony_ci} 15157db96d56Sopenharmony_ci 15167db96d56Sopenharmony_ci 15177db96d56Sopenharmony_ciPyObject * 15187db96d56Sopenharmony_ciPyNumber_Long(PyObject *o) 15197db96d56Sopenharmony_ci{ 15207db96d56Sopenharmony_ci PyObject *result; 15217db96d56Sopenharmony_ci PyNumberMethods *m; 15227db96d56Sopenharmony_ci PyObject *trunc_func; 15237db96d56Sopenharmony_ci Py_buffer view; 15247db96d56Sopenharmony_ci 15257db96d56Sopenharmony_ci if (o == NULL) { 15267db96d56Sopenharmony_ci return null_error(); 15277db96d56Sopenharmony_ci } 15287db96d56Sopenharmony_ci 15297db96d56Sopenharmony_ci if (PyLong_CheckExact(o)) { 15307db96d56Sopenharmony_ci Py_INCREF(o); 15317db96d56Sopenharmony_ci return o; 15327db96d56Sopenharmony_ci } 15337db96d56Sopenharmony_ci m = Py_TYPE(o)->tp_as_number; 15347db96d56Sopenharmony_ci if (m && m->nb_int) { /* This should include subclasses of int */ 15357db96d56Sopenharmony_ci /* Convert using the nb_int slot, which should return something 15367db96d56Sopenharmony_ci of exact type int. */ 15377db96d56Sopenharmony_ci result = m->nb_int(o); 15387db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__int__", result != NULL)); 15397db96d56Sopenharmony_ci if (!result || PyLong_CheckExact(result)) { 15407db96d56Sopenharmony_ci return result; 15417db96d56Sopenharmony_ci } 15427db96d56Sopenharmony_ci 15437db96d56Sopenharmony_ci if (!PyLong_Check(result)) { 15447db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 15457db96d56Sopenharmony_ci "__int__ returned non-int (type %.200s)", 15467db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 15477db96d56Sopenharmony_ci Py_DECREF(result); 15487db96d56Sopenharmony_ci return NULL; 15497db96d56Sopenharmony_ci } 15507db96d56Sopenharmony_ci /* Issue #17576: warn if 'result' not of exact type int. */ 15517db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 15527db96d56Sopenharmony_ci "__int__ returned non-int (type %.200s). " 15537db96d56Sopenharmony_ci "The ability to return an instance of a strict subclass of int " 15547db96d56Sopenharmony_ci "is deprecated, and may be removed in a future version of Python.", 15557db96d56Sopenharmony_ci Py_TYPE(result)->tp_name)) { 15567db96d56Sopenharmony_ci Py_DECREF(result); 15577db96d56Sopenharmony_ci return NULL; 15587db96d56Sopenharmony_ci } 15597db96d56Sopenharmony_ci Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); 15607db96d56Sopenharmony_ci return result; 15617db96d56Sopenharmony_ci } 15627db96d56Sopenharmony_ci if (m && m->nb_index) { 15637db96d56Sopenharmony_ci return PyNumber_Index(o); 15647db96d56Sopenharmony_ci } 15657db96d56Sopenharmony_ci trunc_func = _PyObject_LookupSpecial(o, &_Py_ID(__trunc__)); 15667db96d56Sopenharmony_ci if (trunc_func) { 15677db96d56Sopenharmony_ci if (PyErr_WarnEx(PyExc_DeprecationWarning, 15687db96d56Sopenharmony_ci "The delegation of int() to __trunc__ is deprecated.", 1)) { 15697db96d56Sopenharmony_ci Py_DECREF(trunc_func); 15707db96d56Sopenharmony_ci return NULL; 15717db96d56Sopenharmony_ci } 15727db96d56Sopenharmony_ci result = _PyObject_CallNoArgs(trunc_func); 15737db96d56Sopenharmony_ci Py_DECREF(trunc_func); 15747db96d56Sopenharmony_ci if (result == NULL || PyLong_CheckExact(result)) { 15757db96d56Sopenharmony_ci return result; 15767db96d56Sopenharmony_ci } 15777db96d56Sopenharmony_ci if (PyLong_Check(result)) { 15787db96d56Sopenharmony_ci Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); 15797db96d56Sopenharmony_ci return result; 15807db96d56Sopenharmony_ci } 15817db96d56Sopenharmony_ci /* __trunc__ is specified to return an Integral type, 15827db96d56Sopenharmony_ci but int() needs to return an int. */ 15837db96d56Sopenharmony_ci if (!PyIndex_Check(result)) { 15847db96d56Sopenharmony_ci PyErr_Format( 15857db96d56Sopenharmony_ci PyExc_TypeError, 15867db96d56Sopenharmony_ci "__trunc__ returned non-Integral (type %.200s)", 15877db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 15887db96d56Sopenharmony_ci Py_DECREF(result); 15897db96d56Sopenharmony_ci return NULL; 15907db96d56Sopenharmony_ci } 15917db96d56Sopenharmony_ci Py_SETREF(result, PyNumber_Index(result)); 15927db96d56Sopenharmony_ci return result; 15937db96d56Sopenharmony_ci } 15947db96d56Sopenharmony_ci if (PyErr_Occurred()) 15957db96d56Sopenharmony_ci return NULL; 15967db96d56Sopenharmony_ci 15977db96d56Sopenharmony_ci if (PyUnicode_Check(o)) 15987db96d56Sopenharmony_ci /* The below check is done in PyLong_FromUnicodeObject(). */ 15997db96d56Sopenharmony_ci return PyLong_FromUnicodeObject(o, 10); 16007db96d56Sopenharmony_ci 16017db96d56Sopenharmony_ci if (PyBytes_Check(o)) 16027db96d56Sopenharmony_ci /* need to do extra error checking that PyLong_FromString() 16037db96d56Sopenharmony_ci * doesn't do. In particular int('9\x005') must raise an 16047db96d56Sopenharmony_ci * exception, not truncate at the null. 16057db96d56Sopenharmony_ci */ 16067db96d56Sopenharmony_ci return _PyLong_FromBytes(PyBytes_AS_STRING(o), 16077db96d56Sopenharmony_ci PyBytes_GET_SIZE(o), 10); 16087db96d56Sopenharmony_ci 16097db96d56Sopenharmony_ci if (PyByteArray_Check(o)) 16107db96d56Sopenharmony_ci return _PyLong_FromBytes(PyByteArray_AS_STRING(o), 16117db96d56Sopenharmony_ci PyByteArray_GET_SIZE(o), 10); 16127db96d56Sopenharmony_ci 16137db96d56Sopenharmony_ci if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { 16147db96d56Sopenharmony_ci PyObject *bytes; 16157db96d56Sopenharmony_ci 16167db96d56Sopenharmony_ci /* Copy to NUL-terminated buffer. */ 16177db96d56Sopenharmony_ci bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len); 16187db96d56Sopenharmony_ci if (bytes == NULL) { 16197db96d56Sopenharmony_ci PyBuffer_Release(&view); 16207db96d56Sopenharmony_ci return NULL; 16217db96d56Sopenharmony_ci } 16227db96d56Sopenharmony_ci result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes), 16237db96d56Sopenharmony_ci PyBytes_GET_SIZE(bytes), 10); 16247db96d56Sopenharmony_ci Py_DECREF(bytes); 16257db96d56Sopenharmony_ci PyBuffer_Release(&view); 16267db96d56Sopenharmony_ci return result; 16277db96d56Sopenharmony_ci } 16287db96d56Sopenharmony_ci 16297db96d56Sopenharmony_ci return type_error("int() argument must be a string, a bytes-like object " 16307db96d56Sopenharmony_ci "or a real number, not '%.200s'", o); 16317db96d56Sopenharmony_ci} 16327db96d56Sopenharmony_ci 16337db96d56Sopenharmony_ciPyObject * 16347db96d56Sopenharmony_ciPyNumber_Float(PyObject *o) 16357db96d56Sopenharmony_ci{ 16367db96d56Sopenharmony_ci if (o == NULL) { 16377db96d56Sopenharmony_ci return null_error(); 16387db96d56Sopenharmony_ci } 16397db96d56Sopenharmony_ci 16407db96d56Sopenharmony_ci if (PyFloat_CheckExact(o)) { 16417db96d56Sopenharmony_ci return Py_NewRef(o); 16427db96d56Sopenharmony_ci } 16437db96d56Sopenharmony_ci 16447db96d56Sopenharmony_ci PyNumberMethods *m = Py_TYPE(o)->tp_as_number; 16457db96d56Sopenharmony_ci if (m && m->nb_float) { /* This should include subclasses of float */ 16467db96d56Sopenharmony_ci PyObject *res = m->nb_float(o); 16477db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__float__", res != NULL)); 16487db96d56Sopenharmony_ci if (!res || PyFloat_CheckExact(res)) { 16497db96d56Sopenharmony_ci return res; 16507db96d56Sopenharmony_ci } 16517db96d56Sopenharmony_ci 16527db96d56Sopenharmony_ci if (!PyFloat_Check(res)) { 16537db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 16547db96d56Sopenharmony_ci "%.50s.__float__ returned non-float (type %.50s)", 16557db96d56Sopenharmony_ci Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name); 16567db96d56Sopenharmony_ci Py_DECREF(res); 16577db96d56Sopenharmony_ci return NULL; 16587db96d56Sopenharmony_ci } 16597db96d56Sopenharmony_ci /* Issue #26983: warn if 'res' not of exact type float. */ 16607db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 16617db96d56Sopenharmony_ci "%.50s.__float__ returned non-float (type %.50s). " 16627db96d56Sopenharmony_ci "The ability to return an instance of a strict subclass of float " 16637db96d56Sopenharmony_ci "is deprecated, and may be removed in a future version of Python.", 16647db96d56Sopenharmony_ci Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name)) { 16657db96d56Sopenharmony_ci Py_DECREF(res); 16667db96d56Sopenharmony_ci return NULL; 16677db96d56Sopenharmony_ci } 16687db96d56Sopenharmony_ci double val = PyFloat_AS_DOUBLE(res); 16697db96d56Sopenharmony_ci Py_DECREF(res); 16707db96d56Sopenharmony_ci return PyFloat_FromDouble(val); 16717db96d56Sopenharmony_ci } 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_ci if (m && m->nb_index) { 16747db96d56Sopenharmony_ci PyObject *res = _PyNumber_Index(o); 16757db96d56Sopenharmony_ci if (!res) { 16767db96d56Sopenharmony_ci return NULL; 16777db96d56Sopenharmony_ci } 16787db96d56Sopenharmony_ci double val = PyLong_AsDouble(res); 16797db96d56Sopenharmony_ci Py_DECREF(res); 16807db96d56Sopenharmony_ci if (val == -1.0 && PyErr_Occurred()) { 16817db96d56Sopenharmony_ci return NULL; 16827db96d56Sopenharmony_ci } 16837db96d56Sopenharmony_ci return PyFloat_FromDouble(val); 16847db96d56Sopenharmony_ci } 16857db96d56Sopenharmony_ci 16867db96d56Sopenharmony_ci /* A float subclass with nb_float == NULL */ 16877db96d56Sopenharmony_ci if (PyFloat_Check(o)) { 16887db96d56Sopenharmony_ci return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o)); 16897db96d56Sopenharmony_ci } 16907db96d56Sopenharmony_ci return PyFloat_FromString(o); 16917db96d56Sopenharmony_ci} 16927db96d56Sopenharmony_ci 16937db96d56Sopenharmony_ci 16947db96d56Sopenharmony_ciPyObject * 16957db96d56Sopenharmony_ciPyNumber_ToBase(PyObject *n, int base) 16967db96d56Sopenharmony_ci{ 16977db96d56Sopenharmony_ci if (!(base == 2 || base == 8 || base == 10 || base == 16)) { 16987db96d56Sopenharmony_ci PyErr_SetString(PyExc_SystemError, 16997db96d56Sopenharmony_ci "PyNumber_ToBase: base must be 2, 8, 10 or 16"); 17007db96d56Sopenharmony_ci return NULL; 17017db96d56Sopenharmony_ci } 17027db96d56Sopenharmony_ci PyObject *index = _PyNumber_Index(n); 17037db96d56Sopenharmony_ci if (!index) 17047db96d56Sopenharmony_ci return NULL; 17057db96d56Sopenharmony_ci PyObject *res = _PyLong_Format(index, base); 17067db96d56Sopenharmony_ci Py_DECREF(index); 17077db96d56Sopenharmony_ci return res; 17087db96d56Sopenharmony_ci} 17097db96d56Sopenharmony_ci 17107db96d56Sopenharmony_ci 17117db96d56Sopenharmony_ci/* Operations on sequences */ 17127db96d56Sopenharmony_ci 17137db96d56Sopenharmony_ciint 17147db96d56Sopenharmony_ciPySequence_Check(PyObject *s) 17157db96d56Sopenharmony_ci{ 17167db96d56Sopenharmony_ci if (PyDict_Check(s)) 17177db96d56Sopenharmony_ci return 0; 17187db96d56Sopenharmony_ci return Py_TYPE(s)->tp_as_sequence && 17197db96d56Sopenharmony_ci Py_TYPE(s)->tp_as_sequence->sq_item != NULL; 17207db96d56Sopenharmony_ci} 17217db96d56Sopenharmony_ci 17227db96d56Sopenharmony_ciPy_ssize_t 17237db96d56Sopenharmony_ciPySequence_Size(PyObject *s) 17247db96d56Sopenharmony_ci{ 17257db96d56Sopenharmony_ci if (s == NULL) { 17267db96d56Sopenharmony_ci null_error(); 17277db96d56Sopenharmony_ci return -1; 17287db96d56Sopenharmony_ci } 17297db96d56Sopenharmony_ci 17307db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 17317db96d56Sopenharmony_ci if (m && m->sq_length) { 17327db96d56Sopenharmony_ci Py_ssize_t len = m->sq_length(s); 17337db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__len__", len >= 0)); 17347db96d56Sopenharmony_ci return len; 17357db96d56Sopenharmony_ci } 17367db96d56Sopenharmony_ci 17377db96d56Sopenharmony_ci if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_length) { 17387db96d56Sopenharmony_ci type_error("%.200s is not a sequence", s); 17397db96d56Sopenharmony_ci return -1; 17407db96d56Sopenharmony_ci } 17417db96d56Sopenharmony_ci type_error("object of type '%.200s' has no len()", s); 17427db96d56Sopenharmony_ci return -1; 17437db96d56Sopenharmony_ci} 17447db96d56Sopenharmony_ci 17457db96d56Sopenharmony_ci#undef PySequence_Length 17467db96d56Sopenharmony_ciPy_ssize_t 17477db96d56Sopenharmony_ciPySequence_Length(PyObject *s) 17487db96d56Sopenharmony_ci{ 17497db96d56Sopenharmony_ci return PySequence_Size(s); 17507db96d56Sopenharmony_ci} 17517db96d56Sopenharmony_ci#define PySequence_Length PySequence_Size 17527db96d56Sopenharmony_ci 17537db96d56Sopenharmony_ciPyObject * 17547db96d56Sopenharmony_ciPySequence_Concat(PyObject *s, PyObject *o) 17557db96d56Sopenharmony_ci{ 17567db96d56Sopenharmony_ci if (s == NULL || o == NULL) { 17577db96d56Sopenharmony_ci return null_error(); 17587db96d56Sopenharmony_ci } 17597db96d56Sopenharmony_ci 17607db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 17617db96d56Sopenharmony_ci if (m && m->sq_concat) { 17627db96d56Sopenharmony_ci PyObject *res = m->sq_concat(s, o); 17637db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "+", res != NULL)); 17647db96d56Sopenharmony_ci return res; 17657db96d56Sopenharmony_ci } 17667db96d56Sopenharmony_ci 17677db96d56Sopenharmony_ci /* Instances of user classes defining an __add__() method only 17687db96d56Sopenharmony_ci have an nb_add slot, not an sq_concat slot. So we fall back 17697db96d56Sopenharmony_ci to nb_add if both arguments appear to be sequences. */ 17707db96d56Sopenharmony_ci if (PySequence_Check(s) && PySequence_Check(o)) { 17717db96d56Sopenharmony_ci PyObject *result = BINARY_OP1(s, o, NB_SLOT(nb_add), "+"); 17727db96d56Sopenharmony_ci if (result != Py_NotImplemented) 17737db96d56Sopenharmony_ci return result; 17747db96d56Sopenharmony_ci Py_DECREF(result); 17757db96d56Sopenharmony_ci } 17767db96d56Sopenharmony_ci return type_error("'%.200s' object can't be concatenated", s); 17777db96d56Sopenharmony_ci} 17787db96d56Sopenharmony_ci 17797db96d56Sopenharmony_ciPyObject * 17807db96d56Sopenharmony_ciPySequence_Repeat(PyObject *o, Py_ssize_t count) 17817db96d56Sopenharmony_ci{ 17827db96d56Sopenharmony_ci if (o == NULL) { 17837db96d56Sopenharmony_ci return null_error(); 17847db96d56Sopenharmony_ci } 17857db96d56Sopenharmony_ci 17867db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; 17877db96d56Sopenharmony_ci if (m && m->sq_repeat) { 17887db96d56Sopenharmony_ci PyObject *res = m->sq_repeat(o, count); 17897db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "*", res != NULL)); 17907db96d56Sopenharmony_ci return res; 17917db96d56Sopenharmony_ci } 17927db96d56Sopenharmony_ci 17937db96d56Sopenharmony_ci /* Instances of user classes defining a __mul__() method only 17947db96d56Sopenharmony_ci have an nb_multiply slot, not an sq_repeat slot. so we fall back 17957db96d56Sopenharmony_ci to nb_multiply if o appears to be a sequence. */ 17967db96d56Sopenharmony_ci if (PySequence_Check(o)) { 17977db96d56Sopenharmony_ci PyObject *n, *result; 17987db96d56Sopenharmony_ci n = PyLong_FromSsize_t(count); 17997db96d56Sopenharmony_ci if (n == NULL) 18007db96d56Sopenharmony_ci return NULL; 18017db96d56Sopenharmony_ci result = BINARY_OP1(o, n, NB_SLOT(nb_multiply), "*"); 18027db96d56Sopenharmony_ci Py_DECREF(n); 18037db96d56Sopenharmony_ci if (result != Py_NotImplemented) 18047db96d56Sopenharmony_ci return result; 18057db96d56Sopenharmony_ci Py_DECREF(result); 18067db96d56Sopenharmony_ci } 18077db96d56Sopenharmony_ci return type_error("'%.200s' object can't be repeated", o); 18087db96d56Sopenharmony_ci} 18097db96d56Sopenharmony_ci 18107db96d56Sopenharmony_ciPyObject * 18117db96d56Sopenharmony_ciPySequence_InPlaceConcat(PyObject *s, PyObject *o) 18127db96d56Sopenharmony_ci{ 18137db96d56Sopenharmony_ci if (s == NULL || o == NULL) { 18147db96d56Sopenharmony_ci return null_error(); 18157db96d56Sopenharmony_ci } 18167db96d56Sopenharmony_ci 18177db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 18187db96d56Sopenharmony_ci if (m && m->sq_inplace_concat) { 18197db96d56Sopenharmony_ci PyObject *res = m->sq_inplace_concat(s, o); 18207db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "+=", res != NULL)); 18217db96d56Sopenharmony_ci return res; 18227db96d56Sopenharmony_ci } 18237db96d56Sopenharmony_ci if (m && m->sq_concat) { 18247db96d56Sopenharmony_ci PyObject *res = m->sq_concat(s, o); 18257db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "+", res != NULL)); 18267db96d56Sopenharmony_ci return res; 18277db96d56Sopenharmony_ci } 18287db96d56Sopenharmony_ci 18297db96d56Sopenharmony_ci if (PySequence_Check(s) && PySequence_Check(o)) { 18307db96d56Sopenharmony_ci PyObject *result = BINARY_IOP1(s, o, NB_SLOT(nb_inplace_add), 18317db96d56Sopenharmony_ci NB_SLOT(nb_add), "+="); 18327db96d56Sopenharmony_ci if (result != Py_NotImplemented) 18337db96d56Sopenharmony_ci return result; 18347db96d56Sopenharmony_ci Py_DECREF(result); 18357db96d56Sopenharmony_ci } 18367db96d56Sopenharmony_ci return type_error("'%.200s' object can't be concatenated", s); 18377db96d56Sopenharmony_ci} 18387db96d56Sopenharmony_ci 18397db96d56Sopenharmony_ciPyObject * 18407db96d56Sopenharmony_ciPySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) 18417db96d56Sopenharmony_ci{ 18427db96d56Sopenharmony_ci if (o == NULL) { 18437db96d56Sopenharmony_ci return null_error(); 18447db96d56Sopenharmony_ci } 18457db96d56Sopenharmony_ci 18467db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; 18477db96d56Sopenharmony_ci if (m && m->sq_inplace_repeat) { 18487db96d56Sopenharmony_ci PyObject *res = m->sq_inplace_repeat(o, count); 18497db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "*=", res != NULL)); 18507db96d56Sopenharmony_ci return res; 18517db96d56Sopenharmony_ci } 18527db96d56Sopenharmony_ci if (m && m->sq_repeat) { 18537db96d56Sopenharmony_ci PyObject *res = m->sq_repeat(o, count); 18547db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "*", res != NULL)); 18557db96d56Sopenharmony_ci return res; 18567db96d56Sopenharmony_ci } 18577db96d56Sopenharmony_ci 18587db96d56Sopenharmony_ci if (PySequence_Check(o)) { 18597db96d56Sopenharmony_ci PyObject *n, *result; 18607db96d56Sopenharmony_ci n = PyLong_FromSsize_t(count); 18617db96d56Sopenharmony_ci if (n == NULL) 18627db96d56Sopenharmony_ci return NULL; 18637db96d56Sopenharmony_ci result = BINARY_IOP1(o, n, NB_SLOT(nb_inplace_multiply), 18647db96d56Sopenharmony_ci NB_SLOT(nb_multiply), "*="); 18657db96d56Sopenharmony_ci Py_DECREF(n); 18667db96d56Sopenharmony_ci if (result != Py_NotImplemented) 18677db96d56Sopenharmony_ci return result; 18687db96d56Sopenharmony_ci Py_DECREF(result); 18697db96d56Sopenharmony_ci } 18707db96d56Sopenharmony_ci return type_error("'%.200s' object can't be repeated", o); 18717db96d56Sopenharmony_ci} 18727db96d56Sopenharmony_ci 18737db96d56Sopenharmony_ciPyObject * 18747db96d56Sopenharmony_ciPySequence_GetItem(PyObject *s, Py_ssize_t i) 18757db96d56Sopenharmony_ci{ 18767db96d56Sopenharmony_ci if (s == NULL) { 18777db96d56Sopenharmony_ci return null_error(); 18787db96d56Sopenharmony_ci } 18797db96d56Sopenharmony_ci 18807db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 18817db96d56Sopenharmony_ci if (m && m->sq_item) { 18827db96d56Sopenharmony_ci if (i < 0) { 18837db96d56Sopenharmony_ci if (m->sq_length) { 18847db96d56Sopenharmony_ci Py_ssize_t l = (*m->sq_length)(s); 18857db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); 18867db96d56Sopenharmony_ci if (l < 0) { 18877db96d56Sopenharmony_ci return NULL; 18887db96d56Sopenharmony_ci } 18897db96d56Sopenharmony_ci i += l; 18907db96d56Sopenharmony_ci } 18917db96d56Sopenharmony_ci } 18927db96d56Sopenharmony_ci PyObject *res = m->sq_item(s, i); 18937db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL)); 18947db96d56Sopenharmony_ci return res; 18957db96d56Sopenharmony_ci } 18967db96d56Sopenharmony_ci 18977db96d56Sopenharmony_ci if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_subscript) { 18987db96d56Sopenharmony_ci return type_error("%.200s is not a sequence", s); 18997db96d56Sopenharmony_ci } 19007db96d56Sopenharmony_ci return type_error("'%.200s' object does not support indexing", s); 19017db96d56Sopenharmony_ci} 19027db96d56Sopenharmony_ci 19037db96d56Sopenharmony_ciPyObject * 19047db96d56Sopenharmony_ciPySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) 19057db96d56Sopenharmony_ci{ 19067db96d56Sopenharmony_ci if (!s) { 19077db96d56Sopenharmony_ci return null_error(); 19087db96d56Sopenharmony_ci } 19097db96d56Sopenharmony_ci 19107db96d56Sopenharmony_ci PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; 19117db96d56Sopenharmony_ci if (mp && mp->mp_subscript) { 19127db96d56Sopenharmony_ci PyObject *slice = _PySlice_FromIndices(i1, i2); 19137db96d56Sopenharmony_ci if (!slice) { 19147db96d56Sopenharmony_ci return NULL; 19157db96d56Sopenharmony_ci } 19167db96d56Sopenharmony_ci PyObject *res = mp->mp_subscript(s, slice); 19177db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__getitem__", res != NULL)); 19187db96d56Sopenharmony_ci Py_DECREF(slice); 19197db96d56Sopenharmony_ci return res; 19207db96d56Sopenharmony_ci } 19217db96d56Sopenharmony_ci 19227db96d56Sopenharmony_ci return type_error("'%.200s' object is unsliceable", s); 19237db96d56Sopenharmony_ci} 19247db96d56Sopenharmony_ci 19257db96d56Sopenharmony_ciint 19267db96d56Sopenharmony_ciPySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) 19277db96d56Sopenharmony_ci{ 19287db96d56Sopenharmony_ci if (s == NULL) { 19297db96d56Sopenharmony_ci null_error(); 19307db96d56Sopenharmony_ci return -1; 19317db96d56Sopenharmony_ci } 19327db96d56Sopenharmony_ci 19337db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 19347db96d56Sopenharmony_ci if (m && m->sq_ass_item) { 19357db96d56Sopenharmony_ci if (i < 0) { 19367db96d56Sopenharmony_ci if (m->sq_length) { 19377db96d56Sopenharmony_ci Py_ssize_t l = (*m->sq_length)(s); 19387db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); 19397db96d56Sopenharmony_ci if (l < 0) { 19407db96d56Sopenharmony_ci return -1; 19417db96d56Sopenharmony_ci } 19427db96d56Sopenharmony_ci i += l; 19437db96d56Sopenharmony_ci } 19447db96d56Sopenharmony_ci } 19457db96d56Sopenharmony_ci int res = m->sq_ass_item(s, i, o); 19467db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0)); 19477db96d56Sopenharmony_ci return res; 19487db96d56Sopenharmony_ci } 19497db96d56Sopenharmony_ci 19507db96d56Sopenharmony_ci if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { 19517db96d56Sopenharmony_ci type_error("%.200s is not a sequence", s); 19527db96d56Sopenharmony_ci return -1; 19537db96d56Sopenharmony_ci } 19547db96d56Sopenharmony_ci type_error("'%.200s' object does not support item assignment", s); 19557db96d56Sopenharmony_ci return -1; 19567db96d56Sopenharmony_ci} 19577db96d56Sopenharmony_ci 19587db96d56Sopenharmony_ciint 19597db96d56Sopenharmony_ciPySequence_DelItem(PyObject *s, Py_ssize_t i) 19607db96d56Sopenharmony_ci{ 19617db96d56Sopenharmony_ci if (s == NULL) { 19627db96d56Sopenharmony_ci null_error(); 19637db96d56Sopenharmony_ci return -1; 19647db96d56Sopenharmony_ci } 19657db96d56Sopenharmony_ci 19667db96d56Sopenharmony_ci PySequenceMethods *m = Py_TYPE(s)->tp_as_sequence; 19677db96d56Sopenharmony_ci if (m && m->sq_ass_item) { 19687db96d56Sopenharmony_ci if (i < 0) { 19697db96d56Sopenharmony_ci if (m->sq_length) { 19707db96d56Sopenharmony_ci Py_ssize_t l = (*m->sq_length)(s); 19717db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__len__", l >= 0)); 19727db96d56Sopenharmony_ci if (l < 0) { 19737db96d56Sopenharmony_ci return -1; 19747db96d56Sopenharmony_ci } 19757db96d56Sopenharmony_ci i += l; 19767db96d56Sopenharmony_ci } 19777db96d56Sopenharmony_ci } 19787db96d56Sopenharmony_ci int res = m->sq_ass_item(s, i, (PyObject *)NULL); 19797db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0)); 19807db96d56Sopenharmony_ci return res; 19817db96d56Sopenharmony_ci } 19827db96d56Sopenharmony_ci 19837db96d56Sopenharmony_ci if (Py_TYPE(s)->tp_as_mapping && Py_TYPE(s)->tp_as_mapping->mp_ass_subscript) { 19847db96d56Sopenharmony_ci type_error("%.200s is not a sequence", s); 19857db96d56Sopenharmony_ci return -1; 19867db96d56Sopenharmony_ci } 19877db96d56Sopenharmony_ci type_error("'%.200s' object doesn't support item deletion", s); 19887db96d56Sopenharmony_ci return -1; 19897db96d56Sopenharmony_ci} 19907db96d56Sopenharmony_ci 19917db96d56Sopenharmony_ciint 19927db96d56Sopenharmony_ciPySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) 19937db96d56Sopenharmony_ci{ 19947db96d56Sopenharmony_ci if (s == NULL) { 19957db96d56Sopenharmony_ci null_error(); 19967db96d56Sopenharmony_ci return -1; 19977db96d56Sopenharmony_ci } 19987db96d56Sopenharmony_ci 19997db96d56Sopenharmony_ci PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; 20007db96d56Sopenharmony_ci if (mp && mp->mp_ass_subscript) { 20017db96d56Sopenharmony_ci PyObject *slice = _PySlice_FromIndices(i1, i2); 20027db96d56Sopenharmony_ci if (!slice) 20037db96d56Sopenharmony_ci return -1; 20047db96d56Sopenharmony_ci int res = mp->mp_ass_subscript(s, slice, o); 20057db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__setitem__", res >= 0)); 20067db96d56Sopenharmony_ci Py_DECREF(slice); 20077db96d56Sopenharmony_ci return res; 20087db96d56Sopenharmony_ci } 20097db96d56Sopenharmony_ci 20107db96d56Sopenharmony_ci type_error("'%.200s' object doesn't support slice assignment", s); 20117db96d56Sopenharmony_ci return -1; 20127db96d56Sopenharmony_ci} 20137db96d56Sopenharmony_ci 20147db96d56Sopenharmony_ciint 20157db96d56Sopenharmony_ciPySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) 20167db96d56Sopenharmony_ci{ 20177db96d56Sopenharmony_ci if (s == NULL) { 20187db96d56Sopenharmony_ci null_error(); 20197db96d56Sopenharmony_ci return -1; 20207db96d56Sopenharmony_ci } 20217db96d56Sopenharmony_ci 20227db96d56Sopenharmony_ci PyMappingMethods *mp = Py_TYPE(s)->tp_as_mapping; 20237db96d56Sopenharmony_ci if (mp && mp->mp_ass_subscript) { 20247db96d56Sopenharmony_ci PyObject *slice = _PySlice_FromIndices(i1, i2); 20257db96d56Sopenharmony_ci if (!slice) { 20267db96d56Sopenharmony_ci return -1; 20277db96d56Sopenharmony_ci } 20287db96d56Sopenharmony_ci int res = mp->mp_ass_subscript(s, slice, NULL); 20297db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(s, "__delitem__", res >= 0)); 20307db96d56Sopenharmony_ci Py_DECREF(slice); 20317db96d56Sopenharmony_ci return res; 20327db96d56Sopenharmony_ci } 20337db96d56Sopenharmony_ci type_error("'%.200s' object doesn't support slice deletion", s); 20347db96d56Sopenharmony_ci return -1; 20357db96d56Sopenharmony_ci} 20367db96d56Sopenharmony_ci 20377db96d56Sopenharmony_ciPyObject * 20387db96d56Sopenharmony_ciPySequence_Tuple(PyObject *v) 20397db96d56Sopenharmony_ci{ 20407db96d56Sopenharmony_ci PyObject *it; /* iter(v) */ 20417db96d56Sopenharmony_ci Py_ssize_t n; /* guess for result tuple size */ 20427db96d56Sopenharmony_ci PyObject *result = NULL; 20437db96d56Sopenharmony_ci Py_ssize_t j; 20447db96d56Sopenharmony_ci 20457db96d56Sopenharmony_ci if (v == NULL) { 20467db96d56Sopenharmony_ci return null_error(); 20477db96d56Sopenharmony_ci } 20487db96d56Sopenharmony_ci 20497db96d56Sopenharmony_ci /* Special-case the common tuple and list cases, for efficiency. */ 20507db96d56Sopenharmony_ci if (PyTuple_CheckExact(v)) { 20517db96d56Sopenharmony_ci /* Note that we can't know whether it's safe to return 20527db96d56Sopenharmony_ci a tuple *subclass* instance as-is, hence the restriction 20537db96d56Sopenharmony_ci to exact tuples here. In contrast, lists always make 20547db96d56Sopenharmony_ci a copy, so there's no need for exactness below. */ 20557db96d56Sopenharmony_ci Py_INCREF(v); 20567db96d56Sopenharmony_ci return v; 20577db96d56Sopenharmony_ci } 20587db96d56Sopenharmony_ci if (PyList_CheckExact(v)) 20597db96d56Sopenharmony_ci return PyList_AsTuple(v); 20607db96d56Sopenharmony_ci 20617db96d56Sopenharmony_ci /* Get iterator. */ 20627db96d56Sopenharmony_ci it = PyObject_GetIter(v); 20637db96d56Sopenharmony_ci if (it == NULL) 20647db96d56Sopenharmony_ci return NULL; 20657db96d56Sopenharmony_ci 20667db96d56Sopenharmony_ci /* Guess result size and allocate space. */ 20677db96d56Sopenharmony_ci n = PyObject_LengthHint(v, 10); 20687db96d56Sopenharmony_ci if (n == -1) 20697db96d56Sopenharmony_ci goto Fail; 20707db96d56Sopenharmony_ci result = PyTuple_New(n); 20717db96d56Sopenharmony_ci if (result == NULL) 20727db96d56Sopenharmony_ci goto Fail; 20737db96d56Sopenharmony_ci 20747db96d56Sopenharmony_ci /* Fill the tuple. */ 20757db96d56Sopenharmony_ci for (j = 0; ; ++j) { 20767db96d56Sopenharmony_ci PyObject *item = PyIter_Next(it); 20777db96d56Sopenharmony_ci if (item == NULL) { 20787db96d56Sopenharmony_ci if (PyErr_Occurred()) 20797db96d56Sopenharmony_ci goto Fail; 20807db96d56Sopenharmony_ci break; 20817db96d56Sopenharmony_ci } 20827db96d56Sopenharmony_ci if (j >= n) { 20837db96d56Sopenharmony_ci size_t newn = (size_t)n; 20847db96d56Sopenharmony_ci /* The over-allocation strategy can grow a bit faster 20857db96d56Sopenharmony_ci than for lists because unlike lists the 20867db96d56Sopenharmony_ci over-allocation isn't permanent -- we reclaim 20877db96d56Sopenharmony_ci the excess before the end of this routine. 20887db96d56Sopenharmony_ci So, grow by ten and then add 25%. 20897db96d56Sopenharmony_ci */ 20907db96d56Sopenharmony_ci newn += 10u; 20917db96d56Sopenharmony_ci newn += newn >> 2; 20927db96d56Sopenharmony_ci if (newn > PY_SSIZE_T_MAX) { 20937db96d56Sopenharmony_ci /* Check for overflow */ 20947db96d56Sopenharmony_ci PyErr_NoMemory(); 20957db96d56Sopenharmony_ci Py_DECREF(item); 20967db96d56Sopenharmony_ci goto Fail; 20977db96d56Sopenharmony_ci } 20987db96d56Sopenharmony_ci n = (Py_ssize_t)newn; 20997db96d56Sopenharmony_ci if (_PyTuple_Resize(&result, n) != 0) { 21007db96d56Sopenharmony_ci Py_DECREF(item); 21017db96d56Sopenharmony_ci goto Fail; 21027db96d56Sopenharmony_ci } 21037db96d56Sopenharmony_ci } 21047db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, j, item); 21057db96d56Sopenharmony_ci } 21067db96d56Sopenharmony_ci 21077db96d56Sopenharmony_ci /* Cut tuple back if guess was too large. */ 21087db96d56Sopenharmony_ci if (j < n && 21097db96d56Sopenharmony_ci _PyTuple_Resize(&result, j) != 0) 21107db96d56Sopenharmony_ci goto Fail; 21117db96d56Sopenharmony_ci 21127db96d56Sopenharmony_ci Py_DECREF(it); 21137db96d56Sopenharmony_ci return result; 21147db96d56Sopenharmony_ci 21157db96d56Sopenharmony_ciFail: 21167db96d56Sopenharmony_ci Py_XDECREF(result); 21177db96d56Sopenharmony_ci Py_DECREF(it); 21187db96d56Sopenharmony_ci return NULL; 21197db96d56Sopenharmony_ci} 21207db96d56Sopenharmony_ci 21217db96d56Sopenharmony_ciPyObject * 21227db96d56Sopenharmony_ciPySequence_List(PyObject *v) 21237db96d56Sopenharmony_ci{ 21247db96d56Sopenharmony_ci PyObject *result; /* result list */ 21257db96d56Sopenharmony_ci PyObject *rv; /* return value from PyList_Extend */ 21267db96d56Sopenharmony_ci 21277db96d56Sopenharmony_ci if (v == NULL) { 21287db96d56Sopenharmony_ci return null_error(); 21297db96d56Sopenharmony_ci } 21307db96d56Sopenharmony_ci 21317db96d56Sopenharmony_ci result = PyList_New(0); 21327db96d56Sopenharmony_ci if (result == NULL) 21337db96d56Sopenharmony_ci return NULL; 21347db96d56Sopenharmony_ci 21357db96d56Sopenharmony_ci rv = _PyList_Extend((PyListObject *)result, v); 21367db96d56Sopenharmony_ci if (rv == NULL) { 21377db96d56Sopenharmony_ci Py_DECREF(result); 21387db96d56Sopenharmony_ci return NULL; 21397db96d56Sopenharmony_ci } 21407db96d56Sopenharmony_ci Py_DECREF(rv); 21417db96d56Sopenharmony_ci return result; 21427db96d56Sopenharmony_ci} 21437db96d56Sopenharmony_ci 21447db96d56Sopenharmony_ciPyObject * 21457db96d56Sopenharmony_ciPySequence_Fast(PyObject *v, const char *m) 21467db96d56Sopenharmony_ci{ 21477db96d56Sopenharmony_ci PyObject *it; 21487db96d56Sopenharmony_ci 21497db96d56Sopenharmony_ci if (v == NULL) { 21507db96d56Sopenharmony_ci return null_error(); 21517db96d56Sopenharmony_ci } 21527db96d56Sopenharmony_ci 21537db96d56Sopenharmony_ci if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { 21547db96d56Sopenharmony_ci Py_INCREF(v); 21557db96d56Sopenharmony_ci return v; 21567db96d56Sopenharmony_ci } 21577db96d56Sopenharmony_ci 21587db96d56Sopenharmony_ci it = PyObject_GetIter(v); 21597db96d56Sopenharmony_ci if (it == NULL) { 21607db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 21617db96d56Sopenharmony_ci if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { 21627db96d56Sopenharmony_ci _PyErr_SetString(tstate, PyExc_TypeError, m); 21637db96d56Sopenharmony_ci } 21647db96d56Sopenharmony_ci return NULL; 21657db96d56Sopenharmony_ci } 21667db96d56Sopenharmony_ci 21677db96d56Sopenharmony_ci v = PySequence_List(it); 21687db96d56Sopenharmony_ci Py_DECREF(it); 21697db96d56Sopenharmony_ci 21707db96d56Sopenharmony_ci return v; 21717db96d56Sopenharmony_ci} 21727db96d56Sopenharmony_ci 21737db96d56Sopenharmony_ci/* Iterate over seq. Result depends on the operation: 21747db96d56Sopenharmony_ci PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq. 21757db96d56Sopenharmony_ci PY_ITERSEARCH_INDEX: 0-based index of first occurrence of obj in seq; 21767db96d56Sopenharmony_ci set ValueError and return -1 if none found; also return -1 on error. 21777db96d56Sopenharmony_ci Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error. 21787db96d56Sopenharmony_ci*/ 21797db96d56Sopenharmony_ciPy_ssize_t 21807db96d56Sopenharmony_ci_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) 21817db96d56Sopenharmony_ci{ 21827db96d56Sopenharmony_ci Py_ssize_t n; 21837db96d56Sopenharmony_ci int wrapped; /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */ 21847db96d56Sopenharmony_ci PyObject *it; /* iter(seq) */ 21857db96d56Sopenharmony_ci 21867db96d56Sopenharmony_ci if (seq == NULL || obj == NULL) { 21877db96d56Sopenharmony_ci null_error(); 21887db96d56Sopenharmony_ci return -1; 21897db96d56Sopenharmony_ci } 21907db96d56Sopenharmony_ci 21917db96d56Sopenharmony_ci it = PyObject_GetIter(seq); 21927db96d56Sopenharmony_ci if (it == NULL) { 21937db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_TypeError)) { 21947db96d56Sopenharmony_ci type_error("argument of type '%.200s' is not iterable", seq); 21957db96d56Sopenharmony_ci } 21967db96d56Sopenharmony_ci return -1; 21977db96d56Sopenharmony_ci } 21987db96d56Sopenharmony_ci 21997db96d56Sopenharmony_ci n = wrapped = 0; 22007db96d56Sopenharmony_ci for (;;) { 22017db96d56Sopenharmony_ci int cmp; 22027db96d56Sopenharmony_ci PyObject *item = PyIter_Next(it); 22037db96d56Sopenharmony_ci if (item == NULL) { 22047db96d56Sopenharmony_ci if (PyErr_Occurred()) 22057db96d56Sopenharmony_ci goto Fail; 22067db96d56Sopenharmony_ci break; 22077db96d56Sopenharmony_ci } 22087db96d56Sopenharmony_ci 22097db96d56Sopenharmony_ci cmp = PyObject_RichCompareBool(item, obj, Py_EQ); 22107db96d56Sopenharmony_ci Py_DECREF(item); 22117db96d56Sopenharmony_ci if (cmp < 0) 22127db96d56Sopenharmony_ci goto Fail; 22137db96d56Sopenharmony_ci if (cmp > 0) { 22147db96d56Sopenharmony_ci switch (operation) { 22157db96d56Sopenharmony_ci case PY_ITERSEARCH_COUNT: 22167db96d56Sopenharmony_ci if (n == PY_SSIZE_T_MAX) { 22177db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 22187db96d56Sopenharmony_ci "count exceeds C integer size"); 22197db96d56Sopenharmony_ci goto Fail; 22207db96d56Sopenharmony_ci } 22217db96d56Sopenharmony_ci ++n; 22227db96d56Sopenharmony_ci break; 22237db96d56Sopenharmony_ci 22247db96d56Sopenharmony_ci case PY_ITERSEARCH_INDEX: 22257db96d56Sopenharmony_ci if (wrapped) { 22267db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 22277db96d56Sopenharmony_ci "index exceeds C integer size"); 22287db96d56Sopenharmony_ci goto Fail; 22297db96d56Sopenharmony_ci } 22307db96d56Sopenharmony_ci goto Done; 22317db96d56Sopenharmony_ci 22327db96d56Sopenharmony_ci case PY_ITERSEARCH_CONTAINS: 22337db96d56Sopenharmony_ci n = 1; 22347db96d56Sopenharmony_ci goto Done; 22357db96d56Sopenharmony_ci 22367db96d56Sopenharmony_ci default: 22377db96d56Sopenharmony_ci Py_UNREACHABLE(); 22387db96d56Sopenharmony_ci } 22397db96d56Sopenharmony_ci } 22407db96d56Sopenharmony_ci 22417db96d56Sopenharmony_ci if (operation == PY_ITERSEARCH_INDEX) { 22427db96d56Sopenharmony_ci if (n == PY_SSIZE_T_MAX) 22437db96d56Sopenharmony_ci wrapped = 1; 22447db96d56Sopenharmony_ci ++n; 22457db96d56Sopenharmony_ci } 22467db96d56Sopenharmony_ci } 22477db96d56Sopenharmony_ci 22487db96d56Sopenharmony_ci if (operation != PY_ITERSEARCH_INDEX) 22497db96d56Sopenharmony_ci goto Done; 22507db96d56Sopenharmony_ci 22517db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 22527db96d56Sopenharmony_ci "sequence.index(x): x not in sequence"); 22537db96d56Sopenharmony_ci /* fall into failure code */ 22547db96d56Sopenharmony_ciFail: 22557db96d56Sopenharmony_ci n = -1; 22567db96d56Sopenharmony_ci /* fall through */ 22577db96d56Sopenharmony_ciDone: 22587db96d56Sopenharmony_ci Py_DECREF(it); 22597db96d56Sopenharmony_ci return n; 22607db96d56Sopenharmony_ci 22617db96d56Sopenharmony_ci} 22627db96d56Sopenharmony_ci 22637db96d56Sopenharmony_ci/* Return # of times o appears in s. */ 22647db96d56Sopenharmony_ciPy_ssize_t 22657db96d56Sopenharmony_ciPySequence_Count(PyObject *s, PyObject *o) 22667db96d56Sopenharmony_ci{ 22677db96d56Sopenharmony_ci return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT); 22687db96d56Sopenharmony_ci} 22697db96d56Sopenharmony_ci 22707db96d56Sopenharmony_ci/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. 22717db96d56Sopenharmony_ci * Use sq_contains if possible, else defer to _PySequence_IterSearch(). 22727db96d56Sopenharmony_ci */ 22737db96d56Sopenharmony_ciint 22747db96d56Sopenharmony_ciPySequence_Contains(PyObject *seq, PyObject *ob) 22757db96d56Sopenharmony_ci{ 22767db96d56Sopenharmony_ci PySequenceMethods *sqm = Py_TYPE(seq)->tp_as_sequence; 22777db96d56Sopenharmony_ci if (sqm != NULL && sqm->sq_contains != NULL) { 22787db96d56Sopenharmony_ci int res = (*sqm->sq_contains)(seq, ob); 22797db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(seq, "__contains__", res >= 0)); 22807db96d56Sopenharmony_ci return res; 22817db96d56Sopenharmony_ci } 22827db96d56Sopenharmony_ci Py_ssize_t result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); 22837db96d56Sopenharmony_ci return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); 22847db96d56Sopenharmony_ci} 22857db96d56Sopenharmony_ci 22867db96d56Sopenharmony_ci/* Backwards compatibility */ 22877db96d56Sopenharmony_ci#undef PySequence_In 22887db96d56Sopenharmony_ciint 22897db96d56Sopenharmony_ciPySequence_In(PyObject *w, PyObject *v) 22907db96d56Sopenharmony_ci{ 22917db96d56Sopenharmony_ci return PySequence_Contains(w, v); 22927db96d56Sopenharmony_ci} 22937db96d56Sopenharmony_ci 22947db96d56Sopenharmony_ciPy_ssize_t 22957db96d56Sopenharmony_ciPySequence_Index(PyObject *s, PyObject *o) 22967db96d56Sopenharmony_ci{ 22977db96d56Sopenharmony_ci return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX); 22987db96d56Sopenharmony_ci} 22997db96d56Sopenharmony_ci 23007db96d56Sopenharmony_ci/* Operations on mappings */ 23017db96d56Sopenharmony_ci 23027db96d56Sopenharmony_ciint 23037db96d56Sopenharmony_ciPyMapping_Check(PyObject *o) 23047db96d56Sopenharmony_ci{ 23057db96d56Sopenharmony_ci return o && Py_TYPE(o)->tp_as_mapping && 23067db96d56Sopenharmony_ci Py_TYPE(o)->tp_as_mapping->mp_subscript; 23077db96d56Sopenharmony_ci} 23087db96d56Sopenharmony_ci 23097db96d56Sopenharmony_ciPy_ssize_t 23107db96d56Sopenharmony_ciPyMapping_Size(PyObject *o) 23117db96d56Sopenharmony_ci{ 23127db96d56Sopenharmony_ci if (o == NULL) { 23137db96d56Sopenharmony_ci null_error(); 23147db96d56Sopenharmony_ci return -1; 23157db96d56Sopenharmony_ci } 23167db96d56Sopenharmony_ci 23177db96d56Sopenharmony_ci PyMappingMethods *m = Py_TYPE(o)->tp_as_mapping; 23187db96d56Sopenharmony_ci if (m && m->mp_length) { 23197db96d56Sopenharmony_ci Py_ssize_t len = m->mp_length(o); 23207db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(o, "__len__", len >= 0)); 23217db96d56Sopenharmony_ci return len; 23227db96d56Sopenharmony_ci } 23237db96d56Sopenharmony_ci 23247db96d56Sopenharmony_ci if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) { 23257db96d56Sopenharmony_ci type_error("%.200s is not a mapping", o); 23267db96d56Sopenharmony_ci return -1; 23277db96d56Sopenharmony_ci } 23287db96d56Sopenharmony_ci /* PyMapping_Size() can be called from PyObject_Size(). */ 23297db96d56Sopenharmony_ci type_error("object of type '%.200s' has no len()", o); 23307db96d56Sopenharmony_ci return -1; 23317db96d56Sopenharmony_ci} 23327db96d56Sopenharmony_ci 23337db96d56Sopenharmony_ci#undef PyMapping_Length 23347db96d56Sopenharmony_ciPy_ssize_t 23357db96d56Sopenharmony_ciPyMapping_Length(PyObject *o) 23367db96d56Sopenharmony_ci{ 23377db96d56Sopenharmony_ci return PyMapping_Size(o); 23387db96d56Sopenharmony_ci} 23397db96d56Sopenharmony_ci#define PyMapping_Length PyMapping_Size 23407db96d56Sopenharmony_ci 23417db96d56Sopenharmony_ciPyObject * 23427db96d56Sopenharmony_ciPyMapping_GetItemString(PyObject *o, const char *key) 23437db96d56Sopenharmony_ci{ 23447db96d56Sopenharmony_ci PyObject *okey, *r; 23457db96d56Sopenharmony_ci 23467db96d56Sopenharmony_ci if (key == NULL) { 23477db96d56Sopenharmony_ci return null_error(); 23487db96d56Sopenharmony_ci } 23497db96d56Sopenharmony_ci 23507db96d56Sopenharmony_ci okey = PyUnicode_FromString(key); 23517db96d56Sopenharmony_ci if (okey == NULL) 23527db96d56Sopenharmony_ci return NULL; 23537db96d56Sopenharmony_ci r = PyObject_GetItem(o, okey); 23547db96d56Sopenharmony_ci Py_DECREF(okey); 23557db96d56Sopenharmony_ci return r; 23567db96d56Sopenharmony_ci} 23577db96d56Sopenharmony_ci 23587db96d56Sopenharmony_ciint 23597db96d56Sopenharmony_ciPyMapping_SetItemString(PyObject *o, const char *key, PyObject *value) 23607db96d56Sopenharmony_ci{ 23617db96d56Sopenharmony_ci PyObject *okey; 23627db96d56Sopenharmony_ci int r; 23637db96d56Sopenharmony_ci 23647db96d56Sopenharmony_ci if (key == NULL) { 23657db96d56Sopenharmony_ci null_error(); 23667db96d56Sopenharmony_ci return -1; 23677db96d56Sopenharmony_ci } 23687db96d56Sopenharmony_ci 23697db96d56Sopenharmony_ci okey = PyUnicode_FromString(key); 23707db96d56Sopenharmony_ci if (okey == NULL) 23717db96d56Sopenharmony_ci return -1; 23727db96d56Sopenharmony_ci r = PyObject_SetItem(o, okey, value); 23737db96d56Sopenharmony_ci Py_DECREF(okey); 23747db96d56Sopenharmony_ci return r; 23757db96d56Sopenharmony_ci} 23767db96d56Sopenharmony_ci 23777db96d56Sopenharmony_ciint 23787db96d56Sopenharmony_ciPyMapping_HasKeyString(PyObject *o, const char *key) 23797db96d56Sopenharmony_ci{ 23807db96d56Sopenharmony_ci PyObject *v; 23817db96d56Sopenharmony_ci 23827db96d56Sopenharmony_ci v = PyMapping_GetItemString(o, key); 23837db96d56Sopenharmony_ci if (v) { 23847db96d56Sopenharmony_ci Py_DECREF(v); 23857db96d56Sopenharmony_ci return 1; 23867db96d56Sopenharmony_ci } 23877db96d56Sopenharmony_ci PyErr_Clear(); 23887db96d56Sopenharmony_ci return 0; 23897db96d56Sopenharmony_ci} 23907db96d56Sopenharmony_ci 23917db96d56Sopenharmony_ciint 23927db96d56Sopenharmony_ciPyMapping_HasKey(PyObject *o, PyObject *key) 23937db96d56Sopenharmony_ci{ 23947db96d56Sopenharmony_ci PyObject *v; 23957db96d56Sopenharmony_ci 23967db96d56Sopenharmony_ci v = PyObject_GetItem(o, key); 23977db96d56Sopenharmony_ci if (v) { 23987db96d56Sopenharmony_ci Py_DECREF(v); 23997db96d56Sopenharmony_ci return 1; 24007db96d56Sopenharmony_ci } 24017db96d56Sopenharmony_ci PyErr_Clear(); 24027db96d56Sopenharmony_ci return 0; 24037db96d56Sopenharmony_ci} 24047db96d56Sopenharmony_ci 24057db96d56Sopenharmony_ci/* This function is quite similar to PySequence_Fast(), but specialized to be 24067db96d56Sopenharmony_ci a helper for PyMapping_Keys(), PyMapping_Items() and PyMapping_Values(). 24077db96d56Sopenharmony_ci */ 24087db96d56Sopenharmony_cistatic PyObject * 24097db96d56Sopenharmony_cimethod_output_as_list(PyObject *o, PyObject *meth) 24107db96d56Sopenharmony_ci{ 24117db96d56Sopenharmony_ci PyObject *it, *result, *meth_output; 24127db96d56Sopenharmony_ci 24137db96d56Sopenharmony_ci assert(o != NULL); 24147db96d56Sopenharmony_ci meth_output = PyObject_CallMethodNoArgs(o, meth); 24157db96d56Sopenharmony_ci if (meth_output == NULL || PyList_CheckExact(meth_output)) { 24167db96d56Sopenharmony_ci return meth_output; 24177db96d56Sopenharmony_ci } 24187db96d56Sopenharmony_ci it = PyObject_GetIter(meth_output); 24197db96d56Sopenharmony_ci if (it == NULL) { 24207db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 24217db96d56Sopenharmony_ci if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { 24227db96d56Sopenharmony_ci _PyErr_Format(tstate, PyExc_TypeError, 24237db96d56Sopenharmony_ci "%.200s.%U() returned a non-iterable (type %.200s)", 24247db96d56Sopenharmony_ci Py_TYPE(o)->tp_name, 24257db96d56Sopenharmony_ci meth, 24267db96d56Sopenharmony_ci Py_TYPE(meth_output)->tp_name); 24277db96d56Sopenharmony_ci } 24287db96d56Sopenharmony_ci Py_DECREF(meth_output); 24297db96d56Sopenharmony_ci return NULL; 24307db96d56Sopenharmony_ci } 24317db96d56Sopenharmony_ci Py_DECREF(meth_output); 24327db96d56Sopenharmony_ci result = PySequence_List(it); 24337db96d56Sopenharmony_ci Py_DECREF(it); 24347db96d56Sopenharmony_ci return result; 24357db96d56Sopenharmony_ci} 24367db96d56Sopenharmony_ci 24377db96d56Sopenharmony_ciPyObject * 24387db96d56Sopenharmony_ciPyMapping_Keys(PyObject *o) 24397db96d56Sopenharmony_ci{ 24407db96d56Sopenharmony_ci if (o == NULL) { 24417db96d56Sopenharmony_ci return null_error(); 24427db96d56Sopenharmony_ci } 24437db96d56Sopenharmony_ci if (PyDict_CheckExact(o)) { 24447db96d56Sopenharmony_ci return PyDict_Keys(o); 24457db96d56Sopenharmony_ci } 24467db96d56Sopenharmony_ci return method_output_as_list(o, &_Py_ID(keys)); 24477db96d56Sopenharmony_ci} 24487db96d56Sopenharmony_ci 24497db96d56Sopenharmony_ciPyObject * 24507db96d56Sopenharmony_ciPyMapping_Items(PyObject *o) 24517db96d56Sopenharmony_ci{ 24527db96d56Sopenharmony_ci if (o == NULL) { 24537db96d56Sopenharmony_ci return null_error(); 24547db96d56Sopenharmony_ci } 24557db96d56Sopenharmony_ci if (PyDict_CheckExact(o)) { 24567db96d56Sopenharmony_ci return PyDict_Items(o); 24577db96d56Sopenharmony_ci } 24587db96d56Sopenharmony_ci return method_output_as_list(o, &_Py_ID(items)); 24597db96d56Sopenharmony_ci} 24607db96d56Sopenharmony_ci 24617db96d56Sopenharmony_ciPyObject * 24627db96d56Sopenharmony_ciPyMapping_Values(PyObject *o) 24637db96d56Sopenharmony_ci{ 24647db96d56Sopenharmony_ci if (o == NULL) { 24657db96d56Sopenharmony_ci return null_error(); 24667db96d56Sopenharmony_ci } 24677db96d56Sopenharmony_ci if (PyDict_CheckExact(o)) { 24687db96d56Sopenharmony_ci return PyDict_Values(o); 24697db96d56Sopenharmony_ci } 24707db96d56Sopenharmony_ci return method_output_as_list(o, &_Py_ID(values)); 24717db96d56Sopenharmony_ci} 24727db96d56Sopenharmony_ci 24737db96d56Sopenharmony_ci/* isinstance(), issubclass() */ 24747db96d56Sopenharmony_ci 24757db96d56Sopenharmony_ci/* abstract_get_bases() has logically 4 return states: 24767db96d56Sopenharmony_ci * 24777db96d56Sopenharmony_ci * 1. getattr(cls, '__bases__') could raise an AttributeError 24787db96d56Sopenharmony_ci * 2. getattr(cls, '__bases__') could raise some other exception 24797db96d56Sopenharmony_ci * 3. getattr(cls, '__bases__') could return a tuple 24807db96d56Sopenharmony_ci * 4. getattr(cls, '__bases__') could return something other than a tuple 24817db96d56Sopenharmony_ci * 24827db96d56Sopenharmony_ci * Only state #3 is a non-error state and only it returns a non-NULL object 24837db96d56Sopenharmony_ci * (it returns the retrieved tuple). 24847db96d56Sopenharmony_ci * 24857db96d56Sopenharmony_ci * Any raised AttributeErrors are masked by clearing the exception and 24867db96d56Sopenharmony_ci * returning NULL. If an object other than a tuple comes out of __bases__, 24877db96d56Sopenharmony_ci * then again, the return value is NULL. So yes, these two situations 24887db96d56Sopenharmony_ci * produce exactly the same results: NULL is returned and no error is set. 24897db96d56Sopenharmony_ci * 24907db96d56Sopenharmony_ci * If some exception other than AttributeError is raised, then NULL is also 24917db96d56Sopenharmony_ci * returned, but the exception is not cleared. That's because we want the 24927db96d56Sopenharmony_ci * exception to be propagated along. 24937db96d56Sopenharmony_ci * 24947db96d56Sopenharmony_ci * Callers are expected to test for PyErr_Occurred() when the return value 24957db96d56Sopenharmony_ci * is NULL to decide whether a valid exception should be propagated or not. 24967db96d56Sopenharmony_ci * When there's no exception to propagate, it's customary for the caller to 24977db96d56Sopenharmony_ci * set a TypeError. 24987db96d56Sopenharmony_ci */ 24997db96d56Sopenharmony_cistatic PyObject * 25007db96d56Sopenharmony_ciabstract_get_bases(PyObject *cls) 25017db96d56Sopenharmony_ci{ 25027db96d56Sopenharmony_ci PyObject *bases; 25037db96d56Sopenharmony_ci 25047db96d56Sopenharmony_ci (void)_PyObject_LookupAttr(cls, &_Py_ID(__bases__), &bases); 25057db96d56Sopenharmony_ci if (bases != NULL && !PyTuple_Check(bases)) { 25067db96d56Sopenharmony_ci Py_DECREF(bases); 25077db96d56Sopenharmony_ci return NULL; 25087db96d56Sopenharmony_ci } 25097db96d56Sopenharmony_ci return bases; 25107db96d56Sopenharmony_ci} 25117db96d56Sopenharmony_ci 25127db96d56Sopenharmony_ci 25137db96d56Sopenharmony_cistatic int 25147db96d56Sopenharmony_ciabstract_issubclass(PyObject *derived, PyObject *cls) 25157db96d56Sopenharmony_ci{ 25167db96d56Sopenharmony_ci PyObject *bases = NULL; 25177db96d56Sopenharmony_ci Py_ssize_t i, n; 25187db96d56Sopenharmony_ci int r = 0; 25197db96d56Sopenharmony_ci 25207db96d56Sopenharmony_ci while (1) { 25217db96d56Sopenharmony_ci if (derived == cls) { 25227db96d56Sopenharmony_ci Py_XDECREF(bases); /* See below comment */ 25237db96d56Sopenharmony_ci return 1; 25247db96d56Sopenharmony_ci } 25257db96d56Sopenharmony_ci /* Use XSETREF to drop bases reference *after* finishing with 25267db96d56Sopenharmony_ci derived; bases might be the only reference to it. 25277db96d56Sopenharmony_ci XSETREF is used instead of SETREF, because bases is NULL on the 25287db96d56Sopenharmony_ci first iteration of the loop. 25297db96d56Sopenharmony_ci */ 25307db96d56Sopenharmony_ci Py_XSETREF(bases, abstract_get_bases(derived)); 25317db96d56Sopenharmony_ci if (bases == NULL) { 25327db96d56Sopenharmony_ci if (PyErr_Occurred()) 25337db96d56Sopenharmony_ci return -1; 25347db96d56Sopenharmony_ci return 0; 25357db96d56Sopenharmony_ci } 25367db96d56Sopenharmony_ci n = PyTuple_GET_SIZE(bases); 25377db96d56Sopenharmony_ci if (n == 0) { 25387db96d56Sopenharmony_ci Py_DECREF(bases); 25397db96d56Sopenharmony_ci return 0; 25407db96d56Sopenharmony_ci } 25417db96d56Sopenharmony_ci /* Avoid recursivity in the single inheritance case */ 25427db96d56Sopenharmony_ci if (n == 1) { 25437db96d56Sopenharmony_ci derived = PyTuple_GET_ITEM(bases, 0); 25447db96d56Sopenharmony_ci continue; 25457db96d56Sopenharmony_ci } 25467db96d56Sopenharmony_ci break; 25477db96d56Sopenharmony_ci } 25487db96d56Sopenharmony_ci assert(n >= 2); 25497db96d56Sopenharmony_ci if (_Py_EnterRecursiveCall(" in __issubclass__")) { 25507db96d56Sopenharmony_ci Py_DECREF(bases); 25517db96d56Sopenharmony_ci return -1; 25527db96d56Sopenharmony_ci } 25537db96d56Sopenharmony_ci for (i = 0; i < n; i++) { 25547db96d56Sopenharmony_ci r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls); 25557db96d56Sopenharmony_ci if (r != 0) { 25567db96d56Sopenharmony_ci break; 25577db96d56Sopenharmony_ci } 25587db96d56Sopenharmony_ci } 25597db96d56Sopenharmony_ci _Py_LeaveRecursiveCall(); 25607db96d56Sopenharmony_ci Py_DECREF(bases); 25617db96d56Sopenharmony_ci return r; 25627db96d56Sopenharmony_ci} 25637db96d56Sopenharmony_ci 25647db96d56Sopenharmony_cistatic int 25657db96d56Sopenharmony_cicheck_class(PyObject *cls, const char *error) 25667db96d56Sopenharmony_ci{ 25677db96d56Sopenharmony_ci PyObject *bases = abstract_get_bases(cls); 25687db96d56Sopenharmony_ci if (bases == NULL) { 25697db96d56Sopenharmony_ci /* Do not mask errors. */ 25707db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 25717db96d56Sopenharmony_ci if (!_PyErr_Occurred(tstate)) { 25727db96d56Sopenharmony_ci _PyErr_SetString(tstate, PyExc_TypeError, error); 25737db96d56Sopenharmony_ci } 25747db96d56Sopenharmony_ci return 0; 25757db96d56Sopenharmony_ci } 25767db96d56Sopenharmony_ci Py_DECREF(bases); 25777db96d56Sopenharmony_ci return -1; 25787db96d56Sopenharmony_ci} 25797db96d56Sopenharmony_ci 25807db96d56Sopenharmony_cistatic int 25817db96d56Sopenharmony_ciobject_isinstance(PyObject *inst, PyObject *cls) 25827db96d56Sopenharmony_ci{ 25837db96d56Sopenharmony_ci PyObject *icls; 25847db96d56Sopenharmony_ci int retval; 25857db96d56Sopenharmony_ci if (PyType_Check(cls)) { 25867db96d56Sopenharmony_ci retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); 25877db96d56Sopenharmony_ci if (retval == 0) { 25887db96d56Sopenharmony_ci retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls); 25897db96d56Sopenharmony_ci if (icls != NULL) { 25907db96d56Sopenharmony_ci if (icls != (PyObject *)(Py_TYPE(inst)) && PyType_Check(icls)) { 25917db96d56Sopenharmony_ci retval = PyType_IsSubtype( 25927db96d56Sopenharmony_ci (PyTypeObject *)icls, 25937db96d56Sopenharmony_ci (PyTypeObject *)cls); 25947db96d56Sopenharmony_ci } 25957db96d56Sopenharmony_ci else { 25967db96d56Sopenharmony_ci retval = 0; 25977db96d56Sopenharmony_ci } 25987db96d56Sopenharmony_ci Py_DECREF(icls); 25997db96d56Sopenharmony_ci } 26007db96d56Sopenharmony_ci } 26017db96d56Sopenharmony_ci } 26027db96d56Sopenharmony_ci else { 26037db96d56Sopenharmony_ci if (!check_class(cls, 26047db96d56Sopenharmony_ci "isinstance() arg 2 must be a type, a tuple of types, or a union")) 26057db96d56Sopenharmony_ci return -1; 26067db96d56Sopenharmony_ci retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls); 26077db96d56Sopenharmony_ci if (icls != NULL) { 26087db96d56Sopenharmony_ci retval = abstract_issubclass(icls, cls); 26097db96d56Sopenharmony_ci Py_DECREF(icls); 26107db96d56Sopenharmony_ci } 26117db96d56Sopenharmony_ci } 26127db96d56Sopenharmony_ci 26137db96d56Sopenharmony_ci return retval; 26147db96d56Sopenharmony_ci} 26157db96d56Sopenharmony_ci 26167db96d56Sopenharmony_cistatic int 26177db96d56Sopenharmony_ciobject_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) 26187db96d56Sopenharmony_ci{ 26197db96d56Sopenharmony_ci /* Quick test for an exact match */ 26207db96d56Sopenharmony_ci if (Py_IS_TYPE(inst, (PyTypeObject *)cls)) { 26217db96d56Sopenharmony_ci return 1; 26227db96d56Sopenharmony_ci } 26237db96d56Sopenharmony_ci 26247db96d56Sopenharmony_ci /* We know what type's __instancecheck__ does. */ 26257db96d56Sopenharmony_ci if (PyType_CheckExact(cls)) { 26267db96d56Sopenharmony_ci return object_isinstance(inst, cls); 26277db96d56Sopenharmony_ci } 26287db96d56Sopenharmony_ci 26297db96d56Sopenharmony_ci if (_PyUnion_Check(cls)) { 26307db96d56Sopenharmony_ci cls = _Py_union_args(cls); 26317db96d56Sopenharmony_ci } 26327db96d56Sopenharmony_ci 26337db96d56Sopenharmony_ci if (PyTuple_Check(cls)) { 26347db96d56Sopenharmony_ci /* Not a general sequence -- that opens up the road to 26357db96d56Sopenharmony_ci recursion and stack overflow. */ 26367db96d56Sopenharmony_ci if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) { 26377db96d56Sopenharmony_ci return -1; 26387db96d56Sopenharmony_ci } 26397db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(cls); 26407db96d56Sopenharmony_ci int r = 0; 26417db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < n; ++i) { 26427db96d56Sopenharmony_ci PyObject *item = PyTuple_GET_ITEM(cls, i); 26437db96d56Sopenharmony_ci r = object_recursive_isinstance(tstate, inst, item); 26447db96d56Sopenharmony_ci if (r != 0) { 26457db96d56Sopenharmony_ci /* either found it, or got an error */ 26467db96d56Sopenharmony_ci break; 26477db96d56Sopenharmony_ci } 26487db96d56Sopenharmony_ci } 26497db96d56Sopenharmony_ci _Py_LeaveRecursiveCallTstate(tstate); 26507db96d56Sopenharmony_ci return r; 26517db96d56Sopenharmony_ci } 26527db96d56Sopenharmony_ci 26537db96d56Sopenharmony_ci PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__)); 26547db96d56Sopenharmony_ci if (checker != NULL) { 26557db96d56Sopenharmony_ci if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) { 26567db96d56Sopenharmony_ci Py_DECREF(checker); 26577db96d56Sopenharmony_ci return -1; 26587db96d56Sopenharmony_ci } 26597db96d56Sopenharmony_ci 26607db96d56Sopenharmony_ci PyObject *res = PyObject_CallOneArg(checker, inst); 26617db96d56Sopenharmony_ci _Py_LeaveRecursiveCallTstate(tstate); 26627db96d56Sopenharmony_ci Py_DECREF(checker); 26637db96d56Sopenharmony_ci 26647db96d56Sopenharmony_ci if (res == NULL) { 26657db96d56Sopenharmony_ci return -1; 26667db96d56Sopenharmony_ci } 26677db96d56Sopenharmony_ci int ok = PyObject_IsTrue(res); 26687db96d56Sopenharmony_ci Py_DECREF(res); 26697db96d56Sopenharmony_ci 26707db96d56Sopenharmony_ci return ok; 26717db96d56Sopenharmony_ci } 26727db96d56Sopenharmony_ci else if (_PyErr_Occurred(tstate)) { 26737db96d56Sopenharmony_ci return -1; 26747db96d56Sopenharmony_ci } 26757db96d56Sopenharmony_ci 26767db96d56Sopenharmony_ci /* cls has no __instancecheck__() method */ 26777db96d56Sopenharmony_ci return object_isinstance(inst, cls); 26787db96d56Sopenharmony_ci} 26797db96d56Sopenharmony_ci 26807db96d56Sopenharmony_ci 26817db96d56Sopenharmony_ciint 26827db96d56Sopenharmony_ciPyObject_IsInstance(PyObject *inst, PyObject *cls) 26837db96d56Sopenharmony_ci{ 26847db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 26857db96d56Sopenharmony_ci return object_recursive_isinstance(tstate, inst, cls); 26867db96d56Sopenharmony_ci} 26877db96d56Sopenharmony_ci 26887db96d56Sopenharmony_ci 26897db96d56Sopenharmony_cistatic int 26907db96d56Sopenharmony_cirecursive_issubclass(PyObject *derived, PyObject *cls) 26917db96d56Sopenharmony_ci{ 26927db96d56Sopenharmony_ci if (PyType_Check(cls) && PyType_Check(derived)) { 26937db96d56Sopenharmony_ci /* Fast path (non-recursive) */ 26947db96d56Sopenharmony_ci return PyType_IsSubtype((PyTypeObject *)derived, (PyTypeObject *)cls); 26957db96d56Sopenharmony_ci } 26967db96d56Sopenharmony_ci if (!check_class(derived, 26977db96d56Sopenharmony_ci "issubclass() arg 1 must be a class")) 26987db96d56Sopenharmony_ci return -1; 26997db96d56Sopenharmony_ci 27007db96d56Sopenharmony_ci if (!_PyUnion_Check(cls) && !check_class(cls, 27017db96d56Sopenharmony_ci "issubclass() arg 2 must be a class," 27027db96d56Sopenharmony_ci " a tuple of classes, or a union")) { 27037db96d56Sopenharmony_ci return -1; 27047db96d56Sopenharmony_ci } 27057db96d56Sopenharmony_ci 27067db96d56Sopenharmony_ci return abstract_issubclass(derived, cls); 27077db96d56Sopenharmony_ci} 27087db96d56Sopenharmony_ci 27097db96d56Sopenharmony_cistatic int 27107db96d56Sopenharmony_ciobject_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) 27117db96d56Sopenharmony_ci{ 27127db96d56Sopenharmony_ci PyObject *checker; 27137db96d56Sopenharmony_ci 27147db96d56Sopenharmony_ci /* We know what type's __subclasscheck__ does. */ 27157db96d56Sopenharmony_ci if (PyType_CheckExact(cls)) { 27167db96d56Sopenharmony_ci /* Quick test for an exact match */ 27177db96d56Sopenharmony_ci if (derived == cls) 27187db96d56Sopenharmony_ci return 1; 27197db96d56Sopenharmony_ci return recursive_issubclass(derived, cls); 27207db96d56Sopenharmony_ci } 27217db96d56Sopenharmony_ci 27227db96d56Sopenharmony_ci if (_PyUnion_Check(cls)) { 27237db96d56Sopenharmony_ci cls = _Py_union_args(cls); 27247db96d56Sopenharmony_ci } 27257db96d56Sopenharmony_ci 27267db96d56Sopenharmony_ci if (PyTuple_Check(cls)) { 27277db96d56Sopenharmony_ci 27287db96d56Sopenharmony_ci if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) { 27297db96d56Sopenharmony_ci return -1; 27307db96d56Sopenharmony_ci } 27317db96d56Sopenharmony_ci Py_ssize_t n = PyTuple_GET_SIZE(cls); 27327db96d56Sopenharmony_ci int r = 0; 27337db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < n; ++i) { 27347db96d56Sopenharmony_ci PyObject *item = PyTuple_GET_ITEM(cls, i); 27357db96d56Sopenharmony_ci r = object_issubclass(tstate, derived, item); 27367db96d56Sopenharmony_ci if (r != 0) 27377db96d56Sopenharmony_ci /* either found it, or got an error */ 27387db96d56Sopenharmony_ci break; 27397db96d56Sopenharmony_ci } 27407db96d56Sopenharmony_ci _Py_LeaveRecursiveCallTstate(tstate); 27417db96d56Sopenharmony_ci return r; 27427db96d56Sopenharmony_ci } 27437db96d56Sopenharmony_ci 27447db96d56Sopenharmony_ci checker = _PyObject_LookupSpecial(cls, &_Py_ID(__subclasscheck__)); 27457db96d56Sopenharmony_ci if (checker != NULL) { 27467db96d56Sopenharmony_ci int ok = -1; 27477db96d56Sopenharmony_ci if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) { 27487db96d56Sopenharmony_ci Py_DECREF(checker); 27497db96d56Sopenharmony_ci return ok; 27507db96d56Sopenharmony_ci } 27517db96d56Sopenharmony_ci PyObject *res = PyObject_CallOneArg(checker, derived); 27527db96d56Sopenharmony_ci _Py_LeaveRecursiveCallTstate(tstate); 27537db96d56Sopenharmony_ci Py_DECREF(checker); 27547db96d56Sopenharmony_ci if (res != NULL) { 27557db96d56Sopenharmony_ci ok = PyObject_IsTrue(res); 27567db96d56Sopenharmony_ci Py_DECREF(res); 27577db96d56Sopenharmony_ci } 27587db96d56Sopenharmony_ci return ok; 27597db96d56Sopenharmony_ci } 27607db96d56Sopenharmony_ci else if (_PyErr_Occurred(tstate)) { 27617db96d56Sopenharmony_ci return -1; 27627db96d56Sopenharmony_ci } 27637db96d56Sopenharmony_ci 27647db96d56Sopenharmony_ci /* Probably never reached anymore. */ 27657db96d56Sopenharmony_ci return recursive_issubclass(derived, cls); 27667db96d56Sopenharmony_ci} 27677db96d56Sopenharmony_ci 27687db96d56Sopenharmony_ci 27697db96d56Sopenharmony_ciint 27707db96d56Sopenharmony_ciPyObject_IsSubclass(PyObject *derived, PyObject *cls) 27717db96d56Sopenharmony_ci{ 27727db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 27737db96d56Sopenharmony_ci return object_issubclass(tstate, derived, cls); 27747db96d56Sopenharmony_ci} 27757db96d56Sopenharmony_ci 27767db96d56Sopenharmony_ci 27777db96d56Sopenharmony_ciint 27787db96d56Sopenharmony_ci_PyObject_RealIsInstance(PyObject *inst, PyObject *cls) 27797db96d56Sopenharmony_ci{ 27807db96d56Sopenharmony_ci return object_isinstance(inst, cls); 27817db96d56Sopenharmony_ci} 27827db96d56Sopenharmony_ci 27837db96d56Sopenharmony_ciint 27847db96d56Sopenharmony_ci_PyObject_RealIsSubclass(PyObject *derived, PyObject *cls) 27857db96d56Sopenharmony_ci{ 27867db96d56Sopenharmony_ci return recursive_issubclass(derived, cls); 27877db96d56Sopenharmony_ci} 27887db96d56Sopenharmony_ci 27897db96d56Sopenharmony_ci 27907db96d56Sopenharmony_ciPyObject * 27917db96d56Sopenharmony_ciPyObject_GetIter(PyObject *o) 27927db96d56Sopenharmony_ci{ 27937db96d56Sopenharmony_ci PyTypeObject *t = Py_TYPE(o); 27947db96d56Sopenharmony_ci getiterfunc f; 27957db96d56Sopenharmony_ci 27967db96d56Sopenharmony_ci f = t->tp_iter; 27977db96d56Sopenharmony_ci if (f == NULL) { 27987db96d56Sopenharmony_ci if (PySequence_Check(o)) 27997db96d56Sopenharmony_ci return PySeqIter_New(o); 28007db96d56Sopenharmony_ci return type_error("'%.200s' object is not iterable", o); 28017db96d56Sopenharmony_ci } 28027db96d56Sopenharmony_ci else { 28037db96d56Sopenharmony_ci PyObject *res = (*f)(o); 28047db96d56Sopenharmony_ci if (res != NULL && !PyIter_Check(res)) { 28057db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 28067db96d56Sopenharmony_ci "iter() returned non-iterator " 28077db96d56Sopenharmony_ci "of type '%.100s'", 28087db96d56Sopenharmony_ci Py_TYPE(res)->tp_name); 28097db96d56Sopenharmony_ci Py_DECREF(res); 28107db96d56Sopenharmony_ci res = NULL; 28117db96d56Sopenharmony_ci } 28127db96d56Sopenharmony_ci return res; 28137db96d56Sopenharmony_ci } 28147db96d56Sopenharmony_ci} 28157db96d56Sopenharmony_ci 28167db96d56Sopenharmony_ciPyObject * 28177db96d56Sopenharmony_ciPyObject_GetAIter(PyObject *o) { 28187db96d56Sopenharmony_ci PyTypeObject *t = Py_TYPE(o); 28197db96d56Sopenharmony_ci unaryfunc f; 28207db96d56Sopenharmony_ci 28217db96d56Sopenharmony_ci if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) { 28227db96d56Sopenharmony_ci return type_error("'%.200s' object is not an async iterable", o); 28237db96d56Sopenharmony_ci } 28247db96d56Sopenharmony_ci f = t->tp_as_async->am_aiter; 28257db96d56Sopenharmony_ci PyObject *it = (*f)(o); 28267db96d56Sopenharmony_ci if (it != NULL && !PyAIter_Check(it)) { 28277db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 28287db96d56Sopenharmony_ci "aiter() returned not an async iterator of type '%.100s'", 28297db96d56Sopenharmony_ci Py_TYPE(it)->tp_name); 28307db96d56Sopenharmony_ci Py_DECREF(it); 28317db96d56Sopenharmony_ci it = NULL; 28327db96d56Sopenharmony_ci } 28337db96d56Sopenharmony_ci return it; 28347db96d56Sopenharmony_ci} 28357db96d56Sopenharmony_ci 28367db96d56Sopenharmony_ciint 28377db96d56Sopenharmony_ciPyIter_Check(PyObject *obj) 28387db96d56Sopenharmony_ci{ 28397db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(obj); 28407db96d56Sopenharmony_ci return (tp->tp_iternext != NULL && 28417db96d56Sopenharmony_ci tp->tp_iternext != &_PyObject_NextNotImplemented); 28427db96d56Sopenharmony_ci} 28437db96d56Sopenharmony_ci 28447db96d56Sopenharmony_ciint 28457db96d56Sopenharmony_ciPyAIter_Check(PyObject *obj) 28467db96d56Sopenharmony_ci{ 28477db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(obj); 28487db96d56Sopenharmony_ci return (tp->tp_as_async != NULL && 28497db96d56Sopenharmony_ci tp->tp_as_async->am_anext != NULL && 28507db96d56Sopenharmony_ci tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented); 28517db96d56Sopenharmony_ci} 28527db96d56Sopenharmony_ci 28537db96d56Sopenharmony_ci/* Return next item. 28547db96d56Sopenharmony_ci * If an error occurs, return NULL. PyErr_Occurred() will be true. 28557db96d56Sopenharmony_ci * If the iteration terminates normally, return NULL and clear the 28567db96d56Sopenharmony_ci * PyExc_StopIteration exception (if it was set). PyErr_Occurred() 28577db96d56Sopenharmony_ci * will be false. 28587db96d56Sopenharmony_ci * Else return the next object. PyErr_Occurred() will be false. 28597db96d56Sopenharmony_ci */ 28607db96d56Sopenharmony_ciPyObject * 28617db96d56Sopenharmony_ciPyIter_Next(PyObject *iter) 28627db96d56Sopenharmony_ci{ 28637db96d56Sopenharmony_ci PyObject *result; 28647db96d56Sopenharmony_ci result = (*Py_TYPE(iter)->tp_iternext)(iter); 28657db96d56Sopenharmony_ci if (result == NULL) { 28667db96d56Sopenharmony_ci PyThreadState *tstate = _PyThreadState_GET(); 28677db96d56Sopenharmony_ci if (_PyErr_Occurred(tstate) 28687db96d56Sopenharmony_ci && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) 28697db96d56Sopenharmony_ci { 28707db96d56Sopenharmony_ci _PyErr_Clear(tstate); 28717db96d56Sopenharmony_ci } 28727db96d56Sopenharmony_ci } 28737db96d56Sopenharmony_ci return result; 28747db96d56Sopenharmony_ci} 28757db96d56Sopenharmony_ci 28767db96d56Sopenharmony_ciPySendResult 28777db96d56Sopenharmony_ciPyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) 28787db96d56Sopenharmony_ci{ 28797db96d56Sopenharmony_ci assert(arg != NULL); 28807db96d56Sopenharmony_ci assert(result != NULL); 28817db96d56Sopenharmony_ci if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) { 28827db96d56Sopenharmony_ci PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result); 28837db96d56Sopenharmony_ci assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR)); 28847db96d56Sopenharmony_ci return res; 28857db96d56Sopenharmony_ci } 28867db96d56Sopenharmony_ci if (arg == Py_None && PyIter_Check(iter)) { 28877db96d56Sopenharmony_ci *result = Py_TYPE(iter)->tp_iternext(iter); 28887db96d56Sopenharmony_ci } 28897db96d56Sopenharmony_ci else { 28907db96d56Sopenharmony_ci *result = PyObject_CallMethodOneArg(iter, &_Py_ID(send), arg); 28917db96d56Sopenharmony_ci } 28927db96d56Sopenharmony_ci if (*result != NULL) { 28937db96d56Sopenharmony_ci return PYGEN_NEXT; 28947db96d56Sopenharmony_ci } 28957db96d56Sopenharmony_ci if (_PyGen_FetchStopIterationValue(result) == 0) { 28967db96d56Sopenharmony_ci return PYGEN_RETURN; 28977db96d56Sopenharmony_ci } 28987db96d56Sopenharmony_ci return PYGEN_ERROR; 28997db96d56Sopenharmony_ci} 29007db96d56Sopenharmony_ci 29017db96d56Sopenharmony_ci/* 29027db96d56Sopenharmony_ci * Flatten a sequence of bytes() objects into a C array of 29037db96d56Sopenharmony_ci * NULL terminated string pointers with a NULL char* terminating the array. 29047db96d56Sopenharmony_ci * (ie: an argv or env list) 29057db96d56Sopenharmony_ci * 29067db96d56Sopenharmony_ci * Memory allocated for the returned list is allocated using PyMem_Malloc() 29077db96d56Sopenharmony_ci * and MUST be freed by _Py_FreeCharPArray(). 29087db96d56Sopenharmony_ci */ 29097db96d56Sopenharmony_cichar *const * 29107db96d56Sopenharmony_ci_PySequence_BytesToCharpArray(PyObject* self) 29117db96d56Sopenharmony_ci{ 29127db96d56Sopenharmony_ci char **array; 29137db96d56Sopenharmony_ci Py_ssize_t i, argc; 29147db96d56Sopenharmony_ci PyObject *item = NULL; 29157db96d56Sopenharmony_ci Py_ssize_t size; 29167db96d56Sopenharmony_ci 29177db96d56Sopenharmony_ci argc = PySequence_Size(self); 29187db96d56Sopenharmony_ci if (argc == -1) 29197db96d56Sopenharmony_ci return NULL; 29207db96d56Sopenharmony_ci 29217db96d56Sopenharmony_ci assert(argc >= 0); 29227db96d56Sopenharmony_ci 29237db96d56Sopenharmony_ci if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) { 29247db96d56Sopenharmony_ci PyErr_NoMemory(); 29257db96d56Sopenharmony_ci return NULL; 29267db96d56Sopenharmony_ci } 29277db96d56Sopenharmony_ci 29287db96d56Sopenharmony_ci array = PyMem_Malloc((argc + 1) * sizeof(char *)); 29297db96d56Sopenharmony_ci if (array == NULL) { 29307db96d56Sopenharmony_ci PyErr_NoMemory(); 29317db96d56Sopenharmony_ci return NULL; 29327db96d56Sopenharmony_ci } 29337db96d56Sopenharmony_ci for (i = 0; i < argc; ++i) { 29347db96d56Sopenharmony_ci char *data; 29357db96d56Sopenharmony_ci item = PySequence_GetItem(self, i); 29367db96d56Sopenharmony_ci if (item == NULL) { 29377db96d56Sopenharmony_ci /* NULL terminate before freeing. */ 29387db96d56Sopenharmony_ci array[i] = NULL; 29397db96d56Sopenharmony_ci goto fail; 29407db96d56Sopenharmony_ci } 29417db96d56Sopenharmony_ci /* check for embedded null bytes */ 29427db96d56Sopenharmony_ci if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) { 29437db96d56Sopenharmony_ci /* NULL terminate before freeing. */ 29447db96d56Sopenharmony_ci array[i] = NULL; 29457db96d56Sopenharmony_ci goto fail; 29467db96d56Sopenharmony_ci } 29477db96d56Sopenharmony_ci size = PyBytes_GET_SIZE(item) + 1; 29487db96d56Sopenharmony_ci array[i] = PyMem_Malloc(size); 29497db96d56Sopenharmony_ci if (!array[i]) { 29507db96d56Sopenharmony_ci PyErr_NoMemory(); 29517db96d56Sopenharmony_ci goto fail; 29527db96d56Sopenharmony_ci } 29537db96d56Sopenharmony_ci memcpy(array[i], data, size); 29547db96d56Sopenharmony_ci Py_DECREF(item); 29557db96d56Sopenharmony_ci } 29567db96d56Sopenharmony_ci array[argc] = NULL; 29577db96d56Sopenharmony_ci 29587db96d56Sopenharmony_ci return array; 29597db96d56Sopenharmony_ci 29607db96d56Sopenharmony_cifail: 29617db96d56Sopenharmony_ci Py_XDECREF(item); 29627db96d56Sopenharmony_ci _Py_FreeCharPArray(array); 29637db96d56Sopenharmony_ci return NULL; 29647db96d56Sopenharmony_ci} 29657db96d56Sopenharmony_ci 29667db96d56Sopenharmony_ci 29677db96d56Sopenharmony_ci/* Free's a NULL terminated char** array of C strings. */ 29687db96d56Sopenharmony_civoid 29697db96d56Sopenharmony_ci_Py_FreeCharPArray(char *const array[]) 29707db96d56Sopenharmony_ci{ 29717db96d56Sopenharmony_ci Py_ssize_t i; 29727db96d56Sopenharmony_ci for (i = 0; array[i] != NULL; ++i) { 29737db96d56Sopenharmony_ci PyMem_Free(array[i]); 29747db96d56Sopenharmony_ci } 29757db96d56Sopenharmony_ci PyMem_Free((void*)array); 29767db96d56Sopenharmony_ci} 2977