@@ -64,7 +64,7 void PythonQt::init(int flags) | |||||
64 |
|
64 | |||
65 | PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>"); |
|
65 | PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>"); | |
66 | qRegisterMetaType<QList<QObject*> >("QList<void*>"); |
|
66 | qRegisterMetaType<QList<QObject*> >("QList<void*>"); | |
67 |
|
67 | |||
68 | PythonQtRegisterToolClassesTemplateConverter(int); |
|
68 | PythonQtRegisterToolClassesTemplateConverter(int); | |
69 | PythonQtRegisterToolClassesTemplateConverter(float); |
|
69 | PythonQtRegisterToolClassesTemplateConverter(float); | |
70 | PythonQtRegisterToolClassesTemplateConverter(double); |
|
70 | PythonQtRegisterToolClassesTemplateConverter(double); | |
@@ -103,7 +103,7 void PythonQt::init(int flags) | |||||
103 | PythonQtRegisterToolClassesTemplateConverter(QPoint); |
|
103 | PythonQtRegisterToolClassesTemplateConverter(QPoint); | |
104 | PythonQtRegisterToolClassesTemplateConverter(QPointF); |
|
104 | PythonQtRegisterToolClassesTemplateConverter(QPointF); | |
105 | PythonQtRegisterToolClassesTemplateConverter(QRegExp); |
|
105 | PythonQtRegisterToolClassesTemplateConverter(QRegExp); | |
106 |
|
106 | |||
107 | PythonQt::self()->registerCPPClass("QFont", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QFont>); |
|
107 | PythonQt::self()->registerCPPClass("QFont", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QFont>); | |
108 | PythonQt::self()->registerCPPClass("QPixmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPixmap>); |
|
108 | PythonQt::self()->registerCPPClass("QPixmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPixmap>); | |
109 | PythonQt::self()->registerCPPClass("QBrush", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBrush>); |
|
109 | PythonQt::self()->registerCPPClass("QBrush", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBrush>); | |
@@ -140,7 +140,7 void PythonQt::init(int flags) | |||||
140 | PythonQtRegisterToolClassesTemplateConverter(QTextFormat); |
|
140 | PythonQtRegisterToolClassesTemplateConverter(QTextFormat); | |
141 | PythonQtRegisterToolClassesTemplateConverter(QMatrix); |
|
141 | PythonQtRegisterToolClassesTemplateConverter(QMatrix); | |
142 |
|
142 | |||
143 |
|
143 | |||
144 | PyObject* pack = PythonQt::priv()->packageByName("QtCore"); |
|
144 | PyObject* pack = PythonQt::priv()->packageByName("QtCore"); | |
145 | PyObject* pack2 = PythonQt::priv()->packageByName("Qt"); |
|
145 | PyObject* pack2 = PythonQt::priv()->packageByName("Qt"); | |
146 | PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper(); |
|
146 | PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper(); | |
@@ -172,20 +172,20 PythonQt::PythonQt(int flags) | |||||
172 | _p->_initFlags = flags; |
|
172 | _p->_initFlags = flags; | |
173 |
|
173 | |||
174 | _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr"); |
|
174 | _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr"); | |
175 |
|
175 | |||
176 | Py_SetProgramName("PythonQt"); |
|
176 | Py_SetProgramName("PythonQt"); | |
177 | if (flags & IgnoreSiteModule) { |
|
177 | if (flags & IgnoreSiteModule) { | |
178 | // this prevents the automatic importing of Python site files |
|
178 | // this prevents the automatic importing of Python site files | |
179 | Py_NoSiteFlag = 1; |
|
179 | Py_NoSiteFlag = 1; | |
180 | } |
|
180 | } | |
181 | Py_Initialize(); |
|
181 | Py_Initialize(); | |
182 |
|
182 | |||
183 | // add our own python object types for qt object slots |
|
183 | // add our own python object types for qt object slots | |
184 | if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) { |
|
184 | if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) { | |
185 | std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; |
|
185 | std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; | |
186 | } |
|
186 | } | |
187 | Py_INCREF(&PythonQtSlotFunction_Type); |
|
187 | Py_INCREF(&PythonQtSlotFunction_Type); | |
188 |
|
188 | |||
189 | // according to Python docs, set the type late here, since it can not safely be stored in the struct when declaring it |
|
189 | // according to Python docs, set the type late here, since it can not safely be stored in the struct when declaring it | |
190 | PythonQtClassWrapper_Type.tp_base = &PyType_Type; |
|
190 | PythonQtClassWrapper_Type.tp_base = &PyType_Type; | |
191 | // add our own python object types for classes |
|
191 | // add our own python object types for classes | |
@@ -200,13 +200,13 PythonQt::PythonQt(int flags) | |||||
200 | std::cerr << "could not initialize PythonQtInstanceWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; |
|
200 | std::cerr << "could not initialize PythonQtInstanceWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; | |
201 | } |
|
201 | } | |
202 | Py_INCREF(&PythonQtInstanceWrapper_Type); |
|
202 | Py_INCREF(&PythonQtInstanceWrapper_Type); | |
203 |
|
203 | |||
204 | // add our own python object types for redirection of stdout |
|
204 | // add our own python object types for redirection of stdout | |
205 | if (PyType_Ready(&PythonQtStdOutRedirectType) < 0) { |
|
205 | if (PyType_Ready(&PythonQtStdOutRedirectType) < 0) { | |
206 | std::cerr << "could not initialize PythonQtStdOutRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; |
|
206 | std::cerr << "could not initialize PythonQtStdOutRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; | |
207 | } |
|
207 | } | |
208 | Py_INCREF(&PythonQtStdOutRedirectType); |
|
208 | Py_INCREF(&PythonQtStdOutRedirectType); | |
209 |
|
209 | |||
210 | initPythonQtModule(flags & RedirectStdOut); |
|
210 | initPythonQtModule(flags & RedirectStdOut); | |
211 |
|
211 | |||
212 | _p->setupSharedLibrarySuffixes(); |
|
212 | _p->setupSharedLibrarySuffixes(); | |
@@ -405,7 +405,7 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObje | |||||
405 | result->_wrappedPtr = wrappedPtr; |
|
405 | result->_wrappedPtr = wrappedPtr; | |
406 | result->_ownedByPythonQt = false; |
|
406 | result->_ownedByPythonQt = false; | |
407 | result->_useQMetaTypeDestroy = false; |
|
407 | result->_useQMetaTypeDestroy = false; | |
408 |
|
408 | |||
409 | if (wrappedPtr) { |
|
409 | if (wrappedPtr) { | |
410 | _wrappedObjects.insert(wrappedPtr, result); |
|
410 | _wrappedObjects.insert(wrappedPtr, result); | |
411 | } else { |
|
411 | } else { | |
@@ -425,7 +425,7 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla | |||||
425 |
|
425 | |||
426 | PyObject* baseClasses = PyTuple_New(1); |
|
426 | PyObject* baseClasses = PyTuple_New(1); | |
427 | PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type); |
|
427 | PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type); | |
428 |
|
428 | |||
429 | PyObject* typeDict = PyDict_New(); |
|
429 | PyObject* typeDict = PyDict_New(); | |
430 | QByteArray moduleName("PythonQt"); |
|
430 | QByteArray moduleName("PythonQt"); | |
431 | if (package && strcmp(package, "")!=0) { |
|
431 | if (package && strcmp(package, "")!=0) { | |
@@ -459,18 +459,18 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned | |||||
459 |
|
459 | |||
460 | PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) { |
|
460 | PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) { | |
461 | PyObject* result; |
|
461 | PyObject* result; | |
462 |
|
462 | |||
463 | PyObject* className = PyString_FromString(enumName); |
|
463 | PyObject* className = PyString_FromString(enumName); | |
464 |
|
464 | |||
465 | PyObject* baseClasses = PyTuple_New(1); |
|
465 | PyObject* baseClasses = PyTuple_New(1); | |
466 | PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type); |
|
466 | PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type); | |
467 |
|
467 | |||
468 | PyObject* module = PyObject_GetAttrString(parentObject, "__module__"); |
|
468 | PyObject* module = PyObject_GetAttrString(parentObject, "__module__"); | |
469 | PyObject* typeDict = PyDict_New(); |
|
469 | PyObject* typeDict = PyDict_New(); | |
470 | PyDict_SetItemString(typeDict, "__module__", module); |
|
470 | PyDict_SetItemString(typeDict, "__module__", module); | |
471 |
|
471 | |||
472 | PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict); |
|
472 | PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict); | |
473 |
|
473 | |||
474 | // create the new int derived type object by calling the core type |
|
474 | // create the new int derived type object by calling the core type | |
475 | result = PyObject_Call((PyObject *)&PyType_Type, args, NULL); |
|
475 | result = PyObject_Call((PyObject *)&PyType_Type, args, NULL); | |
476 |
|
476 | |||
@@ -478,7 +478,7 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py | |||||
478 | Py_DECREF(typeDict); |
|
478 | Py_DECREF(typeDict); | |
479 | Py_DECREF(args); |
|
479 | Py_DECREF(args); | |
480 | Py_DECREF(className); |
|
480 | Py_DECREF(className); | |
481 |
|
481 | |||
482 | return result; |
|
482 | return result; | |
483 | } |
|
483 | } | |
484 |
|
484 | |||
@@ -719,7 +719,7 QVariant PythonQt::getVariable(PyObject* object, const QString& objectname) | |||||
719 | QStringList PythonQt::introspection(PyObject* module, const QString& objectname, PythonQt::ObjectType type) |
|
719 | QStringList PythonQt::introspection(PyObject* module, const QString& objectname, PythonQt::ObjectType type) | |
720 | { |
|
720 | { | |
721 | QStringList results; |
|
721 | QStringList results; | |
722 |
|
722 | |||
723 | PythonQtObjectPtr object; |
|
723 | PythonQtObjectPtr object; | |
724 | if (objectname.isEmpty()) { |
|
724 | if (objectname.isEmpty()) { | |
725 | object = module; |
|
725 | object = module; | |
@@ -738,7 +738,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||||
738 | if (PythonQtSlotFunction_Check(object)) { |
|
738 | if (PythonQtSlotFunction_Check(object)) { | |
739 | PythonQtSlotFunctionObject* o = (PythonQtSlotFunctionObject*)object.object(); |
|
739 | PythonQtSlotFunctionObject* o = (PythonQtSlotFunctionObject*)object.object(); | |
740 | PythonQtSlotInfo* info = o->m_ml; |
|
740 | PythonQtSlotInfo* info = o->m_ml; | |
741 |
|
741 | |||
742 | while (info) { |
|
742 | while (info) { | |
743 | results << info->fullSignature(); |
|
743 | results << info->fullSignature(); | |
744 | info = info->nextInfo(); |
|
744 | info = info->nextInfo(); | |
@@ -746,7 +746,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||||
746 | } else if (object->ob_type == &PythonQtClassWrapper_Type) { |
|
746 | } else if (object->ob_type == &PythonQtClassWrapper_Type) { | |
747 | PythonQtClassWrapper* o = (PythonQtClassWrapper*)object.object(); |
|
747 | PythonQtClassWrapper* o = (PythonQtClassWrapper*)object.object(); | |
748 | PythonQtSlotInfo* info = o->classInfo()->constructors(); |
|
748 | PythonQtSlotInfo* info = o->classInfo()->constructors(); | |
749 |
|
749 | |||
750 | while (info) { |
|
750 | while (info) { | |
751 | results << info->fullSignature(); |
|
751 | results << info->fullSignature(); | |
752 | info = info->nextInfo(); |
|
752 | info = info->nextInfo(); | |
@@ -872,7 +872,7 PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList | |||||
872 | break; |
|
872 | break; | |
873 | } |
|
873 | } | |
874 | } |
|
874 | } | |
875 |
|
875 | |||
876 | if (!err) { |
|
876 | if (!err) { | |
877 | PyErr_Clear(); |
|
877 | PyErr_Clear(); | |
878 | result = PyObject_CallObject(callable, pargs); |
|
878 | result = PyObject_CallObject(callable, pargs); | |
@@ -903,8 +903,8 void PythonQt::registerQObjectClassNames(const QStringList& names) | |||||
903 |
|
903 | |||
904 | void PythonQt::setImporter(PythonQtImportFileInterface* importInterface) |
|
904 | void PythonQt::setImporter(PythonQtImportFileInterface* importInterface) | |
905 | { |
|
905 | { | |
906 | PythonQtImport::init(); |
|
|||
907 | _p->_importInterface = importInterface; |
|
906 | _p->_importInterface = importInterface; | |
|
907 | PythonQtImport::init(); | |||
908 | } |
|
908 | } | |
909 |
|
909 | |||
910 | void PythonQt::setImporterIgnorePaths(const QStringList& paths) |
|
910 | void PythonQt::setImporterIgnorePaths(const QStringList& paths) | |
@@ -966,7 +966,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
966 | if ((m.methodType() == QMetaMethod::Method || |
|
966 | if ((m.methodType() == QMetaMethod::Method || | |
967 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { |
|
967 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { | |
968 | if (qstrncmp(m.signature(), "new_", 4)==0) { |
|
968 | if (qstrncmp(m.signature(), "new_", 4)==0) { | |
969 |
if ((decoTypes & ConstructorDecorator) == 0) continue; |
|
969 | if ((decoTypes & ConstructorDecorator) == 0) continue; | |
970 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); |
|
970 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); | |
971 | if (info->parameters().at(0).isPointer) { |
|
971 | if (info->parameters().at(0).isPointer) { | |
972 | QByteArray signature = m.signature(); |
|
972 | QByteArray signature = m.signature(); | |
@@ -976,14 +976,14 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
976 | classInfo->addConstructor(newSlot); |
|
976 | classInfo->addConstructor(newSlot); | |
977 | } |
|
977 | } | |
978 | } else if (qstrncmp(m.signature(), "delete_", 7)==0) { |
|
978 | } else if (qstrncmp(m.signature(), "delete_", 7)==0) { | |
979 |
if ((decoTypes & DestructorDecorator) == 0) continue; |
|
979 | if ((decoTypes & DestructorDecorator) == 0) continue; | |
980 | QByteArray signature = m.signature(); |
|
980 | QByteArray signature = m.signature(); | |
981 | QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7); |
|
981 | QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7); | |
982 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); |
|
982 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); | |
983 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); |
|
983 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); | |
984 | classInfo->setDestructor(newSlot); |
|
984 | classInfo->setDestructor(newSlot); | |
985 | } else if (qstrncmp(m.signature(), "static_", 7)==0) { |
|
985 | } else if (qstrncmp(m.signature(), "static_", 7)==0) { | |
986 |
if ((decoTypes & StaticDecorator) == 0) continue; |
|
986 | if ((decoTypes & StaticDecorator) == 0) continue; | |
987 | QByteArray signature = m.signature(); |
|
987 | QByteArray signature = m.signature(); | |
988 | QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1); |
|
988 | QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1); | |
989 | nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_')); |
|
989 | nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_')); | |
@@ -991,7 +991,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
991 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); |
|
991 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); | |
992 | classInfo->addDecoratorSlot(newSlot); |
|
992 | classInfo->addDecoratorSlot(newSlot); | |
993 | } else { |
|
993 | } else { | |
994 |
if ((decoTypes & InstanceDecorator) == 0) continue; |
|
994 | if ((decoTypes & InstanceDecorator) == 0) continue; | |
995 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); |
|
995 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); | |
996 | if (info->parameters().count()>1) { |
|
996 | if (info->parameters().count()>1) { | |
997 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); |
|
997 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); | |
@@ -1022,17 +1022,17 bool PythonQt::handleError() | |||||
1022 | { |
|
1022 | { | |
1023 | bool flag = false; |
|
1023 | bool flag = false; | |
1024 | if (PyErr_Occurred()) { |
|
1024 | if (PyErr_Occurred()) { | |
1025 |
|
1025 | |||
1026 | // currently we just print the error and the stderr handler parses the errors |
|
1026 | // currently we just print the error and the stderr handler parses the errors | |
1027 | PyErr_Print(); |
|
1027 | PyErr_Print(); | |
1028 |
|
1028 | |||
1029 | /* |
|
1029 | /* | |
1030 | // EXTRA: the format of the ptype and ptraceback is not really documented, so I use PyErr_Print() above |
|
1030 | // EXTRA: the format of the ptype and ptraceback is not really documented, so I use PyErr_Print() above | |
1031 | PyObject *ptype; |
|
1031 | PyObject *ptype; | |
1032 | PyObject *pvalue; |
|
1032 | PyObject *pvalue; | |
1033 | PyObject *ptraceback; |
|
1033 | PyObject *ptraceback; | |
1034 | PyErr_Fetch( &ptype, &pvalue, &ptraceback); |
|
1034 | PyErr_Fetch( &ptype, &pvalue, &ptraceback); | |
1035 |
|
1035 | |||
1036 | Py_XDECREF(ptype); |
|
1036 | Py_XDECREF(ptype); | |
1037 | Py_XDECREF(pvalue); |
|
1037 | Py_XDECREF(pvalue); | |
1038 | Py_XDECREF(ptraceback); |
|
1038 | Py_XDECREF(ptraceback); | |
@@ -1048,7 +1048,7 void PythonQt::addSysPath(const QString& path) | |||||
1048 | PythonQtObjectPtr sys; |
|
1048 | PythonQtObjectPtr sys; | |
1049 | sys.setNewRef(PyImport_ImportModule("sys")); |
|
1049 | sys.setNewRef(PyImport_ImportModule("sys")); | |
1050 | PythonQtObjectPtr obj = lookupObject(sys, "path"); |
|
1050 | PythonQtObjectPtr obj = lookupObject(sys, "path"); | |
1051 |
PyList_Insert(obj, 0, PythonQtConv::QStringToPyObject(path)); |
|
1051 | PyList_Insert(obj, 0, PythonQtConv::QStringToPyObject(path)); | |
1052 | } |
|
1052 | } | |
1053 |
|
1053 | |||
1054 | void PythonQt::overwriteSysPath(const QStringList& paths) |
|
1054 | void PythonQt::overwriteSysPath(const QStringList& paths) | |
@@ -1092,7 +1092,7 static PyMethodDef PythonQtMethods[] = { | |||||
1092 | void PythonQt::initPythonQtModule(bool redirectStdOut) |
|
1092 | void PythonQt::initPythonQtModule(bool redirectStdOut) | |
1093 | { |
|
1093 | { | |
1094 | _p->_pythonQtModule = Py_InitModule("PythonQt", PythonQtMethods); |
|
1094 | _p->_pythonQtModule = Py_InitModule("PythonQt", PythonQtMethods); | |
1095 |
|
1095 | |||
1096 | if (redirectStdOut) { |
|
1096 | if (redirectStdOut) { | |
1097 | PythonQtObjectPtr sys; |
|
1097 | PythonQtObjectPtr sys; | |
1098 | PythonQtObjectPtr out; |
|
1098 | PythonQtObjectPtr out; | |
@@ -1196,7 +1196,7 void PythonQtPrivate::handleVirtualOverloadReturnError(const char* signature, co | |||||
1196 | } |
|
1196 | } | |
1197 |
|
1197 | |||
1198 | PyObject* PythonQt::helpCalled(PythonQtClassInfo* info) |
|
1198 | PyObject* PythonQt::helpCalled(PythonQtClassInfo* info) | |
1199 |
{ |
|
1199 | { | |
1200 | if (_p->_initFlags & ExternalHelp) { |
|
1200 | if (_p->_initFlags & ExternalHelp) { | |
1201 | emit pythonHelpRequest(QByteArray(info->className())); |
|
1201 | emit pythonHelpRequest(QByteArray(info->className())); | |
1202 | return Py_BuildValue(""); |
|
1202 | return Py_BuildValue(""); |
General Comments 0
You need to be logged in to leave comments.
Login now