@@ -47,6 +47,7 | |||
|
47 | 47 | #include "PythonQtImporter.h" |
|
48 | 48 | #include "PythonQtImportFileInterface.h" |
|
49 | 49 | #include "PythonQt.h" |
|
50 | #include "PythonQtConversion.h" | |
|
50 | 51 | #include <QFile> |
|
51 | 52 | #include <QFileInfo> |
|
52 | 53 | |
@@ -87,8 +88,9 QString PythonQtImport::getSubName(const QString& str) | |||
|
87 | 88 | } |
|
88 | 89 | } |
|
89 | 90 | |
|
90 |
PythonQtImport:: |
|
|
91 | PythonQtImport::ModuleInfo PythonQtImport::getModuleInfo(PythonQtImporter* self, const QString& fullname) | |
|
91 | 92 | { |
|
93 | ModuleInfo info; | |
|
92 | 94 | QString subname; |
|
93 | 95 | struct st_mlab_searchorder *zso; |
|
94 | 96 | |
@@ -99,16 +101,22 PythonQtImport::module_info PythonQtImport::getModuleInfo(PythonQtImporter* self | |||
|
99 | 101 | for (zso = mlab_searchorder; *zso->suffix; zso++) { |
|
100 | 102 | test = path + zso->suffix; |
|
101 | 103 | if (PythonQt::importInterface()->exists(test)) { |
|
102 | if (zso->type & IS_PACKAGE) | |
|
103 | return MI_PACKAGE; | |
|
104 | else | |
|
105 |
|
|
|
104 | info.fullPath = test; | |
|
105 | info.moduleName = subname; | |
|
106 | info.type = (zso->type & IS_PACKAGE)?MI_PACKAGE:MI_MODULE; | |
|
107 | return info; | |
|
106 | 108 | } |
|
107 | 109 | } |
|
108 | if (PythonQt::importInterface()->exists(path+".so")) { | |
|
109 | return MI_SHAREDLIBRARY; | |
|
110 | // test if it is a shared library | |
|
111 | foreach(const QString& suffix, PythonQt::priv()->sharedLibrarySuffixes()) { | |
|
112 | test = path+suffix; | |
|
113 | if (PythonQt::importInterface()->exists(test)) { | |
|
114 | info.fullPath = test; | |
|
115 | info.moduleName = subname; | |
|
116 | info.type = MI_SHAREDLIBRARY; | |
|
117 | } | |
|
110 | 118 | } |
|
111 | return MI_NOT_FOUND; | |
|
119 | return info; | |
|
112 | 120 | } |
|
113 | 121 | |
|
114 | 122 | |
@@ -167,13 +175,10 PythonQtImporter_find_module(PyObject *obj, PyObject *args) | |||
|
167 | 175 | &fullname, &path)) |
|
168 | 176 | return NULL; |
|
169 | 177 | |
|
170 | qDebug() << "looking for " << fullname << " at " << *self->_path; | |
|
178 | //qDebug() << "looking for " << fullname << " at " << *self->_path; | |
|
171 | 179 | |
|
172 | // mlabDebugConst("MLABPython", "FindModule " << fullname << " in " << *self->_path); | |
|
173 | ||
|
174 | PythonQtImport::module_info info = PythonQtImport::getModuleInfo(self, fullname); | |
|
175 | if (info == PythonQtImport::MI_MODULE || info == PythonQtImport::MI_PACKAGE || | |
|
176 | info== PythonQtImport::MI_SHAREDLIBRARY) { | |
|
180 | PythonQtImport::ModuleInfo info = PythonQtImport::getModuleInfo(self, fullname); | |
|
181 | if (info.type != PythonQtImport::MI_NOT_FOUND) { | |
|
177 | 182 | Py_INCREF(self); |
|
178 | 183 | return (PyObject *)self; |
|
179 | 184 | } else { |
@@ -187,16 +192,21 PyObject * | |||
|
187 | 192 | PythonQtImporter_load_module(PyObject *obj, PyObject *args) |
|
188 | 193 | { |
|
189 | 194 | PythonQtImporter *self = (PythonQtImporter *)obj; |
|
190 | PyObject *code, *mod, *dict; | |
|
195 | PyObject *code = NULL, *mod = NULL, *dict = NULL; | |
|
191 | 196 | char *fullname; |
|
192 | QString modpath; | |
|
193 | int ispackage; | |
|
194 | 197 | |
|
195 | 198 | if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", |
|
196 | 199 | &fullname)) |
|
197 | 200 | return NULL; |
|
198 | 201 | |
|
199 |
|
|
|
202 | PythonQtImport::ModuleInfo info = PythonQtImport::getModuleInfo(self, fullname); | |
|
203 | if (info.type == PythonQtImport::MI_NOT_FOUND) { | |
|
204 | return NULL; | |
|
205 | } | |
|
206 | ||
|
207 | if (info.type == PythonQtImport::MI_PACKAGE || info.type == PythonQtImport::MI_MODULE) { | |
|
208 | QString fullPath; | |
|
209 | code = PythonQtImport::getModuleCode(self, fullname, fullPath); | |
|
200 | 210 | if (code == NULL) { |
|
201 | 211 | return NULL; |
|
202 | 212 | } |
@@ -214,9 +224,9 PythonQtImporter_load_module(PyObject *obj, PyObject *args) | |||
|
214 | 224 | return NULL; |
|
215 | 225 | } |
|
216 | 226 | |
|
217 | if (ispackage) { | |
|
227 | if (info.type == PythonQtImport::MI_PACKAGE) { | |
|
218 | 228 | PyObject *pkgpath, *fullpath; |
|
219 |
QString subname = |
|
|
229 | QString subname = info.moduleName; | |
|
220 | 230 | int err; |
|
221 | 231 | |
|
222 | 232 | fullpath = PyString_FromFormat("%s%c%s", |
@@ -244,11 +254,45 PythonQtImporter_load_module(PyObject *obj, PyObject *args) | |||
|
244 | 254 | return NULL; |
|
245 | 255 | } |
|
246 | 256 | } |
|
247 |
mod = PyImport_ExecCodeModuleEx(fullname, code, |
|
|
257 | mod = PyImport_ExecCodeModuleEx(fullname, code, fullPath.toLatin1().data()); | |
|
248 | 258 | Py_DECREF(code); |
|
249 | 259 | if (Py_VerboseFlag) { |
|
250 | 260 | PySys_WriteStderr("import %s # loaded from %s\n", |
|
251 |
|
|
|
261 | fullname, fullPath.toLatin1().constData()); | |
|
262 | } | |
|
263 | } else { | |
|
264 | PythonQtObjectPtr imp; | |
|
265 | imp.setNewRef(PyImport_ImportModule("imp")); | |
|
266 | ||
|
267 | // Create a PyList with the current path as its single element, | |
|
268 | // which is required for find_module (it won't accept a tuple...) | |
|
269 | PythonQtObjectPtr pathList; | |
|
270 | pathList.setNewRef(PythonQtConv::QStringListToPyList(QStringList() << *self->_path)); | |
|
271 | ||
|
272 | QVariantList args; | |
|
273 | // Pass the module name without the package prefix | |
|
274 | args.append(info.moduleName); | |
|
275 | // And the path where we know that the shared library is | |
|
276 | args.append(QVariant::fromValue(pathList)); | |
|
277 | QVariant result = imp.call("find_module", args); | |
|
278 | if (result.isValid()) { | |
|
279 | // This will return a tuple with (file, pathname, description) | |
|
280 | QVariantList list = result.toList(); | |
|
281 | if (list.count()==3) { | |
|
282 | // We prepend the full module name (including package prefix) | |
|
283 | list.prepend(fullname); | |
|
284 | // And call "load_module" with (fullname, file, pathname, description) | |
|
285 | PythonQtObjectPtr module = imp.call("load_module", list); | |
|
286 | mod = module.object(); | |
|
287 | if (mod) { | |
|
288 | Py_INCREF(mod); | |
|
289 | } | |
|
290 | ||
|
291 | // Finally, we need to close the file again, which find_module opened for us | |
|
292 | PythonQtObjectPtr file = list.at(1); | |
|
293 | file.call("close"); | |
|
294 | } | |
|
295 | } | |
|
252 | 296 | } |
|
253 | 297 | return mod; |
|
254 | 298 | } |
@@ -271,51 +315,13 PythonQtImporter_get_code(PyObject *obj, PyObject *args) | |||
|
271 | 315 | return NULL; |
|
272 | 316 | |
|
273 | 317 | QString notused; |
|
274 |
return PythonQtImport::getModuleCode(self, fullname, |
|
|
318 | return PythonQtImport::getModuleCode(self, fullname, notused); | |
|
275 | 319 | } |
|
276 | 320 | |
|
277 | 321 | PyObject * |
|
278 | 322 | PythonQtImporter_get_source(PyObject * /*obj*/, PyObject * /*args*/) |
|
279 | 323 | { |
|
280 | 324 | // EXTRA, NOT YET IMPLEMENTED |
|
281 | /* | |
|
282 | PythonQtImporter *self = (PythonQtImporter *)obj; | |
|
283 | PyObject *toc_entry; | |
|
284 | char *fullname, *subname, path[MAXPATHLEN+1]; | |
|
285 | int len; | |
|
286 | enum module_info mi; | |
|
287 | ||
|
288 | if (!PyArg_ParseTuple(args, "s:PythonQtImporter.get_source", &fullname)) | |
|
289 | return NULL; | |
|
290 | ||
|
291 | mi = get_module_info(self, fullname); | |
|
292 | if (mi == MI_ERROR) | |
|
293 | return NULL; | |
|
294 | if (mi == MI_NOT_FOUND) { | |
|
295 | PyErr_Format(PythonQtImportError, "can't find module '%.200s'", | |
|
296 | fullname); | |
|
297 | return NULL; | |
|
298 | } | |
|
299 | subname = get_subname(fullname); | |
|
300 | ||
|
301 | len = make_filename(PyString_AsString(self->prefix), subname, path); | |
|
302 | if (len < 0) | |
|
303 | return NULL; | |
|
304 | ||
|
305 | if (mi == MI_PACKAGE) { | |
|
306 | path[len] = SEP; | |
|
307 | strcpy(path + len + 1, "__init__.py"); | |
|
308 | } | |
|
309 | else | |
|
310 | strcpy(path + len, ".py"); | |
|
311 | ||
|
312 | toc_entry = PyDict_GetItemString(self->files, path); | |
|
313 | if (toc_entry != NULL) | |
|
314 | return get_data(PyString_AsString(self->archive), toc_entry); | |
|
315 | ||
|
316 | Py_INCREF(Py_None); | |
|
317 | return Py_None; | |
|
318 | */ | |
|
319 | 325 | return NULL; |
|
320 | 326 | } |
|
321 | 327 | |
@@ -648,8 +654,7 PythonQtImport::getMTimeOfSource(const QString& path) | |||
|
648 | 654 | /* Get the code object associated with the module specified by |
|
649 | 655 | 'fullname'. */ |
|
650 | 656 | PyObject * |
|
651 |
PythonQtImport::getModuleCode(PythonQtImporter *self, char |
|
|
652 | int *p_ispackage, QString& modpath) | |
|
657 | PythonQtImport::getModuleCode(PythonQtImporter *self, const char* fullname, QString& modpath) | |
|
653 | 658 | { |
|
654 | 659 | QString subname; |
|
655 | 660 | struct st_mlab_searchorder *zso; |
@@ -670,17 +675,17 PythonQtImport::getModuleCode(PythonQtImporter *self, char *fullname, | |||
|
670 | 675 | int ispackage = zso->type & IS_PACKAGE; |
|
671 | 676 | int isbytecode = zso->type & IS_BYTECODE; |
|
672 | 677 | |
|
673 | if (isbytecode) | |
|
678 | if (isbytecode) { | |
|
674 | 679 | mtime = getMTimeOfSource(test); |
|
675 | if (p_ispackage != NULL) | |
|
676 | *p_ispackage = ispackage; | |
|
680 | } | |
|
677 | 681 | code = getCodeFromData(test, isbytecode, ispackage, mtime); |
|
678 | 682 | if (code == Py_None) { |
|
679 | 683 | Py_DECREF(code); |
|
680 | 684 | continue; |
|
681 | 685 | } |
|
682 | if (code != NULL) | |
|
686 | if (code != NULL) { | |
|
683 | 687 | modpath = test; |
|
688 | } | |
|
684 | 689 | return code; |
|
685 | 690 | } |
|
686 | 691 | } |
@@ -66,14 +66,23 typedef struct _PythonQtImporter { | |||
|
66 | 66 | class PythonQtImport |
|
67 | 67 | { |
|
68 | 68 | public: |
|
69 | enum module_info { | |
|
70 | MI_ERROR, | |
|
69 | ||
|
70 | enum ModuleType { | |
|
71 | 71 |
|
|
72 | 72 |
|
|
73 | 73 |
|
|
74 | 74 |
|
|
75 | 75 | }; |
|
76 | 76 | |
|
77 | struct ModuleInfo { | |
|
78 | ModuleInfo() { | |
|
79 | type = MI_NOT_FOUND; | |
|
80 | } | |
|
81 | QString fullPath; //!< the full path to the found file | |
|
82 | QString moduleName; //!< the module name without the package prefix | |
|
83 | ModuleType type; | |
|
84 | }; | |
|
85 | ||
|
77 | 86 | //! initialize |
|
78 | 87 | static void init(); |
|
79 | 88 | |
@@ -98,15 +107,15 public: | |||
|
98 | 107 | |
|
99 | 108 | //! Get the code object associated with the module specified by |
|
100 | 109 | //! 'fullname'. |
|
101 |
static PyObject * getModuleCode(PythonQtImporter *self, |
|
|
102 |
|
|
|
110 | static PyObject * getModuleCode(PythonQtImporter *self, | |
|
111 | const char* fullname, QString& modpath); | |
|
103 | 112 | |
|
104 | 113 | |
|
105 | 114 | //! gets the compiled code for the given *.py file if there is a valid pyc file, otherwise compiles the file and writes the pyc |
|
106 | 115 | static PyObject* getCodeFromPyc(const QString& file); |
|
107 | 116 | |
|
108 | 117 | //! Return if module exists and is a package or a module |
|
109 |
static |
|
|
118 | static ModuleInfo getModuleInfo(PythonQtImporter* self, const QString& fullname); | |
|
110 | 119 | |
|
111 | 120 | //! get the last name of a dot chain (first.second.last) |
|
112 | 121 | static QString getSubName(const QString& str); |
General Comments 0
You need to be logged in to leave comments.
Login now