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",
75 PyErr_SetString(ZipImportError
, "archive path is empty");
78 if (len
>= MAXPATHLEN
) {
79 PyErr_SetString(ZipImportError
,
80 "archive path too long");
86 for (p
= buf
; *p
; p
++) {
99 rv
= stat(buf
, &statbuf
);
102 if (S_ISREG(statbuf
.st_mode
))
108 if (object_exists(buf
)) {
116 /* back up one path element */
117 p
= strrchr(buf
, SEP
);
127 files
= PyDict_GetItemString(zip_directory_cache
, path
);
129 files
= read_directory(buf
);
132 if (PyDict_SetItemString(zip_directory_cache
, path
,
141 PyErr_SetString(ZipImportError
, "not a Zip file");
149 len
= strlen(prefix
);
150 if (prefix
[len
-1] != SEP
) {
151 /* add trailing SEP */
153 prefix
[len
+ 1] = '\0';
157 self
->archive
= PyString_FromString(buf
);
158 if (self
->archive
== NULL
)
161 self
->prefix
= PyString_FromString(prefix
);
162 if (self
->prefix
== NULL
)
170 zipimporter_traverse(PyObject
*obj
, visitproc visit
, void *arg
)
172 ZipImporter
*self
= (ZipImporter
*)obj
;
173 Py_VISIT(self
->files
);
178 zipimporter_dealloc(ZipImporter
*self
)
180 PyObject_GC_UnTrack(self
);
181 Py_XDECREF(self
->archive
);
182 Py_XDECREF(self
->prefix
);
183 Py_XDECREF(self
->files
);
184 Py_TYPE(self
)->tp_free((PyObject
*)self
);
188 zipimporter_repr(ZipImporter
*self
)
191 char *archive
= "???";
194 if (self
->archive
!= NULL
&& PyString_Check(self
->archive
))
195 archive
= PyString_AsString(self
->archive
);
196 if (self
->prefix
!= NULL
&& PyString_Check(self
->prefix
))
197 prefix
= PyString_AsString(self
->prefix
);
198 if (prefix
!= NULL
&& *prefix
)
199 PyOS_snprintf(buf
, sizeof(buf
),
200 "<zipimporter object \"%.300s%c%.150s\">",
201 archive
, SEP
, prefix
);
203 PyOS_snprintf(buf
, sizeof(buf
),
204 "<zipimporter object \"%.300s\">",
206 return PyString_FromString(buf
);
209 /* return fullname.split(".")[-1] */
211 get_subname(char *fullname
)
213 char *subname
= strrchr(fullname
, '.');
221 /* Given a (sub)modulename, write the potential file path in the
222 archive (without extension) to the path buffer. Return the
223 length of the resulting string. */
225 make_filename(char *prefix
, char *name
, char *path
)
230 len
= strlen(prefix
);
232 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
233 if (len
+ strlen(name
) + 13 >= MAXPATHLEN
) {
234 PyErr_SetString(ZipImportError
, "path too long");
238 strcpy(path
, prefix
);
239 strcpy(path
+ len
, name
);
240 for (p
= path
+ len
; *p
; p
++) {
245 assert(len
< INT_MAX
);
249 enum zi_module_info
{
256 /* Return some information about a module. */
257 static enum zi_module_info
258 get_module_info(ZipImporter
*self
, char *fullname
)
260 char *subname
, path
[MAXPATHLEN
+ 1];
262 struct st_zip_searchorder
*zso
;
264 subname
= get_subname(fullname
);
266 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
270 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
271 strcpy(path
+ len
, zso
->suffix
);
272 if (PyDict_GetItemString(self
->files
, path
) != NULL
) {
273 if (zso
->type
& IS_PACKAGE
)
282 /* Check whether we can satisfy the import of the module named by
283 'fullname'. Return self if we can, None if we can't. */
285 zipimporter_find_module(PyObject
*obj
, PyObject
*args
)
287 ZipImporter
*self
= (ZipImporter
*)obj
;
288 PyObject
*path
= NULL
;
290 enum zi_module_info mi
;
292 if (!PyArg_ParseTuple(args
, "s|O:zipimporter.find_module",
296 mi
= get_module_info(self
, fullname
);
299 if (mi
== MI_NOT_FOUND
) {
304 return (PyObject
*)self
;
307 /* Load and return the module named by 'fullname'. */
309 zipimporter_load_module(PyObject
*obj
, PyObject
*args
)
311 ZipImporter
*self
= (ZipImporter
*)obj
;
312 PyObject
*code
, *mod
, *dict
;
313 char *fullname
, *modpath
;
316 if (!PyArg_ParseTuple(args
, "s:zipimporter.load_module",
320 code
= get_module_code(self
, fullname
, &ispackage
, &modpath
);
324 mod
= PyImport_AddModule(fullname
);
329 dict
= PyModule_GetDict(mod
);
331 /* mod.__loader__ = self */
332 if (PyDict_SetItemString(dict
, "__loader__", (PyObject
*)self
) != 0)
336 /* add __path__ to the module *before* the code gets
338 PyObject
*pkgpath
, *fullpath
;
339 char *prefix
= PyString_AsString(self
->prefix
);
340 char *subname
= get_subname(fullname
);
343 fullpath
= PyString_FromFormat("%s%c%s%s",
344 PyString_AsString(self
->archive
),
346 *prefix
? prefix
: "",
348 if (fullpath
== NULL
)
351 pkgpath
= Py_BuildValue("[O]", fullpath
);
355 err
= PyDict_SetItemString(dict
, "__path__", pkgpath
);
360 mod
= PyImport_ExecCodeModuleEx(fullname
, code
, modpath
);
363 PySys_WriteStderr("import %s # loaded from Zip %s\n",
372 /* Return a bool signifying whether the module is a package or not. */
374 zipimporter_is_package(PyObject
*obj
, PyObject
*args
)
376 ZipImporter
*self
= (ZipImporter
*)obj
;
378 enum zi_module_info mi
;
380 if (!PyArg_ParseTuple(args
, "s:zipimporter.is_package",
384 mi
= get_module_info(self
, fullname
);
387 if (mi
== MI_NOT_FOUND
) {
388 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
392 return PyBool_FromLong(mi
== MI_PACKAGE
);
396 zipimporter_get_data(PyObject
*obj
, PyObject
*args
)
398 ZipImporter
*self
= (ZipImporter
*)obj
;
401 char *p
, buf
[MAXPATHLEN
+ 1];
406 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_data", &path
))
410 if (strlen(path
) >= MAXPATHLEN
) {
411 PyErr_SetString(ZipImportError
, "path too long");
415 for (p
= buf
; *p
; p
++) {
421 len
= PyString_Size(self
->archive
);
422 if ((size_t)len
< strlen(path
) &&
423 strncmp(path
, PyString_AsString(self
->archive
), len
) == 0 &&
425 path
= path
+ len
+ 1;
428 toc_entry
= PyDict_GetItemString(self
->files
, path
);
429 if (toc_entry
== NULL
) {
430 PyErr_SetFromErrnoWithFilename(PyExc_IOError
, path
);
433 return get_data(PyString_AsString(self
->archive
), toc_entry
);
437 zipimporter_get_code(PyObject
*obj
, PyObject
*args
)
439 ZipImporter
*self
= (ZipImporter
*)obj
;
442 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_code", &fullname
))
445 return get_module_code(self
, fullname
, NULL
, NULL
);
449 zipimporter_get_source(PyObject
*obj
, PyObject
*args
)
451 ZipImporter
*self
= (ZipImporter
*)obj
;
453 char *fullname
, *subname
, path
[MAXPATHLEN
+1];
455 enum zi_module_info mi
;
457 if (!PyArg_ParseTuple(args
, "s:zipimporter.get_source", &fullname
))
460 mi
= get_module_info(self
, fullname
);
463 if (mi
== MI_NOT_FOUND
) {
464 PyErr_Format(ZipImportError
, "can't find module '%.200s'",
468 subname
= get_subname(fullname
);
470 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
474 if (mi
== MI_PACKAGE
) {
476 strcpy(path
+ len
+ 1, "__init__.py");
479 strcpy(path
+ len
, ".py");
481 toc_entry
= PyDict_GetItemString(self
->files
, path
);
482 if (toc_entry
!= NULL
)
483 return get_data(PyString_AsString(self
->archive
), toc_entry
);
485 /* we have the module, but no source */
490 PyDoc_STRVAR(doc_find_module
,
491 "find_module(fullname, path=None) -> self or None.\n\
493 Search for a module specified by 'fullname'. 'fullname' must be the\n\
494 fully qualified (dotted) module name. It returns the zipimporter\n\
495 instance itself if the module was found, or None if it wasn't.\n\
496 The optional 'path' argument is ignored -- it's there for compatibility\n\
497 with the importer protocol.");
499 PyDoc_STRVAR(doc_load_module
,
500 "load_module(fullname) -> module.\n\
502 Load the module specified by 'fullname'. 'fullname' must be the\n\
503 fully qualified (dotted) module name. It returns the imported\n\
504 module, or raises ZipImportError if it wasn't found.");
506 PyDoc_STRVAR(doc_get_data
,
507 "get_data(pathname) -> string with file data.\n\
509 Return the data associated with 'pathname'. Raise IOError if\n\
510 the file wasn't found.");
512 PyDoc_STRVAR(doc_is_package
,
513 "is_package(fullname) -> bool.\n\
515 Return True if the module specified by fullname is a package.\n\
516 Raise ZipImportError is the module couldn't be found.");
518 PyDoc_STRVAR(doc_get_code
,
519 "get_code(fullname) -> code object.\n\
521 Return the code object for the specified module. Raise ZipImportError\n\
522 is the module couldn't be found.");
524 PyDoc_STRVAR(doc_get_source
,
525 "get_source(fullname) -> source string.\n\
527 Return the source code for the specified module. Raise ZipImportError\n\
528 is the module couldn't be found, return None if the archive does\n\
529 contain the module, but has no source for it.");
531 static PyMethodDef zipimporter_methods
[] = {
532 {"find_module", zipimporter_find_module
, METH_VARARGS
,
534 {"load_module", zipimporter_load_module
, METH_VARARGS
,
536 {"get_data", zipimporter_get_data
, METH_VARARGS
,
538 {"get_code", zipimporter_get_code
, METH_VARARGS
,
540 {"get_source", zipimporter_get_source
, METH_VARARGS
,
542 {"is_package", zipimporter_is_package
, METH_VARARGS
,
544 {NULL
, NULL
} /* sentinel */
547 static PyMemberDef zipimporter_members
[] = {
548 {"archive", T_OBJECT
, offsetof(ZipImporter
, archive
), READONLY
},
549 {"prefix", T_OBJECT
, offsetof(ZipImporter
, prefix
), READONLY
},
550 {"_files", T_OBJECT
, offsetof(ZipImporter
, files
), READONLY
},
554 PyDoc_STRVAR(zipimporter_doc
,
555 "zipimporter(archivepath) -> zipimporter object\n\
557 Create a new zipimporter instance. 'archivepath' must be a path to\n\
558 a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
559 '/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
560 valid directory inside the archive.\n\
562 'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
565 The 'archive' attribute of zipimporter objects contains the name of the\n\
568 #define DEFERRED_ADDRESS(ADDR) 0
570 static PyTypeObject ZipImporter_Type
= {
571 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
), 0)
572 "zipimport.zipimporter",
575 (destructor
)zipimporter_dealloc
, /* tp_dealloc */
580 (reprfunc
)zipimporter_repr
, /* tp_repr */
581 0, /* tp_as_number */
582 0, /* tp_as_sequence */
583 0, /* tp_as_mapping */
587 PyObject_GenericGetAttr
, /* tp_getattro */
589 0, /* tp_as_buffer */
590 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
|
591 Py_TPFLAGS_HAVE_GC
, /* tp_flags */
592 zipimporter_doc
, /* tp_doc */
593 zipimporter_traverse
, /* tp_traverse */
595 0, /* tp_richcompare */
596 0, /* tp_weaklistoffset */
599 zipimporter_methods
, /* tp_methods */
600 zipimporter_members
, /* tp_members */
604 0, /* tp_descr_get */
605 0, /* tp_descr_set */
606 0, /* tp_dictoffset */
607 (initproc
)zipimporter_init
, /* tp_init */
608 PyType_GenericAlloc
, /* tp_alloc */
609 PyType_GenericNew
, /* tp_new */
610 PyObject_GC_Del
, /* tp_free */
616 /* Given a buffer, return the long that is represented by the first
617 4 bytes, encoded as little endian. This partially reimplements
618 marshal.c:r_long() */
620 get_long(unsigned char *buf
) {
623 x
|= (long)buf
[1] << 8;
624 x
|= (long)buf
[2] << 16;
625 x
|= (long)buf
[3] << 24;
627 /* Sign extension for 64-bit machines */
628 x
|= -(x
& 0x80000000L
);
634 read_directory(archive) -> files dict (new reference)
636 Given a path to a Zip archive, build a dict, mapping file names
637 (local to the archive, using SEP as a separator) to toc entries.
639 A toc_entry is a tuple:
641 (__file__, # value to use for __file__, available for all files
642 compress, # compression kind; 0 for uncompressed
643 data_size, # size of compressed data on disk
644 file_size, # size of decompressed data
645 file_offset, # offset of file header from start of archive
646 time, # mod time of file (in dos format)
647 date, # mod data of file (in dos format)
648 crc, # crc checksum of the data
651 Directories can be recognized by the trailing SEP in the name,
652 data_size and file_offset are 0.
655 read_directory(char *archive
)
657 PyObject
*files
= NULL
;
659 long compress
, crc
, data_size
, file_size
, file_offset
, date
, time
;
660 long header_offset
, name_size
, header_size
, header_position
;
663 char path
[MAXPATHLEN
+ 5];
664 char name
[MAXPATHLEN
+ 5];
665 char *p
, endof_central_dir
[22];
666 long arc_offset
; /* offset from beginning of file to start of zip-archive */
668 if (strlen(archive
) > MAXPATHLEN
) {
669 PyErr_SetString(PyExc_OverflowError
,
670 "Zip path name is too long");
673 strcpy(path
, archive
);
675 fp
= fopen(archive
, "rb");
677 PyErr_Format(ZipImportError
, "can't open Zip file: "
678 "'%.200s'", archive
);
681 fseek(fp
, -22, SEEK_END
);
682 header_position
= ftell(fp
);
683 if (fread(endof_central_dir
, 1, 22, fp
) != 22) {
685 PyErr_Format(ZipImportError
, "can't read Zip file: "
686 "'%.200s'", archive
);
689 if (get_long((unsigned char *)endof_central_dir
) != 0x06054B50) {
690 /* Bad: End of Central Dir signature */
692 PyErr_Format(ZipImportError
, "not a Zip file: "
693 "'%.200s'", archive
);
697 header_size
= get_long((unsigned char *)endof_central_dir
+ 12);
698 header_offset
= get_long((unsigned char *)endof_central_dir
+ 16);
699 arc_offset
= header_position
- header_offset
- header_size
;
700 header_offset
+= arc_offset
;
702 files
= PyDict_New();
706 length
= (long)strlen(path
);
709 /* Start of Central Directory */
715 fseek(fp
, header_offset
, 0); /* Start of file header */
716 l
= PyMarshal_ReadLongFromFile(fp
);
718 break; /* Bad: Central Dir File Header */
719 fseek(fp
, header_offset
+ 10, 0);
720 compress
= PyMarshal_ReadShortFromFile(fp
);
721 time
= PyMarshal_ReadShortFromFile(fp
);
722 date
= PyMarshal_ReadShortFromFile(fp
);
723 crc
= PyMarshal_ReadLongFromFile(fp
);
724 data_size
= PyMarshal_ReadLongFromFile(fp
);
725 file_size
= PyMarshal_ReadLongFromFile(fp
);
726 name_size
= PyMarshal_ReadShortFromFile(fp
);
727 header_size
= 46 + name_size
+
728 PyMarshal_ReadShortFromFile(fp
) +
729 PyMarshal_ReadShortFromFile(fp
);
730 fseek(fp
, header_offset
+ 42, 0);
731 file_offset
= PyMarshal_ReadLongFromFile(fp
) + arc_offset
;
732 if (name_size
> MAXPATHLEN
)
733 name_size
= MAXPATHLEN
;
736 for (i
= 0; i
< name_size
; i
++) {
742 *p
= 0; /* Add terminating null byte */
743 header_offset
+= header_size
;
745 strncpy(path
+ length
+ 1, name
, MAXPATHLEN
- length
- 1);
747 t
= Py_BuildValue("siiiiiii", path
, compress
, data_size
,
748 file_size
, file_offset
, time
, date
, crc
);
751 err
= PyDict_SetItemString(files
, name
, t
);
759 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
768 /* Return the zlib.decompress function object, or NULL if zlib couldn't
769 be imported. The function is cached when found, so subsequent calls
770 don't import zlib again. Returns a *borrowed* reference.
771 XXX This makes zlib.decompress immortal. */
773 get_decompress_func(void)
775 static PyObject
*decompress
= NULL
;
777 if (decompress
== NULL
) {
779 static int importing_zlib
= 0;
781 if (importing_zlib
!= 0)
782 /* Someone has a zlib.py[co] in their Zip file;
783 let's avoid a stack overflow. */
786 zlib
= PyImport_ImportModuleNoBlock("zlib");
789 decompress
= PyObject_GetAttrString(zlib
,
796 PySys_WriteStderr("# zipimport: zlib %s\n",
797 zlib
!= NULL
? "available": "UNAVAILABLE");
802 /* Given a path to a Zip file and a toc_entry, return the (uncompressed)
803 data as a new reference. */
805 get_data(char *archive
, PyObject
*toc_entry
)
807 PyObject
*raw_data
, *data
= NULL
, *decompress
;
811 Py_ssize_t bytes_read
= 0;
814 long compress
, data_size
, file_size
, file_offset
;
815 long time
, date
, crc
;
817 if (!PyArg_ParseTuple(toc_entry
, "slllllll", &datapath
, &compress
,
818 &data_size
, &file_size
, &file_offset
, &time
,
823 fp
= fopen(archive
, "rb");
825 PyErr_Format(PyExc_IOError
,
826 "zipimport: can not open file %s", archive
);
830 /* Check to make sure the local file header is correct */
831 fseek(fp
, file_offset
, 0);
832 l
= PyMarshal_ReadLongFromFile(fp
);
833 if (l
!= 0x04034B50) {
834 /* Bad: Local File Header */
835 PyErr_Format(ZipImportError
,
836 "bad local file header in %s",
841 fseek(fp
, file_offset
+ 26, 0);
842 l
= 30 + PyMarshal_ReadShortFromFile(fp
) +
843 PyMarshal_ReadShortFromFile(fp
); /* local header size */
844 file_offset
+= l
; /* Start of file data */
846 raw_data
= PyString_FromStringAndSize((char *)NULL
, compress
== 0 ?
847 data_size
: data_size
+ 1);
848 if (raw_data
== NULL
) {
852 buf
= PyString_AsString(raw_data
);
854 err
= fseek(fp
, file_offset
, 0);
856 bytes_read
= fread(buf
, 1, data_size
, fp
);
858 if (err
|| bytes_read
!= data_size
) {
859 PyErr_SetString(PyExc_IOError
,
860 "zipimport: can't read data");
866 buf
[data_size
] = 'Z'; /* saw this in zipfile.py */
869 buf
[data_size
] = '\0';
871 if (compress
== 0) /* data is not compressed */
874 /* Decompress with zlib */
875 decompress
= get_decompress_func();
876 if (decompress
== NULL
) {
877 PyErr_SetString(ZipImportError
,
878 "can't decompress data; "
879 "zlib not available");
882 data
= PyObject_CallFunction(decompress
, "Oi", raw_data
, -15);
888 /* Lenient date/time comparison function. The precision of the mtime
889 in the archive is lower than the mtime stored in a .pyc: we
890 must allow a difference of at most one second. */
892 eq_mtime(time_t t1
, time_t t2
)
897 /* dostime only stores even seconds, so be lenient */
901 /* Given the contents of a .py[co] file in a buffer, unmarshal the data
902 and return the code object. Return None if it the magic word doesn't
903 match (we do this instead of raising an exception as we fall back
904 to .py if available and we don't want to mask other errors).
905 Returns a new reference. */
907 unmarshal_code(char *pathname
, PyObject
*data
, time_t mtime
)
910 char *buf
= PyString_AsString(data
);
911 Py_ssize_t size
= PyString_Size(data
);
914 PyErr_SetString(ZipImportError
,
919 if (get_long((unsigned char *)buf
) != PyImport_GetMagicNumber()) {
921 PySys_WriteStderr("# %s has bad magic\n",
924 return Py_None
; /* signal caller to try alternative */
927 if (mtime
!= 0 && !eq_mtime(get_long((unsigned char *)buf
+ 4),
930 PySys_WriteStderr("# %s has bad mtime\n",
933 return Py_None
; /* signal caller to try alternative */
936 code
= PyMarshal_ReadObjectFromString(buf
+ 8, size
- 8);
939 if (!PyCode_Check(code
)) {
941 PyErr_Format(PyExc_TypeError
,
942 "compiled module %.200s is not a code object",
949 /* Replace any occurances of "\r\n?" in the input string with "\n".
950 This converts DOS and Mac line endings to Unix line endings.
951 Also append a trailing "\n" to be compatible with
952 PyParser_SimpleParseFile(). Returns a new reference. */
954 normalize_line_endings(PyObject
*source
)
956 char *buf
, *q
, *p
= PyString_AsString(source
);
957 PyObject
*fixed_source
;
962 /* one char extra for trailing \n and one for terminating \0 */
963 buf
= (char *)PyMem_Malloc(PyString_Size(source
) + 2);
965 PyErr_SetString(PyExc_MemoryError
,
966 "zipimport: no memory to allocate "
970 /* replace "\r\n?" by "\n" */
971 for (q
= buf
; *p
!= '\0'; p
++) {
974 if (*(p
+ 1) == '\n')
980 *q
++ = '\n'; /* add trailing \n */
982 fixed_source
= PyString_FromString(buf
);
987 /* Given a string buffer containing Python source code, compile it
988 return and return a code object as a new reference. */
990 compile_source(char *pathname
, PyObject
*source
)
992 PyObject
*code
, *fixed_source
;
994 fixed_source
= normalize_line_endings(source
);
995 if (fixed_source
== NULL
)
998 code
= Py_CompileString(PyString_AsString(fixed_source
), pathname
,
1000 Py_DECREF(fixed_source
);
1004 /* Convert the date/time values found in the Zip archive to a value
1005 that's compatible with the time stamp stored in .pyc files. */
1007 parse_dostime(int dostime
, int dosdate
)
1011 memset((void *) &stm
, '\0', sizeof(stm
));
1013 stm
.tm_sec
= (dostime
& 0x1f) * 2;
1014 stm
.tm_min
= (dostime
>> 5) & 0x3f;
1015 stm
.tm_hour
= (dostime
>> 11) & 0x1f;
1016 stm
.tm_mday
= dosdate
& 0x1f;
1017 stm
.tm_mon
= ((dosdate
>> 5) & 0x0f) - 1;
1018 stm
.tm_year
= ((dosdate
>> 9) & 0x7f) + 80;
1019 stm
.tm_isdst
= -1; /* wday/yday is ignored */
1021 return mktime(&stm
);
1024 /* Given a path to a .pyc or .pyo file in the archive, return the
1025 modifictaion time of the matching .py file, or 0 if no source
1028 get_mtime_of_source(ZipImporter
*self
, char *path
)
1030 PyObject
*toc_entry
;
1032 Py_ssize_t lastchar
= strlen(path
) - 1;
1033 char savechar
= path
[lastchar
];
1034 path
[lastchar
] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1035 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1036 if (toc_entry
!= NULL
&& PyTuple_Check(toc_entry
) &&
1037 PyTuple_Size(toc_entry
) == 8) {
1038 /* fetch the time stamp of the .py file for comparison
1039 with an embedded pyc time stamp */
1041 time
= PyInt_AsLong(PyTuple_GetItem(toc_entry
, 5));
1042 date
= PyInt_AsLong(PyTuple_GetItem(toc_entry
, 6));
1043 mtime
= parse_dostime(time
, date
);
1045 path
[lastchar
] = savechar
;
1049 /* Return the code object for the module named by 'fullname' from the
1050 Zip archive as a new reference. */
1052 get_code_from_data(ZipImporter
*self
, int ispackage
, int isbytecode
,
1053 time_t mtime
, PyObject
*toc_entry
)
1055 PyObject
*data
, *code
;
1057 char *archive
= PyString_AsString(self
->archive
);
1059 if (archive
== NULL
)
1062 data
= get_data(archive
, toc_entry
);
1066 modpath
= PyString_AsString(PyTuple_GetItem(toc_entry
, 0));
1069 code
= unmarshal_code(modpath
, data
, mtime
);
1072 code
= compile_source(modpath
, data
);
1078 /* Get the code object assoiciated with the module specified by
1081 get_module_code(ZipImporter
*self
, char *fullname
,
1082 int *p_ispackage
, char **p_modpath
)
1084 PyObject
*toc_entry
;
1085 char *subname
, path
[MAXPATHLEN
+ 1];
1087 struct st_zip_searchorder
*zso
;
1089 subname
= get_subname(fullname
);
1091 len
= make_filename(PyString_AsString(self
->prefix
), subname
, path
);
1095 for (zso
= zip_searchorder
; *zso
->suffix
; zso
++) {
1096 PyObject
*code
= NULL
;
1098 strcpy(path
+ len
, zso
->suffix
);
1099 if (Py_VerboseFlag
> 1)
1100 PySys_WriteStderr("# trying %s%c%s\n",
1101 PyString_AsString(self
->archive
),
1103 toc_entry
= PyDict_GetItemString(self
->files
, path
);
1104 if (toc_entry
!= NULL
) {
1106 int ispackage
= zso
->type
& IS_PACKAGE
;
1107 int isbytecode
= zso
->type
& IS_BYTECODE
;
1110 mtime
= get_mtime_of_source(self
, path
);
1111 if (p_ispackage
!= NULL
)
1112 *p_ispackage
= ispackage
;
1113 code
= get_code_from_data(self
, ispackage
,
1116 if (code
== Py_None
) {
1117 /* bad magic number or non-matching mtime
1118 in byte code, try next */
1122 if (code
!= NULL
&& p_modpath
!= NULL
)
1123 *p_modpath
= PyString_AsString(
1124 PyTuple_GetItem(toc_entry
, 0));
1128 PyErr_Format(ZipImportError
, "can't find module '%.200s'", fullname
);
1135 PyDoc_STRVAR(zipimport_doc
,
1136 "zipimport provides support for importing Python modules from Zip archives.\n\
1138 This module exports three objects:\n\
1139 - zipimporter: a class; its constructor takes a path to a Zip archive.\n\
1140 - ZipImportError: exception raised by zipimporter objects. It's a\n\
1141 subclass of ImportError, so it can be caught as ImportError, too.\n\
1142 - _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1143 info dicts, as used in zipimporter._files.\n\
1145 It is usually not needed to use the zipimport module explicitly; it is\n\
1146 used by the builtin import mechanism for sys.path items that are paths\n\
1154 if (PyType_Ready(&ZipImporter_Type
) < 0)
1157 /* Correct directory separator */
1158 zip_searchorder
[0].suffix
[0] = SEP
;
1159 zip_searchorder
[1].suffix
[0] = SEP
;
1160 zip_searchorder
[2].suffix
[0] = SEP
;
1161 if (Py_OptimizeFlag
) {
1162 /* Reverse *.pyc and *.pyo */
1163 struct st_zip_searchorder tmp
;
1164 tmp
= zip_searchorder
[0];
1165 zip_searchorder
[0] = zip_searchorder
[1];
1166 zip_searchorder
[1] = tmp
;
1167 tmp
= zip_searchorder
[3];
1168 zip_searchorder
[3] = zip_searchorder
[4];
1169 zip_searchorder
[4] = tmp
;
1172 mod
= Py_InitModule4("zipimport", NULL
, zipimport_doc
,
1173 NULL
, PYTHON_API_VERSION
);
1177 ZipImportError
= PyErr_NewException("zipimport.ZipImportError",
1178 PyExc_ImportError
, NULL
);
1179 if (ZipImportError
== NULL
)
1182 Py_INCREF(ZipImportError
);
1183 if (PyModule_AddObject(mod
, "ZipImportError",
1184 ZipImportError
) < 0)
1187 Py_INCREF(&ZipImporter_Type
);
1188 if (PyModule_AddObject(mod
, "zipimporter",
1189 (PyObject
*)&ZipImporter_Type
) < 0)
1192 zip_directory_cache
= PyDict_New();
1193 if (zip_directory_cache
== NULL
)
1195 Py_INCREF(zip_directory_cache
);
1196 if (PyModule_AddObject(mod
, "_zip_directory_cache",
1197 zip_directory_cache
) < 0)