From 96a4cc767fa930d236262904abebc4cdff54eff0 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 4 May 2011 16:51:59 -0300 Subject: Fix bug 813 - "Can not override connect method when subclassing QObject" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Renato Araújo --- generator/cppgenerator.cpp | 26 ++++++++++++++++++---- .../samplebinding/static_nonstatic_methods_test.py | 25 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 8d3179d5e..790563772 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -3768,10 +3768,18 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass { s << "static PyObject* " << cpythonGetattroFunctionName(metaClass) << "(PyObject* self, PyObject* name)" << endl; s << '{' << endl; + + QString getattrFunc; + if (usePySideExtensions() && metaClass->isQObject()) + getattrFunc = "PySide::getMetaDataFromQObject(Shiboken::Converter::toCpp(self), self, name)"; + else + getattrFunc = "PyObject_GenericGetAttr(self, name)"; + if (classNeedsGetattroFunction(metaClass)) { s << INDENT << "if (self) {" << endl; { Indentation indent(INDENT); + s << INDENT << "// Search the method in the instance dict" << endl; s << INDENT << "if (reinterpret_cast(self)->ob_dict) {" << endl; { Indentation indent(INDENT); @@ -3785,6 +3793,19 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass s << INDENT << '}' << endl; } s << INDENT << '}' << endl; + s << INDENT << "// Search the method in the type dict" << endl; + s << INDENT << "if (Shiboken::Object::isUserType(self)) {" << endl; + { + Indentation indent(INDENT); + s << INDENT << "PyObject* meth = PyDict_GetItem(self->ob_type->tp_dict, name);" << endl; + s << INDENT << "if (meth)" << endl; + { + Indentation indent(INDENT); + s << INDENT << "return PyFunction_Check(meth) ? PyMethod_New(meth, self, (PyObject*)self->ob_type) : " << getattrFunc << ';' << endl; + } + } + s << INDENT << '}' << endl; + s << INDENT << "const char* cname = PyString_AS_STRING(name);" << endl; foreach (const AbstractMetaFunction* func, getMethodsWithBothStaticAndNonStaticMethods(metaClass)) { s << INDENT << "if (strcmp(cname, \"" << func->name() << "\") == 0)" << endl; @@ -3794,10 +3815,7 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass } s << INDENT << '}' << endl; } - if (usePySideExtensions() && metaClass->isQObject()) - s << INDENT << "return PySide::getMetaDataFromQObject(Shiboken::Converter::toCpp(self), self, name);" << endl; - else - s << INDENT << "return PyObject_GenericGetAttr(self, name);" << endl; + s << INDENT << "return " << getattrFunc << ';' << endl; s << '}' << endl; } diff --git a/tests/samplebinding/static_nonstatic_methods_test.py b/tests/samplebinding/static_nonstatic_methods_test.py index c1c7422ee..69ea41bdf 100644 --- a/tests/samplebinding/static_nonstatic_methods_test.py +++ b/tests/samplebinding/static_nonstatic_methods_test.py @@ -31,6 +31,16 @@ import unittest from sample import SimpleFile +class SimpleFile2 (SimpleFile): + def exists(self): + return "Mooo" + +class SimpleFile3 (SimpleFile): + pass + +class SimpleFile4 (SimpleFile): + exists = 5 + class StaticNonStaticMethodsTest(unittest.TestCase): '''Test cases for overloads involving static and non-static versions of a method.''' @@ -74,6 +84,21 @@ class StaticNonStaticMethodsTest(unittest.TestCase): f2 = SimpleFile(self.existing_filename) self.assert_(f2.exists()) + def testOverridingStaticNonStaticMethod(self): + f = SimpleFile2(self.existing_filename) + self.assertEqual(f.exists(), "Mooo") + + f = SimpleFile3(self.existing_filename) + self.assertTrue(f.exists()) + + f = SimpleFile4(self.existing_filename) + self.assertEqual(f.exists, 5) + + def testDuckPunchingStaticNonStaticMethod(self): + f = SimpleFile(self.existing_filename) + f.exists = lambda : "Meee" + self.assertEqual(f.exists(), "Meee") + if __name__ == '__main__': unittest.main() -- cgit v1.2.3