Browse Source

Fix getattr() and hasattr() of vector classes when invalid attribute name is used

rdb 10 years ago
parent
commit
8ecf6a7b9f

+ 7 - 2
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -1813,7 +1813,7 @@ write_module_class(ostream &out, Object *obj) {
           out << "  if (res != NULL) {\n";
           out << "    return res;\n";
           out << "  }\n";
-          out << "  if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {\n";
+          out << "  if (_PyErr_OCCURRED() != PyExc_AttributeError) {\n";
           out << "    return NULL;\n";
           out << "  }\n";
           out << "  PyErr_Clear();\n\n";
@@ -5561,6 +5561,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
         << "return Dtool_Return_Bool(" << return_expr << ");\n";
       return_flags &= ~RF_pyobject;
 
+    } else if (return_null && TypeManager::is_pointer_to_PyObject(remap->_return_type->get_new_type())) {
+      indent(out, indent_level)
+        << "return Dtool_Return(" << return_expr << ");\n";
+      return_flags &= ~RF_pyobject;
+
     } else {
       indent(out, indent_level)
         << "if (Dtool_CheckErrorOccurred()) {\n";
@@ -5661,7 +5666,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
         << "return DTool_PyInit_Finalize(self, " << return_expr << ", &" << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", true, false);\n";
 
     } else if (TypeManager::is_integer(orig_type)) {
-      if (return_flags & RF_compare) {
+      if ((return_flags & RF_compare) == RF_compare) {
         // Make sure it returns -1, 0, or 1, or Python complains with:
         // RuntimeWarning: tp_compare didn't return -1, 0 or 1
         indent(out, indent_level) << "return (int)(" << return_expr << " > 0) - (int)(" << return_expr << " < 0);\n";

+ 41 - 0
dtool/src/interrogatedb/py_panda.cxx

@@ -273,6 +273,29 @@ PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *functio
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Dtool_Raise_AttributeError
+//  Description: Raises an AttributeError of the form:
+//               'type' has no attribute 'attr'
+//
+//               Always returns NULL so that it can be conveniently
+//               used as a return expression for wrapper functions
+//               that return a PyObject pointer.
+////////////////////////////////////////////////////////////////////
+PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute) {
+#if PY_MAJOR_VERSION >= 3
+  PyObject *message = PyUnicode_FromFormat(
+#else
+  PyObject *message = PyString_FromFormat(
+#endif
+    "'%.100s' object has no attribute '%.200s'",
+    Py_TYPE(obj)->tp_name, attribute);
+
+  Py_INCREF(PyExc_TypeError);
+  PyErr_Restore(PyExc_TypeError, message, (PyObject *)NULL);
+  return NULL;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Dtool_Raise_BadArgumentsError
 //  Description: Raises a TypeError of the form:
@@ -330,6 +353,24 @@ PyObject *Dtool_Return_Bool(bool value) {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Dtool_Return
+//  Description: Convenience method that checks for exceptions, and
+//               if one occurred, returns NULL, otherwise the given
+//               return value.  Its reference count is not increased.
+////////////////////////////////////////////////////////////////////
+PyObject *_Dtool_Return(PyObject *value) {
+  if (_PyErr_OCCURRED()) {
+    return NULL;
+  }
+#ifndef NDEBUG
+  if (Notify::ptr()->has_assert_failed()) {
+    return Dtool_Raise_AssertionError();
+  }
+#endif
+  return value;
+}
+
 ////////////////////////////////////////////////////////////////////////
 //  Function : DTool_CreatePyInstanceTyped
 //

+ 4 - 0
dtool/src/interrogatedb/py_panda.h

@@ -340,6 +340,7 @@ EXPCL_DTOOLCONFIG bool Dtool_CheckErrorOccurred();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AssertionError();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_TypeError(const char *message);
 EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
+EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
 
 EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
 #ifdef NDEBUG
@@ -352,11 +353,14 @@ EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
 
 EXPCL_DTOOLCONFIG PyObject *_Dtool_Return_None();
 EXPCL_DTOOLCONFIG PyObject *Dtool_Return_Bool(bool value);
+EXPCL_DTOOLCONFIG PyObject *_Dtool_Return(PyObject *value);
 
 #ifdef NDEBUG
 #define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
+#define Dtool_Return(value) (_PyErr_OCCURRED() != NULL ? NULL : value)
 #else
 #define Dtool_Return_None() _Dtool_Return_None()
+#define Dtool_Return(value) _Dtool_Return(value)
 #endif
 
 ////////////////////////////////////////////////////////////////////////

+ 3 - 3
panda/src/linmath/lpoint2_ext_src.I

@@ -42,7 +42,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint2)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
@@ -52,7 +52,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -83,7 +83,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lpoint2_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LPoint2)> : public ExtensionBase<FLOATNAME(LPoint2)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lpoint2_src.h

@@ -26,7 +26,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE fill_value);
   INLINE_LINMATH FLOATNAME(LPoint2)(FLOATTYPE x, FLOATTYPE y);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LPoint2) &zero();

+ 3 - 3
panda/src/linmath/lpoint3_ext_src.I

@@ -43,7 +43,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint3)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
@@ -53,7 +53,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -84,7 +84,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lpoint3_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LPoint3)> : public ExtensionBase<FLOATNAME(LPoint3)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lpoint3_src.h

@@ -32,7 +32,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LPoint3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
   INLINE_LINMATH FLOATNAME(LPoint3)(const FLOATNAME(LVecBase2) &copy, FLOATTYPE z);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LPoint3) &zero();

+ 3 - 3
panda/src/linmath/lpoint4_ext_src.I

@@ -44,7 +44,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LPoint4)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LPoint3);
@@ -54,7 +54,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -89,7 +89,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lpoint4_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LPoint4)> : public ExtensionBase<FLOATNAME(LPoint4)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lpoint4_src.h

@@ -26,7 +26,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LPoint4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
   INLINE_LINMATH FLOATNAME(LPoint4)(const FLOATNAME(LVecBase3) &copy, FLOATTYPE w);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LPoint4) &zero();

+ 4 - 7
panda/src/linmath/lvecBase2_ext_src.I

@@ -80,7 +80,7 @@ __reduce__(PyObject *self) const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase2)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
@@ -90,7 +90,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -121,7 +121,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -135,10 +135,7 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {
-      PyTypeObject *tp = self->ob_type;
-      PyErr_Format(PyExc_AttributeError,
-                   "'%.100s' object has no attribute '%.200s'",
-                   tp->tp_name, attr_name.c_str());
+      Dtool_Raise_AttributeError(self, attr_name.c_str());
       return -1;
     }
   }

+ 1 - 1
panda/src/linmath/lvecBase2_ext_src.h

@@ -23,7 +23,7 @@ template<>
 class Extension<FLOATNAME(LVecBase2)> : public ExtensionBase<FLOATNAME(LVecBase2)> {
 public:
   INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 

+ 1 - 1
panda/src/linmath/lvecBase2_src.h

@@ -49,7 +49,7 @@ PUBLISHED:
   INLINE_LINMATH ~FLOATNAME(LVecBase2)();
 
   EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;

+ 4 - 7
panda/src/linmath/lvecBase3_ext_src.I

@@ -81,7 +81,7 @@ __reduce__(PyObject *self) const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase3)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
@@ -91,7 +91,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -122,7 +122,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -136,10 +136,7 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {
-      PyTypeObject *tp = self->ob_type;
-      PyErr_Format(PyExc_AttributeError,
-                   "'%.100s' object has no attribute '%.200s'",
-                   tp->tp_name, attr_name.c_str());
+      Dtool_Raise_AttributeError(self, attr_name.c_str());
       return -1;
     }
   }

+ 1 - 1
panda/src/linmath/lvecBase3_ext_src.h

@@ -23,7 +23,7 @@ template<>
 class Extension<FLOATNAME(LVecBase3)> : public ExtensionBase<FLOATNAME(LVecBase3)> {
 public:
   INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 

+ 1 - 1
panda/src/linmath/lvecBase3_src.h

@@ -51,7 +51,7 @@ PUBLISHED:
   INLINE_LINMATH ~FLOATNAME(LVecBase3)();
 
   EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;

+ 4 - 7
panda/src/linmath/lvecBase4_ext_src.I

@@ -82,7 +82,7 @@ __reduce__(PyObject *self) const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase4)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3);
@@ -92,7 +92,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -127,7 +127,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -141,10 +141,7 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {
-      PyTypeObject *tp = self->ob_type;
-      PyErr_Format(PyExc_AttributeError,
-                   "'%.100s' object has no attribute '%.200s'",
-                   tp->tp_name, attr_name.c_str());
+      Dtool_Raise_AttributeError(self, attr_name.c_str());
       return -1;
     }
   }

+ 1 - 1
panda/src/linmath/lvecBase4_ext_src.h

@@ -23,7 +23,7 @@ template<>
 class Extension<FLOATNAME(LVecBase4)> : public ExtensionBase<FLOATNAME(LVecBase4)> {
 public:
   INLINE_LINMATH PyObject *__reduce__(PyObject *self) const;
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 

+ 1 - 1
panda/src/linmath/lvecBase4_src.h

@@ -61,7 +61,7 @@ PUBLISHED:
   INLINE_LINMATH ~FLOATNAME(LVecBase4)();
 
   EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const);
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH FLOATTYPE operator [](int i) const;

+ 3 - 3
panda/src/linmath/lvector2_ext_src.I

@@ -42,7 +42,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector2)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@@ -52,7 +52,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it != 'x' && *it != 'y') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -83,7 +83,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lvector2_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LVector2)> : public ExtensionBase<FLOATNAME(LVector2)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lvector2_src.h

@@ -25,7 +25,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE fill_value);
   INLINE_LINMATH FLOATNAME(LVector2)(FLOATTYPE x, FLOATTYPE y);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LVector2) &zero();

+ 3 - 3
panda/src/linmath/lvector3_ext_src.I

@@ -43,7 +43,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector3)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@@ -53,7 +53,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'x' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -84,7 +84,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lvector3_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LVector3)> : public ExtensionBase<FLOATNAME(LVector3)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lvector3_src.h

@@ -32,7 +32,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
   INLINE_LINMATH FLOATNAME(LVector3)(const FLOATNAME(LVecBase2) &copy, FLOATTYPE z);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LVector3) &zero();

+ 3 - 3
panda/src/linmath/lvector4_ext_src.I

@@ -44,7 +44,7 @@ __repr__() const {
 //  Description: This is used to implement swizzle masks.
 ////////////////////////////////////////////////////////////////////
 INLINE_LINMATH PyObject *Extension<FLOATNAME(LVector4)>::
-__getattr__(const string &attr_name) const {
+__getattr__(PyObject *self, const string &attr_name) const {
 #ifndef CPPPARSER
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector2);
   extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVector3);
@@ -54,7 +54,7 @@ __getattr__(const string &attr_name) const {
   // Validate the attribute name.
   for (string::const_iterator it = attr_name.begin(); it < attr_name.end(); it++) {
     if (*it < 'w' || *it > 'z') {
-      return NULL;
+      return Dtool_Raise_AttributeError(self, attr_name.c_str());
     }
   }
 
@@ -89,7 +89,7 @@ __getattr__(const string &attr_name) const {
     }
   }
 
-  return NULL;
+  return Dtool_Raise_AttributeError(self, attr_name.c_str());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/linmath/lvector4_ext_src.h

@@ -22,7 +22,7 @@
 template<>
 class Extension<FLOATNAME(LVector4)> : public ExtensionBase<FLOATNAME(LVector4)> {
 public:
-  INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const;
+  INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const;
   INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign);
   INLINE_LINMATH string __repr__() const;
 };

+ 1 - 1
panda/src/linmath/lvector4_src.h

@@ -26,7 +26,7 @@ PUBLISHED:
   INLINE_LINMATH FLOATNAME(LVector4)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z, FLOATTYPE w);
   INLINE_LINMATH FLOATNAME(LVector4)(const FLOATNAME(LVecBase3) &copy, FLOATTYPE w);
 
-  EXTENSION(INLINE_LINMATH PyObject *__getattr__(const string &attr_name) const);
+  EXTENSION(INLINE_LINMATH PyObject *__getattr__(PyObject *self, const string &attr_name) const);
   EXTENSION(INLINE_LINMATH int __setattr__(PyObject *self, const string &attr_name, PyObject *assign));
 
   INLINE_LINMATH static const FLOATNAME(LVector4) &zero();