Back to index

python3.2  3.2.2
Classes | Defines | Typedefs | Enumerations | Functions | Variables
zipimport.c File Reference
#include "Python.h"
#include "structmember.h"
#include "osdefs.h"
#include "marshal.h"
#include <time.h>

Go to the source code of this file.

Classes

struct  st_zip_searchorder
struct  _zipimporter

Defines

#define IS_SOURCE   0x0
#define IS_BYTECODE   0x1
#define IS_PACKAGE   0x2
#define ZipImporter_Check(op)   PyObject_TypeCheck(op, &ZipImporter_Type)
#define DEFERRED_ADDRESS(ADDR)   0

Typedefs

typedef struct _zipimporter

Enumerations

enum  zi_module_info { MI_ERROR, MI_NOT_FOUND, MI_MODULE, MI_PACKAGE }

Functions

static PyObjectread_directory (PyObject *archive)
static PyObjectget_data (PyObject *archive, PyObject *toc_entry)
static PyObjectget_module_code (ZipImporter *self, char *fullname, int *p_ispackage, PyObject **p_modpath)
static int zipimporter_init (ZipImporter *self, PyObject *args, PyObject *kwds)
static int zipimporter_traverse (PyObject *obj, visitproc visit, void *arg)
static void zipimporter_dealloc (ZipImporter *self)
static PyObjectzipimporter_repr (ZipImporter *self)
static char * get_subname (char *fullname)
static int make_filename (PyObject *prefix_obj, char *name, char *path, size_t pathsize)
static enum zi_module_info get_module_info (ZipImporter *self, char *fullname)
static PyObjectzipimporter_find_module (PyObject *obj, PyObject *args)
static PyObjectzipimporter_load_module (PyObject *obj, PyObject *args)
static PyObjectzipimporter_get_filename (PyObject *obj, PyObject *args)
static PyObjectzipimporter_is_package (PyObject *obj, PyObject *args)
static PyObjectzipimporter_get_data (PyObject *obj, PyObject *args)
static PyObjectzipimporter_get_code (PyObject *obj, PyObject *args)
static PyObjectzipimporter_get_source (PyObject *obj, PyObject *args)
 PyDoc_STRVAR (doc_find_module,"find_module(fullname, path=None) -> self or None.\n\ \n\ Search for a module specified by 'fullname'. 'fullname' must be the\n\ fully qualified (dotted) module name. It returns the zipimporter\n\ instance itself if the module was found, or None if it wasn't.\n\ The optional 'path' argument is ignored -- it's there for compatibility\n\ with the importer protocol.")
 PyDoc_STRVAR (doc_load_module,"load_module(fullname) -> module.\n\ \n\ Load the module specified by 'fullname'. 'fullname' must be the\n\ fully qualified (dotted) module name. It returns the imported\n\ module, or raises ZipImportError if it wasn't found.")
 PyDoc_STRVAR (doc_get_data,"get_data(pathname) -> string with file data.\n\ \n\ Return the data associated with 'pathname'. Raise IOError if\n\ the file wasn't found.")
 PyDoc_STRVAR (doc_is_package,"is_package(fullname) -> bool.\n\ \n\ Return True if the module specified by fullname is a package.\n\ Raise ZipImportError if the module couldn't be found.")
 PyDoc_STRVAR (doc_get_code,"get_code(fullname) -> code object.\n\ \n\ Return the code object for the specified module. Raise ZipImportError\n\ if the module couldn't be found.")
 PyDoc_STRVAR (doc_get_source,"get_source(fullname) -> source string.\n\ \n\ Return the source code for the specified module. Raise ZipImportError\n\ if the module couldn't be found, return None if the archive does\n\ contain the module, but has no source for it.")
 PyDoc_STRVAR (doc_get_filename,"get_filename(fullname) -> filename string.\n\ \n\ Return the filename for the specified module.")
 PyDoc_STRVAR (zipimporter_doc,"zipimporter(archivepath) -> zipimporter object\n\ \n\ Create a new zipimporter instance. 'archivepath' must be a path to\n\ a zipfile, or to a specific path inside a zipfile. For example, it can be\n\ '/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\ valid directory inside the archive.\n\ \n\ 'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\ archive.\n\ \n\ The 'archive' attribute of zipimporter objects contains the name of the\n\ zipfile targeted.")
static long get_long (unsigned char *buf)
static PyObjectget_decompress_func (void)
static int eq_mtime (time_t t1, time_t t2)
static PyObjectunmarshal_code (char *pathname, PyObject *data, time_t mtime)
static PyObjectnormalize_line_endings (PyObject *source)
static PyObjectcompile_source (char *pathname, PyObject *source)
static time_t parse_dostime (int dostime, int dosdate)
static time_t get_mtime_of_source (ZipImporter *self, char *path)
static PyObjectget_code_from_data (ZipImporter *self, int ispackage, int isbytecode, time_t mtime, PyObject *toc_entry)
 PyDoc_STRVAR (zipimport_doc,"zipimport provides support for importing Python modules from Zip archives.\n\ \n\ This module exports three objects:\n\ - zipimporter: a class; its constructor takes a path to a Zip archive.\n\ - ZipImportError: exception raised by zipimporter objects. It's a\n\ subclass of ImportError, so it can be caught as ImportError, too.\n\ - _zip_directory_cache: a dict, mapping archive paths to zip directory\n\ info dicts, as used in zipimporter._files.\n\ \n\ It is usually not needed to use the zipimport module explicitly; it is\n\ used by the builtin import mechanism for sys.path items that are paths\n\ to Zip archives.")
PyMODINIT_FUNC PyInit_zipimport (void)

Variables

static struct st_zip_searchorder []
static PyObjectZipImportError
static PyObjectzip_directory_cache = NULL
static PyMethodDef zipimporter_methods []
static PyMemberDef zipimporter_members []
static PyTypeObject ZipImporter_Type
static struct PyModuleDef

Class Documentation

struct st_zip_searchorder

Definition at line 12 of file zipimport.c.

Class Members
char suffix
int type
struct _zipimporter

Definition at line 36 of file zipimport.c.

Collaboration diagram for _zipimporter:
Class Members
PyObject_HEAD PyObject * archive
PyObject * files
PyObject * prefix

Define Documentation

#define DEFERRED_ADDRESS (   ADDR)    0

Definition at line 623 of file zipimport.c.

#define IS_BYTECODE   0x1

Definition at line 9 of file zipimport.c.

#define IS_PACKAGE   0x2

Definition at line 10 of file zipimport.c.

#define IS_SOURCE   0x0

Definition at line 8 of file zipimport.c.

Definition at line 56 of file zipimport.c.


Typedef Documentation

typedef struct _zipimporter

Definition at line 34 of file zipimport.c.


Enumeration Type Documentation

Enumerator:
MI_ERROR 
MI_NOT_FOUND 
MI_MODULE 
MI_PACKAGE 

Definition at line 250 of file zipimport.c.


Function Documentation

static PyObject* compile_source ( char *  pathname,
PyObject source 
) [static]

Definition at line 1087 of file zipimport.c.

{
    PyObject *code, *fixed_source;

    fixed_source = normalize_line_endings(source);
    if (fixed_source == NULL)
        return NULL;

    code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
                            Py_file_input);
    Py_DECREF(fixed_source);
    return code;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int eq_mtime ( time_t  t1,
time_t  t2 
) [static]

Definition at line 986 of file zipimport.c.

{
    time_t d = t1 - t2;
    if (d < 0)
        d = -d;
    /* dostime only stores even seconds, so be lenient */
    return d <= 1;
}

Here is the caller graph for this function:

static PyObject* get_code_from_data ( ZipImporter *  self,
int  ispackage,
int  isbytecode,
time_t  mtime,
PyObject toc_entry 
) [static]

Definition at line 1149 of file zipimport.c.

{
    PyObject *data, *code;
    PyObject *modpath;

    data = get_data(self->archive, toc_entry);
    if (data == NULL)
        return NULL;

    modpath = PyUnicode_EncodeFSDefault(PyTuple_GetItem(toc_entry, 0));
    if (modpath == NULL) {
        Py_DECREF(data);
        return NULL;
    }

    if (isbytecode)
        code = unmarshal_code(PyBytes_AS_STRING(modpath), data, mtime);
    else
        code = compile_source(PyBytes_AS_STRING(modpath), data);
    Py_DECREF(modpath);
    Py_DECREF(data);
    return code;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject * get_data ( PyObject archive,
PyObject toc_entry 
) [static]

Definition at line 892 of file zipimport.c.

{
    PyObject *raw_data, *data = NULL, *decompress;
    char *buf;
    FILE *fp;
    int err;
    Py_ssize_t bytes_read = 0;
    long l;
    PyObject *datapath;
    long compress, data_size, file_size, file_offset, bytes_size;
    long time, date, crc;

    if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
                          &data_size, &file_size, &file_offset, &time,
                          &date, &crc)) {
        return NULL;
    }

    fp = _Py_fopen(archive, "rb");
    if (!fp) {
        PyErr_Format(PyExc_IOError,
           "zipimport: can not open file %U", archive);
        return NULL;
    }

    /* Check to make sure the local file header is correct */
    fseek(fp, file_offset, 0);
    l = PyMarshal_ReadLongFromFile(fp);
    if (l != 0x04034B50) {
        /* Bad: Local File Header */
        PyErr_Format(ZipImportError,
                     "bad local file header in %U",
                     archive);
        fclose(fp);
        return NULL;
    }
    fseek(fp, file_offset + 26, 0);
    l = 30 + PyMarshal_ReadShortFromFile(fp) +
        PyMarshal_ReadShortFromFile(fp);        /* local header size */
    file_offset += l;           /* Start of file data */

    bytes_size = compress == 0 ? data_size : data_size + 1;
    if (bytes_size == 0)
        bytes_size++;
    raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);

    if (raw_data == NULL) {
        fclose(fp);
        return NULL;
    }
    buf = PyBytes_AsString(raw_data);

    err = fseek(fp, file_offset, 0);
    if (err == 0)
        bytes_read = fread(buf, 1, data_size, fp);
    fclose(fp);
    if (err || bytes_read != data_size) {
        PyErr_SetString(PyExc_IOError,
                        "zipimport: can't read data");
        Py_DECREF(raw_data);
        return NULL;
    }

    if (compress != 0) {
        buf[data_size] = 'Z';  /* saw this in zipfile.py */
        data_size++;
    }
    buf[data_size] = '\0';

    if (compress == 0) {  /* data is not compressed */
        data = PyBytes_FromStringAndSize(buf, data_size);
        Py_DECREF(raw_data);
        return data;
    }

    /* Decompress with zlib */
    decompress = get_decompress_func();
    if (decompress == NULL) {
        PyErr_SetString(ZipImportError,
                        "can't decompress data; "
                        "zlib not available");
        goto error;
    }
    data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
    Py_DECREF(decompress);
error:
    Py_DECREF(raw_data);
    return data;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* get_decompress_func ( void  ) [static]

Definition at line 861 of file zipimport.c.

{
    static int importing_zlib = 0;
    PyObject *zlib;
    PyObject *decompress;

    if (importing_zlib != 0)
        /* Someone has a zlib.py[co] in their Zip file;
           let's avoid a stack overflow. */
        return NULL;
    importing_zlib = 1;
    zlib = PyImport_ImportModuleNoBlock("zlib");
    importing_zlib = 0;
    if (zlib != NULL) {
        decompress = PyObject_GetAttrString(zlib,
                                            "decompress");
        Py_DECREF(zlib);
    }
    else {
        PyErr_Clear();
        decompress = NULL;
    }
    if (Py_VerboseFlag)
        PySys_WriteStderr("# zipimport: zlib %s\n",
            zlib != NULL ? "available": "UNAVAILABLE");
    return decompress;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long get_long ( unsigned char *  buf) [static]

Definition at line 675 of file zipimport.c.

                             {
    long x;
    x =  buf[0];
    x |= (long)buf[1] <<  8;
    x |= (long)buf[2] << 16;
    x |= (long)buf[3] << 24;
#if SIZEOF_LONG > 4
    /* Sign extension for 64-bit machines */
    x |= -(x & 0x80000000L);
#endif
    return x;
}

Here is the caller graph for this function:

static PyObject * get_module_code ( ZipImporter *  self,
char *  fullname,
int p_ispackage,
PyObject **  p_modpath 
) [static]

Definition at line 1177 of file zipimport.c.

{
    PyObject *toc_entry;
    char *subname, path[MAXPATHLEN + 1];
    int len;
    struct st_zip_searchorder *zso;

    subname = get_subname(fullname);

    len = make_filename(self->prefix, subname, path, sizeof(path));
    if (len < 0)
        return NULL;

    for (zso = zip_searchorder; *zso->suffix; zso++) {
        PyObject *code = NULL;

        strcpy(path + len, zso->suffix);
        if (Py_VerboseFlag > 1)
            PySys_FormatStderr("# trying %U%c%s\n",
                               self->archive, (int)SEP, path);
        toc_entry = PyDict_GetItemString(self->files, path);
        if (toc_entry != NULL) {
            time_t mtime = 0;
            int ispackage = zso->type & IS_PACKAGE;
            int isbytecode = zso->type & IS_BYTECODE;

            if (isbytecode)
                mtime = get_mtime_of_source(self, path);
            if (p_ispackage != NULL)
                *p_ispackage = ispackage;
            code = get_code_from_data(self, ispackage,
                                      isbytecode, mtime,
                                      toc_entry);
            if (code == Py_None) {
                /* bad magic number or non-matching mtime
                   in byte code, try next */
                Py_DECREF(code);
                continue;
            }
            if (code != NULL && p_modpath != NULL) {
                *p_modpath = PyTuple_GetItem(toc_entry, 0);
                Py_INCREF(*p_modpath);
            }
            return code;
        }
    }
    PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static enum zi_module_info get_module_info ( ZipImporter *  self,
char *  fullname 
) [static]

Definition at line 259 of file zipimport.c.

{
    char *subname, path[MAXPATHLEN + 1];
    int len;
    struct st_zip_searchorder *zso;

    subname = get_subname(fullname);

    len = make_filename(self->prefix, subname, path, sizeof(path));
    if (len < 0)
        return MI_ERROR;

    for (zso = zip_searchorder; *zso->suffix; zso++) {
        strcpy(path + len, zso->suffix);
        if (PyDict_GetItemString(self->files, path) != NULL) {
            if (zso->type & IS_PACKAGE)
                return MI_PACKAGE;
            else
                return MI_MODULE;
        }
    }
    return MI_NOT_FOUND;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static time_t get_mtime_of_source ( ZipImporter *  self,
char *  path 
) [static]

Definition at line 1125 of file zipimport.c.

{
    PyObject *toc_entry;
    time_t mtime = 0;
    Py_ssize_t lastchar = strlen(path) - 1;
    char savechar = path[lastchar];
    path[lastchar] = '\0';  /* strip 'c' or 'o' from *.py[co] */
    toc_entry = PyDict_GetItemString(self->files, path);
    if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
        PyTuple_Size(toc_entry) == 8) {
        /* fetch the time stamp of the .py file for comparison
           with an embedded pyc time stamp */
        int time, date;
        time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
        date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
        mtime = parse_dostime(time, date);
    }
    path[lastchar] = savechar;
    return mtime;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* get_subname ( char *  fullname) [static]

Definition at line 206 of file zipimport.c.

{
    char *subname = strrchr(fullname, '.');
    if (subname == NULL)
        subname = fullname;
    else
        subname++;
    return subname;
}

Here is the caller graph for this function:

static int make_filename ( PyObject prefix_obj,
char *  name,
char *  path,
size_t  pathsize 
) [static]

Definition at line 220 of file zipimport.c.

{
    size_t len;
    char *p;
    PyObject *prefix;

    prefix = PyUnicode_EncodeFSDefault(prefix_obj);
    if (prefix == NULL)
        return -1;
    len = PyBytes_GET_SIZE(prefix);

    /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
    if (len + strlen(name) + 13 >= pathsize - 1) {
        PyErr_SetString(ZipImportError, "path too long");
        Py_DECREF(prefix);
        return -1;
    }

    strcpy(path, PyBytes_AS_STRING(prefix));
    Py_DECREF(prefix);
    strcpy(path + len, name);
    for (p = path + len; *p; p++) {
        if (*p == '.')
            *p = SEP;
    }
    len += strlen(name);
    assert(len < INT_MAX);
    return (int)len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* normalize_line_endings ( PyObject source) [static]

Definition at line 1048 of file zipimport.c.

{
    char *buf, *q, *p = PyBytes_AsString(source);
    PyObject *fixed_source;
    int len = 0;

    if (!p) {
        return PyBytes_FromStringAndSize("\n\0", 2);
    }

    /* one char extra for trailing \n and one for terminating \0 */
    buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
    if (buf == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "zipimport: no memory to allocate "
                        "source buffer");
        return NULL;
    }
    /* replace "\r\n?" by "\n" */
    for (q = buf; *p != '\0'; p++) {
        if (*p == '\r') {
            *q++ = '\n';
            if (*(p + 1) == '\n')
                p++;
        }
        else
            *q++ = *p;
        len++;
    }
    *q++ = '\n';  /* add trailing \n */
    *q = '\0';
    fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
    PyMem_Free(buf);
    return fixed_source;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static time_t parse_dostime ( int  dostime,
int  dosdate 
) [static]

Definition at line 1104 of file zipimport.c.

{
    struct tm stm;

    memset((void *) &stm, '\0', sizeof(stm));

    stm.tm_sec   =  (dostime        & 0x1f) * 2;
    stm.tm_min   =  (dostime >> 5)  & 0x3f;
    stm.tm_hour  =  (dostime >> 11) & 0x1f;
    stm.tm_mday  =   dosdate        & 0x1f;
    stm.tm_mon   = ((dosdate >> 5)  & 0x0f) - 1;
    stm.tm_year  = ((dosdate >> 9)  & 0x7f) + 80;
    stm.tm_isdst =   -1; /* wday/yday is ignored */

    return mktime(&stm);
}

Here is the caller graph for this function:

PyDoc_STRVAR ( doc_find_module  ,
"find_module(fullname, path=None) -> self or None.\n\\n\Search for a module specified by 'fullname'. 'fullname' must be the\n\fully qualified (dotted) module name. It returns the zipimporter\n\instance itself if the module was  found,
or None if it wasn't.\n\The optional 'path'argument is ignored--it's there for compatibility\n\with the importer protocol."   
)
PyDoc_STRVAR ( doc_load_module  ,
"load_module(fullname) -> module.\n\\n\Load the module specified by 'fullname'. 'fullname' must be the\n\fully qualified (dotted) module name. It returns the imported\n\  module,
or raises ZipImportError if it wasn't found."   
)
PyDoc_STRVAR ( doc_get_data  ,
"get_data(pathname) -> string with file data.\n\\n\Return the data associated with 'pathname'. Raise IOError if\n\the file wasn't found."   
)
PyDoc_STRVAR ( doc_is_package  ,
"is_package(fullname) -> bool.\n\\n\Return True if the module specified by fullname is a package.\n\Raise ZipImportError if the module couldn't be found."   
)
PyDoc_STRVAR ( doc_get_code  ,
"get_code(fullname) -> code object.\n\\n\Return the code object for the specified module. Raise ZipImportError\n\if the module couldn't be found."   
)
PyDoc_STRVAR ( doc_get_source  ,
"get_source(fullname) -> source string.\n\\n\Return the source code for the specified module. Raise ZipImportError\n\if the module couldn't be  found,
return None if the archive does\n\contain the  module,
but has no source for it."   
)
PyDoc_STRVAR ( doc_get_filename  ,
"get_filename(fullname) -> filename string.\n\\n\Return the filename for the specified module."   
)
PyDoc_STRVAR ( zipimporter_doc  ,
"zipimporter(archivepath) -> zipimporter object\n\\n\Create a new zipimporter instance. 'archivepath' must be a path to\n\a  zipfile,
or to a specific path inside a zipfile.For  example,
it can be\n\'/tmp/myimport.zip'  ,
or '/tmp/myimport.zip/mydirectory'  ,
if mydirectory is a\n\valid directory inside the archive.\n\\n\'ZipImportError is raised if 'archivepath'doesn't point to a valid Zip\n\archive.\n\\n\The 'archive'attribute of zipimporter objects contains the name of the\n\zipfile targeted."   
)
PyDoc_STRVAR ( zipimport_doc  ,
"zipimport provides support for importing Python modules from Zip archives.\n\\n\This module exports three objects:\n\- zipimporter: a class; its constructor takes a path to a Zip archive.\n\- ZipImportError: exception raised by zipimporter objects. It's a\n\ subclass of  ImportError,
so it can be caught as  ImportError,
too.\n\-_zip_directory_cache:a  dict,
mapping archive paths to zip directory\n\info  dicts,
as used in zipimporter._files.\n\\n\It is usually not needed to use the zipimport module explicitly;it is\n\used by the builtin import mechanism for sys.path items that are paths\n\to Zip archives."   
)

Definition at line 1258 of file zipimport.c.

{
    PyObject *mod;

    if (PyType_Ready(&ZipImporter_Type) < 0)
        return NULL;

    /* Correct directory separator */
    zip_searchorder[0].suffix[0] = SEP;
    zip_searchorder[1].suffix[0] = SEP;
    zip_searchorder[2].suffix[0] = SEP;
    if (Py_OptimizeFlag) {
        /* Reverse *.pyc and *.pyo */
        struct st_zip_searchorder tmp;
        tmp = zip_searchorder[0];
        zip_searchorder[0] = zip_searchorder[1];
        zip_searchorder[1] = tmp;
        tmp = zip_searchorder[3];
        zip_searchorder[3] = zip_searchorder[4];
        zip_searchorder[4] = tmp;
    }

    mod = PyModule_Create(&zipimportmodule);
    if (mod == NULL)
        return NULL;

    ZipImportError = PyErr_NewException("zipimport.ZipImportError",
                                        PyExc_ImportError, NULL);
    if (ZipImportError == NULL)
        return NULL;

    Py_INCREF(ZipImportError);
    if (PyModule_AddObject(mod, "ZipImportError",
                           ZipImportError) < 0)
        return NULL;

    Py_INCREF(&ZipImporter_Type);
    if (PyModule_AddObject(mod, "zipimporter",
                           (PyObject *)&ZipImporter_Type) < 0)
        return NULL;

    zip_directory_cache = PyDict_New();
    if (zip_directory_cache == NULL)
        return NULL;
    Py_INCREF(zip_directory_cache);
    if (PyModule_AddObject(mod, "_zip_directory_cache",
                           zip_directory_cache) < 0)
        return NULL;
    return mod;
}

Here is the call graph for this function:

static PyObject * read_directory ( PyObject archive) [static]

Definition at line 711 of file zipimport.c.

{
    /* FIXME: work on Py_UNICODE* instead of char* */
    PyObject *files = NULL;
    FILE *fp;
    unsigned short flags;
    long compress, crc, data_size, file_size, file_offset, date, time;
    long header_offset, name_size, header_size, header_position;
    long i, l, count;
    size_t length;
    Py_UNICODE path[MAXPATHLEN + 5];
    char name[MAXPATHLEN + 5];
    PyObject *nameobj = NULL;
    char *p, endof_central_dir[22];
    long arc_offset; /* offset from beginning of file to start of zip-archive */
    PyObject *pathobj;
    const char *charset;
    int bootstrap;

    if (PyUnicode_GET_SIZE(archive_obj) > MAXPATHLEN) {
        PyErr_SetString(PyExc_OverflowError,
                        "Zip path name is too long");
        return NULL;
    }
    Py_UNICODE_strcpy(path, PyUnicode_AS_UNICODE(archive_obj));

    fp = _Py_fopen(archive_obj, "rb");
    if (fp == NULL) {
        PyErr_Format(ZipImportError, "can't open Zip file: '%U'", archive_obj);
        return NULL;
    }
    fseek(fp, -22, SEEK_END);
    header_position = ftell(fp);
    if (fread(endof_central_dir, 1, 22, fp) != 22) {
        fclose(fp);
        PyErr_Format(ZipImportError, "can't read Zip file: '%U'", archive_obj);
        return NULL;
    }
    if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
        /* Bad: End of Central Dir signature */
        fclose(fp);
        PyErr_Format(ZipImportError, "not a Zip file: '%U'", archive_obj);
        return NULL;
    }

    header_size = get_long((unsigned char *)endof_central_dir + 12);
    header_offset = get_long((unsigned char *)endof_central_dir + 16);
    arc_offset = header_position - header_offset - header_size;
    header_offset += arc_offset;

    files = PyDict_New();
    if (files == NULL)
        goto error;

    length = Py_UNICODE_strlen(path);
    path[length] = SEP;

    /* Start of Central Directory */
    count = 0;
    for (;;) {
        PyObject *t;
        int err;

        fseek(fp, header_offset, 0);  /* Start of file header */
        l = PyMarshal_ReadLongFromFile(fp);
        if (l != 0x02014B50)
            break;              /* Bad: Central Dir File Header */
        fseek(fp, header_offset + 8, 0);
        flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
        compress = PyMarshal_ReadShortFromFile(fp);
        time = PyMarshal_ReadShortFromFile(fp);
        date = PyMarshal_ReadShortFromFile(fp);
        crc = PyMarshal_ReadLongFromFile(fp);
        data_size = PyMarshal_ReadLongFromFile(fp);
        file_size = PyMarshal_ReadLongFromFile(fp);
        name_size = PyMarshal_ReadShortFromFile(fp);
        header_size = 46 + name_size +
           PyMarshal_ReadShortFromFile(fp) +
           PyMarshal_ReadShortFromFile(fp);
        fseek(fp, header_offset + 42, 0);
        file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
        if (name_size > MAXPATHLEN)
            name_size = MAXPATHLEN;

        p = name;
        for (i = 0; i < name_size; i++) {
            *p = (char)getc(fp);
            if (*p == '/')
                *p = SEP;
            p++;
        }
        *p = 0;         /* Add terminating null byte */
        header_offset += header_size;

        bootstrap = 0;
        if (flags & 0x0800)
            charset = "utf-8";
        else if (!PyThreadState_GET()->interp->codecs_initialized) {
            /* During bootstrap, we may need to load the encodings
               package from a ZIP file. But the cp437 encoding is implemented
               in Python in the encodings package.

               Break out of this dependency by assuming that the path to
               the encodings module is ASCII-only. */
            charset = "ascii";
            bootstrap = 1;
        }
        else
            charset = "cp437";
        nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
        if (nameobj == NULL) {
            if (bootstrap)
                PyErr_Format(PyExc_NotImplementedError,
                    "bootstrap issue: python%i%i.zip contains non-ASCII "
                    "filenames without the unicode flag",
                    PY_MAJOR_VERSION, PY_MINOR_VERSION);
            goto error;
        }
        Py_UNICODE_strncpy(path + length + 1, PyUnicode_AS_UNICODE(nameobj), MAXPATHLEN - length - 1);

        pathobj = PyUnicode_FromUnicode(path, Py_UNICODE_strlen(path));
        if (pathobj == NULL)
            goto error;
        t = Py_BuildValue("Niiiiiii", pathobj, compress, data_size,
                          file_size, file_offset, time, date, crc);
        if (t == NULL)
            goto error;
        err = PyDict_SetItem(files, nameobj, t);
        Py_CLEAR(nameobj);
        Py_DECREF(t);
        if (err != 0)
            goto error;
        count++;
    }
    fclose(fp);
    if (Py_VerboseFlag)
        PySys_FormatStderr("# zipimport: found %ld names in %U\n",
            count, archive_obj);
    return files;
error:
    fclose(fp);
    Py_XDECREF(files);
    Py_XDECREF(nameobj);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* unmarshal_code ( char *  pathname,
PyObject data,
time_t  mtime 
) [static]

Definition at line 1001 of file zipimport.c.

{
    PyObject *code;
    char *buf = PyBytes_AsString(data);
    Py_ssize_t size = PyBytes_Size(data);

    if (size <= 9) {
        PyErr_SetString(ZipImportError,
                        "bad pyc data");
        return NULL;
    }

    if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
        if (Py_VerboseFlag)
            PySys_WriteStderr("# %s has bad magic\n",
                              pathname);
        Py_INCREF(Py_None);
        return Py_None;  /* signal caller to try alternative */
    }

    if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
                                mtime)) {
        if (Py_VerboseFlag)
            PySys_WriteStderr("# %s has bad mtime\n",
                              pathname);
        Py_INCREF(Py_None);
        return Py_None;  /* signal caller to try alternative */
    }

    code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
    if (code == NULL)
        return NULL;
    if (!PyCode_Check(code)) {
        Py_DECREF(code);
        PyErr_Format(PyExc_TypeError,
             "compiled module %s is not a code object",
             pathname);
        return NULL;
    }
    return code;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void zipimporter_dealloc ( ZipImporter *  self) [static]

Definition at line 182 of file zipimport.c.

{
    PyObject_GC_UnTrack(self);
    Py_XDECREF(self->archive);
    Py_XDECREF(self->prefix);
    Py_XDECREF(self->files);
    Py_TYPE(self)->tp_free((PyObject *)self);
}

Here is the call graph for this function:

static PyObject* zipimporter_find_module ( PyObject obj,
PyObject args 
) [static]

Definition at line 286 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *path = NULL;
    char *fullname;
    enum zi_module_info mi;

    if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
                          &fullname, &path))
        return NULL;

    mi = get_module_info(self, fullname);
    if (mi == MI_ERROR)
        return NULL;
    if (mi == MI_NOT_FOUND) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    Py_INCREF(self);
    return (PyObject *)self;
}

Here is the call graph for this function:

static PyObject* zipimporter_get_code ( PyObject obj,
PyObject args 
) [static]

Definition at line 477 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    char *fullname;

    if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
        return NULL;

    return get_module_code(self, fullname, NULL, NULL);
}

Here is the call graph for this function:

static PyObject* zipimporter_get_data ( PyObject obj,
PyObject args 
) [static]

Definition at line 425 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *pathobj, *key;
    const Py_UNICODE *path;
#ifdef ALTSEP
    Py_UNICODE *p, buf[MAXPATHLEN + 1];
#endif
    Py_UNICODE *archive;
    PyObject *toc_entry;
    Py_ssize_t path_len, len;

    if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
        return NULL;

    path_len = PyUnicode_GET_SIZE(pathobj);
    path = PyUnicode_AS_UNICODE(pathobj);
#ifdef ALTSEP
    if (path_len >= MAXPATHLEN) {
        PyErr_SetString(ZipImportError, "path too long");
        return NULL;
    }
    Py_UNICODE_strcpy(buf, path);
    for (p = buf; *p; p++) {
        if (*p == ALTSEP)
            *p = SEP;
    }
    path = buf;
#endif
    archive = PyUnicode_AS_UNICODE(self->archive);
    len = PyUnicode_GET_SIZE(self->archive);
    if ((size_t)len < Py_UNICODE_strlen(path) &&
        Py_UNICODE_strncmp(path, archive, len) == 0 &&
        path[len] == SEP) {
        path += len + 1;
        path_len -= len + 1;
    }

    key = PyUnicode_FromUnicode(path, path_len);
    if (key == NULL)
        return NULL;
    toc_entry = PyDict_GetItem(self->files, key);
    if (toc_entry == NULL) {
        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
        Py_DECREF(key);
        return NULL;
    }
    Py_DECREF(key);
    return get_data(self->archive, toc_entry);
}

Here is the call graph for this function:

static PyObject* zipimporter_get_filename ( PyObject obj,
PyObject args 
) [static]

Definition at line 380 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *code;
    char *fullname;
    PyObject *modpath;
    int ispackage;

    if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
                          &fullname))
        return NULL;

    /* Deciding the filename requires working out where the code
       would come from if the module was actually loaded */
    code = get_module_code(self, fullname, &ispackage, &modpath);
    if (code == NULL)
        return NULL;
    Py_DECREF(code); /* Only need the path info */

    return modpath;
}

Here is the call graph for this function:

static PyObject* zipimporter_get_source ( PyObject obj,
PyObject args 
) [static]

Definition at line 489 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *toc_entry;
    char *fullname, *subname, path[MAXPATHLEN+1];
    int len;
    enum zi_module_info mi;

    if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
        return NULL;

    mi = get_module_info(self, fullname);
    if (mi == MI_ERROR)
        return NULL;
    if (mi == MI_NOT_FOUND) {
        PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
        return NULL;
    }
    subname = get_subname(fullname);

    len = make_filename(self->prefix, subname, path, sizeof(path));
    if (len < 0)
        return NULL;

    if (mi == MI_PACKAGE) {
        path[len] = SEP;
        strcpy(path + len + 1, "__init__.py");
    }
    else
        strcpy(path + len, ".py");

    toc_entry = PyDict_GetItemString(self->files, path);
    if (toc_entry != NULL) {
        PyObject *res, *bytes;
        bytes = get_data(self->archive, toc_entry);
        if (bytes == NULL)
            return NULL;
        res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
                                          PyBytes_GET_SIZE(bytes));
        Py_DECREF(bytes);
        return res;
    }

    /* we have the module, but no source */
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

static int zipimporter_init ( ZipImporter *  self,
PyObject args,
PyObject kwds 
) [static]

Definition at line 64 of file zipimport.c.

{
    PyObject *pathobj, *files;
    Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
    Py_ssize_t len;

    if (!_PyArg_NoKeywords("zipimporter()", kwds))
        return -1;

    if (!PyArg_ParseTuple(args, "O&:zipimporter",
                          PyUnicode_FSDecoder, &pathobj))
        return -1;

    /* copy path to buf */
    len = PyUnicode_GET_SIZE(pathobj);
    if (len == 0) {
        PyErr_SetString(ZipImportError, "archive path is empty");
        goto error;
    }
    if (len >= MAXPATHLEN) {
        PyErr_SetString(ZipImportError,
                        "archive path too long");
        goto error;
    }
    Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));

#ifdef ALTSEP
    for (p = buf; *p; p++) {
        if (*p == ALTSEP)
            *p = SEP;
    }
#endif

    path = NULL;
    prefix = NULL;
    for (;;) {
        struct stat statbuf;
        int rv;

        if (pathobj == NULL) {
            pathobj = PyUnicode_FromUnicode(buf, len);
            if (pathobj == NULL)
                goto error;
        }
        rv = _Py_stat(pathobj, &statbuf);
        if (rv == 0) {
            /* it exists */
            if (S_ISREG(statbuf.st_mode))
                /* it's a file */
                path = buf;
            break;
        }
        else if (PyErr_Occurred())
            goto error;
        /* back up one path element */
        p = Py_UNICODE_strrchr(buf, SEP);
        if (prefix != NULL)
            *prefix = SEP;
        if (p == NULL)
            break;
        *p = '\0';
        len = p - buf;
        prefix = p;
        Py_CLEAR(pathobj);
    }
    if (path == NULL) {
        PyErr_SetString(ZipImportError, "not a Zip file");
        goto error;
    }

    files = PyDict_GetItem(zip_directory_cache, pathobj);
    if (files == NULL) {
        files = read_directory(pathobj);
        if (files == NULL)
            goto error;
        if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
            goto error;
    }
    else
        Py_INCREF(files);
    self->files = files;

    self->archive = pathobj;
    pathobj = NULL;

    if (prefix != NULL) {
        prefix++;
        len = Py_UNICODE_strlen(prefix);
        if (prefix[len-1] != SEP) {
            /* add trailing SEP */
            prefix[len] = SEP;
            prefix[len + 1] = '\0';
            len++;
        }
    }
    else
        len = 0;
    self->prefix = PyUnicode_FromUnicode(prefix, len);
    if (self->prefix == NULL)
        goto error;

    return 0;

error:
    Py_XDECREF(pathobj);
    return -1;
}

Here is the call graph for this function:

static PyObject* zipimporter_is_package ( PyObject obj,
PyObject args 
) [static]

Definition at line 404 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    char *fullname;
    enum zi_module_info mi;

    if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
                          &fullname))
        return NULL;

    mi = get_module_info(self, fullname);
    if (mi == MI_ERROR)
        return NULL;
    if (mi == MI_NOT_FOUND) {
        PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
        return NULL;
    }
    return PyBool_FromLong(mi == MI_PACKAGE);
}

Here is the call graph for this function:

static PyObject* zipimporter_load_module ( PyObject obj,
PyObject args 
) [static]

Definition at line 310 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *code = NULL, *mod, *dict;
    char *fullname;
    PyObject *modpath = NULL, *modpath_bytes;
    int ispackage;

    if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
                          &fullname))
        return NULL;

    code = get_module_code(self, fullname, &ispackage, &modpath);
    if (code == NULL)
        goto error;

    mod = PyImport_AddModule(fullname);
    if (mod == NULL)
        goto error;
    dict = PyModule_GetDict(mod);

    /* mod.__loader__ = self */
    if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
        goto error;

    if (ispackage) {
        /* add __path__ to the module *before* the code gets
           executed */
        PyObject *pkgpath, *fullpath;
        char *subname = get_subname(fullname);
        int err;

        fullpath = PyUnicode_FromFormat("%U%c%U%s",
                                self->archive, SEP,
                                self->prefix, subname);
        if (fullpath == NULL)
            goto error;

        pkgpath = Py_BuildValue("[O]", fullpath);
        Py_DECREF(fullpath);
        if (pkgpath == NULL)
            goto error;
        err = PyDict_SetItemString(dict, "__path__", pkgpath);
        Py_DECREF(pkgpath);
        if (err != 0)
            goto error;
    }
    modpath_bytes = PyUnicode_EncodeFSDefault(modpath);
    if (modpath_bytes == NULL)
        goto error;
    mod = PyImport_ExecCodeModuleEx(fullname, code,
                                    PyBytes_AS_STRING(modpath_bytes));
    Py_DECREF(modpath_bytes);
    Py_CLEAR(code);
    if (mod == NULL)
        goto error;

    if (Py_VerboseFlag)
        PySys_FormatStderr("import %s # loaded from Zip %U\n",
                           fullname, modpath);
    Py_DECREF(modpath);
    return mod;
error:
    Py_XDECREF(code);
    Py_XDECREF(modpath);
    return NULL;
}

Here is the call graph for this function:

static PyObject* zipimporter_repr ( ZipImporter *  self) [static]

Definition at line 192 of file zipimport.c.

{
    if (self->archive == NULL)
        return PyUnicode_FromString("<zipimporter object \"???\">");
    else if (self->prefix != NULL && PyUnicode_GET_SIZE(self->prefix) != 0)
        return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
                                    self->archive, SEP, self->prefix);
    else
        return PyUnicode_FromFormat("<zipimporter object \"%U\">",
                                    self->archive);
}

Here is the call graph for this function:

static int zipimporter_traverse ( PyObject obj,
visitproc  visit,
void arg 
) [static]

Definition at line 174 of file zipimport.c.

{
    ZipImporter *self = (ZipImporter *)obj;
    Py_VISIT(self->files);
    return 0;
}

Variable Documentation

struct PyModuleDef [static]
Initial value:
 {
    PyModuleDef_HEAD_INIT,
    "zipimport",
    zipimport_doc,
    -1,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
}

Definition at line 1245 of file zipimport.c.

struct st_zip_searchorder[] [static]
Initial value:
 {
    {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
    {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
    {"/__init__.py", IS_PACKAGE | IS_SOURCE},
    {".pyc", IS_BYTECODE},
    {".pyo", IS_BYTECODE},
    {".py", IS_SOURCE},
    {"", 0}
}

Definition at line 22 of file zipimport.c.

Definition at line 47 of file zipimport.c.

Initial value:
 {
    {"archive",  T_OBJECT, offsetof(ZipImporter, archive),  READONLY},
    {"prefix",   T_OBJECT, offsetof(ZipImporter, prefix),   READONLY},
    {"_files",   T_OBJECT, offsetof(ZipImporter, files),    READONLY},
    {NULL}
}

Definition at line 602 of file zipimport.c.

Initial value:
 {
    {"find_module", zipimporter_find_module, METH_VARARGS,
     doc_find_module},
    {"load_module", zipimporter_load_module, METH_VARARGS,
     doc_load_module},
    {"get_data", zipimporter_get_data, METH_VARARGS,
     doc_get_data},
    {"get_code", zipimporter_get_code, METH_VARARGS,
     doc_get_code},
    {"get_source", zipimporter_get_source, METH_VARARGS,
     doc_get_source},
    {"get_filename", zipimporter_get_filename, METH_VARARGS,
     doc_get_filename},
    {"is_package", zipimporter_is_package, METH_VARARGS,
     doc_is_package},
    {NULL,              NULL}   
}

Definition at line 584 of file zipimport.c.

Definition at line 625 of file zipimport.c.

Definition at line 45 of file zipimport.c.