diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-22 13:47:57 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-22 13:47:57 +0400 |
commit | 785b784e0903f4cc04889a0790f15f6b01b7860b (patch) | |
tree | 5362fc9c5f9298c690de04dc40ff1a51d41ddcac /source/gameengine/Expressions | |
parent | 95038048a2a10ea8703b1a94fc7fe1b0567ef559 (diff) |
BGE Python API
improved how attribute errors are set so each classes py_getattro function dosnt need to set an error if the attribute doesn't exist.
Now py_base_getattro sets an error on a NULL return value when no errors are set to avoid setting errors at multiple levels.
Diffstat (limited to 'source/gameengine/Expressions')
-rw-r--r-- | source/gameengine/Expressions/PyObjectPlus.cpp | 26 | ||||
-rw-r--r-- | source/gameengine/Expressions/PyObjectPlus.h | 10 |
2 files changed, 24 insertions, 12 deletions
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 96753d56d94..30495fc2a45 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -146,9 +146,23 @@ PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) PyObject *ret= self_plus->py_getattro(attr); - if(ret==NULL && (strcmp(PyString_AsString(attr), "__dict__")==0)) - ret= self_plus->py_getattro_dict(); - + /* Attribute not found, was this a __dict__ lookup?, otherwise set an error if none is set */ + if(ret==NULL) { + char *attr_str= PyString_AsString(attr); + + if (strcmp(attr_str, "__dict__")==0) + { + /* the error string will probably not + * be set but just incase clear it */ + PyErr_Clear(); + ret= self_plus->py_getattro_dict(); + } + else if (!PyErr_Occurred()) { + /* We looked for an attribute but it wasnt found + * since py_getattro didnt set the error, set it here */ + PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", self->ob_type->tp_name, attr_str); + } + } return ret; } @@ -183,8 +197,7 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) { PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, "attribute \"%s\" not found", PyString_AsString(attr)); - return NULL; + return NULL; /* py_base_getattro sets the error, this way we can avoid setting the error at many levels */ } else { /* Copied from py_getattro_up */ if (PyCObject_Check(descr)) { @@ -192,8 +205,7 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr) } else if (descr->ob_type->tp_descr_get) { return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); } else { - fprintf(stderr, "Unknown attribute type (PyObjectPlus::py_getattro)"); - return descr; + return NULL; } /* end py_getattro_up copy */ } diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index b0ddfa04e32..a3b3952a6d1 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -114,6 +114,9 @@ typedef struct { // This defines the py_getattro_up macro // which allows attribute and method calls // to be properly passed up the hierarchy. + // + // Note, PyDict_GetItem() WONT set an exception! + // let the py_base_getattro function do this. #define py_getattro_up(Parent) \ \ @@ -125,14 +128,11 @@ typedef struct { } else if (descr->ob_type->tp_descr_get) { \ return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \ } else { \ - fprintf(stderr, "unknown attribute type"); \ - return descr; \ + return NULL; \ } \ } else { \ - PyErr_Clear(); \ return Parent::py_getattro(attr); \ - } \ - return NULL; + } #define py_getattro_dict_up(Parent) \ return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict); |