blob: e320dd9df8522f9d4bbd7fc0eaa5ed996d32c90b [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];
Neal Norwitzd39d8612006-01-08 01:03:36 +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
Just van Rossum52e14d62002-12-30 22:08:05 +000069 if (!PyArg_ParseTuple(args, "s:zipimporter",
70 &path))
71 return -1;
72
73 len = strlen(path);
74 if (len == 0) {
75 PyErr_SetString(ZipImportError, "archive path is empty");
76 return -1;
77 }
78 if (len >= MAXPATHLEN) {
79 PyErr_SetString(ZipImportError,
80 "archive path too long");
81 return -1;
82 }
83 strcpy(buf, path);
84
85#ifdef ALTSEP
86 for (p = buf; *p; p++) {
87 if (*p == ALTSEP)
88 *p = SEP;
89 }
90#endif
91
92 path = NULL;
93 prefix = NULL;
94 for (;;) {
Martin v. Löwisa94568a2003-05-10 07:36:56 +000095#ifndef RISCOS
Just van Rossum52e14d62002-12-30 22:08:05 +000096 struct stat statbuf;
97 int rv;
98
99 rv = stat(buf, &statbuf);
100 if (rv == 0) {
101 /* it exists */
102 if (S_ISREG(statbuf.st_mode))
103 /* it's a file */
104 path = buf;
105 break;
106 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000107#else
108 if (object_exists(buf)) {
109 /* it exists */
110 if (isfile(buf))
111 /* it's a file */
112 path = buf;
113 break;
114 }
115#endif
Just van Rossum52e14d62002-12-30 22:08:05 +0000116 /* back up one path element */
Just van Rossumd35c6db2003-01-02 12:55:48 +0000117 p = strrchr(buf, SEP);
Just van Rossum52e14d62002-12-30 22:08:05 +0000118 if (prefix != NULL)
119 *prefix = SEP;
120 if (p == NULL)
121 break;
122 *p = '\0';
123 prefix = p;
124 }
125 if (path != NULL) {
126 PyObject *files;
127 files = PyDict_GetItemString(zip_directory_cache, path);
128 if (files == NULL) {
129 files = read_directory(buf);
130 if (files == NULL)
131 return -1;
132 if (PyDict_SetItemString(zip_directory_cache, path,
133 files) != 0)
134 return -1;
135 }
136 else
137 Py_INCREF(files);
138 self->files = files;
139 }
140 else {
141 PyErr_SetString(ZipImportError, "not a Zip file");
142 return -1;
143 }
144
145 if (prefix == NULL)
146 prefix = "";
147 else {
148 prefix++;
149 len = strlen(prefix);
150 if (prefix[len-1] != SEP) {
151 /* add trailing SEP */
152 prefix[len] = SEP;
153 prefix[len + 1] = '\0';
154 }
155 }
156
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000157 self->archive = PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000158 if (self->archive == NULL)
159 return -1;
160
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000161 self->prefix = PyString_FromString(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000162 if (self->prefix == NULL)
163 return -1;
164
165 return 0;
166}
167
168/* GC support. */
169static int
170zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
171{
172 ZipImporter *self = (ZipImporter *)obj;
Thomas Woutersc6e55062006-04-15 21:47:09 +0000173 Py_VISIT(self->files);
Just van Rossum52e14d62002-12-30 22:08:05 +0000174 return 0;
175}
176
177static void
178zipimporter_dealloc(ZipImporter *self)
179{
180 PyObject_GC_UnTrack(self);
181 Py_XDECREF(self->archive);
Just van Rossumf8b6de12002-12-31 09:51:59 +0000182 Py_XDECREF(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000183 Py_XDECREF(self->files);
Christian Heimese93237d2007-12-19 02:37:44 +0000184 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000185}
186
187static PyObject *
188zipimporter_repr(ZipImporter *self)
189{
190 char buf[500];
191 char *archive = "???";
192 char *prefix = "";
193
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000194 if (self->archive != NULL && PyString_Check(self->archive))
195 archive = PyString_AsString(self->archive);
196 if (self->prefix != NULL && PyString_Check(self->prefix))
197 prefix = PyString_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000198 if (prefix != NULL && *prefix)
199 PyOS_snprintf(buf, sizeof(buf),
200 "<zipimporter object \"%.300s%c%.150s\">",
201 archive, SEP, prefix);
202 else
203 PyOS_snprintf(buf, sizeof(buf),
204 "<zipimporter object \"%.300s\">",
205 archive);
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000206 return PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000207}
208
209/* return fullname.split(".")[-1] */
210static char *
211get_subname(char *fullname)
212{
213 char *subname = strrchr(fullname, '.');
214 if (subname == NULL)
215 subname = fullname;
216 else
217 subname++;
218 return subname;
219}
220
221/* Given a (sub)modulename, write the potential file path in the
222 archive (without extension) to the path buffer. Return the
223 length of the resulting string. */
224static int
225make_filename(char *prefix, char *name, char *path)
226{
Neal Norwitzd39d8612006-01-08 01:03:36 +0000227 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000228 char *p;
229
230 len = strlen(prefix);
231
232 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
233 if (len + strlen(name) + 13 >= MAXPATHLEN) {
234 PyErr_SetString(ZipImportError, "path too long");
235 return -1;
236 }
237
238 strcpy(path, prefix);
239 strcpy(path + len, name);
240 for (p = path + len; *p; p++) {
241 if (*p == '.')
242 *p = SEP;
243 }
244 len += strlen(name);
Martin v. Löwis18e16552006-02-15 17:27:45 +0000245 assert(len < INT_MAX);
Neal Norwitzd39d8612006-01-08 01:03:36 +0000246 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000247}
248
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000249enum zi_module_info {
Just van Rossum52e14d62002-12-30 22:08:05 +0000250 MI_ERROR,
251 MI_NOT_FOUND,
252 MI_MODULE,
253 MI_PACKAGE
254};
255
256/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000257static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000258get_module_info(ZipImporter *self, char *fullname)
259{
260 char *subname, path[MAXPATHLEN + 1];
261 int len;
262 struct st_zip_searchorder *zso;
263
264 subname = get_subname(fullname);
265
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000266 len = make_filename(PyString_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000267 if (len < 0)
268 return MI_ERROR;
269
270 for (zso = zip_searchorder; *zso->suffix; zso++) {
271 strcpy(path + len, zso->suffix);
272 if (PyDict_GetItemString(self->files, path) != NULL) {
273 if (zso->type & IS_PACKAGE)
274 return MI_PACKAGE;
275 else
276 return MI_MODULE;
277 }
278 }
279 return MI_NOT_FOUND;
280}
281
282/* Check whether we can satisfy the import of the module named by
283 'fullname'. Return self if we can, None if we can't. */
284static PyObject *
285zipimporter_find_module(PyObject *obj, PyObject *args)
286{
287 ZipImporter *self = (ZipImporter *)obj;
288 PyObject *path = NULL;
289 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000290 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000291
292 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
293 &fullname, &path))
294 return NULL;
295
296 mi = get_module_info(self, fullname);
297 if (mi == MI_ERROR)
298 return NULL;
299 if (mi == MI_NOT_FOUND) {
300 Py_INCREF(Py_None);
301 return Py_None;
302 }
303 Py_INCREF(self);
304 return (PyObject *)self;
305}
306
307/* Load and return the module named by 'fullname'. */
308static PyObject *
309zipimporter_load_module(PyObject *obj, PyObject *args)
310{
311 ZipImporter *self = (ZipImporter *)obj;
312 PyObject *code, *mod, *dict;
313 char *fullname, *modpath;
314 int ispackage;
315
316 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
317 &fullname))
318 return NULL;
319
320 code = get_module_code(self, fullname, &ispackage, &modpath);
321 if (code == NULL)
322 return NULL;
323
324 mod = PyImport_AddModule(fullname);
325 if (mod == NULL) {
326 Py_DECREF(code);
327 return NULL;
328 }
329 dict = PyModule_GetDict(mod);
330
331 /* mod.__loader__ = self */
332 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
333 goto error;
334
335 if (ispackage) {
336 /* add __path__ to the module *before* the code gets
337 executed */
338 PyObject *pkgpath, *fullpath;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000339 char *prefix = PyString_AsString(self->prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000340 char *subname = get_subname(fullname);
341 int err;
342
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000343 fullpath = PyString_FromFormat("%s%c%s%s",
344 PyString_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +0000345 SEP,
346 *prefix ? prefix : "",
347 subname);
348 if (fullpath == NULL)
349 goto error;
350
351 pkgpath = Py_BuildValue("[O]", fullpath);
352 Py_DECREF(fullpath);
353 if (pkgpath == NULL)
354 goto error;
355 err = PyDict_SetItemString(dict, "__path__", pkgpath);
356 Py_DECREF(pkgpath);
357 if (err != 0)
358 goto error;
359 }
360 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
361 Py_DECREF(code);
362 if (Py_VerboseFlag)
363 PySys_WriteStderr("import %s # loaded from Zip %s\n",
364 fullname, modpath);
365 return mod;
366error:
367 Py_DECREF(code);
368 Py_DECREF(mod);
369 return NULL;
370}
371
Nick Coghlana2053472008-12-14 10:54:50 +0000372/* Return a string matching __file__ for the named module */
373static PyObject *
374zipimporter_get_filename(PyObject *obj, PyObject *args)
375{
376 ZipImporter *self = (ZipImporter *)obj;
377 PyObject *code;
378 char *fullname, *modpath;
379 int ispackage;
380
381 if (!PyArg_ParseTuple(args, "s:zipimporter._get_filename",
382 &fullname))
383 return NULL;
384
385 /* Deciding the filename requires working out where the code
386 would come from if the module was actually loaded */
387 code = get_module_code(self, fullname, &ispackage, &modpath);
388 if (code == NULL)
389 return NULL;
390 Py_DECREF(code); /* Only need the path info */
391
392 return PyString_FromString(modpath);
393}
394
Just van Rossum52e14d62002-12-30 22:08:05 +0000395/* Return a bool signifying whether the module is a package or not. */
396static PyObject *
397zipimporter_is_package(PyObject *obj, PyObject *args)
398{
399 ZipImporter *self = (ZipImporter *)obj;
400 char *fullname;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000401 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000402
Neal Norwitz5c1ba532003-02-17 18:05:20 +0000403 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
Just van Rossum52e14d62002-12-30 22:08:05 +0000404 &fullname))
405 return NULL;
406
407 mi = get_module_info(self, fullname);
408 if (mi == MI_ERROR)
409 return NULL;
410 if (mi == MI_NOT_FOUND) {
411 PyErr_Format(ZipImportError, "can't find module '%.200s'",
412 fullname);
413 return NULL;
414 }
415 return PyBool_FromLong(mi == MI_PACKAGE);
416}
417
418static PyObject *
419zipimporter_get_data(PyObject *obj, PyObject *args)
420{
421 ZipImporter *self = (ZipImporter *)obj;
422 char *path;
423#ifdef ALTSEP
Tim Peters1ea93f22002-12-30 22:42:57 +0000424 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000425#endif
426 PyObject *toc_entry;
Martin v. Löwisad0a4622006-02-16 14:30:23 +0000427 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000428
429 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
430 return NULL;
431
432#ifdef ALTSEP
433 if (strlen(path) >= MAXPATHLEN) {
434 PyErr_SetString(ZipImportError, "path too long");
435 return NULL;
436 }
437 strcpy(buf, path);
438 for (p = buf; *p; p++) {
439 if (*p == ALTSEP)
440 *p = SEP;
441 }
442 path = buf;
443#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000444 len = PyString_Size(self->archive);
Tim Petersf271c272002-12-30 22:44:03 +0000445 if ((size_t)len < strlen(path) &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000446 strncmp(path, PyString_AsString(self->archive), len) == 0 &&
Just van Rossum52e14d62002-12-30 22:08:05 +0000447 path[len] == SEP) {
448 path = path + len + 1;
449 }
450
451 toc_entry = PyDict_GetItemString(self->files, path);
452 if (toc_entry == NULL) {
Georg Brandle9b19492006-02-19 09:38:58 +0000453 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000454 return NULL;
455 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000456 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000457}
458
459static PyObject *
460zipimporter_get_code(PyObject *obj, PyObject *args)
461{
462 ZipImporter *self = (ZipImporter *)obj;
463 char *fullname;
464
465 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
466 return NULL;
467
468 return get_module_code(self, fullname, NULL, NULL);
469}
470
471static PyObject *
472zipimporter_get_source(PyObject *obj, PyObject *args)
473{
474 ZipImporter *self = (ZipImporter *)obj;
475 PyObject *toc_entry;
476 char *fullname, *subname, path[MAXPATHLEN+1];
477 int len;
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000478 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000479
480 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
481 return NULL;
482
483 mi = get_module_info(self, fullname);
484 if (mi == MI_ERROR)
485 return NULL;
486 if (mi == MI_NOT_FOUND) {
487 PyErr_Format(ZipImportError, "can't find module '%.200s'",
488 fullname);
489 return NULL;
490 }
491 subname = get_subname(fullname);
492
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000493 len = make_filename(PyString_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000494 if (len < 0)
495 return NULL;
496
497 if (mi == MI_PACKAGE) {
498 path[len] = SEP;
499 strcpy(path + len + 1, "__init__.py");
500 }
501 else
502 strcpy(path + len, ".py");
503
504 toc_entry = PyDict_GetItemString(self->files, path);
505 if (toc_entry != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000506 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000507
508 /* we have the module, but no source */
509 Py_INCREF(Py_None);
510 return Py_None;
511}
512
513PyDoc_STRVAR(doc_find_module,
514"find_module(fullname, path=None) -> self or None.\n\
515\n\
516Search for a module specified by 'fullname'. 'fullname' must be the\n\
517fully qualified (dotted) module name. It returns the zipimporter\n\
518instance itself if the module was found, or None if it wasn't.\n\
519The optional 'path' argument is ignored -- it's there for compatibility\n\
520with the importer protocol.");
521
522PyDoc_STRVAR(doc_load_module,
523"load_module(fullname) -> module.\n\
524\n\
525Load the module specified by 'fullname'. 'fullname' must be the\n\
526fully qualified (dotted) module name. It returns the imported\n\
527module, or raises ZipImportError if it wasn't found.");
528
529PyDoc_STRVAR(doc_get_data,
530"get_data(pathname) -> string with file data.\n\
531\n\
532Return the data associated with 'pathname'. Raise IOError if\n\
533the file wasn't found.");
534
535PyDoc_STRVAR(doc_is_package,
536"is_package(fullname) -> bool.\n\
537\n\
538Return True if the module specified by fullname is a package.\n\
539Raise ZipImportError is the module couldn't be found.");
540
541PyDoc_STRVAR(doc_get_code,
542"get_code(fullname) -> code object.\n\
543\n\
544Return the code object for the specified module. Raise ZipImportError\n\
545is the module couldn't be found.");
546
547PyDoc_STRVAR(doc_get_source,
548"get_source(fullname) -> source string.\n\
549\n\
550Return the source code for the specified module. Raise ZipImportError\n\
551is the module couldn't be found, return None if the archive does\n\
552contain the module, but has no source for it.");
553
Nick Coghlana2053472008-12-14 10:54:50 +0000554
555PyDoc_STRVAR(doc_get_filename,
556"_get_filename(fullname) -> filename string.\n\
557\n\
558Return the filename for the specified module.");
559
Just van Rossum52e14d62002-12-30 22:08:05 +0000560static PyMethodDef zipimporter_methods[] = {
561 {"find_module", zipimporter_find_module, METH_VARARGS,
562 doc_find_module},
563 {"load_module", zipimporter_load_module, METH_VARARGS,
564 doc_load_module},
565 {"get_data", zipimporter_get_data, METH_VARARGS,
566 doc_get_data},
567 {"get_code", zipimporter_get_code, METH_VARARGS,
568 doc_get_code},
569 {"get_source", zipimporter_get_source, METH_VARARGS,
570 doc_get_source},
Nick Coghlana2053472008-12-14 10:54:50 +0000571 {"_get_filename", zipimporter_get_filename, METH_VARARGS,
572 doc_get_filename},
Just van Rossum52e14d62002-12-30 22:08:05 +0000573 {"is_package", zipimporter_is_package, METH_VARARGS,
574 doc_is_package},
575 {NULL, NULL} /* sentinel */
576};
577
578static PyMemberDef zipimporter_members[] = {
579 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
580 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
581 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
582 {NULL}
583};
584
585PyDoc_STRVAR(zipimporter_doc,
586"zipimporter(archivepath) -> zipimporter object\n\
587\n\
588Create a new zipimporter instance. 'archivepath' must be a path to\n\
Georg Brandl6a57c082008-05-11 15:05:13 +0000589a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
590'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
591valid directory inside the archive.\n\
592\n\
593'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
594archive.\n\
595\n\
596The 'archive' attribute of zipimporter objects contains the name of the\n\
597zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000598
599#define DEFERRED_ADDRESS(ADDR) 0
600
601static PyTypeObject ZipImporter_Type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000602 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
Just van Rossum52e14d62002-12-30 22:08:05 +0000603 "zipimport.zipimporter",
604 sizeof(ZipImporter),
605 0, /* tp_itemsize */
606 (destructor)zipimporter_dealloc, /* tp_dealloc */
607 0, /* tp_print */
608 0, /* tp_getattr */
609 0, /* tp_setattr */
610 0, /* tp_compare */
611 (reprfunc)zipimporter_repr, /* tp_repr */
612 0, /* tp_as_number */
613 0, /* tp_as_sequence */
614 0, /* tp_as_mapping */
615 0, /* tp_hash */
616 0, /* tp_call */
617 0, /* tp_str */
618 PyObject_GenericGetAttr, /* tp_getattro */
619 0, /* tp_setattro */
620 0, /* tp_as_buffer */
621 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
622 Py_TPFLAGS_HAVE_GC, /* tp_flags */
623 zipimporter_doc, /* tp_doc */
624 zipimporter_traverse, /* tp_traverse */
625 0, /* tp_clear */
626 0, /* tp_richcompare */
627 0, /* tp_weaklistoffset */
628 0, /* tp_iter */
629 0, /* tp_iternext */
630 zipimporter_methods, /* tp_methods */
631 zipimporter_members, /* tp_members */
632 0, /* tp_getset */
633 0, /* tp_base */
634 0, /* tp_dict */
635 0, /* tp_descr_get */
636 0, /* tp_descr_set */
637 0, /* tp_dictoffset */
638 (initproc)zipimporter_init, /* tp_init */
639 PyType_GenericAlloc, /* tp_alloc */
640 PyType_GenericNew, /* tp_new */
641 PyObject_GC_Del, /* tp_free */
642};
643
644
645/* implementation */
646
Just van Rossum52e14d62002-12-30 22:08:05 +0000647/* Given a buffer, return the long that is represented by the first
648 4 bytes, encoded as little endian. This partially reimplements
649 marshal.c:r_long() */
650static long
651get_long(unsigned char *buf) {
652 long x;
653 x = buf[0];
654 x |= (long)buf[1] << 8;
655 x |= (long)buf[2] << 16;
656 x |= (long)buf[3] << 24;
657#if SIZEOF_LONG > 4
658 /* Sign extension for 64-bit machines */
659 x |= -(x & 0x80000000L);
660#endif
661 return x;
662}
663
664/*
665 read_directory(archive) -> files dict (new reference)
666
667 Given a path to a Zip archive, build a dict, mapping file names
668 (local to the archive, using SEP as a separator) to toc entries.
669
670 A toc_entry is a tuple:
671
Fred Drakef5b7fd22005-11-11 19:34:56 +0000672 (__file__, # value to use for __file__, available for all files
673 compress, # compression kind; 0 for uncompressed
Just van Rossum52e14d62002-12-30 22:08:05 +0000674 data_size, # size of compressed data on disk
675 file_size, # size of decompressed data
676 file_offset, # offset of file header from start of archive
677 time, # mod time of file (in dos format)
678 date, # mod data of file (in dos format)
679 crc, # crc checksum of the data
680 )
681
682 Directories can be recognized by the trailing SEP in the name,
683 data_size and file_offset are 0.
684*/
685static PyObject *
686read_directory(char *archive)
687{
688 PyObject *files = NULL;
689 FILE *fp;
690 long compress, crc, data_size, file_size, file_offset, date, time;
Thomas Heller354e3d92003-07-22 18:10:15 +0000691 long header_offset, name_size, header_size, header_position;
Neal Norwitzd39d8612006-01-08 01:03:36 +0000692 long i, l, count;
693 size_t length;
Just van Rossum52e14d62002-12-30 22:08:05 +0000694 char path[MAXPATHLEN + 5];
695 char name[MAXPATHLEN + 5];
696 char *p, endof_central_dir[22];
Thomas Heller354e3d92003-07-22 18:10:15 +0000697 long arc_offset; /* offset from beginning of file to start of zip-archive */
Just van Rossum52e14d62002-12-30 22:08:05 +0000698
699 if (strlen(archive) > MAXPATHLEN) {
700 PyErr_SetString(PyExc_OverflowError,
701 "Zip path name is too long");
702 return NULL;
703 }
704 strcpy(path, archive);
705
706 fp = fopen(archive, "rb");
707 if (fp == NULL) {
708 PyErr_Format(ZipImportError, "can't open Zip file: "
709 "'%.200s'", archive);
710 return NULL;
711 }
Just van Rossumf4ecc752003-02-28 08:54:01 +0000712 fseek(fp, -22, SEEK_END);
Thomas Heller354e3d92003-07-22 18:10:15 +0000713 header_position = ftell(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000714 if (fread(endof_central_dir, 1, 22, fp) != 22) {
715 fclose(fp);
716 PyErr_Format(ZipImportError, "can't read Zip file: "
717 "'%.200s'", archive);
718 return NULL;
719 }
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000720 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000721 /* Bad: End of Central Dir signature */
722 fclose(fp);
723 PyErr_Format(ZipImportError, "not a Zip file: "
724 "'%.200s'", archive);
725 return NULL;
726 }
727
Thomas Heller354e3d92003-07-22 18:10:15 +0000728 header_size = get_long((unsigned char *)endof_central_dir + 12);
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000729 header_offset = get_long((unsigned char *)endof_central_dir + 16);
Thomas Heller354e3d92003-07-22 18:10:15 +0000730 arc_offset = header_position - header_offset - header_size;
731 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000732
733 files = PyDict_New();
734 if (files == NULL)
735 goto error;
736
737 length = (long)strlen(path);
738 path[length] = SEP;
739
740 /* Start of Central Directory */
741 count = 0;
742 for (;;) {
743 PyObject *t;
744 int err;
745
746 fseek(fp, header_offset, 0); /* Start of file header */
747 l = PyMarshal_ReadLongFromFile(fp);
748 if (l != 0x02014B50)
749 break; /* Bad: Central Dir File Header */
750 fseek(fp, header_offset + 10, 0);
751 compress = PyMarshal_ReadShortFromFile(fp);
752 time = PyMarshal_ReadShortFromFile(fp);
753 date = PyMarshal_ReadShortFromFile(fp);
754 crc = PyMarshal_ReadLongFromFile(fp);
755 data_size = PyMarshal_ReadLongFromFile(fp);
756 file_size = PyMarshal_ReadLongFromFile(fp);
757 name_size = PyMarshal_ReadShortFromFile(fp);
758 header_size = 46 + name_size +
759 PyMarshal_ReadShortFromFile(fp) +
760 PyMarshal_ReadShortFromFile(fp);
761 fseek(fp, header_offset + 42, 0);
Thomas Heller354e3d92003-07-22 18:10:15 +0000762 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000763 if (name_size > MAXPATHLEN)
764 name_size = MAXPATHLEN;
765
766 p = name;
767 for (i = 0; i < name_size; i++) {
768 *p = (char)getc(fp);
769 if (*p == '/')
770 *p = SEP;
771 p++;
772 }
773 *p = 0; /* Add terminating null byte */
774 header_offset += header_size;
775
776 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
777
778 t = Py_BuildValue("siiiiiii", path, compress, data_size,
779 file_size, file_offset, time, date, crc);
780 if (t == NULL)
781 goto error;
782 err = PyDict_SetItemString(files, name, t);
783 Py_DECREF(t);
784 if (err != 0)
785 goto error;
786 count++;
787 }
788 fclose(fp);
789 if (Py_VerboseFlag)
790 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
791 count, archive);
792 return files;
793error:
794 fclose(fp);
795 Py_XDECREF(files);
796 return NULL;
797}
798
799/* Return the zlib.decompress function object, or NULL if zlib couldn't
800 be imported. The function is cached when found, so subsequent calls
801 don't import zlib again. Returns a *borrowed* reference.
802 XXX This makes zlib.decompress immortal. */
803static PyObject *
804get_decompress_func(void)
805{
806 static PyObject *decompress = NULL;
807
808 if (decompress == NULL) {
809 PyObject *zlib;
810 static int importing_zlib = 0;
811
812 if (importing_zlib != 0)
813 /* Someone has a zlib.py[co] in their Zip file;
814 let's avoid a stack overflow. */
815 return NULL;
816 importing_zlib = 1;
Christian Heimes000a0742008-01-03 22:16:32 +0000817 zlib = PyImport_ImportModuleNoBlock("zlib");
Just van Rossum52e14d62002-12-30 22:08:05 +0000818 importing_zlib = 0;
819 if (zlib != NULL) {
820 decompress = PyObject_GetAttrString(zlib,
821 "decompress");
822 Py_DECREF(zlib);
823 }
824 else
825 PyErr_Clear();
826 if (Py_VerboseFlag)
827 PySys_WriteStderr("# zipimport: zlib %s\n",
828 zlib != NULL ? "available": "UNAVAILABLE");
829 }
830 return decompress;
831}
832
833/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
834 data as a new reference. */
835static PyObject *
836get_data(char *archive, PyObject *toc_entry)
837{
838 PyObject *raw_data, *data = NULL, *decompress;
839 char *buf;
840 FILE *fp;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000841 int err;
842 Py_ssize_t bytes_read = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000843 long l;
844 char *datapath;
845 long compress, data_size, file_size, file_offset;
846 long time, date, crc;
847
Neal Norwitz0c0aad92003-02-18 03:37:49 +0000848 if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
Just van Rossum52e14d62002-12-30 22:08:05 +0000849 &data_size, &file_size, &file_offset, &time,
850 &date, &crc)) {
851 return NULL;
852 }
853
854 fp = fopen(archive, "rb");
855 if (!fp) {
856 PyErr_Format(PyExc_IOError,
857 "zipimport: can not open file %s", archive);
858 return NULL;
859 }
860
861 /* Check to make sure the local file header is correct */
862 fseek(fp, file_offset, 0);
863 l = PyMarshal_ReadLongFromFile(fp);
864 if (l != 0x04034B50) {
865 /* Bad: Local File Header */
866 PyErr_Format(ZipImportError,
867 "bad local file header in %s",
868 archive);
869 fclose(fp);
870 return NULL;
871 }
872 fseek(fp, file_offset + 26, 0);
873 l = 30 + PyMarshal_ReadShortFromFile(fp) +
874 PyMarshal_ReadShortFromFile(fp); /* local header size */
875 file_offset += l; /* Start of file data */
876
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000877 raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
Just van Rossum52e14d62002-12-30 22:08:05 +0000878 data_size : data_size + 1);
879 if (raw_data == NULL) {
880 fclose(fp);
881 return NULL;
882 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000883 buf = PyString_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000884
885 err = fseek(fp, file_offset, 0);
886 if (err == 0)
887 bytes_read = fread(buf, 1, data_size, fp);
888 fclose(fp);
889 if (err || bytes_read != data_size) {
890 PyErr_SetString(PyExc_IOError,
891 "zipimport: can't read data");
892 Py_DECREF(raw_data);
893 return NULL;
894 }
895
896 if (compress != 0) {
897 buf[data_size] = 'Z'; /* saw this in zipfile.py */
898 data_size++;
899 }
900 buf[data_size] = '\0';
901
902 if (compress == 0) /* data is not compressed */
903 return raw_data;
904
905 /* Decompress with zlib */
906 decompress = get_decompress_func();
907 if (decompress == NULL) {
908 PyErr_SetString(ZipImportError,
909 "can't decompress data; "
910 "zlib not available");
911 goto error;
912 }
Just van Rossumee8f10f2003-09-07 13:36:48 +0000913 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Just van Rossum52e14d62002-12-30 22:08:05 +0000914error:
915 Py_DECREF(raw_data);
916 return data;
917}
918
919/* Lenient date/time comparison function. The precision of the mtime
920 in the archive is lower than the mtime stored in a .pyc: we
921 must allow a difference of at most one second. */
922static int
923eq_mtime(time_t t1, time_t t2)
924{
925 time_t d = t1 - t2;
926 if (d < 0)
927 d = -d;
928 /* dostime only stores even seconds, so be lenient */
929 return d <= 1;
930}
931
932/* Given the contents of a .py[co] file in a buffer, unmarshal the data
933 and return the code object. Return None if it the magic word doesn't
934 match (we do this instead of raising an exception as we fall back
935 to .py if available and we don't want to mask other errors).
936 Returns a new reference. */
937static PyObject *
938unmarshal_code(char *pathname, PyObject *data, time_t mtime)
939{
940 PyObject *code;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000941 char *buf = PyString_AsString(data);
942 Py_ssize_t size = PyString_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000943
944 if (size <= 9) {
945 PyErr_SetString(ZipImportError,
946 "bad pyc data");
947 return NULL;
948 }
949
Jack Jansen5eaeaf92002-12-30 23:06:14 +0000950 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000951 if (Py_VerboseFlag)
952 PySys_WriteStderr("# %s has bad magic\n",
953 pathname);
954 Py_INCREF(Py_None);
955 return Py_None; /* signal caller to try alternative */
956 }
957
Just van Rossum9a3129c2003-01-03 11:18:56 +0000958 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
959 mtime)) {
Just van Rossum52e14d62002-12-30 22:08:05 +0000960 if (Py_VerboseFlag)
961 PySys_WriteStderr("# %s has bad mtime\n",
962 pathname);
963 Py_INCREF(Py_None);
964 return Py_None; /* signal caller to try alternative */
965 }
966
967 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
968 if (code == NULL)
969 return NULL;
970 if (!PyCode_Check(code)) {
971 Py_DECREF(code);
972 PyErr_Format(PyExc_TypeError,
973 "compiled module %.200s is not a code object",
974 pathname);
975 return NULL;
976 }
977 return code;
978}
979
980/* Replace any occurances of "\r\n?" in the input string with "\n".
981 This converts DOS and Mac line endings to Unix line endings.
982 Also append a trailing "\n" to be compatible with
983 PyParser_SimpleParseFile(). Returns a new reference. */
984static PyObject *
985normalize_line_endings(PyObject *source)
986{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000987 char *buf, *q, *p = PyString_AsString(source);
Just van Rossum52e14d62002-12-30 22:08:05 +0000988 PyObject *fixed_source;
989
Neal Norwitzee7c8f92006-08-13 18:12:03 +0000990 if (!p)
991 return NULL;
992
Just van Rossum9a3129c2003-01-03 11:18:56 +0000993 /* one char extra for trailing \n and one for terminating \0 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000994 buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
Just van Rossum9a3129c2003-01-03 11:18:56 +0000995 if (buf == NULL) {
996 PyErr_SetString(PyExc_MemoryError,
997 "zipimport: no memory to allocate "
998 "source buffer");
Just van Rossum52e14d62002-12-30 22:08:05 +0000999 return NULL;
Just van Rossum9a3129c2003-01-03 11:18:56 +00001000 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001001 /* replace "\r\n?" by "\n" */
Neal Norwitz5c1ba532003-02-17 18:05:20 +00001002 for (q = buf; *p != '\0'; p++) {
Just van Rossum52e14d62002-12-30 22:08:05 +00001003 if (*p == '\r') {
1004 *q++ = '\n';
Just van Rossum9a3129c2003-01-03 11:18:56 +00001005 if (*(p + 1) == '\n')
Just van Rossum52e14d62002-12-30 22:08:05 +00001006 p++;
Just van Rossum52e14d62002-12-30 22:08:05 +00001007 }
1008 else
1009 *q++ = *p;
Just van Rossum52e14d62002-12-30 22:08:05 +00001010 }
1011 *q++ = '\n'; /* add trailing \n */
1012 *q = '\0';
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001013 fixed_source = PyString_FromString(buf);
Just van Rossum9a3129c2003-01-03 11:18:56 +00001014 PyMem_Free(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +00001015 return fixed_source;
1016}
1017
1018/* Given a string buffer containing Python source code, compile it
1019 return and return a code object as a new reference. */
1020static PyObject *
1021compile_source(char *pathname, PyObject *source)
1022{
1023 PyObject *code, *fixed_source;
1024
1025 fixed_source = normalize_line_endings(source);
1026 if (fixed_source == NULL)
1027 return NULL;
1028
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001029 code = Py_CompileString(PyString_AsString(fixed_source), pathname,
Just van Rossum52e14d62002-12-30 22:08:05 +00001030 Py_file_input);
1031 Py_DECREF(fixed_source);
1032 return code;
1033}
1034
1035/* Convert the date/time values found in the Zip archive to a value
1036 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001037static time_t
1038parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001039{
1040 struct tm stm;
1041
Christian Heimes62a8e952008-01-18 07:30:20 +00001042 memset((void *) &stm, '\0', sizeof(stm));
1043
Just van Rossum52e14d62002-12-30 22:08:05 +00001044 stm.tm_sec = (dostime & 0x1f) * 2;
1045 stm.tm_min = (dostime >> 5) & 0x3f;
1046 stm.tm_hour = (dostime >> 11) & 0x1f;
1047 stm.tm_mday = dosdate & 0x1f;
1048 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1049 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
Just van Rossum547eb422003-04-08 20:07:15 +00001050 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001051
1052 return mktime(&stm);
1053}
1054
1055/* Given a path to a .pyc or .pyo file in the archive, return the
1056 modifictaion time of the matching .py file, or 0 if no source
1057 is available. */
1058static time_t
1059get_mtime_of_source(ZipImporter *self, char *path)
1060{
1061 PyObject *toc_entry;
1062 time_t mtime = 0;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001063 Py_ssize_t lastchar = strlen(path) - 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001064 char savechar = path[lastchar];
1065 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1066 toc_entry = PyDict_GetItemString(self->files, path);
1067 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1068 PyTuple_Size(toc_entry) == 8) {
Just van Rossumf8b6de12002-12-31 09:51:59 +00001069 /* fetch the time stamp of the .py file for comparison
1070 with an embedded pyc time stamp */
1071 int time, date;
Just van Rossum52e14d62002-12-30 22:08:05 +00001072 time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
1073 date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
1074 mtime = parse_dostime(time, date);
1075 }
1076 path[lastchar] = savechar;
1077 return mtime;
1078}
1079
1080/* Return the code object for the module named by 'fullname' from the
1081 Zip archive as a new reference. */
1082static PyObject *
1083get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1084 time_t mtime, PyObject *toc_entry)
1085{
1086 PyObject *data, *code;
1087 char *modpath;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001088 char *archive = PyString_AsString(self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +00001089
1090 if (archive == NULL)
1091 return NULL;
1092
1093 data = get_data(archive, toc_entry);
1094 if (data == NULL)
1095 return NULL;
1096
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001097 modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001098
1099 if (isbytecode) {
1100 code = unmarshal_code(modpath, data, mtime);
1101 }
1102 else {
1103 code = compile_source(modpath, data);
1104 }
1105 Py_DECREF(data);
1106 return code;
1107}
1108
1109/* Get the code object assoiciated with the module specified by
1110 'fullname'. */
1111static PyObject *
1112get_module_code(ZipImporter *self, char *fullname,
1113 int *p_ispackage, char **p_modpath)
1114{
1115 PyObject *toc_entry;
1116 char *subname, path[MAXPATHLEN + 1];
1117 int len;
1118 struct st_zip_searchorder *zso;
1119
1120 subname = get_subname(fullname);
1121
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001122 len = make_filename(PyString_AsString(self->prefix), subname, path);
Just van Rossum52e14d62002-12-30 22:08:05 +00001123 if (len < 0)
1124 return NULL;
1125
1126 for (zso = zip_searchorder; *zso->suffix; zso++) {
1127 PyObject *code = NULL;
1128
1129 strcpy(path + len, zso->suffix);
1130 if (Py_VerboseFlag > 1)
1131 PySys_WriteStderr("# trying %s%c%s\n",
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001132 PyString_AsString(self->archive),
Just van Rossum52e14d62002-12-30 22:08:05 +00001133 SEP, path);
1134 toc_entry = PyDict_GetItemString(self->files, path);
1135 if (toc_entry != NULL) {
1136 time_t mtime = 0;
1137 int ispackage = zso->type & IS_PACKAGE;
1138 int isbytecode = zso->type & IS_BYTECODE;
1139
1140 if (isbytecode)
1141 mtime = get_mtime_of_source(self, path);
1142 if (p_ispackage != NULL)
1143 *p_ispackage = ispackage;
1144 code = get_code_from_data(self, ispackage,
1145 isbytecode, mtime,
1146 toc_entry);
1147 if (code == Py_None) {
1148 /* bad magic number or non-matching mtime
1149 in byte code, try next */
1150 Py_DECREF(code);
1151 continue;
1152 }
1153 if (code != NULL && p_modpath != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001154 *p_modpath = PyString_AsString(
Just van Rossum52e14d62002-12-30 22:08:05 +00001155 PyTuple_GetItem(toc_entry, 0));
1156 return code;
1157 }
1158 }
1159 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1160 return NULL;
1161}
1162
1163
1164/* Module init */
1165
1166PyDoc_STRVAR(zipimport_doc,
1167"zipimport provides support for importing Python modules from Zip archives.\n\
1168\n\
1169This module exports three objects:\n\
1170- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001171- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001172 subclass of ImportError, so it can be caught as ImportError, too.\n\
1173- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1174 info dicts, as used in zipimporter._files.\n\
1175\n\
1176It is usually not needed to use the zipimport module explicitly; it is\n\
1177used by the builtin import mechanism for sys.path items that are paths\n\
1178to Zip archives.");
1179
1180PyMODINIT_FUNC
1181initzipimport(void)
1182{
1183 PyObject *mod;
1184
1185 if (PyType_Ready(&ZipImporter_Type) < 0)
1186 return;
1187
1188 /* Correct directory separator */
1189 zip_searchorder[0].suffix[0] = SEP;
1190 zip_searchorder[1].suffix[0] = SEP;
1191 zip_searchorder[2].suffix[0] = SEP;
1192 if (Py_OptimizeFlag) {
1193 /* Reverse *.pyc and *.pyo */
1194 struct st_zip_searchorder tmp;
1195 tmp = zip_searchorder[0];
1196 zip_searchorder[0] = zip_searchorder[1];
1197 zip_searchorder[1] = tmp;
1198 tmp = zip_searchorder[3];
1199 zip_searchorder[3] = zip_searchorder[4];
1200 zip_searchorder[4] = tmp;
1201 }
1202
1203 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1204 NULL, PYTHON_API_VERSION);
Hye-Shik Chang4af5c8c2006-03-07 15:39:21 +00001205 if (mod == NULL)
1206 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001207
1208 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1209 PyExc_ImportError, NULL);
1210 if (ZipImportError == NULL)
1211 return;
1212
1213 Py_INCREF(ZipImportError);
1214 if (PyModule_AddObject(mod, "ZipImportError",
1215 ZipImportError) < 0)
1216 return;
1217
1218 Py_INCREF(&ZipImporter_Type);
1219 if (PyModule_AddObject(mod, "zipimporter",
1220 (PyObject *)&ZipImporter_Type) < 0)
1221 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001222
Just van Rossum52e14d62002-12-30 22:08:05 +00001223 zip_directory_cache = PyDict_New();
1224 if (zip_directory_cache == NULL)
1225 return;
1226 Py_INCREF(zip_directory_cache);
1227 if (PyModule_AddObject(mod, "_zip_directory_cache",
1228 zip_directory_cache) < 0)
1229 return;
1230}