@@ -497,18 +497,15 @@ def isSimpleType(self, field):
497497
498498 def visitField (self , field , name , sum = None , prod = None , depth = 0 ):
499499 ctype = get_c_type (field .type )
500- if field .opt :
501- check = "exists_not_none (obj, &PyId_%s)" % ( field .name ,)
500+ if not field .opt :
501+ self . emit ( "tmp = _PyObject_GetAttrId (obj, &PyId_%s); " % field .name , depth )
502502 else :
503- check = "_PyObject_HasAttrId (obj, &PyId_%s)" % ( field .name ,)
504- self .emit ("if (%s ) {" % ( check ,), depth , reflow = False )
503+ self . emit ( "tmp = get_not_none (obj, &PyId_%s); " % field .name , depth )
504+ self .emit ("if (tmp != NULL ) {" , depth )
505505 self .emit ("int res;" , depth + 1 )
506506 if field .seq :
507507 self .emit ("Py_ssize_t len;" , depth + 1 )
508508 self .emit ("Py_ssize_t i;" , depth + 1 )
509- self .emit ("tmp = _PyObject_GetAttrId(obj, &PyId_%s);" % field .name , depth + 1 )
510- self .emit ("if (tmp == NULL) goto failed;" , depth + 1 )
511- if field .seq :
512509 self .emit ("if (!PyList_Check(tmp)) {" , depth + 1 )
513510 self .emit ("PyErr_Format(PyExc_TypeError, \" %s field \\ \" %s\\ \" must "
514511 "be a list, not a %%.200s\" , tmp->ob_type->tp_name);" %
@@ -542,13 +539,19 @@ def visitField(self, field, name, sum=None, prod=None, depth=0):
542539 self .emit ("if (res != 0) goto failed;" , depth + 1 )
543540
544541 self .emit ("Py_CLEAR(tmp);" , depth + 1 )
545- self .emit ("} else {" , depth )
546542 if not field .opt :
543+ self .emit ("} else {" , depth )
544+ self .emit ("if (PyErr_ExceptionMatches(PyExc_AttributeError)) {" , depth + 1 )
547545 message = "required field \\ \" %s\\ \" missing from %s" % (field .name , name )
548546 format = "PyErr_SetString(PyExc_TypeError, \" %s\" );"
549- self .emit (format % message , depth + 1 , reflow = False )
547+ self .emit (format % message , depth + 2 , reflow = False )
548+ self .emit ("}" , depth + 1 )
550549 self .emit ("return 1;" , depth + 1 )
551550 else :
551+ self .emit ("} else if (PyErr_Occurred()) {" , depth )
552+ self .emit ("return 1;" , depth + 1 )
553+ self .emit ("} else {" , depth )
554+
552555 if self .isNumeric (field ):
553556 self .emit ("%s = 0;" % field .name , depth + 1 )
554557 elif not self .isSimpleType (field ):
@@ -660,13 +663,17 @@ def visitModule(self, mod):
660663 int res = -1;
661664 PyObject *key, *value, *fields;
662665 fields = _PyObject_GetAttrId((PyObject*)Py_TYPE(self), &PyId__fields);
663- if (!fields)
664- PyErr_Clear();
665666 if (fields) {
666667 numfields = PySequence_Size(fields);
667668 if (numfields == -1)
668669 goto cleanup;
669670 }
671+ else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
672+ PyErr_Clear();
673+ }
674+ else {
675+ goto cleanup;
676+ }
670677
671678 res = 0; /* if no error occurs, this stays 0 to the end */
672679 if (numfields < PyTuple_GET_SIZE(args)) {
@@ -958,17 +965,20 @@ def visitModule(self, mod):
958965 return 0;
959966}
960967
961- static int exists_not_none (PyObject *obj, _Py_Identifier *id)
968+ static PyObject *get_not_none (PyObject *obj, _Py_Identifier *id)
962969{
963- int isnone;
964970 PyObject *attr = _PyObject_GetAttrId(obj, id);
965971 if (!attr) {
966- PyErr_Clear();
967- return 0;
972+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
973+ PyErr_Clear();
974+ }
975+ return NULL;
976+ }
977+ else if (attr == Py_None) {
978+ Py_DECREF(attr);
979+ return NULL;
968980 }
969- isnone = attr == Py_None;
970- Py_DECREF(attr);
971- return !isnone;
981+ return attr;
972982}
973983
974984""" , 0 , reflow = False )
0 commit comments