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)