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