blob: 023d1d4efb2a0ad2752ed45a5ef64dac23a45864 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00005#include <time.h>
6
7
8#define IS_SOURCE 0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE 0x2
11
12struct st_zip_searchorder {
13 char suffix[14];
14 int type;
15};
16
17/* zip_searchorder defines how we search for a module in the Zip
18 archive: we first search for a package __init__, then for
19 non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
20 are swapped by initzipimport() if we run in optimized mode. Also,
21 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000022static struct st_zip_searchorder zip_searchorder[] = {
Just van Rossum52e14d62002-12-30 22:08:05 +000023 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
24 {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
25 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
26 {".pyc", IS_BYTECODE},
27 {".pyo", IS_BYTECODE},
28 {".py", IS_SOURCE},
29 {"", 0}
30};
31
32/* zipimporter object definition and support */
33
34typedef struct _zipimporter ZipImporter;
35
36struct _zipimporter {
37 PyObject_HEAD
38 PyObject *archive; /* pathname of the Zip archive */
39 PyObject *prefix; /* file prefix: "a/sub/directory/" */
40 PyObject *files; /* dict with file info {path: toc_entry} */
41};
42
Just van Rossum52e14d62002-12-30 22:08:05 +000043static PyObject *ZipImportError;
44static PyObject *zip_directory_cache = NULL;
45
46/* forward decls */
47static PyObject *read_directory(char *archive);
48static PyObject *get_data(char *archive, PyObject *toc_entry);
49static PyObject *get_module_code(ZipImporter *self, char *fullname,
50 int *p_ispackage, char **p_modpath);
51
52
53#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
54
55
56/* zipimporter.__init__
57 Split the "subdirectory" from the Zip archive path, lookup a matching
58 entry in sys.path_importer_cache, fetch the file directory from there
59 if found, or else read it from the archive. */
60static int
61zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
62{
63 char *path, *p, *prefix, buf[MAXPATHLEN+2];
Alexandre Vassalottiec924c92008-05-07 02:48:42 +000064 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000065
Georg Brandl02c42872005-08-26 06:42:30 +000066 if (!_PyArg_NoKeywords("zipimporter()", kwds))
67 return -1;
68
Alexandre Vassalottiec924c92008-05-07 02:48:42 +000069 if (!PyArg_ParseTuple(args, "s:zipimporter", &path))
Just van Rossum52e14d62002-12-30 22:08:05 +000070 return -1;
71
Alexandre Vassalottiec924c92008-05-07 02:48:42 +000072 len = strlen(path);
Just van Rossum52e14d62002-12-30 22:08:05 +000073 if (len == 0) {
74 PyErr_SetString(ZipImportError, "archive path is empty");
75 return -1;
76 }
77 if (len >= MAXPATHLEN) {
78 PyErr_SetString(ZipImportError,
79 "archive path too long");
80 return -1;
81 }
82 strcpy(buf, path);
83
84#ifdef ALTSEP
85 for (p = buf; *p; p++) {
86 if (*p == ALTSEP)
87 *p = SEP;
88 }
89#endif
90
91 path = NULL;
92 prefix = NULL;
93 for (;;) {
94 struct stat statbuf;
95 int rv;
96
97 rv = stat(buf, &statbuf);
98 if (rv == 0) {
99 /* it exists */
100 if (S_ISREG(statbuf.st_mode))
101 /* it's a file */
102 path = buf;
103 break;
104 }
105 /* back up one path element */
Just van Rossumd35c6db2003-01-02 12:55:48 +0000106 p = strrchr(buf, SEP);
Just van Rossum52e14d62002-12-30 22:08:05 +0000107 if (prefix != NULL)
108 *prefix = SEP;
109 if (p == NULL)
110 break;
111 *p = '\0';
112 prefix = p;
113 }
114 if (path != NULL) {
115 PyObject *files;
116 files = PyDict_GetItemString(zip_directory_cache, path);
117 if (files == NULL) {
118 files = read_directory(buf);
119 if (files == NULL)
120 return -1;
121 if (PyDict_SetItemString(zip_directory_cache, path,
122 files) != 0)
123 return -1;
124 }
125 else
126 Py_INCREF(files);
127 self->files = files;
128 }
129 else {
130 PyErr_SetString(ZipImportError, "not a Zip file");
131 return -1;
132 }
133
134 if (prefix == NULL)
135 prefix = "";
136 else {
137 prefix++;
138 len = strlen(prefix);
139 if (prefix[len-1] != SEP) {
140 /* add trailing SEP */
141 prefix[len] = SEP;
142 prefix[len + 1] = '\0';
143 }
144 }
145
Neal Norwitz3c814d22007-08-26 05:08:21 +0000146 self->archive = PyUnicode_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000147 if (self->archive == NULL)
148 return -1;
149
Neal Norwitz3c814d22007-08-26 05:08:21 +0000150 self->prefix = PyUnicode_FromString(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000151 if (self->prefix == NULL)
152 return -1;
153
154 return 0;
155}
156
157/* GC support. */
158static int
159zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
160{
161 ZipImporter *self = (ZipImporter *)obj;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162 Py_VISIT(self->files);
Just van Rossum52e14d62002-12-30 22:08:05 +0000163 return 0;
164}
165
166static void
167zipimporter_dealloc(ZipImporter *self)
168{
169 PyObject_GC_UnTrack(self);
170 Py_XDECREF(self->archive);
Just van Rossumf8b6de12002-12-31 09:51:59 +0000171 Py_XDECREF(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000172 Py_XDECREF(self->files);
Christian Heimes90aa7642007-12-19 02:45:37 +0000173 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000174}
175
176static PyObject *
177zipimporter_repr(ZipImporter *self)
178{
Just van Rossum52e14d62002-12-30 22:08:05 +0000179 char *archive = "???";
180 char *prefix = "";
181
Neal Norwitz3c814d22007-08-26 05:08:21 +0000182 if (self->archive != NULL && PyUnicode_Check(self->archive))
183 archive = PyUnicode_AsString(self->archive);
184 if (self->prefix != NULL && PyUnicode_Check(self->prefix))
185 prefix = PyUnicode_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000186 if (prefix != NULL && *prefix)
Walter Dörwald5b0443c2007-06-05 16:19:33 +0000187 return PyUnicode_FromFormat("<zipimporter object \"%.300s%c%.150s\">",
188 archive, SEP, prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000189 else
Walter Dörwald5b0443c2007-06-05 16:19:33 +0000190 return PyUnicode_FromFormat("<zipimporter object \"%.300s\">",
191 archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000192}
193
194/* return fullname.split(".")[-1] */
195static char *
196get_subname(char *fullname)
197{
198 char *subname = strrchr(fullname, '.');
199 if (subname == NULL)
200 subname = fullname;
201 else
202 subname++;
203 return subname;
204}
205
206/* Given a (sub)modulename, write the potential file path in the
207 archive (without extension) to the path buffer. Return the
208 length of the resulting string. */
209static int
210make_filename(char *prefix, char *name, char *path)
211{
Neal Norwitzd39d8612006-01-08 01:03:36 +0000212 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000213 char *p;
214
215 len = strlen(prefix);
216
217 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
218 if (len + strlen(name) + 13 >= MAXPATHLEN) {
219 PyErr_SetString(ZipImportError, "path too long");
220 return -1;
221 }
222
223 strcpy(path, prefix);
224 strcpy(path + len, name);
225 for (p = path + len; *p; p++) {
226 if (*p == '.')
227 *p = SEP;
228 }
229 len += strlen(name);
Martin v. Löwis18e16552006-02-15 17:27:45 +0000230 assert(len < INT_MAX);
Neal Norwitzd39d8612006-01-08 01:03:36 +0000231 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000232}
233
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000234enum zi_module_info {
Just van Rossum52e14d62002-12-30 22:08:05 +0000235 MI_ERROR,
236 MI_NOT_FOUND,
237 MI_MODULE,
238 MI_PACKAGE
239};
240
241/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000242static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000243get_module_info(ZipImporter *self, char *fullname)
244{
245 char *subname, path[MAXPATHLEN + 1];
246 int len;
247 struct st_zip_searchorder *zso;
248
249 subname = get_subname(fullname);
250
Neal Norwitz3c814d22007-08-26 05:08:21 +0000251 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000252 if (len < 0)
253 return MI_ERROR;
254
255 for (zso = zip_searchorder; *zso->suffix; zso++) {
256 strcpy(path + len, zso->suffix);
257 if (PyDict_GetItemString(self->files, path) != NULL) {
258 if (zso->type & IS_PACKAGE)
259 return MI_PACKAGE;
260 else
261 return MI_MODULE;
262 }
263 }
264 return MI_NOT_FOUND;
265}
266
267/* Check whether we can satisfy the import of the module named by
268 'fullname'. Return self if we can, None if we can't. */
269static PyObject *
270zipimporter_find_module(PyObject *obj, PyObject *args)
271{
272 ZipImporter *self = (ZipImporter *)obj;
273 PyObject *path = NULL;
274 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000275 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000276
277 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
278 &fullname, &path))
279 return NULL;
280
281 mi = get_module_info(self, fullname);
282 if (mi == MI_ERROR)
283 return NULL;
284 if (mi == MI_NOT_FOUND) {
285 Py_INCREF(Py_None);
286 return Py_None;
287 }
288 Py_INCREF(self);
289 return (PyObject *)self;
290}
291
292/* Load and return the module named by 'fullname'. */
293static PyObject *
294zipimporter_load_module(PyObject *obj, PyObject *args)
295{
296 ZipImporter *self = (ZipImporter *)obj;
297 PyObject *code, *mod, *dict;
298 char *fullname, *modpath;
299 int ispackage;
300
301 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
302 &fullname))
303 return NULL;
304
305 code = get_module_code(self, fullname, &ispackage, &modpath);
306 if (code == NULL)
307 return NULL;
308
309 mod = PyImport_AddModule(fullname);
310 if (mod == NULL) {
311 Py_DECREF(code);
312 return NULL;
313 }
314 dict = PyModule_GetDict(mod);
315
316 /* mod.__loader__ = self */
317 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
318 goto error;
319
320 if (ispackage) {
321 /* add __path__ to the module *before* the code gets
322 executed */
323 PyObject *pkgpath, *fullpath;
Neal Norwitz3c814d22007-08-26 05:08:21 +0000324 char *prefix = PyUnicode_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000325 char *subname = get_subname(fullname);
326 int err;
327
Neal Norwitz3c814d22007-08-26 05:08:21 +0000328 fullpath = PyUnicode_FromFormat("%s%c%s%s",
329 PyUnicode_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +0000330 SEP,
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000331 prefix ? prefix : "",
Just van Rossum52e14d62002-12-30 22:08:05 +0000332 subname);
333 if (fullpath == NULL)
334 goto error;
335
336 pkgpath = Py_BuildValue("[O]", fullpath);
337 Py_DECREF(fullpath);
338 if (pkgpath == NULL)
339 goto error;
340 err = PyDict_SetItemString(dict, "__path__", pkgpath);
341 Py_DECREF(pkgpath);
342 if (err != 0)
343 goto error;
344 }
345 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
346 Py_DECREF(code);
347 if (Py_VerboseFlag)
348 PySys_WriteStderr("import %s # loaded from Zip %s\n",
349 fullname, modpath);
350 return mod;
351error:
352 Py_DECREF(code);
353 Py_DECREF(mod);
354 return NULL;
355}
356
357/* Return a bool signifying whether the module is a package or not. */
358static PyObject *
359zipimporter_is_package(PyObject *obj, PyObject *args)
360{
361 ZipImporter *self = (ZipImporter *)obj;
362 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000363 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000364
Neal Norwitz5c1ba532003-02-17 18:05:20 +0000365 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
Just van Rossum52e14d62002-12-30 22:08:05 +0000366 &fullname))
367 return NULL;
368
369 mi = get_module_info(self, fullname);
370 if (mi == MI_ERROR)
371 return NULL;
372 if (mi == MI_NOT_FOUND) {
373 PyErr_Format(ZipImportError, "can't find module '%.200s'",
374 fullname);
375 return NULL;
376 }
377 return PyBool_FromLong(mi == MI_PACKAGE);
378}
379
380static PyObject *
381zipimporter_get_data(PyObject *obj, PyObject *args)
382{
383 ZipImporter *self = (ZipImporter *)obj;
384 char *path;
385#ifdef ALTSEP
Tim Peters1ea93f22002-12-30 22:42:57 +0000386 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000387#endif
388 PyObject *toc_entry;
Martin v. Löwisad0a4622006-02-16 14:30:23 +0000389 Py_ssize_t len;
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000390 char *archive_str;
Just van Rossum52e14d62002-12-30 22:08:05 +0000391
392 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
393 return NULL;
394
395#ifdef ALTSEP
396 if (strlen(path) >= MAXPATHLEN) {
397 PyErr_SetString(ZipImportError, "path too long");
398 return NULL;
399 }
400 strcpy(buf, path);
401 for (p = buf; *p; p++) {
402 if (*p == ALTSEP)
403 *p = SEP;
404 }
405 path = buf;
406#endif
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000407 archive_str = PyUnicode_AsStringAndSize(self->archive, &len);
Tim Petersf271c272002-12-30 22:44:03 +0000408 if ((size_t)len < strlen(path) &&
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000409 strncmp(path, archive_str, len) == 0 &&
Just van Rossum52e14d62002-12-30 22:08:05 +0000410 path[len] == SEP) {
411 path = path + len + 1;
412 }
413
414 toc_entry = PyDict_GetItemString(self->files, path);
415 if (toc_entry == NULL) {
Georg Brandle9b19492006-02-19 09:38:58 +0000416 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000417 return NULL;
418 }
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000419 return get_data(archive_str, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000420}
421
422static PyObject *
423zipimporter_get_code(PyObject *obj, PyObject *args)
424{
425 ZipImporter *self = (ZipImporter *)obj;
426 char *fullname;
427
428 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
429 return NULL;
430
431 return get_module_code(self, fullname, NULL, NULL);
432}
433
434static PyObject *
435zipimporter_get_source(PyObject *obj, PyObject *args)
436{
437 ZipImporter *self = (ZipImporter *)obj;
438 PyObject *toc_entry;
439 char *fullname, *subname, path[MAXPATHLEN+1];
440 int len;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000441 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000442
443 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
444 return NULL;
445
446 mi = get_module_info(self, fullname);
447 if (mi == MI_ERROR)
448 return NULL;
449 if (mi == MI_NOT_FOUND) {
450 PyErr_Format(ZipImportError, "can't find module '%.200s'",
451 fullname);
452 return NULL;
453 }
454 subname = get_subname(fullname);
455
Neal Norwitz3c814d22007-08-26 05:08:21 +0000456 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000457 if (len < 0)
458 return NULL;
459
460 if (mi == MI_PACKAGE) {
461 path[len] = SEP;
462 strcpy(path + len + 1, "__init__.py");
463 }
464 else
465 strcpy(path + len, ".py");
466
467 toc_entry = PyDict_GetItemString(self->files, path);
Guido van Rossumad8d3002007-08-03 18:40:49 +0000468 if (toc_entry != NULL) {
Neal Norwitz3c814d22007-08-26 05:08:21 +0000469 PyObject *bytes = get_data(PyUnicode_AsString(self->archive), toc_entry);
Christian Heimes9c4756e2008-05-26 13:22:05 +0000470 PyObject *res = PyUnicode_FromString(PyByteArray_AsString(bytes));
Guido van Rossumad8d3002007-08-03 18:40:49 +0000471 Py_XDECREF(bytes);
472 return res;
473 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000474
475 /* we have the module, but no source */
476 Py_INCREF(Py_None);
477 return Py_None;
478}
479
480PyDoc_STRVAR(doc_find_module,
481"find_module(fullname, path=None) -> self or None.\n\
482\n\
483Search for a module specified by 'fullname'. 'fullname' must be the\n\
484fully qualified (dotted) module name. It returns the zipimporter\n\
485instance itself if the module was found, or None if it wasn't.\n\
486The optional 'path' argument is ignored -- it's there for compatibility\n\
487with the importer protocol.");
488
489PyDoc_STRVAR(doc_load_module,
490"load_module(fullname) -> module.\n\
491\n\
492Load the module specified by 'fullname'. 'fullname' must be the\n\
493fully qualified (dotted) module name. It returns the imported\n\
494module, or raises ZipImportError if it wasn't found.");
495
496PyDoc_STRVAR(doc_get_data,
497"get_data(pathname) -> string with file data.\n\
498\n\
499Return the data associated with 'pathname'. Raise IOError if\n\
500the file wasn't found.");
501
502PyDoc_STRVAR(doc_is_package,
503"is_package(fullname) -> bool.\n\
504\n\
505Return True if the module specified by fullname is a package.\n\
506Raise ZipImportError is the module couldn't be found.");
507
508PyDoc_STRVAR(doc_get_code,
509"get_code(fullname) -> code object.\n\
510\n\
511Return the code object for the specified module. Raise ZipImportError\n\
512is the module couldn't be found.");
513
514PyDoc_STRVAR(doc_get_source,
515"get_source(fullname) -> source string.\n\
516\n\
517Return the source code for the specified module. Raise ZipImportError\n\
518is the module couldn't be found, return None if the archive does\n\
519contain the module, but has no source for it.");
520
521static PyMethodDef zipimporter_methods[] = {
522 {"find_module", zipimporter_find_module, METH_VARARGS,
523 doc_find_module},
524 {"load_module", zipimporter_load_module, METH_VARARGS,
525 doc_load_module},
526 {"get_data", zipimporter_get_data, METH_VARARGS,
527 doc_get_data},
528 {"get_code", zipimporter_get_code, METH_VARARGS,
529 doc_get_code},
530 {"get_source", zipimporter_get_source, METH_VARARGS,
531 doc_get_source},
532 {"is_package", zipimporter_is_package, METH_VARARGS,
533 doc_is_package},
534 {NULL, NULL} /* sentinel */
535};
536
537static PyMemberDef zipimporter_members[] = {
538 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
539 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
540 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
541 {NULL}
542};
543
544PyDoc_STRVAR(zipimporter_doc,
545"zipimporter(archivepath) -> zipimporter object\n\
546\n\
547Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000548a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
549'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
550valid directory inside the archive.\n\
551\n\
552'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
553archive.\n\
554\n\
555The 'archive' attribute of zipimporter objects contains the name of the\n\
556zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000557
558#define DEFERRED_ADDRESS(ADDR) 0
559
560static PyTypeObject ZipImporter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000561 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
Just van Rossum52e14d62002-12-30 22:08:05 +0000562 "zipimport.zipimporter",
563 sizeof(ZipImporter),
564 0, /* tp_itemsize */
565 (destructor)zipimporter_dealloc, /* tp_dealloc */
566 0, /* tp_print */
567 0, /* tp_getattr */
568 0, /* tp_setattr */
569 0, /* tp_compare */
570 (reprfunc)zipimporter_repr, /* tp_repr */
571 0, /* tp_as_number */
572 0, /* tp_as_sequence */
573 0, /* tp_as_mapping */
574 0, /* tp_hash */
575 0, /* tp_call */
576 0, /* tp_str */
577 PyObject_GenericGetAttr, /* tp_getattro */
578 0, /* tp_setattro */
579 0, /* tp_as_buffer */
580 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
581 Py_TPFLAGS_HAVE_GC, /* tp_flags */
582 zipimporter_doc, /* tp_doc */
583 zipimporter_traverse, /* tp_traverse */
584 0, /* tp_clear */
585 0, /* tp_richcompare */
586 0, /* tp_weaklistoffset */
587 0, /* tp_iter */
588 0, /* tp_iternext */
589 zipimporter_methods, /* tp_methods */
590 zipimporter_members, /* tp_members */
591 0, /* tp_getset */
592 0, /* tp_base */
593 0, /* tp_dict */
594 0, /* tp_descr_get */
595 0, /* tp_descr_set */
596 0, /* tp_dictoffset */
597 (initproc)zipimporter_init, /* tp_init */
598 PyType_GenericAlloc, /* tp_alloc */
599 PyType_GenericNew, /* tp_new */
600 PyObject_GC_Del, /* tp_free */
601};
602
603
604/* implementation */
605
Just van Rossum52e14d62002-12-30 22:08:05 +0000606/* Given a buffer, return the long that is represented by the first
607 4 bytes, encoded as little endian. This partially reimplements
608 marshal.c:r_long() */
609static long
610get_long(unsigned char *buf) {
611 long x;
612 x = buf[0];
613 x |= (long)buf[1] << 8;
614 x |= (long)buf[2] << 16;
615 x |= (long)buf[3] << 24;
616#if SIZEOF_LONG > 4
617 /* Sign extension for 64-bit machines */
618 x |= -(x & 0x80000000L);
619#endif
620 return x;
621}
622
623/*
624 read_directory(archive) -> files dict (new reference)
625
626 Given a path to a Zip archive, build a dict, mapping file names
627 (local to the archive, using SEP as a separator) to toc entries.
628
629 A toc_entry is a tuple:
630
Fred Drakef5b7fd22005-11-11 19:34:56 +0000631 (__file__, # value to use for __file__, available for all files
632 compress, # compression kind; 0 for uncompressed
Just van Rossum52e14d62002-12-30 22:08:05 +0000633 data_size, # size of compressed data on disk
634 file_size, # size of decompressed data
635 file_offset, # offset of file header from start of archive
636 time, # mod time of file (in dos format)
637 date, # mod data of file (in dos format)
638 crc, # crc checksum of the data
639 )
640
641 Directories can be recognized by the trailing SEP in the name,
642 data_size and file_offset are 0.
643*/
644static PyObject *
645read_directory(char *archive)
646{
647 PyObject *files = NULL;
648 FILE *fp;
649 long compress, crc, data_size, file_size, file_offset, date, time;
Thomas Heller354e3d92003-07-22 18:10:15 +0000650 long header_offset, name_size, header_size, header_position;
Neal Norwitzd39d8612006-01-08 01:03:36 +0000651 long i, l, count;
652 size_t length;
Just van Rossum52e14d62002-12-30 22:08:05 +0000653 char path[MAXPATHLEN + 5];
654 char name[MAXPATHLEN + 5];
655 char *p, endof_central_dir[22];
Thomas Heller354e3d92003-07-22 18:10:15 +0000656 long arc_offset; /* offset from beginning of file to start of zip-archive */
Just van Rossum52e14d62002-12-30 22:08:05 +0000657
658 if (strlen(archive) > MAXPATHLEN) {
659 PyErr_SetString(PyExc_OverflowError,
660 "Zip path name is too long");
661 return NULL;
662 }
663 strcpy(path, archive);
664
665 fp = fopen(archive, "rb");
666 if (fp == NULL) {
667 PyErr_Format(ZipImportError, "can't open Zip file: "
668 "'%.200s'", archive);
669 return NULL;
670 }
Just van Rossumf4ecc752003-02-28 08:54:01 +0000671 fseek(fp, -22, SEEK_END);
Thomas Heller354e3d92003-07-22 18:10:15 +0000672 header_position = ftell(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000673 if (fread(endof_central_dir, 1, 22, fp) != 22) {
674 fclose(fp);
675 PyErr_Format(ZipImportError, "can't read Zip file: "
676 "'%.200s'", archive);
677 return NULL;
678 }
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000679 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000680 /* Bad: End of Central Dir signature */
681 fclose(fp);
682 PyErr_Format(ZipImportError, "not a Zip file: "
683 "'%.200s'", archive);
684 return NULL;
685 }
686
Thomas Heller354e3d92003-07-22 18:10:15 +0000687 header_size = get_long((unsigned char *)endof_central_dir + 12);
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000688 header_offset = get_long((unsigned char *)endof_central_dir + 16);
Thomas Heller354e3d92003-07-22 18:10:15 +0000689 arc_offset = header_position - header_offset - header_size;
690 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000691
692 files = PyDict_New();
693 if (files == NULL)
694 goto error;
695
696 length = (long)strlen(path);
697 path[length] = SEP;
698
699 /* Start of Central Directory */
700 count = 0;
701 for (;;) {
702 PyObject *t;
703 int err;
704
705 fseek(fp, header_offset, 0); /* Start of file header */
706 l = PyMarshal_ReadLongFromFile(fp);
707 if (l != 0x02014B50)
708 break; /* Bad: Central Dir File Header */
709 fseek(fp, header_offset + 10, 0);
710 compress = PyMarshal_ReadShortFromFile(fp);
711 time = PyMarshal_ReadShortFromFile(fp);
712 date = PyMarshal_ReadShortFromFile(fp);
713 crc = PyMarshal_ReadLongFromFile(fp);
714 data_size = PyMarshal_ReadLongFromFile(fp);
715 file_size = PyMarshal_ReadLongFromFile(fp);
716 name_size = PyMarshal_ReadShortFromFile(fp);
717 header_size = 46 + name_size +
718 PyMarshal_ReadShortFromFile(fp) +
719 PyMarshal_ReadShortFromFile(fp);
720 fseek(fp, header_offset + 42, 0);
Thomas Heller354e3d92003-07-22 18:10:15 +0000721 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000722 if (name_size > MAXPATHLEN)
723 name_size = MAXPATHLEN;
724
725 p = name;
726 for (i = 0; i < name_size; i++) {
727 *p = (char)getc(fp);
728 if (*p == '/')
729 *p = SEP;
730 p++;
731 }
732 *p = 0; /* Add terminating null byte */
733 header_offset += header_size;
734
735 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
736
737 t = Py_BuildValue("siiiiiii", path, compress, data_size,
738 file_size, file_offset, time, date, crc);
739 if (t == NULL)
740 goto error;
741 err = PyDict_SetItemString(files, name, t);
742 Py_DECREF(t);
743 if (err != 0)
744 goto error;
745 count++;
746 }
747 fclose(fp);
748 if (Py_VerboseFlag)
749 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
750 count, archive);
751 return files;
752error:
753 fclose(fp);
754 Py_XDECREF(files);
755 return NULL;
756}
757
758/* Return the zlib.decompress function object, or NULL if zlib couldn't
759 be imported. The function is cached when found, so subsequent calls
760 don't import zlib again. Returns a *borrowed* reference.
761 XXX This makes zlib.decompress immortal. */
762static PyObject *
763get_decompress_func(void)
764{
765 static PyObject *decompress = NULL;
766
767 if (decompress == NULL) {
768 PyObject *zlib;
769 static int importing_zlib = 0;
770
771 if (importing_zlib != 0)
772 /* Someone has a zlib.py[co] in their Zip file;
773 let's avoid a stack overflow. */
774 return NULL;
775 importing_zlib = 1;
Christian Heimes072c0f12008-01-03 23:01:04 +0000776 zlib = PyImport_ImportModuleNoBlock("zlib");
Just van Rossum52e14d62002-12-30 22:08:05 +0000777 importing_zlib = 0;
778 if (zlib != NULL) {
779 decompress = PyObject_GetAttrString(zlib,
780 "decompress");
781 Py_DECREF(zlib);
782 }
783 else
784 PyErr_Clear();
785 if (Py_VerboseFlag)
786 PySys_WriteStderr("# zipimport: zlib %s\n",
787 zlib != NULL ? "available": "UNAVAILABLE");
788 }
789 return decompress;
790}
791
792/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
793 data as a new reference. */
794static PyObject *
795get_data(char *archive, PyObject *toc_entry)
796{
797 PyObject *raw_data, *data = NULL, *decompress;
798 char *buf;
799 FILE *fp;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000800 int err;
801 Py_ssize_t bytes_read = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000802 long l;
803 char *datapath;
Neal Norwitz3c814d22007-08-26 05:08:21 +0000804 long compress, data_size, file_size, file_offset, bytes_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000805 long time, date, crc;
806
Neal Norwitz0c0aad92003-02-18 03:37:49 +0000807 if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
Just van Rossum52e14d62002-12-30 22:08:05 +0000808 &data_size, &file_size, &file_offset, &time,
809 &date, &crc)) {
810 return NULL;
811 }
812
813 fp = fopen(archive, "rb");
814 if (!fp) {
815 PyErr_Format(PyExc_IOError,
816 "zipimport: can not open file %s", archive);
817 return NULL;
818 }
819
820 /* Check to make sure the local file header is correct */
821 fseek(fp, file_offset, 0);
822 l = PyMarshal_ReadLongFromFile(fp);
823 if (l != 0x04034B50) {
824 /* Bad: Local File Header */
825 PyErr_Format(ZipImportError,
826 "bad local file header in %s",
827 archive);
828 fclose(fp);
829 return NULL;
830 }
831 fseek(fp, file_offset + 26, 0);
832 l = 30 + PyMarshal_ReadShortFromFile(fp) +
833 PyMarshal_ReadShortFromFile(fp); /* local header size */
834 file_offset += l; /* Start of file data */
835
Neal Norwitz3c814d22007-08-26 05:08:21 +0000836 bytes_size = compress == 0 ? data_size : data_size + 1;
837 if (bytes_size == 0)
838 bytes_size++;
Christian Heimes9c4756e2008-05-26 13:22:05 +0000839 raw_data = PyByteArray_FromStringAndSize((char *)NULL, bytes_size);
Neal Norwitz3c814d22007-08-26 05:08:21 +0000840
Just van Rossum52e14d62002-12-30 22:08:05 +0000841 if (raw_data == NULL) {
842 fclose(fp);
843 return NULL;
844 }
Christian Heimes9c4756e2008-05-26 13:22:05 +0000845 buf = PyByteArray_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000846
847 err = fseek(fp, file_offset, 0);
848 if (err == 0)
849 bytes_read = fread(buf, 1, data_size, fp);
850 fclose(fp);
851 if (err || bytes_read != data_size) {
852 PyErr_SetString(PyExc_IOError,
853 "zipimport: can't read data");
854 Py_DECREF(raw_data);
855 return NULL;
856 }
857
858 if (compress != 0) {
859 buf[data_size] = 'Z'; /* saw this in zipfile.py */
860 data_size++;
861 }
862 buf[data_size] = '\0';
863
Guido van Rossumad8d3002007-08-03 18:40:49 +0000864 if (compress == 0) { /* data is not compressed */
Christian Heimes9c4756e2008-05-26 13:22:05 +0000865 data = PyByteArray_FromStringAndSize(buf, data_size);
Guido van Rossum76f2b242007-08-17 14:33:37 +0000866 Py_DECREF(raw_data);
867 return data;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000868 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000869
870 /* Decompress with zlib */
871 decompress = get_decompress_func();
872 if (decompress == NULL) {
873 PyErr_SetString(ZipImportError,
874 "can't decompress data; "
875 "zlib not available");
876 goto error;
877 }
Just van Rossumee8f10f2003-09-07 13:36:48 +0000878 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Just van Rossum52e14d62002-12-30 22:08:05 +0000879error:
880 Py_DECREF(raw_data);
881 return data;
882}
883
884/* Lenient date/time comparison function. The precision of the mtime
885 in the archive is lower than the mtime stored in a .pyc: we
886 must allow a difference of at most one second. */
887static int
888eq_mtime(time_t t1, time_t t2)
889{
890 time_t d = t1 - t2;
891 if (d < 0)
892 d = -d;
893 /* dostime only stores even seconds, so be lenient */
894 return d <= 1;
895}
896
897/* Given the contents of a .py[co] file in a buffer, unmarshal the data
898 and return the code object. Return None if it the magic word doesn't
899 match (we do this instead of raising an exception as we fall back
900 to .py if available and we don't want to mask other errors).
901 Returns a new reference. */
902static PyObject *
903unmarshal_code(char *pathname, PyObject *data, time_t mtime)
904{
905 PyObject *code;
Christian Heimes9c4756e2008-05-26 13:22:05 +0000906 char *buf = PyByteArray_AsString(data);
907 Py_ssize_t size = PyByteArray_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000908
909 if (size <= 9) {
910 PyErr_SetString(ZipImportError,
911 "bad pyc data");
912 return NULL;
913 }
914
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000915 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000916 if (Py_VerboseFlag)
917 PySys_WriteStderr("# %s has bad magic\n",
918 pathname);
919 Py_INCREF(Py_None);
920 return Py_None; /* signal caller to try alternative */
921 }
922
Just van Rossum9a3129c2003-01-03 11:18:56 +0000923 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
924 mtime)) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000925 if (Py_VerboseFlag)
926 PySys_WriteStderr("# %s has bad mtime\n",
927 pathname);
928 Py_INCREF(Py_None);
929 return Py_None; /* signal caller to try alternative */
930 }
931
932 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
933 if (code == NULL)
934 return NULL;
935 if (!PyCode_Check(code)) {
936 Py_DECREF(code);
937 PyErr_Format(PyExc_TypeError,
938 "compiled module %.200s is not a code object",
939 pathname);
940 return NULL;
941 }
942 return code;
943}
944
945/* Replace any occurances of "\r\n?" in the input string with "\n".
946 This converts DOS and Mac line endings to Unix line endings.
947 Also append a trailing "\n" to be compatible with
948 PyParser_SimpleParseFile(). Returns a new reference. */
949static PyObject *
950normalize_line_endings(PyObject *source)
951{
Christian Heimes9c4756e2008-05-26 13:22:05 +0000952 char *buf, *q, *p = PyByteArray_AsString(source);
Just van Rossum52e14d62002-12-30 22:08:05 +0000953 PyObject *fixed_source;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000954 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000955
Guido van Rossumad8d3002007-08-03 18:40:49 +0000956 if (!p) {
Christian Heimes9c4756e2008-05-26 13:22:05 +0000957 return PyByteArray_FromStringAndSize("\n\0", 2);
Guido van Rossumad8d3002007-08-03 18:40:49 +0000958 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000959
Just van Rossum9a3129c2003-01-03 11:18:56 +0000960 /* one char extra for trailing \n and one for terminating \0 */
Christian Heimes9c4756e2008-05-26 13:22:05 +0000961 buf = (char *)PyMem_Malloc(PyByteArray_Size(source) + 2);
Just van Rossum9a3129c2003-01-03 11:18:56 +0000962 if (buf == NULL) {
963 PyErr_SetString(PyExc_MemoryError,
964 "zipimport: no memory to allocate "
965 "source buffer");
Just van Rossum52e14d62002-12-30 22:08:05 +0000966 return NULL;
Just van Rossum9a3129c2003-01-03 11:18:56 +0000967 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000968 /* replace "\r\n?" by "\n" */
Neal Norwitz5c1ba532003-02-17 18:05:20 +0000969 for (q = buf; *p != '\0'; p++) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000970 if (*p == '\r') {
971 *q++ = '\n';
Just van Rossum9a3129c2003-01-03 11:18:56 +0000972 if (*(p + 1) == '\n')
Just van Rossum52e14d62002-12-30 22:08:05 +0000973 p++;
Just van Rossum52e14d62002-12-30 22:08:05 +0000974 }
975 else
976 *q++ = *p;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000977 len++;
Just van Rossum52e14d62002-12-30 22:08:05 +0000978 }
979 *q++ = '\n'; /* add trailing \n */
980 *q = '\0';
Christian Heimes9c4756e2008-05-26 13:22:05 +0000981 fixed_source = PyByteArray_FromStringAndSize(buf, len + 2);
Just van Rossum9a3129c2003-01-03 11:18:56 +0000982 PyMem_Free(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000983 return fixed_source;
984}
985
986/* Given a string buffer containing Python source code, compile it
987 return and return a code object as a new reference. */
988static PyObject *
989compile_source(char *pathname, PyObject *source)
990{
991 PyObject *code, *fixed_source;
992
993 fixed_source = normalize_line_endings(source);
994 if (fixed_source == NULL)
995 return NULL;
996
Christian Heimes9c4756e2008-05-26 13:22:05 +0000997 code = Py_CompileString(PyByteArray_AsString(fixed_source), pathname,
Just van Rossum52e14d62002-12-30 22:08:05 +0000998 Py_file_input);
999 Py_DECREF(fixed_source);
1000 return code;
1001}
1002
1003/* Convert the date/time values found in the Zip archive to a value
1004 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001005static time_t
1006parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001007{
1008 struct tm stm;
1009
Christian Heimes679db4a2008-01-18 09:56:22 +00001010 memset((void *) &stm, '\0', sizeof(stm));
1011
Just van Rossum52e14d62002-12-30 22:08:05 +00001012 stm.tm_sec = (dostime & 0x1f) * 2;
1013 stm.tm_min = (dostime >> 5) & 0x3f;
1014 stm.tm_hour = (dostime >> 11) & 0x1f;
1015 stm.tm_mday = dosdate & 0x1f;
1016 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1017 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
Just van Rossum547eb422003-04-08 20:07:15 +00001018 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001019
1020 return mktime(&stm);
1021}
1022
1023/* Given a path to a .pyc or .pyo file in the archive, return the
1024 modifictaion time of the matching .py file, or 0 if no source
1025 is available. */
1026static time_t
1027get_mtime_of_source(ZipImporter *self, char *path)
1028{
1029 PyObject *toc_entry;
1030 time_t mtime = 0;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001031 Py_ssize_t lastchar = strlen(path) - 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001032 char savechar = path[lastchar];
1033 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1034 toc_entry = PyDict_GetItemString(self->files, path);
1035 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1036 PyTuple_Size(toc_entry) == 8) {
Just van Rossumf8b6de12002-12-31 09:51:59 +00001037 /* fetch the time stamp of the .py file for comparison
1038 with an embedded pyc time stamp */
1039 int time, date;
Christian Heimes217cfd12007-12-02 14:31:20 +00001040 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1041 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
Just van Rossum52e14d62002-12-30 22:08:05 +00001042 mtime = parse_dostime(time, date);
1043 }
1044 path[lastchar] = savechar;
1045 return mtime;
1046}
1047
1048/* Return the code object for the module named by 'fullname' from the
1049 Zip archive as a new reference. */
1050static PyObject *
1051get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1052 time_t mtime, PyObject *toc_entry)
1053{
1054 PyObject *data, *code;
1055 char *modpath;
Neal Norwitz3c814d22007-08-26 05:08:21 +00001056 char *archive = PyUnicode_AsString(self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +00001057
1058 if (archive == NULL)
1059 return NULL;
1060
1061 data = get_data(archive, toc_entry);
1062 if (data == NULL)
1063 return NULL;
1064
Neal Norwitz3c814d22007-08-26 05:08:21 +00001065 modpath = PyUnicode_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001066
1067 if (isbytecode) {
1068 code = unmarshal_code(modpath, data, mtime);
1069 }
1070 else {
1071 code = compile_source(modpath, data);
1072 }
1073 Py_DECREF(data);
1074 return code;
1075}
1076
1077/* Get the code object assoiciated with the module specified by
1078 'fullname'. */
1079static PyObject *
1080get_module_code(ZipImporter *self, char *fullname,
1081 int *p_ispackage, char **p_modpath)
1082{
1083 PyObject *toc_entry;
1084 char *subname, path[MAXPATHLEN + 1];
1085 int len;
1086 struct st_zip_searchorder *zso;
1087
1088 subname = get_subname(fullname);
1089
Neal Norwitz3c814d22007-08-26 05:08:21 +00001090 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +00001091 if (len < 0)
1092 return NULL;
1093
1094 for (zso = zip_searchorder; *zso->suffix; zso++) {
1095 PyObject *code = NULL;
1096
1097 strcpy(path + len, zso->suffix);
1098 if (Py_VerboseFlag > 1)
1099 PySys_WriteStderr("# trying %s%c%s\n",
Neal Norwitz3c814d22007-08-26 05:08:21 +00001100 PyUnicode_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +00001101 SEP, path);
1102 toc_entry = PyDict_GetItemString(self->files, path);
1103 if (toc_entry != NULL) {
1104 time_t mtime = 0;
1105 int ispackage = zso->type & IS_PACKAGE;
1106 int isbytecode = zso->type & IS_BYTECODE;
1107
1108 if (isbytecode)
1109 mtime = get_mtime_of_source(self, path);
1110 if (p_ispackage != NULL)
1111 *p_ispackage = ispackage;
1112 code = get_code_from_data(self, ispackage,
1113 isbytecode, mtime,
1114 toc_entry);
1115 if (code == Py_None) {
1116 /* bad magic number or non-matching mtime
1117 in byte code, try next */
1118 Py_DECREF(code);
1119 continue;
1120 }
1121 if (code != NULL && p_modpath != NULL)
Neal Norwitz3c814d22007-08-26 05:08:21 +00001122 *p_modpath = PyUnicode_AsString(
Just van Rossum52e14d62002-12-30 22:08:05 +00001123 PyTuple_GetItem(toc_entry, 0));
1124 return code;
1125 }
1126 }
1127 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1128 return NULL;
1129}
1130
1131
1132/* Module init */
1133
1134PyDoc_STRVAR(zipimport_doc,
1135"zipimport provides support for importing Python modules from Zip archives.\n\
1136\n\
1137This module exports three objects:\n\
1138- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001139- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001140 subclass of ImportError, so it can be caught as ImportError, too.\n\
1141- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1142 info dicts, as used in zipimporter._files.\n\
1143\n\
1144It is usually not needed to use the zipimport module explicitly; it is\n\
1145used by the builtin import mechanism for sys.path items that are paths\n\
1146to Zip archives.");
1147
Martin v. Löwis1a214512008-06-11 05:26:20 +00001148static struct PyModuleDef zipimportmodule = {
1149 PyModuleDef_HEAD_INIT,
1150 "zipimport",
1151 zipimport_doc,
1152 -1,
1153 NULL,
1154 NULL,
1155 NULL,
1156 NULL,
1157 NULL
1158};
1159
Just van Rossum52e14d62002-12-30 22:08:05 +00001160PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001161PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001162{
1163 PyObject *mod;
1164
1165 if (PyType_Ready(&ZipImporter_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001166 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001167
1168 /* Correct directory separator */
1169 zip_searchorder[0].suffix[0] = SEP;
1170 zip_searchorder[1].suffix[0] = SEP;
1171 zip_searchorder[2].suffix[0] = SEP;
1172 if (Py_OptimizeFlag) {
1173 /* Reverse *.pyc and *.pyo */
1174 struct st_zip_searchorder tmp;
1175 tmp = zip_searchorder[0];
1176 zip_searchorder[0] = zip_searchorder[1];
1177 zip_searchorder[1] = tmp;
1178 tmp = zip_searchorder[3];
1179 zip_searchorder[3] = zip_searchorder[4];
1180 zip_searchorder[4] = tmp;
1181 }
1182
Martin v. Löwis1a214512008-06-11 05:26:20 +00001183 mod = PyModule_Create(&zipimportmodule);
Hye-Shik Chang4af5c8c2006-03-07 15:39:21 +00001184 if (mod == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001185 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001186
1187 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1188 PyExc_ImportError, NULL);
1189 if (ZipImportError == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001190 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001191
1192 Py_INCREF(ZipImportError);
1193 if (PyModule_AddObject(mod, "ZipImportError",
1194 ZipImportError) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001195 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001196
1197 Py_INCREF(&ZipImporter_Type);
1198 if (PyModule_AddObject(mod, "zipimporter",
1199 (PyObject *)&ZipImporter_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001200 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001201
Just van Rossum52e14d62002-12-30 22:08:05 +00001202 zip_directory_cache = PyDict_New();
1203 if (zip_directory_cache == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001204 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001205 Py_INCREF(zip_directory_cache);
1206 if (PyModule_AddObject(mod, "_zip_directory_cache",
1207 zip_directory_cache) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001208 return NULL;
1209 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001210}