| #include "parts.h" |
| #include "util.h" |
| |
| |
| static PyObject * |
| object_getoptionalattr(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR; |
| if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| NULLABLE(attr_name); |
| |
| switch (PyObject_GetOptionalAttr(obj, attr_name, &value)) { |
| case -1: |
| assert(value == NULL); |
| return NULL; |
| case 0: |
| assert(value == NULL); |
| return Py_NewRef(PyExc_AttributeError); |
| case 1: |
| return value; |
| default: |
| Py_FatalError("PyObject_GetOptionalAttr() returned invalid code"); |
| Py_UNREACHABLE(); |
| } |
| } |
| |
| static PyObject * |
| object_getoptionalattrstring(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *value = UNINITIALIZED_PTR; |
| const char *attr_name; |
| Py_ssize_t size; |
| if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| |
| switch (PyObject_GetOptionalAttrString(obj, attr_name, &value)) { |
| case -1: |
| assert(value == NULL); |
| return NULL; |
| case 0: |
| assert(value == NULL); |
| return Py_NewRef(PyExc_AttributeError); |
| case 1: |
| return value; |
| default: |
| Py_FatalError("PyObject_GetOptionalAttrString() returned invalid code"); |
| Py_UNREACHABLE(); |
| } |
| } |
| |
| static PyObject * |
| object_hasattrwitherror(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *attr_name; |
| if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| NULLABLE(attr_name); |
| RETURN_INT(PyObject_HasAttrWithError(obj, attr_name)); |
| } |
| |
| static PyObject * |
| object_hasattrstringwitherror(PyObject *self, PyObject *args) |
| { |
| PyObject *obj; |
| const char *attr_name; |
| Py_ssize_t size; |
| if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| RETURN_INT(PyObject_HasAttrStringWithError(obj, attr_name)); |
| } |
| |
| static PyObject * |
| mapping_getoptionalitemstring(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *value = UNINITIALIZED_PTR; |
| const char *attr_name; |
| Py_ssize_t size; |
| if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| |
| switch (PyMapping_GetOptionalItemString(obj, attr_name, &value)) { |
| case -1: |
| assert(value == NULL); |
| return NULL; |
| case 0: |
| assert(value == NULL); |
| return Py_NewRef(PyExc_KeyError); |
| case 1: |
| return value; |
| default: |
| Py_FatalError("PyMapping_GetOptionalItemString() returned invalid code"); |
| Py_UNREACHABLE(); |
| } |
| } |
| |
| static PyObject * |
| mapping_getoptionalitem(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR; |
| if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| NULLABLE(attr_name); |
| |
| switch (PyMapping_GetOptionalItem(obj, attr_name, &value)) { |
| case -1: |
| assert(value == NULL); |
| return NULL; |
| case 0: |
| assert(value == NULL); |
| return Py_NewRef(PyExc_KeyError); |
| case 1: |
| return value; |
| default: |
| Py_FatalError("PyMapping_GetOptionalItem() returned invalid code"); |
| Py_UNREACHABLE(); |
| } |
| } |
| |
| static PyObject * |
| pyiter_next(PyObject *self, PyObject *iter) |
| { |
| PyObject *item = PyIter_Next(iter); |
| if (item == NULL && !PyErr_Occurred()) { |
| Py_RETURN_NONE; |
| } |
| return item; |
| } |
| |
| static PyObject * |
| pyiter_nextitem(PyObject *self, PyObject *iter) |
| { |
| PyObject *item; |
| int rc = PyIter_NextItem(iter, &item); |
| if (rc < 0) { |
| assert(PyErr_Occurred()); |
| assert(item == NULL); |
| return NULL; |
| } |
| assert(!PyErr_Occurred()); |
| if (item == NULL) { |
| Py_RETURN_NONE; |
| } |
| return item; |
| } |
| |
| |
| static PyObject * |
| sequence_fast_get_size(PyObject *self, PyObject *obj) |
| { |
| NULLABLE(obj); |
| return PyLong_FromSsize_t(PySequence_Fast_GET_SIZE(obj)); |
| } |
| |
| |
| static PyObject * |
| sequence_fast_get_item(PyObject *self, PyObject *args) |
| { |
| PyObject *obj; |
| Py_ssize_t index; |
| if (!PyArg_ParseTuple(args, "On", &obj, &index)) { |
| return NULL; |
| } |
| NULLABLE(obj); |
| return PySequence_Fast_GET_ITEM(obj, index); |
| } |
| |
| |
| static PyObject * |
| object_setattr_null_exc(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *name, *exc; |
| if (!PyArg_ParseTuple(args, "OOO", &obj, &name, &exc)) { |
| return NULL; |
| } |
| |
| PyErr_SetObject((PyObject*)Py_TYPE(exc), exc); |
| if (PyObject_SetAttr(obj, name, NULL) < 0) { |
| return NULL; |
| } |
| assert(PyErr_Occurred()); |
| return NULL; |
| } |
| |
| |
| static PyObject * |
| object_setattrstring_null_exc(PyObject *self, PyObject *args) |
| { |
| PyObject *obj, *exc; |
| const char *name; |
| Py_ssize_t size; |
| if (!PyArg_ParseTuple(args, "Oz#O", &obj, &name, &size, &exc)) { |
| return NULL; |
| } |
| |
| PyErr_SetObject((PyObject*)Py_TYPE(exc), exc); |
| if (PyObject_SetAttrString(obj, name, NULL) < 0) { |
| return NULL; |
| } |
| assert(PyErr_Occurred()); |
| return NULL; |
| } |
| |
| |
| static PyMethodDef test_methods[] = { |
| {"object_getoptionalattr", object_getoptionalattr, METH_VARARGS}, |
| {"object_getoptionalattrstring", object_getoptionalattrstring, METH_VARARGS}, |
| {"object_hasattrwitherror", object_hasattrwitherror, METH_VARARGS}, |
| {"object_hasattrstringwitherror", object_hasattrstringwitherror, METH_VARARGS}, |
| {"mapping_getoptionalitem", mapping_getoptionalitem, METH_VARARGS}, |
| {"mapping_getoptionalitemstring", mapping_getoptionalitemstring, METH_VARARGS}, |
| |
| {"PyIter_Next", pyiter_next, METH_O}, |
| {"PyIter_NextItem", pyiter_nextitem, METH_O}, |
| |
| {"sequence_fast_get_size", sequence_fast_get_size, METH_O}, |
| {"sequence_fast_get_item", sequence_fast_get_item, METH_VARARGS}, |
| {"object_setattr_null_exc", object_setattr_null_exc, METH_VARARGS}, |
| {"object_setattrstring_null_exc", object_setattrstring_null_exc, METH_VARARGS}, |
| {NULL}, |
| }; |
| |
| int |
| _PyTestCapi_Init_Abstract(PyObject *m) |
| { |
| if (PyModule_AddFunctions(m, test_methods) < 0) { |
| return -1; |
| } |
| |
| return 0; |
| } |