blob: bfac46233db06bc0b1d7ec69672807cf274d9d8e [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 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
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[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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}
Just van Rossum52e14d62002-12-30 22:08:05 +000030};
31
32/* zipimporter object definition and support */
33
34typedef struct _zipimporter ZipImporter;
35
36struct _zipimporter {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000038 PyObject *archive; /* pathname of the Zip archive,
39 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000040 PyObject *prefix; /* file prefix: "a/sub/directory/",
41 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000043};
44
Just van Rossum52e14d62002-12-30 22:08:05 +000045static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000046/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000047static PyObject *zip_directory_cache = NULL;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -080048static PyObject *zip_stat_cache = NULL;
49/* posix.fstat or nt.fstat function. Used due to posixmodule.c's
50 * superior fstat implementation over libc's on Windows. */
51static PyObject *fstat_function = NULL; /* posix.fstat() or nt.fstat() */
Just van Rossum52e14d62002-12-30 22:08:05 +000052
53/* forward decls */
Gregory P. Smith2bcbc142014-01-07 18:30:07 -080054static FILE *fopen_rb_and_stat(PyObject *path, PyObject **py_stat_p);
55static FILE *safely_reopen_archive(ZipImporter *self);
56static PyObject *read_directory(FILE *fp, PyObject *archive);
57static PyObject *get_data(FILE *fp, PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040058static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000059 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000060
61
62#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
63
64
65/* zipimporter.__init__
66 Split the "subdirectory" from the Zip archive path, lookup a matching
67 entry in sys.path_importer_cache, fetch the file directory from there
68 if found, or else read it from the archive. */
69static int
70zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
71{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010072 PyObject *path, *files, *tmp;
73 PyObject *filename = NULL;
74 Py_ssize_t len, flen;
75#ifdef ALTSEP
76 _Py_IDENTIFIER(replace);
77#endif
Just van Rossum52e14d62002-12-30 22:08:05 +000078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 if (!_PyArg_NoKeywords("zipimporter()", kwds))
80 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000081
Victor Stinner2b8dab72010-08-14 14:54:10 +000082 if (!PyArg_ParseTuple(args, "O&:zipimporter",
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010083 PyUnicode_FSDecoder, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000085
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010086 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020087 return -1;
88
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010089 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 if (len == 0) {
91 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000092 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 }
Just van Rossum52e14d62002-12-30 22:08:05 +000094
95#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +010096 tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010097 if (!tmp)
98 goto error;
99 Py_DECREF(path);
100 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000101#endif
102
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100103 filename = path;
104 Py_INCREF(filename);
105 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 for (;;) {
107 struct stat statbuf;
108 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000109
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100110 rv = _Py_stat(filename, &statbuf);
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100111 if (rv == -2)
112 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (rv == 0) {
114 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100115 if (!S_ISREG(statbuf.st_mode))
116 /* it's a not file */
117 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 break;
119 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100120 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100122 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
123 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100125 filename = PyUnicode_Substring(path, 0, flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100127 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000129 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000131
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100132 if (PyUnicode_READY(filename) < 0)
133 goto error;
134
135 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000136 if (files == NULL) {
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800137 PyObject *zip_stat = NULL;
138 FILE *fp = fopen_rb_and_stat(filename, &zip_stat);
139 if (fp == NULL) {
140 if (!PyErr_Occurred())
141 PyErr_Format(ZipImportError, "can't open Zip file: %R",
142 filename);
143
144 Py_XDECREF(zip_stat);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000145 goto error;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800146 }
147
148 if (Py_VerboseFlag)
149 PySys_FormatStderr("# zipimport: %U not cached, "
150 "reading TOC.\n", filename);
151
152 files = read_directory(fp, filename);
153 fclose(fp);
154 if (files == NULL) {
155 Py_XDECREF(zip_stat);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000156 goto error;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800157 }
158 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0) {
159 Py_DECREF(files);
160 Py_XDECREF(zip_stat);
161 goto error;
162 }
163 if (zip_stat && PyDict_SetItem(zip_stat_cache, filename,
164 zip_stat) != 0) {
165 Py_DECREF(files);
166 Py_DECREF(zip_stat);
167 goto error;
168 }
169 Py_XDECREF(zip_stat);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000170 }
171 else
172 Py_INCREF(files);
173 self->files = files;
174
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100175 /* Transfer reference */
176 self->archive = filename;
177 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000178
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100179 /* Check if there is a prefix directory following the filename. */
180 if (flen != len) {
181 tmp = PyUnicode_Substring(path, flen+1,
182 PyUnicode_GET_LENGTH(path));
183 if (tmp == NULL)
184 goto error;
185 self->prefix = tmp;
186 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100188 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
189 if (tmp == NULL)
190 goto error;
191 Py_DECREF(self->prefix);
192 self->prefix = tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 }
194 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000195 else
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100196 self->prefix = PyUnicode_New(0, 0);
197 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000199
200error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100201 Py_DECREF(path);
202 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000203 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000204}
205
206/* GC support. */
207static int
208zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 ZipImporter *self = (ZipImporter *)obj;
211 Py_VISIT(self->files);
212 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000213}
214
215static void
216zipimporter_dealloc(ZipImporter *self)
217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 PyObject_GC_UnTrack(self);
219 Py_XDECREF(self->archive);
220 Py_XDECREF(self->prefix);
221 Py_XDECREF(self->files);
222 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000223}
224
225static PyObject *
226zipimporter_repr(ZipImporter *self)
227{
Victor Stinner028dd972010-08-17 00:04:48 +0000228 if (self->archive == NULL)
229 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200230 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000231 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000232 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 else
Victor Stinner07298a12010-10-18 22:45:54 +0000234 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000235 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000236}
237
238/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400239static PyObject *
240get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000241{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100242 Py_ssize_t len, dot;
243 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200244 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100245 len = PyUnicode_GET_LENGTH(fullname);
246 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
247 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400248 Py_INCREF(fullname);
249 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100250 } else
251 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000252}
253
254/* Given a (sub)modulename, write the potential file path in the
255 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400256 length of the resulting string.
257
258 return self.prefix + name.replace('.', os.sep) */
259static PyObject*
260make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000261{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400262 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200263 Py_UCS4 *p, *buf;
264 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000265
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200266 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
267 p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len);
268 if (buf == NULL) {
269 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400270 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200271 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000272
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200273 if (!PyUnicode_AsUCS4(prefix, p, len, 0)) {
274 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200275 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200276 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200277 p += PyUnicode_GET_LENGTH(prefix);
278 len -= PyUnicode_GET_LENGTH(prefix);
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200279 if (!PyUnicode_AsUCS4(name, p, len, 1)) {
280 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200281 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200282 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400283 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 if (*p == '.')
285 *p = SEP;
286 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200287 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
288 buf, p-buf);
289 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400290 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000291}
292
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000293enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 MI_ERROR,
295 MI_NOT_FOUND,
296 MI_MODULE,
297 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000298};
299
Eric V. Smith984b11f2012-05-24 20:21:04 -0400300/* Does this path represent a directory?
301 on error, return < 0
302 if not a dir, return 0
303 if a dir, return 1
304*/
305static int
306check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
307{
308 PyObject *dirpath;
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700309 int res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400310
311 /* See if this is a "directory". If so, it's eligible to be part
312 of a namespace package. We test by seeing if the name, with an
313 appended path separator, exists. */
314 dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
315 if (dirpath == NULL)
316 return -1;
317 /* If dirpath is present in self->files, we have a directory. */
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700318 res = PyDict_Contains(self->files, dirpath);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400319 Py_DECREF(dirpath);
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700320 return res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400321}
322
Just van Rossum52e14d62002-12-30 22:08:05 +0000323/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000324static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400325get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000326{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400327 PyObject *subname;
328 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000330
Victor Stinner965a8a12010-10-18 21:44:33 +0000331 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400332 if (subname == NULL)
333 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400335 path = make_filename(self->prefix, subname);
336 Py_DECREF(subname);
337 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400341 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
342 if (fullpath == NULL) {
343 Py_DECREF(path);
344 return MI_ERROR;
345 }
346 item = PyDict_GetItem(self->files, fullpath);
347 Py_DECREF(fullpath);
348 if (item != NULL) {
349 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if (zso->type & IS_PACKAGE)
351 return MI_PACKAGE;
352 else
353 return MI_MODULE;
354 }
355 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400356 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000358}
359
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700360typedef enum {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700361 FL_ERROR,
362 FL_NOT_FOUND,
363 FL_MODULE_FOUND,
364 FL_NS_FOUND
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700365} find_loader_result;
366
Eric V. Smith984b11f2012-05-24 20:21:04 -0400367/* The guts of "find_loader" and "find_module". Return values:
368 -1: error
369 0: no loader or namespace portions found
370 1: module/package found
371 2: namespace portion found: *namespace_portion will point to the name
372*/
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700373static find_loader_result
Eric V. Smith984b11f2012-05-24 20:21:04 -0400374find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
375{
376 enum zi_module_info mi;
377
378 *namespace_portion = NULL;
379
380 mi = get_module_info(self, fullname);
381 if (mi == MI_ERROR)
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700382 return FL_ERROR;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400383 if (mi == MI_NOT_FOUND) {
384 /* Not a module or regular package. See if this is a directory, and
385 therefore possibly a portion of a namespace package. */
386 int is_dir = check_is_directory(self, self->prefix, fullname);
387 if (is_dir < 0)
388 return -1;
389 if (is_dir) {
390 /* This is possibly a portion of a namespace
391 package. Return the string representing its path,
392 without a trailing separator. */
393 *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
394 self->archive, SEP,
395 self->prefix, fullname);
396 if (*namespace_portion == NULL)
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700397 return FL_ERROR;
398 return FL_NS_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400399 }
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700400 return FL_NOT_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400401 }
402 /* This is a module or package. */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700403 return FL_MODULE_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400404}
405
406
Just van Rossum52e14d62002-12-30 22:08:05 +0000407/* Check whether we can satisfy the import of the module named by
408 'fullname'. Return self if we can, None if we can't. */
409static PyObject *
410zipimporter_find_module(PyObject *obj, PyObject *args)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 ZipImporter *self = (ZipImporter *)obj;
413 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400414 PyObject *fullname;
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700415 PyObject *namespace_portion = NULL;
416 PyObject *result = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000417
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700418 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
419 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000420
Eric V. Smith984b11f2012-05-24 20:21:04 -0400421 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700422 case FL_ERROR:
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700423 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700424 case FL_NS_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700425 /* A namespace portion is not allowed via find_module, so return None. */
Eric V. Smith984b11f2012-05-24 20:21:04 -0400426 Py_DECREF(namespace_portion);
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700427 /* FALL THROUGH */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700428 case FL_NOT_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700429 result = Py_None;
430 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700431 case FL_MODULE_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700432 result = (PyObject *)self;
433 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 }
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700435 Py_INCREF(result);
Benjamin Peterson2d12e142012-05-25 00:19:40 -0700436 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400437}
438
439
440/* Check whether we can satisfy the import of the module named by
441 'fullname', or whether it could be a portion of a namespace
442 package. Return self if we can load it, a string containing the
443 full path if it's a possible namespace portion, None if we
444 can't load it. */
445static PyObject *
446zipimporter_find_loader(PyObject *obj, PyObject *args)
447{
448 ZipImporter *self = (ZipImporter *)obj;
449 PyObject *path = NULL;
450 PyObject *fullname;
451 PyObject *result = NULL;
452 PyObject *namespace_portion = NULL;
453
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700454 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
455 return NULL;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400456
457 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700458 case FL_ERROR:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700459 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700460 case FL_NOT_FOUND: /* Not found, return (None, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700461 result = Py_BuildValue("O[]", Py_None);
462 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700463 case FL_MODULE_FOUND: /* Return (self, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700464 result = Py_BuildValue("O[]", self);
465 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700466 case FL_NS_FOUND: /* Return (None, [namespace_portion]) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700467 result = Py_BuildValue("O[O]", Py_None, namespace_portion);
Benjamin Peterson209e04c2012-05-24 22:35:39 -0700468 Py_DECREF(namespace_portion);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400469 return result;
470 }
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700471 return result;
Just van Rossum52e14d62002-12-30 22:08:05 +0000472}
473
474/* Load and return the module named by 'fullname'. */
475static PyObject *
476zipimporter_load_module(PyObject *obj, PyObject *args)
477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000479 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400480 PyObject *fullname;
481 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000483
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400484 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 &fullname))
486 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200487 if (PyUnicode_READY(fullname) == -1)
488 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 code = get_module_code(self, fullname, &ispackage, &modpath);
491 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000492 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000493
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400494 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000495 if (mod == NULL)
496 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 /* mod.__loader__ = self */
500 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
501 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 if (ispackage) {
504 /* add __path__ to the module *before* the code gets
505 executed */
506 PyObject *pkgpath, *fullpath;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400507 PyObject *subname = get_subname(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000509
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400510 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 self->archive, SEP,
512 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400513 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (fullpath == NULL)
515 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000516
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400517 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 if (pkgpath == NULL)
519 goto error;
520 err = PyDict_SetItemString(dict, "__path__", pkgpath);
521 Py_DECREF(pkgpath);
522 if (err != 0)
523 goto error;
524 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400525 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000526 Py_CLEAR(code);
527 if (mod == NULL)
528 goto error;
529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400531 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000532 fullname, modpath);
533 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000535error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000536 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000537 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000539}
540
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000541/* Return a string matching __file__ for the named module */
542static PyObject *
543zipimporter_get_filename(PyObject *obj, PyObject *args)
544{
545 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400546 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000547 int ispackage;
548
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400549 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000550 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000551 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000552
553 /* Deciding the filename requires working out where the code
554 would come from if the module was actually loaded */
555 code = get_module_code(self, fullname, &ispackage, &modpath);
556 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000557 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000558 Py_DECREF(code); /* Only need the path info */
559
Victor Stinner08654e12010-10-18 12:09:02 +0000560 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000561}
562
Just van Rossum52e14d62002-12-30 22:08:05 +0000563/* Return a bool signifying whether the module is a package or not. */
564static PyObject *
565zipimporter_is_package(PyObject *obj, PyObject *args)
566{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400568 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000570
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400571 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000572 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 mi = get_module_info(self, fullname);
576 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000577 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400579 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000580 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 }
582 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000583}
584
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585
Just van Rossum52e14d62002-12-30 22:08:05 +0000586static PyObject *
587zipimporter_get_data(PyObject *obj, PyObject *args)
588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 ZipImporter *self = (ZipImporter *)obj;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100590 PyObject *path, *key;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800591 FILE *fp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000592#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100593 _Py_IDENTIFIER(replace);
Just van Rossum52e14d62002-12-30 22:08:05 +0000594#endif
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800595 PyObject *toc_entry, *data;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100596 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000597
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100598 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000600
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200601#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100602 path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100603 if (!path)
604 return NULL;
605#else
606 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000607#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100608 if (PyUnicode_READY(path) == -1)
609 goto error;
610
611 path_len = PyUnicode_GET_LENGTH(path);
612
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200613 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100614 path_start = 0;
615 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
616 && PyUnicode_READ_CHAR(path, len) == SEP) {
617 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000619
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100620 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000621 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100622 goto error;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800623
624 fp = safely_reopen_archive(self);
625 if (fp == NULL)
626 goto error;
627
Victor Stinner60fe8d92010-08-16 23:48:11 +0000628 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000630 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
631 Py_DECREF(key);
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800632 fclose(fp);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100633 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000635 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100636 Py_DECREF(path);
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800637 data = get_data(fp, self->archive, toc_entry);
638 fclose(fp);
639 return data;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100640 error:
641 Py_DECREF(path);
642 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000643}
644
645static PyObject *
646zipimporter_get_code(PyObject *obj, PyObject *args)
647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400649 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000650
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400651 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000655}
656
657static PyObject *
658zipimporter_get_source(PyObject *obj, PyObject *args)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 ZipImporter *self = (ZipImporter *)obj;
661 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400662 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 enum zi_module_info mi;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800664 FILE *fp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000665
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400666 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000670 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000672 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400673 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000674 return NULL;
675 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400676
Victor Stinner965a8a12010-10-18 21:44:33 +0000677 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400678 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000680
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400681 path = make_filename(self->prefix, subname);
682 Py_DECREF(subname);
683 if (path == NULL)
684 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000685
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400686 if (mi == MI_PACKAGE)
687 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
688 else
689 fullpath = PyUnicode_FromFormat("%U.py", path);
690 Py_DECREF(path);
691 if (fullpath == NULL)
692 return NULL;
693
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800694 fp = safely_reopen_archive(self);
695 if (fp == NULL) {
696 Py_DECREF(fullpath);
697 return NULL;
698 }
699
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400700 toc_entry = PyDict_GetItem(self->files, fullpath);
701 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000703 PyObject *res, *bytes;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800704 bytes = get_data(fp, self->archive, toc_entry);
705 fclose(fp);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000706 if (bytes == NULL)
707 return NULL;
708 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
709 PyBytes_GET_SIZE(bytes));
710 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 return res;
712 }
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800713 fclose(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 /* we have the module, but no source */
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800716 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000717}
718
719PyDoc_STRVAR(doc_find_module,
720"find_module(fullname, path=None) -> self or None.\n\
721\n\
722Search for a module specified by 'fullname'. 'fullname' must be the\n\
723fully qualified (dotted) module name. It returns the zipimporter\n\
724instance itself if the module was found, or None if it wasn't.\n\
725The optional 'path' argument is ignored -- it's there for compatibility\n\
726with the importer protocol.");
727
Eric V. Smith984b11f2012-05-24 20:21:04 -0400728PyDoc_STRVAR(doc_find_loader,
729"find_loader(fullname, path=None) -> self, str or None.\n\
730\n\
731Search for a module specified by 'fullname'. 'fullname' must be the\n\
732fully qualified (dotted) module name. It returns the zipimporter\n\
733instance itself if the module was found, a string containing the\n\
734full path name if it's possibly a portion of a namespace package,\n\
735or None otherwise. The optional 'path' argument is ignored -- it's\n\
736 there for compatibility with the importer protocol.");
737
Just van Rossum52e14d62002-12-30 22:08:05 +0000738PyDoc_STRVAR(doc_load_module,
739"load_module(fullname) -> module.\n\
740\n\
741Load the module specified by 'fullname'. 'fullname' must be the\n\
742fully qualified (dotted) module name. It returns the imported\n\
743module, or raises ZipImportError if it wasn't found.");
744
745PyDoc_STRVAR(doc_get_data,
746"get_data(pathname) -> string with file data.\n\
747\n\
748Return the data associated with 'pathname'. Raise IOError if\n\
749the file wasn't found.");
750
751PyDoc_STRVAR(doc_is_package,
752"is_package(fullname) -> bool.\n\
753\n\
754Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000755Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000756
757PyDoc_STRVAR(doc_get_code,
758"get_code(fullname) -> code object.\n\
759\n\
760Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000761if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000762
763PyDoc_STRVAR(doc_get_source,
764"get_source(fullname) -> source string.\n\
765\n\
766Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000767if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000768contain the module, but has no source for it.");
769
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000770
771PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000772"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000773\n\
774Return the filename for the specified module.");
775
Just van Rossum52e14d62002-12-30 22:08:05 +0000776static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 {"find_module", zipimporter_find_module, METH_VARARGS,
778 doc_find_module},
Eric V. Smith984b11f2012-05-24 20:21:04 -0400779 {"find_loader", zipimporter_find_loader, METH_VARARGS,
780 doc_find_loader},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 {"load_module", zipimporter_load_module, METH_VARARGS,
782 doc_load_module},
783 {"get_data", zipimporter_get_data, METH_VARARGS,
784 doc_get_data},
785 {"get_code", zipimporter_get_code, METH_VARARGS,
786 doc_get_code},
787 {"get_source", zipimporter_get_source, METH_VARARGS,
788 doc_get_source},
789 {"get_filename", zipimporter_get_filename, METH_VARARGS,
790 doc_get_filename},
791 {"is_package", zipimporter_is_package, METH_VARARGS,
792 doc_is_package},
793 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000794};
795
796static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
798 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
799 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
800 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000801};
802
803PyDoc_STRVAR(zipimporter_doc,
804"zipimporter(archivepath) -> zipimporter object\n\
805\n\
806Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000807a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
808'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
809valid directory inside the archive.\n\
810\n\
811'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
812archive.\n\
813\n\
814The 'archive' attribute of zipimporter objects contains the name of the\n\
815zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000816
817#define DEFERRED_ADDRESS(ADDR) 0
818
819static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
821 "zipimport.zipimporter",
822 sizeof(ZipImporter),
823 0, /* tp_itemsize */
824 (destructor)zipimporter_dealloc, /* tp_dealloc */
825 0, /* tp_print */
826 0, /* tp_getattr */
827 0, /* tp_setattr */
828 0, /* tp_reserved */
829 (reprfunc)zipimporter_repr, /* tp_repr */
830 0, /* tp_as_number */
831 0, /* tp_as_sequence */
832 0, /* tp_as_mapping */
833 0, /* tp_hash */
834 0, /* tp_call */
835 0, /* tp_str */
836 PyObject_GenericGetAttr, /* tp_getattro */
837 0, /* tp_setattro */
838 0, /* tp_as_buffer */
839 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
840 Py_TPFLAGS_HAVE_GC, /* tp_flags */
841 zipimporter_doc, /* tp_doc */
842 zipimporter_traverse, /* tp_traverse */
843 0, /* tp_clear */
844 0, /* tp_richcompare */
845 0, /* tp_weaklistoffset */
846 0, /* tp_iter */
847 0, /* tp_iternext */
848 zipimporter_methods, /* tp_methods */
849 zipimporter_members, /* tp_members */
850 0, /* tp_getset */
851 0, /* tp_base */
852 0, /* tp_dict */
853 0, /* tp_descr_get */
854 0, /* tp_descr_set */
855 0, /* tp_dictoffset */
856 (initproc)zipimporter_init, /* tp_init */
857 PyType_GenericAlloc, /* tp_alloc */
858 PyType_GenericNew, /* tp_new */
859 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000860};
861
862
863/* implementation */
864
Just van Rossum52e14d62002-12-30 22:08:05 +0000865/* Given a buffer, return the long that is represented by the first
866 4 bytes, encoded as little endian. This partially reimplements
867 marshal.c:r_long() */
868static long
869get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 long x;
871 x = buf[0];
872 x |= (long)buf[1] << 8;
873 x |= (long)buf[2] << 16;
874 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000875#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 /* Sign extension for 64-bit machines */
877 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000878#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000880}
881
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800882/* Return 1 if objects a and b fail a Py_EQ test for an attr. */
883static int
884compare_obj_attr_strings(PyObject *obj_a, PyObject *obj_b, char *attr_name)
885{
886 int problem = 0;
887 PyObject *attr_a = PyObject_GetAttrString(obj_a, attr_name);
888 PyObject *attr_b = PyObject_GetAttrString(obj_b, attr_name);
889 if (attr_a == NULL || attr_b == NULL)
890 problem = 1;
891 else
892 problem = (PyObject_RichCompareBool(attr_a, attr_b, Py_EQ) != 1);
893 Py_XDECREF(attr_a);
894 Py_XDECREF(attr_b);
895 return problem;
896}
Just van Rossum52e14d62002-12-30 22:08:05 +0000897
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800898/*
899 * Returns an open FILE * on success.
900 * Returns NULL on error with the Python error context set.
901 */
902static FILE *
903safely_reopen_archive(ZipImporter *self)
904{
905 FILE *fp;
906 PyObject *stat_now = NULL;
907
908 fp = fopen_rb_and_stat(self->archive, &stat_now);
909 if (!fp) {
910 PyErr_Format(ZipImportError,
911 "zipimport: can not open file %U", self->archive);
912 Py_XDECREF(stat_now);
913 return NULL;
914 }
915
916 if (stat_now != NULL) {
917 int problem = 0;
918 PyObject *files;
919 PyObject *prev_stat = PyDict_GetItem(zip_stat_cache, self->archive);
920 /* Test stat_now vs the old cached stat on some key attributes. */
921 if (prev_stat != NULL) {
922 problem = compare_obj_attr_strings(prev_stat, stat_now,
923 "st_ino");
924 problem |= compare_obj_attr_strings(prev_stat, stat_now,
925 "st_size");
926 problem |= compare_obj_attr_strings(prev_stat, stat_now,
927 "st_mtime");
928 } else {
929 if (Py_VerboseFlag)
930 PySys_FormatStderr("# zipimport: no stat data for %U!\n",
931 self->archive);
932 problem = 1;
933 }
934
935 if (problem) {
936 if (Py_VerboseFlag)
937 PySys_FormatStderr("# zipimport: %U modified since last"
938 " import, rereading TOC.\n", self->archive);
939 files = read_directory(fp, self->archive);
940 if (files == NULL) {
941 Py_DECREF(stat_now);
942 fclose(fp);
943 return NULL;
944 }
945 if (PyDict_SetItem(zip_directory_cache, self->archive,
946 files) != 0) {
947 Py_DECREF(files);
948 Py_DECREF(stat_now);
949 fclose(fp);
950 return NULL;
951 }
952 if (stat_now && PyDict_SetItem(zip_stat_cache, self->archive,
953 stat_now) != 0) {
954 Py_DECREF(files);
955 Py_DECREF(stat_now);
956 fclose(fp);
957 return NULL;
958 }
959 Py_XDECREF(self->files); /* free the old value. */
960 self->files = files;
961 } else {
962 /* No problem, discard the new stat data. */
963 Py_DECREF(stat_now);
964 }
965 } /* stat succeeded */
966
967 return fp;
968}
969
970/*
971 fopen_rb_and_stat(path, &py_stat) -> FILE *
972
973 Opens path in "rb" mode and populates the Python py_stat stat_result
974 with information about the opened file. *py_stat may not be changed
975 if there is no fstat_function or if fstat_function fails.
976
977 Returns NULL and does nothing to *py_stat if the open failed.
978*/
979static FILE *
980fopen_rb_and_stat(PyObject *path, PyObject **py_stat_p)
981{
982 FILE *fp;
983 assert(py_stat_p != NULL);
984 assert(*py_stat_p == NULL);
985
986 fp = _Py_fopen(path, "rb");
987 if (fp == NULL) {
988 if (!PyErr_Occurred())
989 PyErr_Format(ZipImportError,
990 "zipimport: can not open file %U", path);
991 return NULL;
992 }
993
994 if (fstat_function) {
995 PyObject *stat_result = PyObject_CallFunction(fstat_function,
996 "i", fileno(fp));
997 if (stat_result == NULL) {
998 PyErr_Clear(); /* We can function without it. */
999 } else {
1000 *py_stat_p = stat_result;
1001 }
1002 }
1003
1004 return fp;
1005}
1006
1007/*
1008 read_directory(fp, archive) -> files dict (new reference)
1009
1010 Given an open Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +00001011 (local to the archive, using SEP as a separator) to toc entries.
1012
1013 A toc_entry is a tuple:
1014
Victor Stinner08654e12010-10-18 12:09:02 +00001015 (__file__, # value to use for __file__, available for all files,
1016 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 compress, # compression kind; 0 for uncompressed
1018 data_size, # size of compressed data on disk
1019 file_size, # size of decompressed data
1020 file_offset, # offset of file header from start of archive
1021 time, # mod time of file (in dos format)
1022 date, # mod data of file (in dos format)
1023 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +00001024 )
Just van Rossum52e14d62002-12-30 22:08:05 +00001025
1026 Directories can be recognized by the trailing SEP in the name,
1027 data_size and file_offset are 0.
1028*/
1029static PyObject *
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001030read_directory(FILE *fp, PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +00001031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 PyObject *files = NULL;
Victor Stinnerd36c8212010-10-18 12:13:46 +00001033 unsigned short flags;
Gregory P. Smithab320662012-01-30 15:17:33 -08001034 short compress, time, date, name_size;
1035 long crc, data_size, file_size, header_size;
1036 Py_ssize_t file_offset, header_position, header_offset;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001037 long l, count;
1038 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +00001040 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 char *p, endof_central_dir[22];
Gregory P. Smithab320662012-01-30 15:17:33 -08001042 Py_ssize_t arc_offset; /* Absolute offset to start of the zip-archive. */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001043 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +00001044 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001045 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +00001046
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001047 assert(fp != NULL);
Jesus Cea09bf7a72012-10-03 02:13:05 +02001048 if (fseek(fp, -22, SEEK_END) == -1) {
Jesus Cea09bf7a72012-10-03 02:13:05 +02001049 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1050 return NULL;
1051 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 header_position = ftell(fp);
1053 if (fread(endof_central_dir, 1, 22, fp) != 22) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001054 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 return NULL;
1056 }
1057 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
1058 /* Bad: End of Central Dir signature */
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001059 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 return NULL;
1061 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 header_size = get_long((unsigned char *)endof_central_dir + 12);
1064 header_offset = get_long((unsigned char *)endof_central_dir + 16);
1065 arc_offset = header_position - header_offset - header_size;
1066 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 files = PyDict_New();
1069 if (files == NULL)
1070 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 /* Start of Central Directory */
1073 count = 0;
1074 for (;;) {
1075 PyObject *t;
1076 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +00001077
Jesus Cea09bf7a72012-10-03 02:13:05 +02001078 if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
1079 goto fseek_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 l = PyMarshal_ReadLongFromFile(fp);
1081 if (l != 0x02014B50)
1082 break; /* Bad: Central Dir File Header */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001083 if (fseek(fp, header_offset + 8, 0) == -1)
1084 goto fseek_error;
Victor Stinnerd36c8212010-10-18 12:13:46 +00001085 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 compress = PyMarshal_ReadShortFromFile(fp);
1087 time = PyMarshal_ReadShortFromFile(fp);
1088 date = PyMarshal_ReadShortFromFile(fp);
1089 crc = PyMarshal_ReadLongFromFile(fp);
1090 data_size = PyMarshal_ReadLongFromFile(fp);
1091 file_size = PyMarshal_ReadLongFromFile(fp);
1092 name_size = PyMarshal_ReadShortFromFile(fp);
1093 header_size = 46 + name_size +
1094 PyMarshal_ReadShortFromFile(fp) +
1095 PyMarshal_ReadShortFromFile(fp);
Jesus Cea09bf7a72012-10-03 02:13:05 +02001096 if (fseek(fp, header_offset + 42, 0) == -1)
1097 goto fseek_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
1099 if (name_size > MAXPATHLEN)
1100 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001103 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 *p = (char)getc(fp);
1105 if (*p == '/')
1106 *p = SEP;
1107 p++;
1108 }
1109 *p = 0; /* Add terminating null byte */
1110 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +00001111
Victor Stinner4ee65a92011-01-22 10:30:29 +00001112 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +00001113 if (flags & 0x0800)
1114 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +00001115 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1116 /* During bootstrap, we may need to load the encodings
1117 package from a ZIP file. But the cp437 encoding is implemented
1118 in Python in the encodings package.
1119
1120 Break out of this dependency by assuming that the path to
1121 the encodings module is ASCII-only. */
1122 charset = "ascii";
1123 bootstrap = 1;
1124 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001125 else
1126 charset = "cp437";
1127 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001128 if (nameobj == NULL) {
1129 if (bootstrap)
1130 PyErr_Format(PyExc_NotImplementedError,
1131 "bootstrap issue: python%i%i.zip contains non-ASCII "
1132 "filenames without the unicode flag",
1133 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +00001134 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001135 }
Stefan Krah000fde92012-08-20 14:14:49 +02001136 if (PyUnicode_READY(nameobj) == -1)
1137 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001138 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
1139 if (path == NULL)
Victor Stinner2460a432010-08-16 17:54:28 +00001140 goto error;
Gregory P. Smithcc6abd52012-01-30 15:55:29 -08001141 t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 file_size, file_offset, time, date, crc);
1143 if (t == NULL)
1144 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +00001145 err = PyDict_SetItem(files, nameobj, t);
1146 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 Py_DECREF(t);
1148 if (err != 0)
1149 goto error;
1150 count++;
1151 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001153 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
1154 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 return files;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001156fseek_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001157 Py_XDECREF(files);
1158 Py_XDECREF(nameobj);
1159 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1160 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001161error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001163 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001165}
1166
1167/* Return the zlib.decompress function object, or NULL if zlib couldn't
1168 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001169 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001170static PyObject *
1171get_decompress_func(void)
1172{
Victor Stinner4925cde2011-05-20 00:16:09 +02001173 static int importing_zlib = 0;
1174 PyObject *zlib;
1175 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001176 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001177
Victor Stinner4925cde2011-05-20 00:16:09 +02001178 if (importing_zlib != 0)
1179 /* Someone has a zlib.py[co] in their Zip file;
1180 let's avoid a stack overflow. */
1181 return NULL;
1182 importing_zlib = 1;
1183 zlib = PyImport_ImportModuleNoBlock("zlib");
1184 importing_zlib = 0;
1185 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001186 decompress = _PyObject_GetAttrId(zlib,
1187 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001188 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001190 else {
1191 PyErr_Clear();
1192 decompress = NULL;
1193 }
1194 if (Py_VerboseFlag)
1195 PySys_WriteStderr("# zipimport: zlib %s\n",
1196 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001198}
1199
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001200/* Given a FILE* to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001201 data as a new reference. */
1202static PyObject *
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001203get_data(FILE *fp, PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 PyObject *raw_data, *data = NULL, *decompress;
1206 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 int err;
1208 Py_ssize_t bytes_read = 0;
1209 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001210 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 long compress, data_size, file_size, file_offset, bytes_size;
1212 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +00001213
Victor Stinner60fe8d92010-08-16 23:48:11 +00001214 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 &data_size, &file_size, &file_offset, &time,
1216 &date, &crc)) {
1217 return NULL;
1218 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001221 if (fseek(fp, file_offset, 0) == -1) {
Jesus Cea09bf7a72012-10-03 02:13:05 +02001222 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1223 return NULL;
1224 }
1225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 l = PyMarshal_ReadLongFromFile(fp);
1227 if (l != 0x04034B50) {
1228 /* Bad: Local File Header */
1229 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +00001230 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return NULL;
1233 }
Jesus Cea09bf7a72012-10-03 02:13:05 +02001234 if (fseek(fp, file_offset + 26, 0) == -1) {
Jesus Cea09bf7a72012-10-03 02:13:05 +02001235 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1236 return NULL;
1237 }
1238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 l = 30 + PyMarshal_ReadShortFromFile(fp) +
1240 PyMarshal_ReadShortFromFile(fp); /* local header size */
1241 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 bytes_size = compress == 0 ? data_size : data_size + 1;
1244 if (bytes_size == 0)
1245 bytes_size++;
1246 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 if (raw_data == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 return NULL;
1250 }
1251 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 err = fseek(fp, file_offset, 0);
Jesus Cea09bf7a72012-10-03 02:13:05 +02001254 if (err == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 bytes_read = fread(buf, 1, data_size, fp);
Jesus Cea09bf7a72012-10-03 02:13:05 +02001256 } else {
Jesus Cea09bf7a72012-10-03 02:13:05 +02001257 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1258 return NULL;
1259 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (err || bytes_read != data_size) {
1261 PyErr_SetString(PyExc_IOError,
1262 "zipimport: can't read data");
1263 Py_DECREF(raw_data);
1264 return NULL;
1265 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 if (compress != 0) {
1268 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1269 data_size++;
1270 }
1271 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 if (compress == 0) { /* data is not compressed */
1274 data = PyBytes_FromStringAndSize(buf, data_size);
1275 Py_DECREF(raw_data);
1276 return data;
1277 }
1278
1279 /* Decompress with zlib */
1280 decompress = get_decompress_func();
1281 if (decompress == NULL) {
1282 PyErr_SetString(ZipImportError,
1283 "can't decompress data; "
1284 "zlib not available");
1285 goto error;
1286 }
1287 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001288 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001289error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 Py_DECREF(raw_data);
1291 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001292}
1293
1294/* Lenient date/time comparison function. The precision of the mtime
1295 in the archive is lower than the mtime stored in a .pyc: we
1296 must allow a difference of at most one second. */
1297static int
1298eq_mtime(time_t t1, time_t t2)
1299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 time_t d = t1 - t2;
1301 if (d < 0)
1302 d = -d;
1303 /* dostime only stores even seconds, so be lenient */
1304 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001305}
1306
1307/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1308 and return the code object. Return None if it the magic word doesn't
1309 match (we do this instead of raising an exception as we fall back
1310 to .py if available and we don't want to mask other errors).
1311 Returns a new reference. */
1312static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001313unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 PyObject *code;
1316 char *buf = PyBytes_AsString(data);
1317 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 if (size <= 9) {
1320 PyErr_SetString(ZipImportError,
1321 "bad pyc data");
1322 return NULL;
1323 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1326 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001327 PySys_FormatStderr("# %R has bad magic\n",
1328 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 Py_INCREF(Py_None);
1330 return Py_None; /* signal caller to try alternative */
1331 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1334 mtime)) {
1335 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001336 PySys_FormatStderr("# %R has bad mtime\n",
1337 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 Py_INCREF(Py_None);
1339 return Py_None; /* signal caller to try alternative */
1340 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001341
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001342 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1343 unimportant with zip files. */
1344 code = PyMarshal_ReadObjectFromString(buf + 12, size - 12);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (code == NULL)
1346 return NULL;
1347 if (!PyCode_Check(code)) {
1348 Py_DECREF(code);
1349 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001350 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 pathname);
1352 return NULL;
1353 }
1354 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001355}
1356
1357/* Replace any occurances of "\r\n?" in the input string with "\n".
1358 This converts DOS and Mac line endings to Unix line endings.
1359 Also append a trailing "\n" to be compatible with
1360 PyParser_SimpleParseFile(). Returns a new reference. */
1361static PyObject *
1362normalize_line_endings(PyObject *source)
1363{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001364 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *fixed_source;
1366 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001367
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001368 p = PyBytes_AsString(source);
1369 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 return PyBytes_FromStringAndSize("\n\0", 2);
1371 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 /* one char extra for trailing \n and one for terminating \0 */
1374 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1375 if (buf == NULL) {
1376 PyErr_SetString(PyExc_MemoryError,
1377 "zipimport: no memory to allocate "
1378 "source buffer");
1379 return NULL;
1380 }
1381 /* replace "\r\n?" by "\n" */
1382 for (q = buf; *p != '\0'; p++) {
1383 if (*p == '\r') {
1384 *q++ = '\n';
1385 if (*(p + 1) == '\n')
1386 p++;
1387 }
1388 else
1389 *q++ = *p;
1390 len++;
1391 }
1392 *q++ = '\n'; /* add trailing \n */
1393 *q = '\0';
1394 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1395 PyMem_Free(buf);
1396 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001397}
1398
1399/* Given a string buffer containing Python source code, compile it
1400 return and return a code object as a new reference. */
1401static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001402compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001403{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001404 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001405
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001406 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1407 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001409
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001410 fixed_source = normalize_line_endings(source);
1411 if (fixed_source == NULL) {
1412 Py_DECREF(pathbytes);
1413 return NULL;
1414 }
1415
1416 code = Py_CompileString(PyBytes_AsString(fixed_source),
1417 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001419 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 Py_DECREF(fixed_source);
1421 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001422}
1423
1424/* Convert the date/time values found in the Zip archive to a value
1425 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001426static time_t
1427parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 stm.tm_sec = (dostime & 0x1f) * 2;
1434 stm.tm_min = (dostime >> 5) & 0x3f;
1435 stm.tm_hour = (dostime >> 11) & 0x1f;
1436 stm.tm_mday = dosdate & 0x1f;
1437 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1438 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1439 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001442}
1443
1444/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001445 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001446 is available. */
1447static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001448get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001449{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001450 PyObject *toc_entry, *stripped;
1451 time_t mtime;
1452
1453 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001454 if (PyUnicode_READY(path) == -1)
1455 return (time_t)-1;
1456 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1457 PyUnicode_DATA(path),
1458 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001459 if (stripped == NULL)
1460 return (time_t)-1;
1461
1462 toc_entry = PyDict_GetItem(self->files, stripped);
1463 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1465 PyTuple_Size(toc_entry) == 8) {
1466 /* fetch the time stamp of the .py file for comparison
1467 with an embedded pyc time stamp */
1468 int time, date;
1469 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1470 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1471 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001472 } else
1473 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001475}
1476
1477/* Return the code object for the module named by 'fullname' from the
1478 Zip archive as a new reference. */
1479static PyObject *
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001480get_code_from_data(ZipImporter *self, FILE *fp, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001482{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001483 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001484
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001485 data = get_data(fp, self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 if (data == NULL)
1487 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001488
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001489 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001490 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001491 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001492 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001493 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 Py_DECREF(data);
1495 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001496}
1497
Ezio Melotti42da6632011-03-15 05:18:48 +02001498/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001499 'fullname'. */
1500static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001501get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001502 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001503{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001504 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001505 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 struct st_zip_searchorder *zso;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001507 FILE *fp;
Just van Rossum52e14d62002-12-30 22:08:05 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001510 if (subname == NULL)
1511 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001512
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001513 path = make_filename(self->prefix, subname);
1514 Py_DECREF(subname);
1515 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001517
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001518 fp = safely_reopen_archive(self);
1519 if (fp == NULL) {
1520 Py_DECREF(path);
1521 return NULL;
1522 }
1523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001525 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001526
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001527 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1528 if (fullpath == NULL)
1529 goto exit;
1530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001532 PySys_FormatStderr("# trying %U%c%U\n",
1533 self->archive, (int)SEP, fullpath);
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001534
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001535 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 if (toc_entry != NULL) {
1537 time_t mtime = 0;
1538 int ispackage = zso->type & IS_PACKAGE;
1539 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001540
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001541 if (isbytecode) {
1542 mtime = get_mtime_of_source(self, fullpath);
1543 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1544 goto exit;
1545 }
1546 }
1547 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (p_ispackage != NULL)
1549 *p_ispackage = ispackage;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001550 code = get_code_from_data(self, fp, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 isbytecode, mtime,
1552 toc_entry);
1553 if (code == Py_None) {
1554 /* bad magic number or non-matching mtime
1555 in byte code, try next */
1556 Py_DECREF(code);
1557 continue;
1558 }
Victor Stinner08654e12010-10-18 12:09:02 +00001559 if (code != NULL && p_modpath != NULL) {
1560 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1561 Py_INCREF(*p_modpath);
1562 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001563 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001565 else
1566 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001568 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1569exit:
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001570 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001571 Py_DECREF(path);
1572 Py_XDECREF(fullpath);
1573 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001574}
1575
1576
1577/* Module init */
1578
1579PyDoc_STRVAR(zipimport_doc,
1580"zipimport provides support for importing Python modules from Zip archives.\n\
1581\n\
1582This module exports three objects:\n\
1583- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001584- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001585 subclass of ImportError, so it can be caught as ImportError, too.\n\
1586- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1587 info dicts, as used in zipimporter._files.\n\
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001588- _zip_stat_cache: a dict, mapping archive paths to stat_result\n\
1589 info for the .zip the last time anything was imported from it.\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001590\n\
1591It is usually not needed to use the zipimport module explicitly; it is\n\
1592used by the builtin import mechanism for sys.path items that are paths\n\
1593to Zip archives.");
1594
Martin v. Löwis1a214512008-06-11 05:26:20 +00001595static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 PyModuleDef_HEAD_INIT,
1597 "zipimport",
1598 zipimport_doc,
1599 -1,
1600 NULL,
1601 NULL,
1602 NULL,
1603 NULL,
1604 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001605};
1606
Just van Rossum52e14d62002-12-30 22:08:05 +00001607PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001608PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 if (PyType_Ready(&ZipImporter_Type) < 0)
1613 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 /* Correct directory separator */
1616 zip_searchorder[0].suffix[0] = SEP;
1617 zip_searchorder[1].suffix[0] = SEP;
1618 zip_searchorder[2].suffix[0] = SEP;
1619 if (Py_OptimizeFlag) {
1620 /* Reverse *.pyc and *.pyo */
1621 struct st_zip_searchorder tmp;
1622 tmp = zip_searchorder[0];
1623 zip_searchorder[0] = zip_searchorder[1];
1624 zip_searchorder[1] = tmp;
1625 tmp = zip_searchorder[3];
1626 zip_searchorder[3] = zip_searchorder[4];
1627 zip_searchorder[4] = tmp;
1628 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 mod = PyModule_Create(&zipimportmodule);
1631 if (mod == NULL)
1632 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1635 PyExc_ImportError, NULL);
1636 if (ZipImportError == NULL)
1637 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 Py_INCREF(ZipImportError);
1640 if (PyModule_AddObject(mod, "ZipImportError",
1641 ZipImportError) < 0)
1642 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 Py_INCREF(&ZipImporter_Type);
1645 if (PyModule_AddObject(mod, "zipimporter",
1646 (PyObject *)&ZipImporter_Type) < 0)
1647 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001648
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001649 Py_XDECREF(zip_directory_cache); /* Avoid embedded interpreter leaks. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 zip_directory_cache = PyDict_New();
1651 if (zip_directory_cache == NULL)
1652 return NULL;
1653 Py_INCREF(zip_directory_cache);
1654 if (PyModule_AddObject(mod, "_zip_directory_cache",
1655 zip_directory_cache) < 0)
1656 return NULL;
Gregory P. Smith2bcbc142014-01-07 18:30:07 -08001657
1658 Py_XDECREF(zip_stat_cache); /* Avoid embedded interpreter leaks. */
1659 zip_stat_cache = PyDict_New();
1660 if (zip_stat_cache == NULL)
1661 return NULL;
1662 Py_INCREF(zip_stat_cache);
1663 if (PyModule_AddObject(mod, "_zip_stat_cache", zip_stat_cache) < 0)
1664 return NULL;
1665
1666 {
1667 /* We cannot import "os" here as that is a .py/.pyc file that could
1668 * live within a zipped up standard library. Import the posix or nt
1669 * builtin that provides the fstat() function we want instead. */
1670 PyObject *os_like_module;
1671 Py_CLEAR(fstat_function); /* Avoid embedded interpreter leaks. */
1672 os_like_module = PyImport_ImportModule("posix");
1673 if (os_like_module == NULL) {
1674 PyErr_Clear();
1675 os_like_module = PyImport_ImportModule("nt");
1676 }
1677 if (os_like_module != NULL) {
1678 fstat_function = PyObject_GetAttrString(os_like_module, "fstat");
1679 Py_DECREF(os_like_module);
1680 }
1681 if (fstat_function == NULL) {
1682 PyErr_Clear(); /* non-fatal, we'll go on without it. */
1683 if (Py_VerboseFlag)
1684 PySys_WriteStderr("# zipimport unable to use os.fstat().\n");
1685 }
1686 }
1687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001689}