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 PyTypeObject ZipImporter_Type
;
44 static PyObject
*ZipImportError
;
45 static PyObject
*zip_directory_cache
= NULL
;
48 static PyObject
*read_directory(char *archive
);
49 static PyObject
*get_data(char *archive
, PyObject
*toc_entry
);
50 static PyObject
*get_module_code(ZipImporter
*self
, char *fullname
,
51 int *p_ispackage
, char **p_modpath
);
54 #define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
57 /* zipimporter.__init__
58 Split the "subdirectory" from the Zip archive path, lookup a matching
59 entry in sys.path_importer_cache, fetch the file directory from there
60 if found, or else read it from the archive. */
62 zipimporter_init(ZipImporter
*self
, PyObject
*args
, PyObject
*kwds
)
64 char *path
, *p
, *prefix
, buf
[MAXPATHLEN
+2];
67 if (!_PyArg_NoKeywords("zipimporter()", kwds
))
70 if (!PyArg_ParseTuple(args
, "s:zipimporter",
76 PyErr_SetString(ZipImportError
, "archive path is empty");
79 if (len
>= MAXPATHLEN
) {
80 PyErr_SetString(ZipImportError
,
81 "archive path too long");
87 for (p
= buf
; *p
; p
++) {
100 rv
= stat(buf
, &statbuf
);
103 if (S_ISREG(statbuf
.st_mode
))
109 if (object_exists(buf
)) {
117 /* back up one path element */
118 p
= strrchr(buf
, SEP
);
128 files
= PyDict_GetItemString(zip_directory_cache
, path
);
130 files
= read_directory(buf
);
133 if (PyDict_SetItemString(zip_directory_cache
, path
,
142 PyErr_SetString(ZipImportError
, "not a Zip file");
150 len
= strlen(prefix
);
151 if (prefix
[len
-1] != SEP
) {
152 /* add trailing SEP */
154 prefix
[len
+ 1] = '\0';
158 self
->archive
= PyString_FromString(buf
);
159 if (self
->archive
== NULL
)
162 self
->prefix
= PyString_FromString(prefix
);
163 if (self
->prefix
== NULL
)
171 zipimporter_traverse(PyObject
*obj
, visitproc visit
, void *arg
)
173 ZipImporter
*self
= (ZipImporter
*)obj
;
176 if (self
->files
!= NULL
) {
177 err
= visit(self
->files
, arg
);
185 zipimporter_dealloc(ZipImporter
*self
)
187 PyObject_GC_UnTrack(self
);
188 Py_XDECREF(self
->archive
);
189 Py_XDECREF(self
->prefix
);
190 Py_XDECREF(self
->files
);
191 self
->ob_type
->tp_free((PyObject
*)self
);
195 zipimporter_repr(ZipImporter
*self
)
198 char *archive
= "???";
201 if (self
->archive
!= NULL
&& PyString_Check(self
->archive
))
202 archive
= PyString_AsString(self
->archive
);
203 if (self
->prefix
!= NULL
&& PyString_Check(self
->prefix
))
204 prefix
= PyString_AsString(self
->prefix
);
205 if (prefix
!= NULL
&& *prefix
)
206 PyOS_snprintf(buf
, sizeof(buf
),
207 "<zipimporter object \"%.300s%c%.150s\">",
208 archive
, SEP
, prefix
);
210 PyOS_snprintf(buf
, sizeof(buf
),
211 "<zipimporter object \"%.300s\">",
213 return PyString_FromString(buf
);
216 /* return fullname.split(".")[-1] */
218 get_subname(char *fullname
)
220 char *subname
= strrchr(fullname
, '.');
228 /* Given a (sub)modulename, write the potential file path in the
229 archive (without extension) to the path buffer. Return the
230 length of the resulting string. */
232 make_filename(char *prefix
, char *name
, char *path
)
237 len
= strlen(prefix
);
239 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
240 if (len
+ strlen(name
) + 13 >= MAXPATHLEN
) {
241 PyErr_SetString(ZipImportError
, "path too long");
245 strcpy(path
, prefix
);
246 strcpy(path
+ len
, name
);
247 for (p
= path
+ len
; *p
; p
++) {
252 assert(len
< INT_MAX
);
256 enum zi_module_info
{
263 /* Return some information about a module. */
264 static enum zi_module_info
265 get_module_info(ZipImporter
*self
, char *fullname
)
267 char *subname
, path
[MAXPATHLEN
+ 1];
269 struct st_zip_searchorder
*zso
;
271 subname
= get_subname(fullname
);
273 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
277 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
278 strcpy(path
+ len
, zso
->suffix
);
279 if (PyDict_GetItemString(self
->files
, path
) != NULL
) {
280 if (zso
->type
& IS_PACKAGE
)
289 /* Check whether we can satisfy the import of the module named by
290 'fullname'. Return self if we can, None if we can't. */
292 zipimporter_find_module(PyObject
*obj
, PyObject
*args
)
294 ZipImporter
*self
= (ZipImporter
*)obj
;
295 PyObject
*path
= NULL
;
297 enum zi_module_info mi
;
299 if (!PyArg_ParseTuple(args
, "s|O:zipimporter.find_module",
303 mi
= get_module_info(self
, fullname
);
306 if (mi
== MI_NOT_FOUND
) {
311 return (PyObject
*)self
;
314 /* Load and return the module named by 'fullname'. */
316 zipimporter_load_module(PyObject
*obj
, PyObject
*args
)
318 ZipImporter
*self
= (ZipImporter
*)obj
;
319 PyObject
*code
, *mod
, *dict
;
320 char *fullname
, *modpath
;
323 if (!PyArg_ParseTuple(args
, "s:zipimporter.load_module",
327 code
= get_module_code(self
, fullname
, &ispackage
, &modpath
);
331 mod
= PyImport_AddModule(fullname
);
336 dict
= PyModule_GetDict(mod
);
338 /* mod.__loader__ = self */
339 if (PyDict_SetItemString(dict
, "__loader__", (PyObject
*)self
) != 0)
343 /* add __path__ to the module *before* the code gets
345 PyObject
*pkgpath
, *fullpath
;
346 char *prefix
= PyString_AsString(self
->prefix
);
347 char *subname
= get_subname(fullname
);
350 fullpath
= PyString_FromFormat("%s%c%s%s",
351 PyString_AsString(self
->archive
),
353 *prefix
? prefix
: "",
355 if (fullpath
== NULL
)
358 pkgpath
= Py_BuildValue("[O]", fullpath
);
362 err
= PyDict_SetItemString(dict
, "__path__", pkgpath
);
367 mod
= PyImport_ExecCodeModuleEx(fullname
, code
, modpath
);
370 PySys_WriteStderr("import %s # loaded from Zip %s\n",
379 /* Return a bool signifying whether the module is a package or not. */
381 zipimporter_is_package(PyObject
*obj
, PyObject
*args
)
383 ZipImporter
*self
= (ZipImporter
*)obj
;
385 enum zi_module_info mi
;
387 if (!PyArg_ParseTuple(args
, "s:zipimporter.is_package",
391 mi
= get_module_info(self
, fullname
);
394 if (mi
== MI_NOT_FOUND
) {
395 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
399 return PyBool_FromLong(mi
== MI_PACKAGE
);
403 zipimporter_get_data(PyObject
*obj
, PyObject
*args
)
405 ZipImporter
*self
= (ZipImporter
*)obj
;
408 char *p
, buf
[MAXPATHLEN
+ 1];
413 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_data", &path
))
417 if (strlen(path
) >= MAXPATHLEN
) {
418 PyErr_SetString(ZipImportError
, "path too long");
422 for (p
= buf
; *p
; p
++) {
428 len
= PyString_Size(self
->archive
);
429 if ((size_t)len
< strlen(path
) &&
430 strncmp(path
, PyString_AsString(self
->archive
), len
) == 0 &&
432 path
= path
+ len
+ 1;
435 toc_entry
= PyDict_GetItemString(self
->files
, path
);
436 if (toc_entry
== NULL
) {
437 PyErr_SetFromErrnoWithFilename(PyExc_IOError
, path
);
440 return get_data(PyString_AsString(self
->archive
), toc_entry
);
444 zipimporter_get_code(PyObject
*obj
, PyObject
*args
)
446 ZipImporter
*self
= (ZipImporter
*)obj
;
449 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_code", &fullname
))
452 return get_module_code(self
, fullname
, NULL
, NULL
);
456 zipimporter_get_source(PyObject
*obj
, PyObject
*args
)
458 ZipImporter
*self
= (ZipImporter
*)obj
;
460 char *fullname
, *subname
, path
[MAXPATHLEN
+1];
462 enum zi_module_info mi
;
464 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_source", &fullname
))
467 mi
= get_module_info(self
, fullname
);
470 if (mi
== MI_NOT_FOUND
) {
471 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
475 subname
= get_subname(fullname
);
477 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
481 if (mi
== MI_PACKAGE
) {
483 strcpy(path
+ len
+ 1, "__init__.py");
486 strcpy(path
+ len
, ".py");
488 toc_entry
= PyDict_GetItemString(self
->files
, path
);
489 if (toc_entry
!= NULL
)
490 return get_data(PyString_AsString(self
->archive
), toc_entry
);
492 /* we have the module, but no source */
497 PyDoc_STRVAR(doc_find_module
,
498 "find_module(fullname, path=None) -> self or None.\n\
500 Search for a module specified by 'fullname'. 'fullname' must be the\n\
501 fully qualified (dotted) module name. It returns the zipimporter\n\
502 instance itself if the module was found, or None if it wasn't.\n\
503 The optional 'path' argument is ignored -- it's there for compatibility\n\
504 with the importer protocol.");
506 PyDoc_STRVAR(doc_load_module
,
507 "load_module(fullname) -> module.\n\
509 Load the module specified by 'fullname'. 'fullname' must be the\n\
510 fully qualified (dotted) module name. It returns the imported\n\
511 module, or raises ZipImportError if it wasn't found.");
513 PyDoc_STRVAR(doc_get_data
,
514 "get_data(pathname) -> string with file data.\n\
516 Return the data associated with 'pathname'. Raise IOError if\n\
517 the file wasn't found.");
519 PyDoc_STRVAR(doc_is_package
,
520 "is_package(fullname) -> bool.\n\
522 Return True if the module specified by fullname is a package.\n\
523 Raise ZipImportError is the module couldn't be found.");
525 PyDoc_STRVAR(doc_get_code
,
526 "get_code(fullname) -> code object.\n\
528 Return the code object for the specified module. Raise ZipImportError\n\
529 is the module couldn't be found.");
531 PyDoc_STRVAR(doc_get_source
,
532 "get_source(fullname) -> source string.\n\
534 Return the source code for the specified module. Raise ZipImportError\n\
535 is the module couldn't be found, return None if the archive does\n\
536 contain the module, but has no source for it.");
538 static PyMethodDef zipimporter_methods
[] = {
539 {"find_module", zipimporter_find_module
, METH_VARARGS
,
541 {"load_module", zipimporter_load_module
, METH_VARARGS
,
543 {"get_data", zipimporter_get_data
, METH_VARARGS
,
545 {"get_code", zipimporter_get_code
, METH_VARARGS
,
547 {"get_source", zipimporter_get_source
, METH_VARARGS
,
549 {"is_package", zipimporter_is_package
, METH_VARARGS
,
551 {NULL
, NULL
} /* sentinel */
554 static PyMemberDef zipimporter_members
[] = {
555 {"archive", T_OBJECT
, offsetof(ZipImporter
, archive
), READONLY
},
556 {"prefix", T_OBJECT
, offsetof(ZipImporter
, prefix
), READONLY
},
557 {"_files", T_OBJECT
, offsetof(ZipImporter
, files
), READONLY
},
561 PyDoc_STRVAR(zipimporter_doc
,
562 "zipimporter(archivepath) -> zipimporter object\n\
564 Create a new zipimporter instance. 'archivepath' must be a path to\n\
565 a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\
566 a valid Zip archive.");
568 #define DEFERRED_ADDRESS(ADDR) 0
570 static PyTypeObject ZipImporter_Type
= {
571 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
573 "zipimport.zipimporter",
576 (destructor
)zipimporter_dealloc
, /* tp_dealloc */
581 (reprfunc
)zipimporter_repr
, /* tp_repr */
582 0, /* tp_as_number */
583 0, /* tp_as_sequence */
584 0, /* tp_as_mapping */
588 PyObject_GenericGetAttr
, /* tp_getattro */
590 0, /* tp_as_buffer */
591 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
|
592 Py_TPFLAGS_HAVE_GC
, /* tp_flags */
593 zipimporter_doc
, /* tp_doc */
594 zipimporter_traverse
, /* tp_traverse */
596 0, /* tp_richcompare */
597 0, /* tp_weaklistoffset */
600 zipimporter_methods
, /* tp_methods */
601 zipimporter_members
, /* tp_members */
605 0, /* tp_descr_get */
606 0, /* tp_descr_set */
607 0, /* tp_dictoffset */
608 (initproc
)zipimporter_init
, /* tp_init */
609 PyType_GenericAlloc
, /* tp_alloc */
610 PyType_GenericNew
, /* tp_new */
611 PyObject_GC_Del
, /* tp_free */
617 /* Given a buffer, return the long that is represented by the first
618 4 bytes, encoded as little endian. This partially reimplements
619 marshal.c:r_long() */
621 get_long(unsigned char *buf
) {
624 x
|= (long)buf
[1] << 8;
625 x
|= (long)buf
[2] << 16;
626 x
|= (long)buf
[3] << 24;
628 /* Sign extension for 64-bit machines */
629 x
|= -(x
& 0x80000000L
);
635 read_directory(archive) -> files dict (new reference)
637 Given a path to a Zip archive, build a dict, mapping file names
638 (local to the archive, using SEP as a separator) to toc entries.
640 A toc_entry is a tuple:
642 (__file__, # value to use for __file__, available for all files
643 compress, # compression kind; 0 for uncompressed
644 data_size, # size of compressed data on disk
645 file_size, # size of decompressed data
646 file_offset, # offset of file header from start of archive
647 time, # mod time of file (in dos format)
648 date, # mod data of file (in dos format)
649 crc, # crc checksum of the data
652 Directories can be recognized by the trailing SEP in the name,
653 data_size and file_offset are 0.
656 read_directory(char *archive
)
658 PyObject
*files
= NULL
;
660 long compress
, crc
, data_size
, file_size
, file_offset
, date
, time
;
661 long header_offset
, name_size
, header_size
, header_position
;
664 char path
[MAXPATHLEN
+ 5];
665 char name
[MAXPATHLEN
+ 5];
666 char *p
, endof_central_dir
[22];
667 long arc_offset
; /* offset from beginning of file to start of zip-archive */
669 if (strlen(archive
) > MAXPATHLEN
) {
670 PyErr_SetString(PyExc_OverflowError
,
671 "Zip path name is too long");
674 strcpy(path
, archive
);
676 fp
= fopen(archive
, "rb");
678 PyErr_Format(ZipImportError
, "can't open Zip file: "
679 "'%.200s'", archive
);
682 fseek(fp
, -22, SEEK_END
);
683 header_position
= ftell(fp
);
684 if (fread(endof_central_dir
, 1, 22, fp
) != 22) {
686 PyErr_Format(ZipImportError
, "can't read Zip file: "
687 "'%.200s'", archive
);
690 if (get_long((unsigned char *)endof_central_dir
) != 0x06054B50) {
691 /* Bad: End of Central Dir signature */
693 PyErr_Format(ZipImportError
, "not a Zip file: "
694 "'%.200s'", archive
);
698 header_size
= get_long((unsigned char *)endof_central_dir
+ 12);
699 header_offset
= get_long((unsigned char *)endof_central_dir
+ 16);
700 arc_offset
= header_position
- header_offset
- header_size
;
701 header_offset
+= arc_offset
;
703 files
= PyDict_New();
707 length
= (long)strlen(path
);
710 /* Start of Central Directory */
716 fseek(fp
, header_offset
, 0); /* Start of file header */
717 l
= PyMarshal_ReadLongFromFile(fp
);
719 break; /* Bad: Central Dir File Header */
720 fseek(fp
, header_offset
+ 10, 0);
721 compress
= PyMarshal_ReadShortFromFile(fp
);
722 time
= PyMarshal_ReadShortFromFile(fp
);
723 date
= PyMarshal_ReadShortFromFile(fp
);
724 crc
= PyMarshal_ReadLongFromFile(fp
);
725 data_size
= PyMarshal_ReadLongFromFile(fp
);
726 file_size
= PyMarshal_ReadLongFromFile(fp
);
727 name_size
= PyMarshal_ReadShortFromFile(fp
);
728 header_size
= 46 + name_size
+
729 PyMarshal_ReadShortFromFile(fp
) +
730 PyMarshal_ReadShortFromFile(fp
);
731 fseek(fp
, header_offset
+ 42, 0);
732 file_offset
= PyMarshal_ReadLongFromFile(fp
) + arc_offset
;
733 if (name_size
> MAXPATHLEN
)
734 name_size
= MAXPATHLEN
;
737 for (i
= 0; i
< name_size
; i
++) {
743 *p
= 0; /* Add terminating null byte */
744 header_offset
+= header_size
;
746 strncpy(path
+ length
+ 1, name
, MAXPATHLEN
- length
- 1);
748 t
= Py_BuildValue("siiiiiii", path
, compress
, data_size
,
749 file_size
, file_offset
, time
, date
, crc
);
752 err
= PyDict_SetItemString(files
, name
, t
);
760 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
769 /* Return the zlib.decompress function object, or NULL if zlib couldn't
770 be imported. The function is cached when found, so subsequent calls
771 don't import zlib again. Returns a *borrowed* reference.
772 XXX This makes zlib.decompress immortal. */
774 get_decompress_func(void)
776 static PyObject
*decompress
= NULL
;
778 if (decompress
== NULL
) {
780 static int importing_zlib
= 0;
782 if (importing_zlib
!= 0)
783 /* Someone has a zlib.py[co] in their Zip file;
784 let's avoid a stack overflow. */
787 zlib
= PyImport_ImportModule("zlib"); /* import zlib */
790 decompress
= PyObject_GetAttrString(zlib
,
797 PySys_WriteStderr("# zipimport: zlib %s\n",
798 zlib
!= NULL
? "available": "UNAVAILABLE");
803 /* Given a path to a Zip file and a toc_entry, return the (uncompressed)
804 data as a new reference. */
806 get_data(char *archive
, PyObject
*toc_entry
)
808 PyObject
*raw_data
, *data
= NULL
, *decompress
;
812 Py_ssize_t bytes_read
= 0;
815 long compress
, data_size
, file_size
, file_offset
;
816 long time
, date
, crc
;
818 if (!PyArg_ParseTuple(toc_entry
, "slllllll", &datapath
, &compress
,
819 &data_size
, &file_size
, &file_offset
, &time
,
824 fp
= fopen(archive
, "rb");
826 PyErr_Format(PyExc_IOError
,
827 "zipimport: can not open file %s", archive
);
831 /* Check to make sure the local file header is correct */
832 fseek(fp
, file_offset
, 0);
833 l
= PyMarshal_ReadLongFromFile(fp
);
834 if (l
!= 0x04034B50) {
835 /* Bad: Local File Header */
836 PyErr_Format(ZipImportError
,
837 "bad local file header in %s",
842 fseek(fp
, file_offset
+ 26, 0);
843 l
= 30 + PyMarshal_ReadShortFromFile(fp
) +
844 PyMarshal_ReadShortFromFile(fp
); /* local header size */
845 file_offset
+= l
; /* Start of file data */
847 raw_data
= PyString_FromStringAndSize((char *)NULL
, compress
== 0 ?
848 data_size
: data_size
+ 1);
849 if (raw_data
== NULL
) {
853 buf
= PyString_AsString(raw_data
);
855 err
= fseek(fp
, file_offset
, 0);
857 bytes_read
= fread(buf
, 1, data_size
, fp
);
859 if (err
|| bytes_read
!= data_size
) {
860 PyErr_SetString(PyExc_IOError
,
861 "zipimport: can't read data");
867 buf
[data_size
] = 'Z'; /* saw this in zipfile.py */
870 buf
[data_size
] = '\0';
872 if (compress
== 0) /* data is not compressed */
875 /* Decompress with zlib */
876 decompress
= get_decompress_func();
877 if (decompress
== NULL
) {
878 PyErr_SetString(ZipImportError
,
879 "can't decompress data; "
880 "zlib not available");
883 data
= PyObject_CallFunction(decompress
, "Oi", raw_data
, -15);
889 /* Lenient date/time comparison function. The precision of the mtime
890 in the archive is lower than the mtime stored in a .pyc: we
891 must allow a difference of at most one second. */
893 eq_mtime(time_t t1
, time_t t2
)
898 /* dostime only stores even seconds, so be lenient */
902 /* Given the contents of a .py[co] file in a buffer, unmarshal the data
903 and return the code object. Return None if it the magic word doesn't
904 match (we do this instead of raising an exception as we fall back
905 to .py if available and we don't want to mask other errors).
906 Returns a new reference. */
908 unmarshal_code(char *pathname
, PyObject
*data
, time_t mtime
)
911 char *buf
= PyString_AsString(data
);
912 Py_ssize_t size
= PyString_Size(data
);
915 PyErr_SetString(ZipImportError
,
920 if (get_long((unsigned char *)buf
) != PyImport_GetMagicNumber()) {
922 PySys_WriteStderr("# %s has bad magic\n",
925 return Py_None
; /* signal caller to try alternative */
928 if (mtime
!= 0 && !eq_mtime(get_long((unsigned char *)buf
+ 4),
931 PySys_WriteStderr("# %s has bad mtime\n",
934 return Py_None
; /* signal caller to try alternative */
937 code
= PyMarshal_ReadObjectFromString(buf
+ 8, size
- 8);
940 if (!PyCode_Check(code
)) {
942 PyErr_Format(PyExc_TypeError
,
943 "compiled module %.200s is not a code object",
950 /* Replace any occurances of "\r\n?" in the input string with "\n".
951 This converts DOS and Mac line endings to Unix line endings.
952 Also append a trailing "\n" to be compatible with
953 PyParser_SimpleParseFile(). Returns a new reference. */
955 normalize_line_endings(PyObject
*source
)
957 char *buf
, *q
, *p
= PyString_AsString(source
);
958 PyObject
*fixed_source
;
960 /* one char extra for trailing \n and one for terminating \0 */
961 buf
= PyMem_Malloc(PyString_Size(source
) + 2);
963 PyErr_SetString(PyExc_MemoryError
,
964 "zipimport: no memory to allocate "
968 /* replace "\r\n?" by "\n" */
969 for (q
= buf
; *p
!= '\0'; p
++) {
972 if (*(p
+ 1) == '\n')
978 *q
++ = '\n'; /* add trailing \n */
980 fixed_source
= PyString_FromString(buf
);
985 /* Given a string buffer containing Python source code, compile it
986 return and return a code object as a new reference. */
988 compile_source(char *pathname
, PyObject
*source
)
990 PyObject
*code
, *fixed_source
;
992 fixed_source
= normalize_line_endings(source
);
993 if (fixed_source
== NULL
)
996 code
= Py_CompileString(PyString_AsString(fixed_source
), pathname
,
998 Py_DECREF(fixed_source
);
1002 /* Convert the date/time values found in the Zip archive to a value
1003 that's compatible with the time stamp stored in .pyc files. */
1005 parse_dostime(int dostime
, int dosdate
)
1009 stm
.tm_sec
= (dostime
& 0x1f) * 2;
1010 stm
.tm_min
= (dostime
>> 5) & 0x3f;
1011 stm
.tm_hour
= (dostime
>> 11) & 0x1f;
1012 stm
.tm_mday
= dosdate
& 0x1f;
1013 stm
.tm_mon
= ((dosdate
>> 5) & 0x0f) - 1;
1014 stm
.tm_year
= ((dosdate
>> 9) & 0x7f) + 80;
1015 stm
.tm_isdst
= -1; /* wday/yday is ignored */
1017 return mktime(&stm
);
1020 /* Given a path to a .pyc or .pyo file in the archive, return the
1021 modifictaion time of the matching .py file, or 0 if no source
1024 get_mtime_of_source(ZipImporter
*self
, char *path
)
1026 PyObject
*toc_entry
;
1028 Py_ssize_t lastchar
= strlen(path
) - 1;
1029 char savechar
= path
[lastchar
];
1030 path
[lastchar
] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1031 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1032 if (toc_entry
!= NULL
&& PyTuple_Check(toc_entry
) &&
1033 PyTuple_Size(toc_entry
) == 8) {
1034 /* fetch the time stamp of the .py file for comparison
1035 with an embedded pyc time stamp */
1037 time
= PyInt_AsLong(PyTuple_GetItem(toc_entry
, 5));
1038 date
= PyInt_AsLong(PyTuple_GetItem(toc_entry
, 6));
1039 mtime
= parse_dostime(time
, date
);
1041 path
[lastchar
] = savechar
;
1045 /* Return the code object for the module named by 'fullname' from the
1046 Zip archive as a new reference. */
1048 get_code_from_data(ZipImporter
*self
, int ispackage
, int isbytecode
,
1049 time_t mtime
, PyObject
*toc_entry
)
1051 PyObject
*data
, *code
;
1053 char *archive
= PyString_AsString(self
->archive
);
1055 if (archive
== NULL
)
1058 data
= get_data(archive
, toc_entry
);
1062 modpath
= PyString_AsString(PyTuple_GetItem(toc_entry
, 0));
1065 code
= unmarshal_code(modpath
, data
, mtime
);
1068 code
= compile_source(modpath
, data
);
1074 /* Get the code object assoiciated with the module specified by
1077 get_module_code(ZipImporter
*self
, char *fullname
,
1078 int *p_ispackage
, char **p_modpath
)
1080 PyObject
*toc_entry
;
1081 char *subname
, path
[MAXPATHLEN
+ 1];
1083 struct st_zip_searchorder
*zso
;
1085 subname
= get_subname(fullname
);
1087 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
1091 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
1092 PyObject
*code
= NULL
;
1094 strcpy(path
+ len
, zso
->suffix
);
1095 if (Py_VerboseFlag
> 1)
1096 PySys_WriteStderr("# trying %s%c%s\n",
1097 PyString_AsString(self
->archive
),
1099 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1100 if (toc_entry
!= NULL
) {
1102 int ispackage
= zso
->type
& IS_PACKAGE
;
1103 int isbytecode
= zso
->type
& IS_BYTECODE
;
1106 mtime
= get_mtime_of_source(self
, path
);
1107 if (p_ispackage
!= NULL
)
1108 *p_ispackage
= ispackage
;
1109 code
= get_code_from_data(self
, ispackage
,
1112 if (code
== Py_None
) {
1113 /* bad magic number or non-matching mtime
1114 in byte code, try next */
1118 if (code
!= NULL
&& p_modpath
!= NULL
)
1119 *p_modpath
= PyString_AsString(
1120 PyTuple_GetItem(toc_entry
, 0));
1124 PyErr_Format(ZipImportError
, "can't find module '%.200s'", fullname
);
1131 PyDoc_STRVAR(zipimport_doc
,
1132 "zipimport provides support for importing Python modules from Zip archives.\n\
1134 This module exports three objects:\n\
1135 - zipimporter: a class; its constructor takes a path to a Zip archive.\n\
1136 - ZipImportError: exception raised by zipimporter objects. It's a\n\
1137 subclass of ImportError, so it can be caught as ImportError, too.\n\
1138 - _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1139 info dicts, as used in zipimporter._files.\n\
1141 It is usually not needed to use the zipimport module explicitly; it is\n\
1142 used by the builtin import mechanism for sys.path items that are paths\n\
1150 if (PyType_Ready(&ZipImporter_Type
) < 0)
1153 /* Correct directory separator */
1154 zip_searchorder
[0].suffix
[0] = SEP
;
1155 zip_searchorder
[1].suffix
[0] = SEP
;
1156 zip_searchorder
[2].suffix
[0] = SEP
;
1157 if (Py_OptimizeFlag
) {
1158 /* Reverse *.pyc and *.pyo */
1159 struct st_zip_searchorder tmp
;
1160 tmp
= zip_searchorder
[0];
1161 zip_searchorder
[0] = zip_searchorder
[1];
1162 zip_searchorder
[1] = tmp
;
1163 tmp
= zip_searchorder
[3];
1164 zip_searchorder
[3] = zip_searchorder
[4];
1165 zip_searchorder
[4] = tmp
;
1168 mod
= Py_InitModule4("zipimport", NULL
, zipimport_doc
,
1169 NULL
, PYTHON_API_VERSION
);
1173 ZipImportError
= PyErr_NewException("zipimport.ZipImportError",
1174 PyExc_ImportError
, NULL
);
1175 if (ZipImportError
== NULL
)
1178 Py_INCREF(ZipImportError
);
1179 if (PyModule_AddObject(mod
, "ZipImportError",
1180 ZipImportError
) < 0)
1183 Py_INCREF(&ZipImporter_Type
);
1184 if (PyModule_AddObject(mod
, "zipimporter",
1185 (PyObject
*)&ZipImporter_Type
) < 0)
1188 zip_directory_cache
= PyDict_New();
1189 if (zip_directory_cache
== NULL
)
1191 Py_INCREF(zip_directory_cache
);
1192 if (PyModule_AddObject(mod
, "_zip_directory_cache",
1193 zip_directory_cache
) < 0)