@@ -47,6 +47,7 | |||||
47 | #include "PythonQtImporter.h" |
|
47 | #include "PythonQtImporter.h" | |
48 | #include "PythonQtImportFileInterface.h" |
|
48 | #include "PythonQtImportFileInterface.h" | |
49 | #include "PythonQt.h" |
|
49 | #include "PythonQt.h" | |
|
50 | #include "PythonQtConversion.h" | |||
50 | #include <QFile> |
|
51 | #include <QFile> | |
51 | #include <QFileInfo> |
|
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 | QString subname; |
|
94 | QString subname; | |
93 | struct st_mlab_searchorder *zso; |
|
95 | struct st_mlab_searchorder *zso; | |
94 |
|
96 | |||
@@ -99,16 +101,22 PythonQtImport::module_info PythonQtImport::getModuleInfo(PythonQtImporter* self | |||||
99 | for (zso = mlab_searchorder; *zso->suffix; zso++) { |
|
101 | for (zso = mlab_searchorder; *zso->suffix; zso++) { | |
100 | test = path + zso->suffix; |
|
102 | test = path + zso->suffix; | |
101 | if (PythonQt::importInterface()->exists(test)) { |
|
103 | if (PythonQt::importInterface()->exists(test)) { | |
102 | if (zso->type & IS_PACKAGE) |
|
104 | info.fullPath = test; | |
103 | return MI_PACKAGE; |
|
105 | info.moduleName = subname; | |
104 | else |
|
106 | info.type = (zso->type & IS_PACKAGE)?MI_PACKAGE:MI_MODULE; | |
105 |
|
|
107 | return info; | |
106 | } |
|
108 | } | |
107 | } |
|
109 | } | |
108 | if (PythonQt::importInterface()->exists(path+".so")) { |
|
110 | // test if it is a shared library | |
109 | return MI_SHAREDLIBRARY; |
|
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 | &fullname, &path)) |
|
175 | &fullname, &path)) | |
168 | return NULL; |
|
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); |
|
180 | PythonQtImport::ModuleInfo info = PythonQtImport::getModuleInfo(self, fullname); | |
173 |
|
181 | if (info.type != PythonQtImport::MI_NOT_FOUND) { | ||
174 | PythonQtImport::module_info info = PythonQtImport::getModuleInfo(self, fullname); |
|
|||
175 | if (info == PythonQtImport::MI_MODULE || info == PythonQtImport::MI_PACKAGE || |
|
|||
176 | info== PythonQtImport::MI_SHAREDLIBRARY) { |
|
|||
177 | Py_INCREF(self); |
|
182 | Py_INCREF(self); | |
178 | return (PyObject *)self; |
|
183 | return (PyObject *)self; | |
179 | } else { |
|
184 | } else { | |
@@ -187,16 +192,21 PyObject * | |||||
187 | PythonQtImporter_load_module(PyObject *obj, PyObject *args) |
|
192 | PythonQtImporter_load_module(PyObject *obj, PyObject *args) | |
188 | { |
|
193 | { | |
189 | PythonQtImporter *self = (PythonQtImporter *)obj; |
|
194 | PythonQtImporter *self = (PythonQtImporter *)obj; | |
190 | PyObject *code, *mod, *dict; |
|
195 | PyObject *code = NULL, *mod = NULL, *dict = NULL; | |
191 | char *fullname; |
|
196 | char *fullname; | |
192 | QString modpath; |
|
|||
193 | int ispackage; |
|
|||
194 |
|
197 | |||
195 | if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", |
|
198 | if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", | |
196 | &fullname)) |
|
199 | &fullname)) | |
197 | return NULL; |
|
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 | if (code == NULL) { |
|
210 | if (code == NULL) { | |
201 | return NULL; |
|
211 | return NULL; | |
202 | } |
|
212 | } | |
@@ -214,9 +224,9 PythonQtImporter_load_module(PyObject *obj, PyObject *args) | |||||
214 | return NULL; |
|
224 | return NULL; | |
215 | } |
|
225 | } | |
216 |
|
226 | |||
217 | if (ispackage) { |
|
227 | if (info.type == PythonQtImport::MI_PACKAGE) { | |
218 | PyObject *pkgpath, *fullpath; |
|
228 | PyObject *pkgpath, *fullpath; | |
219 |
QString subname = |
|
229 | QString subname = info.moduleName; | |
220 | int err; |
|
230 | int err; | |
221 |
|
231 | |||
222 | fullpath = PyString_FromFormat("%s%c%s", |
|
232 | fullpath = PyString_FromFormat("%s%c%s", | |
@@ -244,11 +254,45 PythonQtImporter_load_module(PyObject *obj, PyObject *args) | |||||
244 | return NULL; |
|
254 | return NULL; | |
245 | } |
|
255 | } | |
246 | } |
|
256 | } | |
247 |
mod = PyImport_ExecCodeModuleEx(fullname, code, |
|
257 | mod = PyImport_ExecCodeModuleEx(fullname, code, fullPath.toLatin1().data()); | |
248 | Py_DECREF(code); |
|
258 | Py_DECREF(code); | |
249 | if (Py_VerboseFlag) { |
|
259 | if (Py_VerboseFlag) { | |
250 | PySys_WriteStderr("import %s # loaded from %s\n", |
|
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 | return mod; |
|
297 | return mod; | |
254 | } |
|
298 | } | |
@@ -271,51 +315,13 PythonQtImporter_get_code(PyObject *obj, PyObject *args) | |||||
271 | return NULL; |
|
315 | return NULL; | |
272 |
|
316 | |||
273 | QString notused; |
|
317 | QString notused; | |
274 |
return PythonQtImport::getModuleCode(self, fullname, |
|
318 | return PythonQtImport::getModuleCode(self, fullname, notused); | |
275 | } |
|
319 | } | |
276 |
|
320 | |||
277 | PyObject * |
|
321 | PyObject * | |
278 | PythonQtImporter_get_source(PyObject * /*obj*/, PyObject * /*args*/) |
|
322 | PythonQtImporter_get_source(PyObject * /*obj*/, PyObject * /*args*/) | |
279 | { |
|
323 | { | |
280 | // EXTRA, NOT YET IMPLEMENTED |
|
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 | return NULL; |
|
325 | return NULL; | |
320 | } |
|
326 | } | |
321 |
|
327 | |||
@@ -648,8 +654,7 PythonQtImport::getMTimeOfSource(const QString& path) | |||||
648 | /* Get the code object associated with the module specified by |
|
654 | /* Get the code object associated with the module specified by | |
649 | 'fullname'. */ |
|
655 | 'fullname'. */ | |
650 | PyObject * |
|
656 | PyObject * | |
651 |
PythonQtImport::getModuleCode(PythonQtImporter *self, char |
|
657 | PythonQtImport::getModuleCode(PythonQtImporter *self, const char* fullname, QString& modpath) | |
652 | int *p_ispackage, QString& modpath) |
|
|||
653 | { |
|
658 | { | |
654 | QString subname; |
|
659 | QString subname; | |
655 | struct st_mlab_searchorder *zso; |
|
660 | struct st_mlab_searchorder *zso; | |
@@ -670,17 +675,17 PythonQtImport::getModuleCode(PythonQtImporter *self, char *fullname, | |||||
670 | int ispackage = zso->type & IS_PACKAGE; |
|
675 | int ispackage = zso->type & IS_PACKAGE; | |
671 | int isbytecode = zso->type & IS_BYTECODE; |
|
676 | int isbytecode = zso->type & IS_BYTECODE; | |
672 |
|
677 | |||
673 | if (isbytecode) |
|
678 | if (isbytecode) { | |
674 | mtime = getMTimeOfSource(test); |
|
679 | mtime = getMTimeOfSource(test); | |
675 | if (p_ispackage != NULL) |
|
680 | } | |
676 | *p_ispackage = ispackage; |
|
|||
677 | code = getCodeFromData(test, isbytecode, ispackage, mtime); |
|
681 | code = getCodeFromData(test, isbytecode, ispackage, mtime); | |
678 | if (code == Py_None) { |
|
682 | if (code == Py_None) { | |
679 | Py_DECREF(code); |
|
683 | Py_DECREF(code); | |
680 | continue; |
|
684 | continue; | |
681 | } |
|
685 | } | |
682 | if (code != NULL) |
|
686 | if (code != NULL) { | |
683 | modpath = test; |
|
687 | modpath = test; | |
|
688 | } | |||
684 | return code; |
|
689 | return code; | |
685 | } |
|
690 | } | |
686 | } |
|
691 | } |
@@ -66,14 +66,23 typedef struct _PythonQtImporter { | |||||
66 | class PythonQtImport |
|
66 | class PythonQtImport | |
67 | { |
|
67 | { | |
68 | public: |
|
68 | public: | |
69 | enum module_info { |
|
69 | ||
70 | MI_ERROR, |
|
70 | enum ModuleType { | |
71 |
|
|
71 | MI_NOT_FOUND, | |
72 |
|
|
72 | MI_MODULE, | |
73 |
|
|
73 | MI_PACKAGE, | |
74 |
|
|
74 | MI_SHAREDLIBRARY | |
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 | //! initialize |
|
86 | //! initialize | |
78 | static void init(); |
|
87 | static void init(); | |
79 |
|
88 | |||
@@ -98,15 +107,15 public: | |||||
98 |
|
107 | |||
99 | //! Get the code object associated with the module specified by |
|
108 | //! Get the code object associated with the module specified by | |
100 | //! 'fullname'. |
|
109 | //! 'fullname'. | |
101 |
static PyObject * getModuleCode(PythonQtImporter *self, |
|
110 | static PyObject * getModuleCode(PythonQtImporter *self, | |
102 |
|
|
111 | const char* fullname, QString& modpath); | |
103 |
|
112 | |||
104 |
|
113 | |||
105 | //! gets the compiled code for the given *.py file if there is a valid pyc file, otherwise compiles the file and writes the pyc |
|
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 | static PyObject* getCodeFromPyc(const QString& file); |
|
115 | static PyObject* getCodeFromPyc(const QString& file); | |
107 |
|
116 | |||
108 | //! Return if module exists and is a package or a module |
|
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 | //! get the last name of a dot chain (first.second.last) |
|
120 | //! get the last name of a dot chain (first.second.last) | |
112 | static QString getSubName(const QString& str); |
|
121 | static QString getSubName(const QString& str); |
General Comments 0
You need to be logged in to leave comments.
Login now