##// END OF EJS Templates
Fix __getattr__ problems.
Orochimarufan -
r207:99eb8a233276
parent child
Show More
@@ -105,16 +105,20 endif()
105 105 #-----------------------------------------------------------------------------
106 106 # Find Python
107 107 option(PythonQt_Python3 "Use Python 3.x (3.3+)" OFF)
108 if(PythonQt_Python3)
109 set(PythonQt_PythonMin 3.3)
110 else(PythonQt_Python3)
111 set(PythonQt_PythonMin 2.6)
108 option(PythonQt_Python "Use specific Python Version" OFF)
109 if(PythonQt_Python)
110 find_package(Python ${PythonQt_Python} REQUIRED EXACT)
111 elseif(PythonQt_Python3)
112 find_package(Python 3.3 REQUIRED)
113 else()
114 find_package(Python 2.6 REQUIRED)
112 115 endif()
113 116
114 find_package(Python ${PythonQt_PythonMin} REQUIRED)
115 117 include_directories(${PYTHON_INCLUDE_DIRS})
116 118 add_definitions(-DPYTHONQT_USE_RELEASE_PYTHON_FALLBACK)
117 119
120 #-----------------------------------------------------------------------------
121 # Core
118 122 add_subdirectory(src)
119 123
120 124 #-----------------------------------------------------------------------------
@@ -142,7 +142,7 void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
142 142 Py_INCREF(obj);
143 143 PyModule_AddObject(pack2, names[i], obj);
144 144 } else {
145 std::cerr << "method not found " << names[i];
145 std::cerr << "method not found " << names[i] << std::endl;
146 146 }
147 147 }
148 148 }
@@ -1492,7 +1492,7 static PyMethodDef PythonQtMethods[] = {
1492 1492 };
1493 1493
1494 1494 #ifdef PY3K
1495 static PyModuleDef PythonQtModule = {
1495 static PyModuleDef PythonQtModuleDef = {
1496 1496 PyModuleDef_HEAD_INIT,
1497 1497 "",
1498 1498 NULL,
@@ -1512,18 +1512,19 void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
1512 1512 name = pythonQtModuleName;
1513 1513 }
1514 1514 #ifdef PY3K
1515 PythonQtModule.m_name = name.constData();
1516 _p->_pythonQtModule = PyModule_Create(&PythonQtModule);
1515 PythonQtModuleDef.m_name = name.constData();
1516 _p->_pythonQtModule = PyModule_Create(&PythonQtModuleDef);
1517 1517 #else
1518 1518 _p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods);
1519 1519 #endif
1520 1520 _p->_pythonQtModuleName = name;
1521 1521
1522 PythonQtObjectPtr sys;
1523 sys.setNewRef(PyImport_ImportModule("sys"));
1524
1522 1525 if (redirectStdOut) {
1523 PythonQtObjectPtr sys;
1524 1526 PythonQtObjectPtr out;
1525 1527 PythonQtObjectPtr err;
1526 sys.setNewRef(PyImport_ImportModule("sys"));
1527 1528 // create a redirection object for stdout and stderr
1528 1529 out = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
1529 1530 ((PythonQtStdOutRedirect*)out.object())->_cb = stdOutRedirectCB;
@@ -1535,8 +1536,6 void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
1535 1536 }
1536 1537
1537 1538 // add PythonQt to the list of builtin module names
1538 PythonQtObjectPtr sys;
1539 sys.setNewRef(PyImport_ImportModule("sys"));
1540 1539 PyObject *old_module_names = PyObject_GetAttrString(sys.object(),"builtin_module_names");
1541 1540 Py_ssize_t old_size = PyTuple_Size(old_module_names);
1542 1541 PyObject *module_names = PyTuple_New(old_size+1);
@@ -1549,6 +1548,10 void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
1549 1548 #endif
1550 1549 PyModule_AddObject(sys.object(),"builtin_module_names",module_names);
1551 1550 Py_DecRef(old_module_names);
1551
1552 #ifdef PY3K
1553 PyDict_SetItem(PyObject_GetAttrString(sys.object(), "modules"), PyUnicode_FromString(name.constData()), _p->_pythonQtModule.object());
1554 #endif
1552 1555 }
1553 1556
1554 1557 QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString& name)
@@ -389,9 +389,6 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
389 389 }
390 390
391 391 // look in Python to support derived Python classes
392 #ifdef PY3K
393 return PyObject_GenericGetAttr(obj, name);
394 #else
395 392 PyObject* superAttr = PyType_Type.tp_getattro(obj, name);
396 393 if (superAttr) {
397 394 return superAttr;
@@ -418,7 +415,11 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
418 415 }
419 416
420 417 // look for the internal methods (className(), help())
418 #ifdef PY3K
419 PyObject* internalMethod = PyObject_GenericGetAttr(obj, name);
420 #else
421 421 PyObject* internalMethod = Py_FindMethod( PythonQtClassWrapper_methods, obj, (char*)attributeName);
422 #endif
422 423 if (internalMethod) {
423 424 return internalMethod;
424 425 }
@@ -426,7 +427,6 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
426 427 QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'";
427 428 PyErr_SetString(PyExc_AttributeError, error.toLatin1().data());
428 429 return NULL;
429 #endif
430 430 }
431 431
432 432 static int PythonQtClassWrapper_setattro(PyObject *obj,PyObject *name,PyObject *value)
@@ -486,7 +486,7 PyTypeObject PythonQtClassWrapper_Type = {
486 486 0, /* tp_weaklistoffset */
487 487 0, /* tp_iter */
488 488 0, /* tp_iternext */
489 0, /* tp_methods */
489 PythonQtClassWrapper_methods, /* tp_methods */
490 490 0, /* tp_members */
491 491 0, /* tp_getset */
492 492 0, /* tp_base */
@@ -45,10 +45,6
45 45 #include <QTime>
46 46 #include <QDate>
47 47
48 #if PY_MAJOR_VERSION >= 3
49 #define PY3K
50 #endif
51
52 48 PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
53 49 PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
54 50 PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
@@ -51,10 +51,6
51 51 #include <QFile>
52 52 #include <QFileInfo>
53 53
54 #if PY_MAJOR_VERSION >= 3
55 #define PY3K
56 #endif
57
58 54 #define IS_SOURCE 0x0
59 55 #define IS_BYTECODE 0x1
60 56 #define IS_PACKAGE 0x2
@@ -48,10 +48,6
48 48 #include "PythonQtConversion.h"
49 49 #include "PythonQtClassWrapper.h"
50 50
51 #if PY_MAJOR_VERSION >= 3
52 #define PY3K
53 #endif
54
55 51 PythonQtClassInfo* PythonQtInstanceWrapperStruct::classInfo()
56 52 {
57 53 // take the class info from our type object
@@ -831,7 +827,7 PyTypeObject PythonQtInstanceWrapper_Type = {
831 827 0, /* tp_weaklistoffset */
832 828 0, /* tp_iter */
833 829 0, /* tp_iternext */
834 0, /* tp_methods */
830 PythonQtInstanceWrapper_methods, /* tp_methods */
835 831 0, /* tp_members */
836 832 0, /* tp_getset */
837 833 0, /* tp_base */
@@ -52,10 +52,6
52 52
53 53 #include <QByteArray>
54 54
55 #if PY_MAJOR_VERSION >= 3
56 #define PY3K
57 #endif
58
59 55 #define PYTHONQT_MAX_ARGS 32
60 56
61 57
@@ -243,25 +243,25 void PythonQtTestSlotCalling::testCppFactory()
243 243 QVERIFY(_helper->runScript("if obj.getPQCppObjectNoWrapAsValue().getH()==47: obj.setPassed();\n"));
244 244
245 245 qRegisterMetaType<PQUnknownButRegisteredValueObject>("PQUnknownButRegisteredValueObject");
246 QVERIFY(_helper->runScript("a = obj.getUnknownButRegisteredValueObjectAsPtr();print a;\nif a!=None: obj.setPassed();\n"));
247 QVERIFY(_helper->runScript("a = obj.getUnknownButRegisteredValueObjectAsValue();print a;\nif a!=None: obj.setPassed();\n"));
248 QVERIFY(_helper->runScript("a = obj.getUnknownValueObjectAsPtr();print a;\nif a!=None: obj.setPassed();\n"));
246 QVERIFY(_helper->runScript("a = obj.getUnknownButRegisteredValueObjectAsPtr();print (a);\nif a!=None: obj.setPassed();\n"));
247 QVERIFY(_helper->runScript("a = obj.getUnknownButRegisteredValueObjectAsValue();print (a);\nif a!=None: obj.setPassed();\n"));
248 QVERIFY(_helper->runScript("a = obj.getUnknownValueObjectAsPtr();print (a);\nif a!=None: obj.setPassed();\n"));
249 249 QEXPECT_FAIL("", "Testing by value return without the object being registered as QMetaType or having registered a default constructor decorator", Continue);
250 QVERIFY(_helper->runScript("a = obj.getUnknownValueObjectAsValue();print a;\nif a!=None: obj.setPassed();\n"));
250 QVERIFY(_helper->runScript("a = obj.getUnknownValueObjectAsValue();print (a);\nif a!=None: obj.setPassed();\n"));
251 251
252 252 // expect to get strict call to double overload
253 253 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObjectNoWrap\na = PQCppObjectNoWrap(22.2)\nif a.getH()==2: obj.setPassed();\n"));
254 254 // expect to get un-strict call to double overload
255 255 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObjectNoWrap\na = PQCppObjectNoWrap(22)\nif a.getH()==2: obj.setPassed();\n"));
256 256 // expect to get strict call to copy constructor overload
257 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObjectNoWrap\na = PQCppObjectNoWrap(PQCppObjectNoWrap())\nprint a.getH()\nif a.getH()==1: obj.setPassed();\n"));
257 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObjectNoWrap\na = PQCppObjectNoWrap(PQCppObjectNoWrap())\nprint (a.getH())\nif a.getH()==1: obj.setPassed();\n"));
258 258
259 259 // test decorated enums
260 260 // already registered by signals test
261 261 //PythonQt::self()->registerCPPClass("PQCppObject2",NULL,NULL, PythonQtCreateObject<PQCppObject2Decorator>);
262 262
263 263 // local enum (decorated)
264 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObject2\na = PQCppObject2()\nprint a.testEnumFlag1\nif a.testEnumFlag1(PQCppObject2.TestEnumValue2)==PQCppObject2.TestEnumValue2: obj.setPassed();\n"));
264 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObject2\na = PQCppObject2()\nprint (a.testEnumFlag1)\nif a.testEnumFlag1(PQCppObject2.TestEnumValue2)==PQCppObject2.TestEnumValue2: obj.setPassed();\n"));
265 265 // enum with namespace (decorated)
266 266 QVERIFY(_helper->runScript("obj.testNoArg()\nfrom PythonQt.private import PQCppObject2\na = PQCppObject2()\nif a.testEnumFlag2(PQCppObject2.TestEnumValue2)==PQCppObject2.TestEnumValue2: obj.setPassed();\n"));
267 267 // with int overload to check overloading
@@ -565,17 +565,25 void PythonQtTestApi::testRedirect()
565 565 {
566 566 connect(PythonQt::self(), SIGNAL(pythonStdOut(const QString&)), _helper, SLOT(stdOut(const QString&)));
567 567 connect(PythonQt::self(), SIGNAL(pythonStdErr(const QString&)), _helper, SLOT(stdErr(const QString&)));
568 PyRun_SimpleString("print 'test'\n");
568 PyRun_SimpleString("print ('test')\n");
569 569 }
570 570
571 571 void PythonQtTestApiHelper::stdOut(const QString& s)
572 572 {
573 qDebug() << s;
573 outBuf.append(s);
574 QStringList x = outBuf.split("\n");
575 outBuf = x.takeLast();
576 foreach(QString s, x)
577 qDebug() << s;
574 578 }
575 579
576 580 void PythonQtTestApiHelper::stdErr(const QString& s)
577 581 {
578 qDebug() << s;
582 errBuf.append(s);
583 QStringList x = errBuf.split("\n");
584 errBuf = x.takeLast();
585 foreach(QString s, x)
586 qDebug() << s;
579 587 }
580 588
581 589 QObject* PythonQtTestCppFactory::create(const QByteArray& name, void *ptr)
@@ -170,6 +170,8 public slots:
170 170 void stdErr(const QString&);
171 171
172 172 private:
173 QString outBuf;
174 QString errBuf;
173 175 bool _passed;
174 176 };
175 177
General Comments 0
You need to be logged in to leave comments. Login now