mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	 e006c7371d
			
		
	
	
		e006c7371d
		
			
		
	
	
	
	
		
			
			Return -1 and set an exception on error; return 0 if the iterator is exhausted, and return 1 if the next item was fetched successfully. Prefer this API to PyIter_Next(), which requires the caller to use PyErr_Occurred() to differentiate between iterator exhaustion and errors. Co-authered-by: Irit Katriel <iritkatriel@yahoo.com>
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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 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},
 | |
|     {NULL},
 | |
| };
 | |
| 
 | |
| int
 | |
| _PyTestCapi_Init_Abstract(PyObject *m)
 | |
| {
 | |
|     if (PyModule_AddFunctions(m, test_methods) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 |