blob: 3b8eb936b1b516363fc90d322c5beb6e225de3a3 [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 Vassalottia85998a2008-05-03 18:24:43 +000064 Py_ssize_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 Vassalottia85998a2008-05-03 18:24:43 +000069 if (!PyArg_ParseTuple(args, "s#:zipimporter", &path, &len))
Just van Rossum52e14d62002-12-30 22:08:05 +000070 return -1;
71
Just van Rossum52e14d62002-12-30 22:08:05 +000072 if (len == 0) {
73 PyErr_SetString(ZipImportError, "archive path is empty");
74 return -1;
75 }
76 if (len >= MAXPATHLEN) {
77 PyErr_SetString(ZipImportError,
78 "archive path too long");
79 return -1;
80 }
81 strcpy(buf, path);
82
83#ifdef ALTSEP
84 for (p = buf; *p; p++) {
85 if (*p == ALTSEP)
86 *p = SEP;
87 }
88#endif
89
90 path = NULL;
91 prefix = NULL;
92 for (;;) {
93 struct stat statbuf;
94 int rv;
95
96 rv = stat(buf, &statbuf);
97 if (rv == 0) {
98 /* it exists */
99 if (S_ISREG(statbuf.st_mode))
100 /* it's a file */
101 path = buf;
102 break;
103 }
104 /* back up one path element */
Just van Rossumd35c6db2003-01-02 12:55:48 +0000105 p = strrchr(buf, SEP);
Just van Rossum52e14d62002-12-30 22:08:05 +0000106 if (prefix != NULL)
107 *prefix = SEP;
108 if (p == NULL)
109 break;
110 *p = '\0';
111 prefix = p;
112 }
113 if (path != NULL) {
114 PyObject *files;
115 files = PyDict_GetItemString(zip_directory_cache, path);
116 if (files == NULL) {
117 files = read_directory(buf);
118 if (files == NULL)
119 return -1;
120 if (PyDict_SetItemString(zip_directory_cache, path,
121 files) != 0)
122 return -1;
123 }
124 else
125 Py_INCREF(files);
126 self->files = files;
127 }
128 else {
129 PyErr_SetString(ZipImportError, "not a Zip file");
130 return -1;
131 }
132
133 if (prefix == NULL)
134 prefix = "";
135 else {
136 prefix++;
137 len = strlen(prefix);
138 if (prefix[len-1] != SEP) {
139 /* add trailing SEP */
140 prefix[len] = SEP;
141 prefix[len + 1] = '\0';
142 }
143 }
144
Neal Norwitz3c814d22007-08-26 05:08:21 +0000145 self->archive = PyUnicode_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000146 if (self->archive == NULL)
147 return -1;
148
Neal Norwitz3c814d22007-08-26 05:08:21 +0000149 self->prefix = PyUnicode_FromString(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000150 if (self->prefix == NULL)
151 return -1;
152
153 return 0;
154}
155
156/* GC support. */
157static int
158zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
159{
160 ZipImporter *self = (ZipImporter *)obj;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000161 Py_VISIT(self->files);
Just van Rossum52e14d62002-12-30 22:08:05 +0000162 return 0;
163}
164
165static void
166zipimporter_dealloc(ZipImporter *self)
167{
168 PyObject_GC_UnTrack(self);
169 Py_XDECREF(self->archive);
Just van Rossumf8b6de12002-12-31 09:51:59 +0000170 Py_XDECREF(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000171 Py_XDECREF(self->files);
Christian Heimes90aa7642007-12-19 02:45:37 +0000172 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000173}
174
175static PyObject *
176zipimporter_repr(ZipImporter *self)
177{
Just van Rossum52e14d62002-12-30 22:08:05 +0000178 char *archive = "???";
179 char *prefix = "";
180
Neal Norwitz3c814d22007-08-26 05:08:21 +0000181 if (self->archive != NULL && PyUnicode_Check(self->archive))
182 archive = PyUnicode_AsString(self->archive);
183 if (self->prefix != NULL && PyUnicode_Check(self->prefix))
184 prefix = PyUnicode_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000185 if (prefix != NULL && *prefix)
Walter Dörwald5b0443c2007-06-05 16:19:33 +0000186 return PyUnicode_FromFormat("<zipimporter object \"%.300s%c%.150s\">",
187 archive, SEP, prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000188 else
Walter Dörwald5b0443c2007-06-05 16:19:33 +0000189 return PyUnicode_FromFormat("<zipimporter object \"%.300s\">",
190 archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000191}
192
193/* return fullname.split(".")[-1] */
194static char *
195get_subname(char *fullname)
196{
197 char *subname = strrchr(fullname, '.');
198 if (subname == NULL)
199 subname = fullname;
200 else
201 subname++;
202 return subname;
203}
204
205/* Given a (sub)modulename, write the potential file path in the
206 archive (without extension) to the path buffer. Return the
207 length of the resulting string. */
208static int
209make_filename(char *prefix, char *name, char *path)
210{
Neal Norwitzd39d8612006-01-08 01:03:36 +0000211 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000212 char *p;
213
214 len = strlen(prefix);
215
216 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
217 if (len + strlen(name) + 13 >= MAXPATHLEN) {
218 PyErr_SetString(ZipImportError, "path too long");
219 return -1;
220 }
221
222 strcpy(path, prefix);
223 strcpy(path + len, name);
224 for (p = path + len; *p; p++) {
225 if (*p == '.')
226 *p = SEP;
227 }
228 len += strlen(name);
Martin v. Löwis18e16552006-02-15 17:27:45 +0000229 assert(len < INT_MAX);
Neal Norwitzd39d8612006-01-08 01:03:36 +0000230 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000231}
232
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000233enum zi_module_info {
Just van Rossum52e14d62002-12-30 22:08:05 +0000234 MI_ERROR,
235 MI_NOT_FOUND,
236 MI_MODULE,
237 MI_PACKAGE
238};
239
240/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000241static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000242get_module_info(ZipImporter *self, char *fullname)
243{
244 char *subname, path[MAXPATHLEN + 1];
245 int len;
246 struct st_zip_searchorder *zso;
247
248 subname = get_subname(fullname);
249
Neal Norwitz3c814d22007-08-26 05:08:21 +0000250 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000251 if (len < 0)
252 return MI_ERROR;
253
254 for (zso = zip_searchorder; *zso->suffix; zso++) {
255 strcpy(path + len, zso->suffix);
256 if (PyDict_GetItemString(self->files, path) != NULL) {
257 if (zso->type & IS_PACKAGE)
258 return MI_PACKAGE;
259 else
260 return MI_MODULE;
261 }
262 }
263 return MI_NOT_FOUND;
264}
265
266/* Check whether we can satisfy the import of the module named by
267 'fullname'. Return self if we can, None if we can't. */
268static PyObject *
269zipimporter_find_module(PyObject *obj, PyObject *args)
270{
271 ZipImporter *self = (ZipImporter *)obj;
272 PyObject *path = NULL;
273 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000274 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000275
276 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
277 &fullname, &path))
278 return NULL;
279
280 mi = get_module_info(self, fullname);
281 if (mi == MI_ERROR)
282 return NULL;
283 if (mi == MI_NOT_FOUND) {
284 Py_INCREF(Py_None);
285 return Py_None;
286 }
287 Py_INCREF(self);
288 return (PyObject *)self;
289}
290
291/* Load and return the module named by 'fullname'. */
292static PyObject *
293zipimporter_load_module(PyObject *obj, PyObject *args)
294{
295 ZipImporter *self = (ZipImporter *)obj;
296 PyObject *code, *mod, *dict;
297 char *fullname, *modpath;
298 int ispackage;
299
300 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
301 &fullname))
302 return NULL;
303
304 code = get_module_code(self, fullname, &ispackage, &modpath);
305 if (code == NULL)
306 return NULL;
307
308 mod = PyImport_AddModule(fullname);
309 if (mod == NULL) {
310 Py_DECREF(code);
311 return NULL;
312 }
313 dict = PyModule_GetDict(mod);
314
315 /* mod.__loader__ = self */
316 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
317 goto error;
318
319 if (ispackage) {
320 /* add __path__ to the module *before* the code gets
321 executed */
322 PyObject *pkgpath, *fullpath;
Neal Norwitz3c814d22007-08-26 05:08:21 +0000323 char *prefix = PyUnicode_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000324 char *subname = get_subname(fullname);
325 int err;
326
Neal Norwitz3c814d22007-08-26 05:08:21 +0000327 fullpath = PyUnicode_FromFormat("%s%c%s%s",
328 PyUnicode_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +0000329 SEP,
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000330 prefix ? prefix : "",
Just van Rossum52e14d62002-12-30 22:08:05 +0000331 subname);
332 if (fullpath == NULL)
333 goto error;
334
335 pkgpath = Py_BuildValue("[O]", fullpath);
336 Py_DECREF(fullpath);
337 if (pkgpath == NULL)
338 goto error;
339 err = PyDict_SetItemString(dict, "__path__", pkgpath);
340 Py_DECREF(pkgpath);
341 if (err != 0)
342 goto error;
343 }
344 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
345 Py_DECREF(code);
346 if (Py_VerboseFlag)
347 PySys_WriteStderr("import %s # loaded from Zip %s\n",
348 fullname, modpath);
349 return mod;
350error:
351 Py_DECREF(code);
352 Py_DECREF(mod);
353 return NULL;
354}
355
356/* Return a bool signifying whether the module is a package or not. */
357static PyObject *
358zipimporter_is_package(PyObject *obj, PyObject *args)
359{
360 ZipImporter *self = (ZipImporter *)obj;
361 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000362 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000363
Neal Norwitz5c1ba532003-02-17 18:05:20 +0000364 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
Just van Rossum52e14d62002-12-30 22:08:05 +0000365 &fullname))
366 return NULL;
367
368 mi = get_module_info(self, fullname);
369 if (mi == MI_ERROR)
370 return NULL;
371 if (mi == MI_NOT_FOUND) {
372 PyErr_Format(ZipImportError, "can't find module '%.200s'",
373 fullname);
374 return NULL;
375 }
376 return PyBool_FromLong(mi == MI_PACKAGE);
377}
378
379static PyObject *
380zipimporter_get_data(PyObject *obj, PyObject *args)
381{
382 ZipImporter *self = (ZipImporter *)obj;
383 char *path;
384#ifdef ALTSEP
Tim Peters1ea93f22002-12-30 22:42:57 +0000385 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000386#endif
387 PyObject *toc_entry;
Martin v. Löwisad0a4622006-02-16 14:30:23 +0000388 Py_ssize_t len;
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000389 char *archive_str;
Just van Rossum52e14d62002-12-30 22:08:05 +0000390
391 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
392 return NULL;
393
394#ifdef ALTSEP
395 if (strlen(path) >= MAXPATHLEN) {
396 PyErr_SetString(ZipImportError, "path too long");
397 return NULL;
398 }
399 strcpy(buf, path);
400 for (p = buf; *p; p++) {
401 if (*p == ALTSEP)
402 *p = SEP;
403 }
404 path = buf;
405#endif
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000406 archive_str = PyUnicode_AsStringAndSize(self->archive, &len);
Tim Petersf271c272002-12-30 22:44:03 +0000407 if ((size_t)len < strlen(path) &&
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000408 strncmp(path, archive_str, len) == 0 &&
Just van Rossum52e14d62002-12-30 22:08:05 +0000409 path[len] == SEP) {
410 path = path + len + 1;
411 }
412
413 toc_entry = PyDict_GetItemString(self->files, path);
414 if (toc_entry == NULL) {
Georg Brandle9b19492006-02-19 09:38:58 +0000415 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000416 return NULL;
417 }
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000418 return get_data(archive_str, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000419}
420
421static PyObject *
422zipimporter_get_code(PyObject *obj, PyObject *args)
423{
424 ZipImporter *self = (ZipImporter *)obj;
425 char *fullname;
426
427 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
428 return NULL;
429
430 return get_module_code(self, fullname, NULL, NULL);
431}
432
433static PyObject *
434zipimporter_get_source(PyObject *obj, PyObject *args)
435{
436 ZipImporter *self = (ZipImporter *)obj;
437 PyObject *toc_entry;
438 char *fullname, *subname, path[MAXPATHLEN+1];
439 int len;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000440 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000441
442 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
443 return NULL;
444
445 mi = get_module_info(self, fullname);
446 if (mi == MI_ERROR)
447 return NULL;
448 if (mi == MI_NOT_FOUND) {
449 PyErr_Format(ZipImportError, "can't find module '%.200s'",
450 fullname);
451 return NULL;
452 }
453 subname = get_subname(fullname);
454
Neal Norwitz3c814d22007-08-26 05:08:21 +0000455 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000456 if (len < 0)
457 return NULL;
458
459 if (mi == MI_PACKAGE) {
460 path[len] = SEP;
461 strcpy(path + len + 1, "__init__.py");
462 }
463 else
464 strcpy(path + len, ".py");
465
466 toc_entry = PyDict_GetItemString(self->files, path);
Guido van Rossumad8d3002007-08-03 18:40:49 +0000467 if (toc_entry != NULL) {
Neal Norwitz3c814d22007-08-26 05:08:21 +0000468 PyObject *bytes = get_data(PyUnicode_AsString(self->archive), toc_entry);
Guido van Rossumad8d3002007-08-03 18:40:49 +0000469 PyObject *res = PyUnicode_FromString(PyBytes_AsString(bytes));
470 Py_XDECREF(bytes);
471 return res;
472 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000473
474 /* we have the module, but no source */
475 Py_INCREF(Py_None);
476 return Py_None;
477}
478
479PyDoc_STRVAR(doc_find_module,
480"find_module(fullname, path=None) -> self or None.\n\
481\n\
482Search for a module specified by 'fullname'. 'fullname' must be the\n\
483fully qualified (dotted) module name. It returns the zipimporter\n\
484instance itself if the module was found, or None if it wasn't.\n\
485The optional 'path' argument is ignored -- it's there for compatibility\n\
486with the importer protocol.");
487
488PyDoc_STRVAR(doc_load_module,
489"load_module(fullname) -> module.\n\
490\n\
491Load the module specified by 'fullname'. 'fullname' must be the\n\
492fully qualified (dotted) module name. It returns the imported\n\
493module, or raises ZipImportError if it wasn't found.");
494
495PyDoc_STRVAR(doc_get_data,
496"get_data(pathname) -> string with file data.\n\
497\n\
498Return the data associated with 'pathname'. Raise IOError if\n\
499the file wasn't found.");
500
501PyDoc_STRVAR(doc_is_package,
502"is_package(fullname) -> bool.\n\
503\n\
504Return True if the module specified by fullname is a package.\n\
505Raise ZipImportError is the module couldn't be found.");
506
507PyDoc_STRVAR(doc_get_code,
508"get_code(fullname) -> code object.\n\
509\n\
510Return the code object for the specified module. Raise ZipImportError\n\
511is the module couldn't be found.");
512
513PyDoc_STRVAR(doc_get_source,
514"get_source(fullname) -> source string.\n\
515\n\
516Return the source code for the specified module. Raise ZipImportError\n\
517is the module couldn't be found, return None if the archive does\n\
518contain the module, but has no source for it.");
519
520static PyMethodDef zipimporter_methods[] = {
521 {"find_module", zipimporter_find_module, METH_VARARGS,
522 doc_find_module},
523 {"load_module", zipimporter_load_module, METH_VARARGS,
524 doc_load_module},
525 {"get_data", zipimporter_get_data, METH_VARARGS,
526 doc_get_data},
527 {"get_code", zipimporter_get_code, METH_VARARGS,
528 doc_get_code},
529 {"get_source", zipimporter_get_source, METH_VARARGS,
530 doc_get_source},
531 {"is_package", zipimporter_is_package, METH_VARARGS,
532 doc_is_package},
533 {NULL, NULL} /* sentinel */
534};
535
536static PyMemberDef zipimporter_members[] = {
537 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
538 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
539 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
540 {NULL}
541};
542
543PyDoc_STRVAR(zipimporter_doc,
544"zipimporter(archivepath) -> zipimporter object\n\
545\n\
546Create a new zipimporter instance. 'archivepath' must be a path to\n\
547a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\
548a valid Zip archive.");
549
550#define DEFERRED_ADDRESS(ADDR) 0
551
552static PyTypeObject ZipImporter_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000553 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
Just van Rossum52e14d62002-12-30 22:08:05 +0000554 "zipimport.zipimporter",
555 sizeof(ZipImporter),
556 0, /* tp_itemsize */
557 (destructor)zipimporter_dealloc, /* tp_dealloc */
558 0, /* tp_print */
559 0, /* tp_getattr */
560 0, /* tp_setattr */
561 0, /* tp_compare */
562 (reprfunc)zipimporter_repr, /* tp_repr */
563 0, /* tp_as_number */
564 0, /* tp_as_sequence */
565 0, /* tp_as_mapping */
566 0, /* tp_hash */
567 0, /* tp_call */
568 0, /* tp_str */
569 PyObject_GenericGetAttr, /* tp_getattro */
570 0, /* tp_setattro */
571 0, /* tp_as_buffer */
572 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
573 Py_TPFLAGS_HAVE_GC, /* tp_flags */
574 zipimporter_doc, /* tp_doc */
575 zipimporter_traverse, /* tp_traverse */
576 0, /* tp_clear */
577 0, /* tp_richcompare */
578 0, /* tp_weaklistoffset */
579 0, /* tp_iter */
580 0, /* tp_iternext */
581 zipimporter_methods, /* tp_methods */
582 zipimporter_members, /* tp_members */
583 0, /* tp_getset */
584 0, /* tp_base */
585 0, /* tp_dict */
586 0, /* tp_descr_get */
587 0, /* tp_descr_set */
588 0, /* tp_dictoffset */
589 (initproc)zipimporter_init, /* tp_init */
590 PyType_GenericAlloc, /* tp_alloc */
591 PyType_GenericNew, /* tp_new */
592 PyObject_GC_Del, /* tp_free */
593};
594
595
596/* implementation */
597
Just van Rossum52e14d62002-12-30 22:08:05 +0000598/* Given a buffer, return the long that is represented by the first
599 4 bytes, encoded as little endian. This partially reimplements
600 marshal.c:r_long() */
601static long
602get_long(unsigned char *buf) {
603 long x;
604 x = buf[0];
605 x |= (long)buf[1] << 8;
606 x |= (long)buf[2] << 16;
607 x |= (long)buf[3] << 24;
608#if SIZEOF_LONG > 4
609 /* Sign extension for 64-bit machines */
610 x |= -(x & 0x80000000L);
611#endif
612 return x;
613}
614
615/*
616 read_directory(archive) -> files dict (new reference)
617
618 Given a path to a Zip archive, build a dict, mapping file names
619 (local to the archive, using SEP as a separator) to toc entries.
620
621 A toc_entry is a tuple:
622
Fred Drakef5b7fd22005-11-11 19:34:56 +0000623 (__file__, # value to use for __file__, available for all files
624 compress, # compression kind; 0 for uncompressed
Just van Rossum52e14d62002-12-30 22:08:05 +0000625 data_size, # size of compressed data on disk
626 file_size, # size of decompressed data
627 file_offset, # offset of file header from start of archive
628 time, # mod time of file (in dos format)
629 date, # mod data of file (in dos format)
630 crc, # crc checksum of the data
631 )
632
633 Directories can be recognized by the trailing SEP in the name,
634 data_size and file_offset are 0.
635*/
636static PyObject *
637read_directory(char *archive)
638{
639 PyObject *files = NULL;
640 FILE *fp;
641 long compress, crc, data_size, file_size, file_offset, date, time;
Thomas Heller354e3d92003-07-22 18:10:15 +0000642 long header_offset, name_size, header_size, header_position;
Neal Norwitzd39d8612006-01-08 01:03:36 +0000643 long i, l, count;
644 size_t length;
Just van Rossum52e14d62002-12-30 22:08:05 +0000645 char path[MAXPATHLEN + 5];
646 char name[MAXPATHLEN + 5];
647 char *p, endof_central_dir[22];
Thomas Heller354e3d92003-07-22 18:10:15 +0000648 long arc_offset; /* offset from beginning of file to start of zip-archive */
Just van Rossum52e14d62002-12-30 22:08:05 +0000649
650 if (strlen(archive) > MAXPATHLEN) {
651 PyErr_SetString(PyExc_OverflowError,
652 "Zip path name is too long");
653 return NULL;
654 }
655 strcpy(path, archive);
656
657 fp = fopen(archive, "rb");
658 if (fp == NULL) {
659 PyErr_Format(ZipImportError, "can't open Zip file: "
660 "'%.200s'", archive);
661 return NULL;
662 }
Just van Rossumf4ecc752003-02-28 08:54:01 +0000663 fseek(fp, -22, SEEK_END);
Thomas Heller354e3d92003-07-22 18:10:15 +0000664 header_position = ftell(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000665 if (fread(endof_central_dir, 1, 22, fp) != 22) {
666 fclose(fp);
667 PyErr_Format(ZipImportError, "can't read Zip file: "
668 "'%.200s'", archive);
669 return NULL;
670 }
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000671 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000672 /* Bad: End of Central Dir signature */
673 fclose(fp);
674 PyErr_Format(ZipImportError, "not a Zip file: "
675 "'%.200s'", archive);
676 return NULL;
677 }
678
Thomas Heller354e3d92003-07-22 18:10:15 +0000679 header_size = get_long((unsigned char *)endof_central_dir + 12);
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000680 header_offset = get_long((unsigned char *)endof_central_dir + 16);
Thomas Heller354e3d92003-07-22 18:10:15 +0000681 arc_offset = header_position - header_offset - header_size;
682 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000683
684 files = PyDict_New();
685 if (files == NULL)
686 goto error;
687
688 length = (long)strlen(path);
689 path[length] = SEP;
690
691 /* Start of Central Directory */
692 count = 0;
693 for (;;) {
694 PyObject *t;
695 int err;
696
697 fseek(fp, header_offset, 0); /* Start of file header */
698 l = PyMarshal_ReadLongFromFile(fp);
699 if (l != 0x02014B50)
700 break; /* Bad: Central Dir File Header */
701 fseek(fp, header_offset + 10, 0);
702 compress = PyMarshal_ReadShortFromFile(fp);
703 time = PyMarshal_ReadShortFromFile(fp);
704 date = PyMarshal_ReadShortFromFile(fp);
705 crc = PyMarshal_ReadLongFromFile(fp);
706 data_size = PyMarshal_ReadLongFromFile(fp);
707 file_size = PyMarshal_ReadLongFromFile(fp);
708 name_size = PyMarshal_ReadShortFromFile(fp);
709 header_size = 46 + name_size +
710 PyMarshal_ReadShortFromFile(fp) +
711 PyMarshal_ReadShortFromFile(fp);
712 fseek(fp, header_offset + 42, 0);
Thomas Heller354e3d92003-07-22 18:10:15 +0000713 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000714 if (name_size > MAXPATHLEN)
715 name_size = MAXPATHLEN;
716
717 p = name;
718 for (i = 0; i < name_size; i++) {
719 *p = (char)getc(fp);
720 if (*p == '/')
721 *p = SEP;
722 p++;
723 }
724 *p = 0; /* Add terminating null byte */
725 header_offset += header_size;
726
727 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
728
729 t = Py_BuildValue("siiiiiii", path, compress, data_size,
730 file_size, file_offset, time, date, crc);
731 if (t == NULL)
732 goto error;
733 err = PyDict_SetItemString(files, name, t);
734 Py_DECREF(t);
735 if (err != 0)
736 goto error;
737 count++;
738 }
739 fclose(fp);
740 if (Py_VerboseFlag)
741 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
742 count, archive);
743 return files;
744error:
745 fclose(fp);
746 Py_XDECREF(files);
747 return NULL;
748}
749
750/* Return the zlib.decompress function object, or NULL if zlib couldn't
751 be imported. The function is cached when found, so subsequent calls
752 don't import zlib again. Returns a *borrowed* reference.
753 XXX This makes zlib.decompress immortal. */
754static PyObject *
755get_decompress_func(void)
756{
757 static PyObject *decompress = NULL;
758
759 if (decompress == NULL) {
760 PyObject *zlib;
761 static int importing_zlib = 0;
762
763 if (importing_zlib != 0)
764 /* Someone has a zlib.py[co] in their Zip file;
765 let's avoid a stack overflow. */
766 return NULL;
767 importing_zlib = 1;
Christian Heimes072c0f12008-01-03 23:01:04 +0000768 zlib = PyImport_ImportModuleNoBlock("zlib");
Just van Rossum52e14d62002-12-30 22:08:05 +0000769 importing_zlib = 0;
770 if (zlib != NULL) {
771 decompress = PyObject_GetAttrString(zlib,
772 "decompress");
773 Py_DECREF(zlib);
774 }
775 else
776 PyErr_Clear();
777 if (Py_VerboseFlag)
778 PySys_WriteStderr("# zipimport: zlib %s\n",
779 zlib != NULL ? "available": "UNAVAILABLE");
780 }
781 return decompress;
782}
783
784/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
785 data as a new reference. */
786static PyObject *
787get_data(char *archive, PyObject *toc_entry)
788{
789 PyObject *raw_data, *data = NULL, *decompress;
790 char *buf;
791 FILE *fp;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000792 int err;
793 Py_ssize_t bytes_read = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000794 long l;
795 char *datapath;
Neal Norwitz3c814d22007-08-26 05:08:21 +0000796 long compress, data_size, file_size, file_offset, bytes_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000797 long time, date, crc;
798
Neal Norwitz0c0aad92003-02-18 03:37:49 +0000799 if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
Just van Rossum52e14d62002-12-30 22:08:05 +0000800 &data_size, &file_size, &file_offset, &time,
801 &date, &crc)) {
802 return NULL;
803 }
804
805 fp = fopen(archive, "rb");
806 if (!fp) {
807 PyErr_Format(PyExc_IOError,
808 "zipimport: can not open file %s", archive);
809 return NULL;
810 }
811
812 /* Check to make sure the local file header is correct */
813 fseek(fp, file_offset, 0);
814 l = PyMarshal_ReadLongFromFile(fp);
815 if (l != 0x04034B50) {
816 /* Bad: Local File Header */
817 PyErr_Format(ZipImportError,
818 "bad local file header in %s",
819 archive);
820 fclose(fp);
821 return NULL;
822 }
823 fseek(fp, file_offset + 26, 0);
824 l = 30 + PyMarshal_ReadShortFromFile(fp) +
825 PyMarshal_ReadShortFromFile(fp); /* local header size */
826 file_offset += l; /* Start of file data */
827
Neal Norwitz3c814d22007-08-26 05:08:21 +0000828 bytes_size = compress == 0 ? data_size : data_size + 1;
829 if (bytes_size == 0)
830 bytes_size++;
831 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
832
Just van Rossum52e14d62002-12-30 22:08:05 +0000833 if (raw_data == NULL) {
834 fclose(fp);
835 return NULL;
836 }
Neal Norwitz3c814d22007-08-26 05:08:21 +0000837 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000838
839 err = fseek(fp, file_offset, 0);
840 if (err == 0)
841 bytes_read = fread(buf, 1, data_size, fp);
842 fclose(fp);
843 if (err || bytes_read != data_size) {
844 PyErr_SetString(PyExc_IOError,
845 "zipimport: can't read data");
846 Py_DECREF(raw_data);
847 return NULL;
848 }
849
850 if (compress != 0) {
851 buf[data_size] = 'Z'; /* saw this in zipfile.py */
852 data_size++;
853 }
854 buf[data_size] = '\0';
855
Guido van Rossumad8d3002007-08-03 18:40:49 +0000856 if (compress == 0) { /* data is not compressed */
Guido van Rossum76f2b242007-08-17 14:33:37 +0000857 data = PyBytes_FromStringAndSize(buf, data_size);
858 Py_DECREF(raw_data);
859 return data;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000860 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000861
862 /* Decompress with zlib */
863 decompress = get_decompress_func();
864 if (decompress == NULL) {
865 PyErr_SetString(ZipImportError,
866 "can't decompress data; "
867 "zlib not available");
868 goto error;
869 }
Just van Rossumee8f10f2003-09-07 13:36:48 +0000870 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Just van Rossum52e14d62002-12-30 22:08:05 +0000871error:
872 Py_DECREF(raw_data);
873 return data;
874}
875
876/* Lenient date/time comparison function. The precision of the mtime
877 in the archive is lower than the mtime stored in a .pyc: we
878 must allow a difference of at most one second. */
879static int
880eq_mtime(time_t t1, time_t t2)
881{
882 time_t d = t1 - t2;
883 if (d < 0)
884 d = -d;
885 /* dostime only stores even seconds, so be lenient */
886 return d <= 1;
887}
888
889/* Given the contents of a .py[co] file in a buffer, unmarshal the data
890 and return the code object. Return None if it the magic word doesn't
891 match (we do this instead of raising an exception as we fall back
892 to .py if available and we don't want to mask other errors).
893 Returns a new reference. */
894static PyObject *
895unmarshal_code(char *pathname, PyObject *data, time_t mtime)
896{
897 PyObject *code;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000898 char *buf = PyBytes_AsString(data);
899 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000900
901 if (size <= 9) {
902 PyErr_SetString(ZipImportError,
903 "bad pyc data");
904 return NULL;
905 }
906
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000907 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000908 if (Py_VerboseFlag)
909 PySys_WriteStderr("# %s has bad magic\n",
910 pathname);
911 Py_INCREF(Py_None);
912 return Py_None; /* signal caller to try alternative */
913 }
914
Just van Rossum9a3129c2003-01-03 11:18:56 +0000915 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
916 mtime)) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000917 if (Py_VerboseFlag)
918 PySys_WriteStderr("# %s has bad mtime\n",
919 pathname);
920 Py_INCREF(Py_None);
921 return Py_None; /* signal caller to try alternative */
922 }
923
924 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
925 if (code == NULL)
926 return NULL;
927 if (!PyCode_Check(code)) {
928 Py_DECREF(code);
929 PyErr_Format(PyExc_TypeError,
930 "compiled module %.200s is not a code object",
931 pathname);
932 return NULL;
933 }
934 return code;
935}
936
937/* Replace any occurances of "\r\n?" in the input string with "\n".
938 This converts DOS and Mac line endings to Unix line endings.
939 Also append a trailing "\n" to be compatible with
940 PyParser_SimpleParseFile(). Returns a new reference. */
941static PyObject *
942normalize_line_endings(PyObject *source)
943{
Guido van Rossumad8d3002007-08-03 18:40:49 +0000944 char *buf, *q, *p = PyBytes_AsString(source);
Just van Rossum52e14d62002-12-30 22:08:05 +0000945 PyObject *fixed_source;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000946 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000947
Guido van Rossumad8d3002007-08-03 18:40:49 +0000948 if (!p) {
949 return PyBytes_FromStringAndSize("\n\0", 2);
950 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000951
Just van Rossum9a3129c2003-01-03 11:18:56 +0000952 /* one char extra for trailing \n and one for terminating \0 */
Guido van Rossumad8d3002007-08-03 18:40:49 +0000953 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
Just van Rossum9a3129c2003-01-03 11:18:56 +0000954 if (buf == NULL) {
955 PyErr_SetString(PyExc_MemoryError,
956 "zipimport: no memory to allocate "
957 "source buffer");
Just van Rossum52e14d62002-12-30 22:08:05 +0000958 return NULL;
Just van Rossum9a3129c2003-01-03 11:18:56 +0000959 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000960 /* replace "\r\n?" by "\n" */
Neal Norwitz5c1ba532003-02-17 18:05:20 +0000961 for (q = buf; *p != '\0'; p++) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000962 if (*p == '\r') {
963 *q++ = '\n';
Just van Rossum9a3129c2003-01-03 11:18:56 +0000964 if (*(p + 1) == '\n')
Just van Rossum52e14d62002-12-30 22:08:05 +0000965 p++;
Just van Rossum52e14d62002-12-30 22:08:05 +0000966 }
967 else
968 *q++ = *p;
Guido van Rossumad8d3002007-08-03 18:40:49 +0000969 len++;
Just van Rossum52e14d62002-12-30 22:08:05 +0000970 }
971 *q++ = '\n'; /* add trailing \n */
972 *q = '\0';
Guido van Rossumad8d3002007-08-03 18:40:49 +0000973 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
Just van Rossum9a3129c2003-01-03 11:18:56 +0000974 PyMem_Free(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000975 return fixed_source;
976}
977
978/* Given a string buffer containing Python source code, compile it
979 return and return a code object as a new reference. */
980static PyObject *
981compile_source(char *pathname, PyObject *source)
982{
983 PyObject *code, *fixed_source;
984
985 fixed_source = normalize_line_endings(source);
986 if (fixed_source == NULL)
987 return NULL;
988
Guido van Rossumad8d3002007-08-03 18:40:49 +0000989 code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
Just van Rossum52e14d62002-12-30 22:08:05 +0000990 Py_file_input);
991 Py_DECREF(fixed_source);
992 return code;
993}
994
995/* Convert the date/time values found in the Zip archive to a value
996 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +0000997static time_t
998parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +0000999{
1000 struct tm stm;
1001
Christian Heimes679db4a2008-01-18 09:56:22 +00001002 memset((void *) &stm, '\0', sizeof(stm));
1003
Just van Rossum52e14d62002-12-30 22:08:05 +00001004 stm.tm_sec = (dostime & 0x1f) * 2;
1005 stm.tm_min = (dostime >> 5) & 0x3f;
1006 stm.tm_hour = (dostime >> 11) & 0x1f;
1007 stm.tm_mday = dosdate & 0x1f;
1008 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1009 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
Just van Rossum547eb422003-04-08 20:07:15 +00001010 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001011
1012 return mktime(&stm);
1013}
1014
1015/* Given a path to a .pyc or .pyo file in the archive, return the
1016 modifictaion time of the matching .py file, or 0 if no source
1017 is available. */
1018static time_t
1019get_mtime_of_source(ZipImporter *self, char *path)
1020{
1021 PyObject *toc_entry;
1022 time_t mtime = 0;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001023 Py_ssize_t lastchar = strlen(path) - 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001024 char savechar = path[lastchar];
1025 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1026 toc_entry = PyDict_GetItemString(self->files, path);
1027 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1028 PyTuple_Size(toc_entry) == 8) {
Just van Rossumf8b6de12002-12-31 09:51:59 +00001029 /* fetch the time stamp of the .py file for comparison
1030 with an embedded pyc time stamp */
1031 int time, date;
Christian Heimes217cfd12007-12-02 14:31:20 +00001032 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1033 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
Just van Rossum52e14d62002-12-30 22:08:05 +00001034 mtime = parse_dostime(time, date);
1035 }
1036 path[lastchar] = savechar;
1037 return mtime;
1038}
1039
1040/* Return the code object for the module named by 'fullname' from the
1041 Zip archive as a new reference. */
1042static PyObject *
1043get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1044 time_t mtime, PyObject *toc_entry)
1045{
1046 PyObject *data, *code;
1047 char *modpath;
Neal Norwitz3c814d22007-08-26 05:08:21 +00001048 char *archive = PyUnicode_AsString(self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +00001049
1050 if (archive == NULL)
1051 return NULL;
1052
1053 data = get_data(archive, toc_entry);
1054 if (data == NULL)
1055 return NULL;
1056
Neal Norwitz3c814d22007-08-26 05:08:21 +00001057 modpath = PyUnicode_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001058
1059 if (isbytecode) {
1060 code = unmarshal_code(modpath, data, mtime);
1061 }
1062 else {
1063 code = compile_source(modpath, data);
1064 }
1065 Py_DECREF(data);
1066 return code;
1067}
1068
1069/* Get the code object assoiciated with the module specified by
1070 'fullname'. */
1071static PyObject *
1072get_module_code(ZipImporter *self, char *fullname,
1073 int *p_ispackage, char **p_modpath)
1074{
1075 PyObject *toc_entry;
1076 char *subname, path[MAXPATHLEN + 1];
1077 int len;
1078 struct st_zip_searchorder *zso;
1079
1080 subname = get_subname(fullname);
1081
Neal Norwitz3c814d22007-08-26 05:08:21 +00001082 len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +00001083 if (len < 0)
1084 return NULL;
1085
1086 for (zso = zip_searchorder; *zso->suffix; zso++) {
1087 PyObject *code = NULL;
1088
1089 strcpy(path + len, zso->suffix);
1090 if (Py_VerboseFlag > 1)
1091 PySys_WriteStderr("# trying %s%c%s\n",
Neal Norwitz3c814d22007-08-26 05:08:21 +00001092 PyUnicode_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +00001093 SEP, path);
1094 toc_entry = PyDict_GetItemString(self->files, path);
1095 if (toc_entry != NULL) {
1096 time_t mtime = 0;
1097 int ispackage = zso->type & IS_PACKAGE;
1098 int isbytecode = zso->type & IS_BYTECODE;
1099
1100 if (isbytecode)
1101 mtime = get_mtime_of_source(self, path);
1102 if (p_ispackage != NULL)
1103 *p_ispackage = ispackage;
1104 code = get_code_from_data(self, ispackage,
1105 isbytecode, mtime,
1106 toc_entry);
1107 if (code == Py_None) {
1108 /* bad magic number or non-matching mtime
1109 in byte code, try next */
1110 Py_DECREF(code);
1111 continue;
1112 }
1113 if (code != NULL && p_modpath != NULL)
Neal Norwitz3c814d22007-08-26 05:08:21 +00001114 *p_modpath = PyUnicode_AsString(
Just van Rossum52e14d62002-12-30 22:08:05 +00001115 PyTuple_GetItem(toc_entry, 0));
1116 return code;
1117 }
1118 }
1119 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1120 return NULL;
1121}
1122
1123
1124/* Module init */
1125
1126PyDoc_STRVAR(zipimport_doc,
1127"zipimport provides support for importing Python modules from Zip archives.\n\
1128\n\
1129This module exports three objects:\n\
1130- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001131- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001132 subclass of ImportError, so it can be caught as ImportError, too.\n\
1133- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1134 info dicts, as used in zipimporter._files.\n\
1135\n\
1136It is usually not needed to use the zipimport module explicitly; it is\n\
1137used by the builtin import mechanism for sys.path items that are paths\n\
1138to Zip archives.");
1139
1140PyMODINIT_FUNC
1141initzipimport(void)
1142{
1143 PyObject *mod;
1144
1145 if (PyType_Ready(&ZipImporter_Type) < 0)
1146 return;
1147
1148 /* Correct directory separator */
1149 zip_searchorder[0].suffix[0] = SEP;
1150 zip_searchorder[1].suffix[0] = SEP;
1151 zip_searchorder[2].suffix[0] = SEP;
1152 if (Py_OptimizeFlag) {
1153 /* Reverse *.pyc and *.pyo */
1154 struct st_zip_searchorder tmp;
1155 tmp = zip_searchorder[0];
1156 zip_searchorder[0] = zip_searchorder[1];
1157 zip_searchorder[1] = tmp;
1158 tmp = zip_searchorder[3];
1159 zip_searchorder[3] = zip_searchorder[4];
1160 zip_searchorder[4] = tmp;
1161 }
1162
1163 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1164 NULL, PYTHON_API_VERSION);
Hye-Shik Chang4af5c8c2006-03-07 15:39:21 +00001165 if (mod == NULL)
1166 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001167
1168 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1169 PyExc_ImportError, NULL);
1170 if (ZipImportError == NULL)
1171 return;
1172
1173 Py_INCREF(ZipImportError);
1174 if (PyModule_AddObject(mod, "ZipImportError",
1175 ZipImportError) < 0)
1176 return;
1177
1178 Py_INCREF(&ZipImporter_Type);
1179 if (PyModule_AddObject(mod, "zipimporter",
1180 (PyObject *)&ZipImporter_Type) < 0)
1181 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001182
Just van Rossum52e14d62002-12-30 22:08:05 +00001183 zip_directory_cache = PyDict_New();
1184 if (zip_directory_cache == NULL)
1185 return;
1186 Py_INCREF(zip_directory_cache);
1187 if (PyModule_AddObject(mod, "_zip_directory_cache",
1188 zip_directory_cache) < 0)
1189 return;
1190}