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

This commit is contained in:
rdb 2015-06-21 15:33:42 +02:00
parent 89d2fbd7e1
commit 8ecf6a7b9f
30 changed files with 100 additions and 59 deletions

View File

@ -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";

View File

@ -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
//

View File

@ -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
////////////////////////////////////////////////////////////////////////

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();

View File

@ -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());
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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();