2 #include "structmember.h"
9 #define IS_BYTECODE 0x1
10 #define IS_PACKAGE 0x2
12 struct st_zip_searchorder
{
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. */
22 static struct st_zip_searchorder zip_searchorder
[] = {
23 {"/__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
},
32 /* zipimporter object definition and support */
34 typedef struct _zipimporter ZipImporter
;
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} */
43 static PyObject
*ZipImportError
;
44 static PyObject
*zip_directory_cache
= NULL
;
47 static PyObject
*read_directory(char *archive
);
48 static PyObject
*get_data(char *archive
, PyObject
*toc_entry
);
49 static PyObject
*get_module_code(ZipImporter
*self
, char *fullname
,
50 int *p_ispackage
, char **p_modpath
);
53 #define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
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. */
61 zipimporter_init(ZipImporter
*self
, PyObject
*args
, PyObject
*kwds
)
63 char *path
, *p
, *prefix
, buf
[MAXPATHLEN
+2];
66 if (!_PyArg_NoKeywords("zipimporter()", kwds
))
69 if (!PyArg_ParseTuple(args
, "s:zipimporter", &path
))
74 PyErr_SetString(ZipImportError
, "archive path is empty");
77 if (len
>= MAXPATHLEN
) {
78 PyErr_SetString(ZipImportError
,
79 "archive path too long");
85 for (p
= buf
; *p
; p
++) {
97 rv
= stat(buf
, &statbuf
);
100 if (S_ISREG(statbuf
.st_mode
))
105 /* back up one path element */
106 p
= strrchr(buf
, SEP
);
116 files
= PyDict_GetItemString(zip_directory_cache
, path
);
118 files
= read_directory(buf
);
121 if (PyDict_SetItemString(zip_directory_cache
, path
,
130 PyErr_SetString(ZipImportError
, "not a Zip file");
138 len
= strlen(prefix
);
139 if (prefix
[len
-1] != SEP
) {
140 /* add trailing SEP */
142 prefix
[len
+ 1] = '\0';
146 self
->archive
= PyUnicode_FromString(buf
);
147 if (self
->archive
== NULL
)
150 self
->prefix
= PyUnicode_FromString(prefix
);
151 if (self
->prefix
== NULL
)
159 zipimporter_traverse(PyObject
*obj
, visitproc visit
, void *arg
)
161 ZipImporter
*self
= (ZipImporter
*)obj
;
162 Py_VISIT(self
->files
);
167 zipimporter_dealloc(ZipImporter
*self
)
169 PyObject_GC_UnTrack(self
);
170 Py_XDECREF(self
->archive
);
171 Py_XDECREF(self
->prefix
);
172 Py_XDECREF(self
->files
);
173 Py_TYPE(self
)->tp_free((PyObject
*)self
);
177 zipimporter_repr(ZipImporter
*self
)
179 char *archive
= "???";
182 if (self
->archive
!= NULL
&& PyUnicode_Check(self
->archive
))
183 archive
= _PyUnicode_AsString(self
->archive
);
184 if (self
->prefix
!= NULL
&& PyUnicode_Check(self
->prefix
))
185 prefix
= _PyUnicode_AsString(self
->prefix
);
186 if (prefix
!= NULL
&& *prefix
)
187 return PyUnicode_FromFormat("<zipimporter object \"%.300s%c%.150s\">",
188 archive
, SEP
, prefix
);
190 return PyUnicode_FromFormat("<zipimporter object \"%.300s\">",
194 /* return fullname.split(".")[-1] */
196 get_subname(char *fullname
)
198 char *subname
= strrchr(fullname
, '.');
206 /* Given a (sub)modulename, write the potential file path in the
207 archive (without extension) to the path buffer. Return the
208 length of the resulting string. */
210 make_filename(char *prefix
, char *name
, char *path
)
215 len
= strlen(prefix
);
217 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
218 if (len
+ strlen(name
) + 13 >= MAXPATHLEN
) {
219 PyErr_SetString(ZipImportError
, "path too long");
223 strcpy(path
, prefix
);
224 strcpy(path
+ len
, name
);
225 for (p
= path
+ len
; *p
; p
++) {
230 assert(len
< INT_MAX
);
234 enum zi_module_info
{
241 /* Return some information about a module. */
242 static enum zi_module_info
243 get_module_info(ZipImporter
*self
, char *fullname
)
245 char *subname
, path
[MAXPATHLEN
+ 1];
247 struct st_zip_searchorder
*zso
;
249 subname
= get_subname(fullname
);
251 len
= make_filename(_PyUnicode_AsString(self
->prefix
), subname
, path
);
255 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
256 strcpy(path
+ len
, zso
->suffix
);
257 if (PyDict_GetItemString(self
->files
, path
) != NULL
) {
258 if (zso
->type
& IS_PACKAGE
)
267 /* Check whether we can satisfy the import of the module named by
268 'fullname'. Return self if we can, None if we can't. */
270 zipimporter_find_module(PyObject
*obj
, PyObject
*args
)
272 ZipImporter
*self
= (ZipImporter
*)obj
;
273 PyObject
*path
= NULL
;
275 enum zi_module_info mi
;
277 if (!PyArg_ParseTuple(args
, "s|O:zipimporter.find_module",
281 mi
= get_module_info(self
, fullname
);
284 if (mi
== MI_NOT_FOUND
) {
289 return (PyObject
*)self
;
292 /* Load and return the module named by 'fullname'. */
294 zipimporter_load_module(PyObject
*obj
, PyObject
*args
)
296 ZipImporter
*self
= (ZipImporter
*)obj
;
297 PyObject
*code
, *mod
, *dict
;
298 char *fullname
, *modpath
;
301 if (!PyArg_ParseTuple(args
, "s:zipimporter.load_module",
305 code
= get_module_code(self
, fullname
, &ispackage
, &modpath
);
309 mod
= PyImport_AddModule(fullname
);
314 dict
= PyModule_GetDict(mod
);
316 /* mod.__loader__ = self */
317 if (PyDict_SetItemString(dict
, "__loader__", (PyObject
*)self
) != 0)
321 /* add __path__ to the module *before* the code gets
323 PyObject
*pkgpath
, *fullpath
;
324 char *subname
= get_subname(fullname
);
327 fullpath
= PyUnicode_FromFormat("%U%c%U%s",
329 self
->prefix
, subname
);
330 if (fullpath
== NULL
)
333 pkgpath
= Py_BuildValue("[O]", fullpath
);
337 err
= PyDict_SetItemString(dict
, "__path__", pkgpath
);
342 mod
= PyImport_ExecCodeModuleEx(fullname
, code
, modpath
);
345 PySys_WriteStderr("import %s # loaded from Zip %s\n",
354 /* Return a string matching __file__ for the named module */
356 zipimporter_get_filename(PyObject
*obj
, PyObject
*args
)
358 ZipImporter
*self
= (ZipImporter
*)obj
;
360 char *fullname
, *modpath
;
363 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_filename",
367 /* Deciding the filename requires working out where the code
368 would come from if the module was actually loaded */
369 code
= get_module_code(self
, fullname
, &ispackage
, &modpath
);
372 Py_DECREF(code
); /* Only need the path info */
374 return PyUnicode_FromString(modpath
);
377 /* Return a bool signifying whether the module is a package or not. */
379 zipimporter_is_package(PyObject
*obj
, PyObject
*args
)
381 ZipImporter
*self
= (ZipImporter
*)obj
;
383 enum zi_module_info mi
;
385 if (!PyArg_ParseTuple(args
, "s:zipimporter.is_package",
389 mi
= get_module_info(self
, fullname
);
392 if (mi
== MI_NOT_FOUND
) {
393 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
397 return PyBool_FromLong(mi
== MI_PACKAGE
);
401 zipimporter_get_data(PyObject
*obj
, PyObject
*args
)
403 ZipImporter
*self
= (ZipImporter
*)obj
;
406 char *p
, buf
[MAXPATHLEN
+ 1];
412 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_data", &path
))
416 if (strlen(path
) >= MAXPATHLEN
) {
417 PyErr_SetString(ZipImportError
, "path too long");
421 for (p
= buf
; *p
; p
++) {
427 archive_str
= _PyUnicode_AsStringAndSize(self
->archive
, &len
);
428 if ((size_t)len
< strlen(path
) &&
429 strncmp(path
, archive_str
, len
) == 0 &&
431 path
= path
+ len
+ 1;
434 toc_entry
= PyDict_GetItemString(self
->files
, path
);
435 if (toc_entry
== NULL
) {
436 PyErr_SetFromErrnoWithFilename(PyExc_IOError
, path
);
439 return get_data(archive_str
, toc_entry
);
443 zipimporter_get_code(PyObject
*obj
, PyObject
*args
)
445 ZipImporter
*self
= (ZipImporter
*)obj
;
448 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_code", &fullname
))
451 return get_module_code(self
, fullname
, NULL
, NULL
);
455 zipimporter_get_source(PyObject
*obj
, PyObject
*args
)
457 ZipImporter
*self
= (ZipImporter
*)obj
;
459 char *fullname
, *subname
, path
[MAXPATHLEN
+1];
461 enum zi_module_info mi
;
463 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_source", &fullname
))
466 mi
= get_module_info(self
, fullname
);
469 if (mi
== MI_NOT_FOUND
) {
470 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
474 subname
= get_subname(fullname
);
476 len
= make_filename(_PyUnicode_AsString(self
->prefix
), subname
, path
);
480 if (mi
== MI_PACKAGE
) {
482 strcpy(path
+ len
+ 1, "__init__.py");
485 strcpy(path
+ len
, ".py");
487 toc_entry
= PyDict_GetItemString(self
->files
, path
);
488 if (toc_entry
!= NULL
) {
489 PyObject
*bytes
= get_data(_PyUnicode_AsString(self
->archive
), toc_entry
);
490 PyObject
*res
= PyUnicode_FromString(PyBytes_AsString(bytes
));
495 /* we have the module, but no source */
500 PyDoc_STRVAR(doc_find_module
,
501 "find_module(fullname, path=None) -> self or None.\n\
503 Search for a module specified by 'fullname'. 'fullname' must be the\n\
504 fully qualified (dotted) module name. It returns the zipimporter\n\
505 instance itself if the module was found, or None if it wasn't.\n\
506 The optional 'path' argument is ignored -- it's there for compatibility\n\
507 with the importer protocol.");
509 PyDoc_STRVAR(doc_load_module
,
510 "load_module(fullname) -> module.\n\
512 Load the module specified by 'fullname'. 'fullname' must be the\n\
513 fully qualified (dotted) module name. It returns the imported\n\
514 module, or raises ZipImportError if it wasn't found.");
516 PyDoc_STRVAR(doc_get_data
,
517 "get_data(pathname) -> string with file data.\n\
519 Return the data associated with 'pathname'. Raise IOError if\n\
520 the file wasn't found.");
522 PyDoc_STRVAR(doc_is_package
,
523 "is_package(fullname) -> bool.\n\
525 Return True if the module specified by fullname is a package.\n\
526 Raise ZipImportError is the module couldn't be found.");
528 PyDoc_STRVAR(doc_get_code
,
529 "get_code(fullname) -> code object.\n\
531 Return the code object for the specified module. Raise ZipImportError\n\
532 is the module couldn't be found.");
534 PyDoc_STRVAR(doc_get_source
,
535 "get_source(fullname) -> source string.\n\
537 Return the source code for the specified module. Raise ZipImportError\n\
538 is the module couldn't be found, return None if the archive does\n\
539 contain the module, but has no source for it.");
542 PyDoc_STRVAR(doc_get_filename
,
543 "get_filename(fullname) -> filename string.\n\
545 Return the filename for the specified module.");
547 static PyMethodDef zipimporter_methods
[] = {
548 {"find_module", zipimporter_find_module
, METH_VARARGS
,
550 {"load_module", zipimporter_load_module
, METH_VARARGS
,
552 {"get_data", zipimporter_get_data
, METH_VARARGS
,
554 {"get_code", zipimporter_get_code
, METH_VARARGS
,
556 {"get_source", zipimporter_get_source
, METH_VARARGS
,
558 {"get_filename", zipimporter_get_filename
, METH_VARARGS
,
560 {"is_package", zipimporter_is_package
, METH_VARARGS
,
562 {NULL
, NULL
} /* sentinel */
565 static PyMemberDef zipimporter_members
[] = {
566 {"archive", T_OBJECT
, offsetof(ZipImporter
, archive
), READONLY
},
567 {"prefix", T_OBJECT
, offsetof(ZipImporter
, prefix
), READONLY
},
568 {"_files", T_OBJECT
, offsetof(ZipImporter
, files
), READONLY
},
572 PyDoc_STRVAR(zipimporter_doc
,
573 "zipimporter(archivepath) -> zipimporter object\n\
575 Create a new zipimporter instance. 'archivepath' must be a path to\n\
576 a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
577 '/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
578 valid directory inside the archive.\n\
580 'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
583 The 'archive' attribute of zipimporter objects contains the name of the\n\
586 #define DEFERRED_ADDRESS(ADDR) 0
588 static PyTypeObject ZipImporter_Type
= {
589 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
), 0)
590 "zipimport.zipimporter",
593 (destructor
)zipimporter_dealloc
, /* tp_dealloc */
598 (reprfunc
)zipimporter_repr
, /* tp_repr */
599 0, /* tp_as_number */
600 0, /* tp_as_sequence */
601 0, /* tp_as_mapping */
605 PyObject_GenericGetAttr
, /* tp_getattro */
607 0, /* tp_as_buffer */
608 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
|
609 Py_TPFLAGS_HAVE_GC
, /* tp_flags */
610 zipimporter_doc
, /* tp_doc */
611 zipimporter_traverse
, /* tp_traverse */
613 0, /* tp_richcompare */
614 0, /* tp_weaklistoffset */
617 zipimporter_methods
, /* tp_methods */
618 zipimporter_members
, /* tp_members */
622 0, /* tp_descr_get */
623 0, /* tp_descr_set */
624 0, /* tp_dictoffset */
625 (initproc
)zipimporter_init
, /* tp_init */
626 PyType_GenericAlloc
, /* tp_alloc */
627 PyType_GenericNew
, /* tp_new */
628 PyObject_GC_Del
, /* tp_free */
634 /* Given a buffer, return the long that is represented by the first
635 4 bytes, encoded as little endian. This partially reimplements
636 marshal.c:r_long() */
638 get_long(unsigned char *buf
) {
641 x
|= (long)buf
[1] << 8;
642 x
|= (long)buf
[2] << 16;
643 x
|= (long)buf
[3] << 24;
645 /* Sign extension for 64-bit machines */
646 x
|= -(x
& 0x80000000L
);
652 read_directory(archive) -> files dict (new reference)
654 Given a path to a Zip archive, build a dict, mapping file names
655 (local to the archive, using SEP as a separator) to toc entries.
657 A toc_entry is a tuple:
659 (__file__, # value to use for __file__, available for all files
660 compress, # compression kind; 0 for uncompressed
661 data_size, # size of compressed data on disk
662 file_size, # size of decompressed data
663 file_offset, # offset of file header from start of archive
664 time, # mod time of file (in dos format)
665 date, # mod data of file (in dos format)
666 crc, # crc checksum of the data
669 Directories can be recognized by the trailing SEP in the name,
670 data_size and file_offset are 0.
673 read_directory(char *archive
)
675 PyObject
*files
= NULL
;
677 long compress
, crc
, data_size
, file_size
, file_offset
, date
, time
;
678 long header_offset
, name_size
, header_size
, header_position
;
681 char path
[MAXPATHLEN
+ 5];
682 char name
[MAXPATHLEN
+ 5];
683 char *p
, endof_central_dir
[22];
684 long arc_offset
; /* offset from beginning of file to start of zip-archive */
686 if (strlen(archive
) > MAXPATHLEN
) {
687 PyErr_SetString(PyExc_OverflowError
,
688 "Zip path name is too long");
691 strcpy(path
, archive
);
693 fp
= fopen(archive
, "rb");
695 PyErr_Format(ZipImportError
, "can't open Zip file: "
696 "'%.200s'", archive
);
699 fseek(fp
, -22, SEEK_END
);
700 header_position
= ftell(fp
);
701 if (fread(endof_central_dir
, 1, 22, fp
) != 22) {
703 PyErr_Format(ZipImportError
, "can't read Zip file: "
704 "'%.200s'", archive
);
707 if (get_long((unsigned char *)endof_central_dir
) != 0x06054B50) {
708 /* Bad: End of Central Dir signature */
710 PyErr_Format(ZipImportError
, "not a Zip file: "
711 "'%.200s'", archive
);
715 header_size
= get_long((unsigned char *)endof_central_dir
+ 12);
716 header_offset
= get_long((unsigned char *)endof_central_dir
+ 16);
717 arc_offset
= header_position
- header_offset
- header_size
;
718 header_offset
+= arc_offset
;
720 files
= PyDict_New();
724 length
= (long)strlen(path
);
727 /* Start of Central Directory */
733 fseek(fp
, header_offset
, 0); /* Start of file header */
734 l
= PyMarshal_ReadLongFromFile(fp
);
736 break; /* Bad: Central Dir File Header */
737 fseek(fp
, header_offset
+ 10, 0);
738 compress
= PyMarshal_ReadShortFromFile(fp
);
739 time
= PyMarshal_ReadShortFromFile(fp
);
740 date
= PyMarshal_ReadShortFromFile(fp
);
741 crc
= PyMarshal_ReadLongFromFile(fp
);
742 data_size
= PyMarshal_ReadLongFromFile(fp
);
743 file_size
= PyMarshal_ReadLongFromFile(fp
);
744 name_size
= PyMarshal_ReadShortFromFile(fp
);
745 header_size
= 46 + name_size
+
746 PyMarshal_ReadShortFromFile(fp
) +
747 PyMarshal_ReadShortFromFile(fp
);
748 fseek(fp
, header_offset
+ 42, 0);
749 file_offset
= PyMarshal_ReadLongFromFile(fp
) + arc_offset
;
750 if (name_size
> MAXPATHLEN
)
751 name_size
= MAXPATHLEN
;
754 for (i
= 0; i
< name_size
; i
++) {
760 *p
= 0; /* Add terminating null byte */
761 header_offset
+= header_size
;
763 strncpy(path
+ length
+ 1, name
, MAXPATHLEN
- length
- 1);
765 t
= Py_BuildValue("siiiiiii", path
, compress
, data_size
,
766 file_size
, file_offset
, time
, date
, crc
);
769 err
= PyDict_SetItemString(files
, name
, t
);
777 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
786 /* Return the zlib.decompress function object, or NULL if zlib couldn't
787 be imported. The function is cached when found, so subsequent calls
788 don't import zlib again. Returns a *borrowed* reference.
789 XXX This makes zlib.decompress immortal. */
791 get_decompress_func(void)
793 static PyObject
*decompress
= NULL
;
795 if (decompress
== NULL
) {
797 static int importing_zlib
= 0;
799 if (importing_zlib
!= 0)
800 /* Someone has a zlib.py[co] in their Zip file;
801 let's avoid a stack overflow. */
804 zlib
= PyImport_ImportModuleNoBlock("zlib");
807 decompress
= PyObject_GetAttrString(zlib
,
814 PySys_WriteStderr("# zipimport: zlib %s\n",
815 zlib
!= NULL
? "available": "UNAVAILABLE");
820 /* Given a path to a Zip file and a toc_entry, return the (uncompressed)
821 data as a new reference. */
823 get_data(char *archive
, PyObject
*toc_entry
)
825 PyObject
*raw_data
, *data
= NULL
, *decompress
;
829 Py_ssize_t bytes_read
= 0;
832 long compress
, data_size
, file_size
, file_offset
, bytes_size
;
833 long time
, date
, crc
;
835 if (!PyArg_ParseTuple(toc_entry
, "slllllll", &datapath
, &compress
,
836 &data_size
, &file_size
, &file_offset
, &time
,
841 fp
= fopen(archive
, "rb");
843 PyErr_Format(PyExc_IOError
,
844 "zipimport: can not open file %s", archive
);
848 /* Check to make sure the local file header is correct */
849 fseek(fp
, file_offset
, 0);
850 l
= PyMarshal_ReadLongFromFile(fp
);
851 if (l
!= 0x04034B50) {
852 /* Bad: Local File Header */
853 PyErr_Format(ZipImportError
,
854 "bad local file header in %s",
859 fseek(fp
, file_offset
+ 26, 0);
860 l
= 30 + PyMarshal_ReadShortFromFile(fp
) +
861 PyMarshal_ReadShortFromFile(fp
); /* local header size */
862 file_offset
+= l
; /* Start of file data */
864 bytes_size
= compress
== 0 ? data_size
: data_size
+ 1;
867 raw_data
= PyBytes_FromStringAndSize((char *)NULL
, bytes_size
);
869 if (raw_data
== NULL
) {
873 buf
= PyBytes_AsString(raw_data
);
875 err
= fseek(fp
, file_offset
, 0);
877 bytes_read
= fread(buf
, 1, data_size
, fp
);
879 if (err
|| bytes_read
!= data_size
) {
880 PyErr_SetString(PyExc_IOError
,
881 "zipimport: can't read data");
887 buf
[data_size
] = 'Z'; /* saw this in zipfile.py */
890 buf
[data_size
] = '\0';
892 if (compress
== 0) { /* data is not compressed */
893 data
= PyBytes_FromStringAndSize(buf
, data_size
);
898 /* Decompress with zlib */
899 decompress
= get_decompress_func();
900 if (decompress
== NULL
) {
901 PyErr_SetString(ZipImportError
,
902 "can't decompress data; "
903 "zlib not available");
906 data
= PyObject_CallFunction(decompress
, "Oi", raw_data
, -15);
912 /* Lenient date/time comparison function. The precision of the mtime
913 in the archive is lower than the mtime stored in a .pyc: we
914 must allow a difference of at most one second. */
916 eq_mtime(time_t t1
, time_t t2
)
921 /* dostime only stores even seconds, so be lenient */
925 /* Given the contents of a .py[co] file in a buffer, unmarshal the data
926 and return the code object. Return None if it the magic word doesn't
927 match (we do this instead of raising an exception as we fall back
928 to .py if available and we don't want to mask other errors).
929 Returns a new reference. */
931 unmarshal_code(char *pathname
, PyObject
*data
, time_t mtime
)
934 char *buf
= PyBytes_AsString(data
);
935 Py_ssize_t size
= PyBytes_Size(data
);
938 PyErr_SetString(ZipImportError
,
943 if (get_long((unsigned char *)buf
) != PyImport_GetMagicNumber()) {
945 PySys_WriteStderr("# %s has bad magic\n",
948 return Py_None
; /* signal caller to try alternative */
951 if (mtime
!= 0 && !eq_mtime(get_long((unsigned char *)buf
+ 4),
954 PySys_WriteStderr("# %s has bad mtime\n",
957 return Py_None
; /* signal caller to try alternative */
960 code
= PyMarshal_ReadObjectFromString(buf
+ 8, size
- 8);
963 if (!PyCode_Check(code
)) {
965 PyErr_Format(PyExc_TypeError
,
966 "compiled module %.200s is not a code object",
973 /* Replace any occurances of "\r\n?" in the input string with "\n".
974 This converts DOS and Mac line endings to Unix line endings.
975 Also append a trailing "\n" to be compatible with
976 PyParser_SimpleParseFile(). Returns a new reference. */
978 normalize_line_endings(PyObject
*source
)
980 char *buf
, *q
, *p
= PyBytes_AsString(source
);
981 PyObject
*fixed_source
;
985 return PyBytes_FromStringAndSize("\n\0", 2);
988 /* one char extra for trailing \n and one for terminating \0 */
989 buf
= (char *)PyMem_Malloc(PyBytes_Size(source
) + 2);
991 PyErr_SetString(PyExc_MemoryError
,
992 "zipimport: no memory to allocate "
996 /* replace "\r\n?" by "\n" */
997 for (q
= buf
; *p
!= '\0'; p
++) {
1000 if (*(p
+ 1) == '\n')
1007 *q
++ = '\n'; /* add trailing \n */
1009 fixed_source
= PyBytes_FromStringAndSize(buf
, len
+ 2);
1011 return fixed_source
;
1014 /* Given a string buffer containing Python source code, compile it
1015 return and return a code object as a new reference. */
1017 compile_source(char *pathname
, PyObject
*source
)
1019 PyObject
*code
, *fixed_source
;
1021 fixed_source
= normalize_line_endings(source
);
1022 if (fixed_source
== NULL
)
1025 code
= Py_CompileString(PyBytes_AsString(fixed_source
), pathname
,
1027 Py_DECREF(fixed_source
);
1031 /* Convert the date/time values found in the Zip archive to a value
1032 that's compatible with the time stamp stored in .pyc files. */
1034 parse_dostime(int dostime
, int dosdate
)
1038 memset((void *) &stm
, '\0', sizeof(stm
));
1040 stm
.tm_sec
= (dostime
& 0x1f) * 2;
1041 stm
.tm_min
= (dostime
>> 5) & 0x3f;
1042 stm
.tm_hour
= (dostime
>> 11) & 0x1f;
1043 stm
.tm_mday
= dosdate
& 0x1f;
1044 stm
.tm_mon
= ((dosdate
>> 5) & 0x0f) - 1;
1045 stm
.tm_year
= ((dosdate
>> 9) & 0x7f) + 80;
1046 stm
.tm_isdst
= -1; /* wday/yday is ignored */
1048 return mktime(&stm
);
1051 /* Given a path to a .pyc or .pyo file in the archive, return the
1052 modifictaion time of the matching .py file, or 0 if no source
1055 get_mtime_of_source(ZipImporter
*self
, char *path
)
1057 PyObject
*toc_entry
;
1059 Py_ssize_t lastchar
= strlen(path
) - 1;
1060 char savechar
= path
[lastchar
];
1061 path
[lastchar
] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1062 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1063 if (toc_entry
!= NULL
&& PyTuple_Check(toc_entry
) &&
1064 PyTuple_Size(toc_entry
) == 8) {
1065 /* fetch the time stamp of the .py file for comparison
1066 with an embedded pyc time stamp */
1068 time
= PyLong_AsLong(PyTuple_GetItem(toc_entry
, 5));
1069 date
= PyLong_AsLong(PyTuple_GetItem(toc_entry
, 6));
1070 mtime
= parse_dostime(time
, date
);
1072 path
[lastchar
] = savechar
;
1076 /* Return the code object for the module named by 'fullname' from the
1077 Zip archive as a new reference. */
1079 get_code_from_data(ZipImporter
*self
, int ispackage
, int isbytecode
,
1080 time_t mtime
, PyObject
*toc_entry
)
1082 PyObject
*data
, *code
;
1084 char *archive
= _PyUnicode_AsString(self
->archive
);
1086 if (archive
== NULL
)
1089 data
= get_data(archive
, toc_entry
);
1093 modpath
= _PyUnicode_AsString(PyTuple_GetItem(toc_entry
, 0));
1096 code
= unmarshal_code(modpath
, data
, mtime
);
1099 code
= compile_source(modpath
, data
);
1105 /* Get the code object assoiciated with the module specified by
1108 get_module_code(ZipImporter
*self
, char *fullname
,
1109 int *p_ispackage
, char **p_modpath
)
1111 PyObject
*toc_entry
;
1112 char *subname
, path
[MAXPATHLEN
+ 1];
1114 struct st_zip_searchorder
*zso
;
1116 subname
= get_subname(fullname
);
1118 len
= make_filename(_PyUnicode_AsString(self
->prefix
), subname
, path
);
1122 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
1123 PyObject
*code
= NULL
;
1125 strcpy(path
+ len
, zso
->suffix
);
1126 if (Py_VerboseFlag
> 1)
1127 PySys_WriteStderr("# trying %s%c%s\n",
1128 _PyUnicode_AsString(self
->archive
),
1130 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1131 if (toc_entry
!= NULL
) {
1133 int ispackage
= zso
->type
& IS_PACKAGE
;
1134 int isbytecode
= zso
->type
& IS_BYTECODE
;
1137 mtime
= get_mtime_of_source(self
, path
);
1138 if (p_ispackage
!= NULL
)
1139 *p_ispackage
= ispackage
;
1140 code
= get_code_from_data(self
, ispackage
,
1143 if (code
== Py_None
) {
1144 /* bad magic number or non-matching mtime
1145 in byte code, try next */
1149 if (code
!= NULL
&& p_modpath
!= NULL
)
1150 *p_modpath
= _PyUnicode_AsString(
1151 PyTuple_GetItem(toc_entry
, 0));
1155 PyErr_Format(ZipImportError
, "can't find module '%.200s'", fullname
);
1162 PyDoc_STRVAR(zipimport_doc
,
1163 "zipimport provides support for importing Python modules from Zip archives.\n\
1165 This module exports three objects:\n\
1166 - zipimporter: a class; its constructor takes a path to a Zip archive.\n\
1167 - ZipImportError: exception raised by zipimporter objects. It's a\n\
1168 subclass of ImportError, so it can be caught as ImportError, too.\n\
1169 - _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1170 info dicts, as used in zipimporter._files.\n\
1172 It is usually not needed to use the zipimport module explicitly; it is\n\
1173 used by the builtin import mechanism for sys.path items that are paths\n\
1176 static struct PyModuleDef zipimportmodule
= {
1177 PyModuleDef_HEAD_INIT
,
1189 PyInit_zipimport(void)
1193 if (PyType_Ready(&ZipImporter_Type
) < 0)
1196 /* Correct directory separator */
1197 zip_searchorder
[0].suffix
[0] = SEP
;
1198 zip_searchorder
[1].suffix
[0] = SEP
;
1199 zip_searchorder
[2].suffix
[0] = SEP
;
1200 if (Py_OptimizeFlag
) {
1201 /* Reverse *.pyc and *.pyo */
1202 struct st_zip_searchorder tmp
;
1203 tmp
= zip_searchorder
[0];
1204 zip_searchorder
[0] = zip_searchorder
[1];
1205 zip_searchorder
[1] = tmp
;
1206 tmp
= zip_searchorder
[3];
1207 zip_searchorder
[3] = zip_searchorder
[4];
1208 zip_searchorder
[4] = tmp
;
1211 mod
= PyModule_Create(&zipimportmodule
);
1215 ZipImportError
= PyErr_NewException("zipimport.ZipImportError",
1216 PyExc_ImportError
, NULL
);
1217 if (ZipImportError
== NULL
)
1220 Py_INCREF(ZipImportError
);
1221 if (PyModule_AddObject(mod
, "ZipImportError",
1222 ZipImportError
) < 0)
1225 Py_INCREF(&ZipImporter_Type
);
1226 if (PyModule_AddObject(mod
, "zipimporter",
1227 (PyObject
*)&ZipImporter_Type
) < 0)
1230 zip_directory_cache
= PyDict_New();
1231 if (zip_directory_cache
== NULL
)
1233 Py_INCREF(zip_directory_cache
);
1234 if (PyModule_AddObject(mod
, "_zip_directory_cache",
1235 zip_directory_cache
) < 0)