Ejemplo n.º 1
0
/* New reference. */
static PyObject *
normalize_module(PyObject *filename)
{
    PyObject *module;
    int kind;
    void *data;
    Py_ssize_t len;

    len = PyUnicode_GetLength(filename);
    if (len < 0)
        return NULL;

    if (len == 0)
        return PyUnicode_FromString("<unknown>");

    kind = PyUnicode_KIND(filename);
    data = PyUnicode_DATA(filename);

    /* if filename.endswith(".py"): */
    if (len >= 3 &&
        PyUnicode_READ(kind, data, len-3) == '.' &&
        PyUnicode_READ(kind, data, len-2) == 'p' &&
        PyUnicode_READ(kind, data, len-1) == 'y')
    {
        module = PyUnicode_Substring(filename, 0, len-3);
    }
    else {
        module = filename;
        Py_INCREF(module);
    }
    return module;
}
Ejemplo n.º 2
0
/* Get the variable part of a module's export symbol name.
 * Returns a bytes instance. For non-ASCII-named modules, the name is
 * encoded as per PEP 489.
 * The hook_prefix pointer is set to either ascii_only_prefix or
 * nonascii_prefix, as appropriate.
 */
static PyObject *
get_encoded_name(PyObject *name, const char **hook_prefix) {
    PyObject *tmp;
    PyObject *encoded = NULL;
    PyObject *modname = NULL;
    Py_ssize_t name_len, lastdot;
    _Py_IDENTIFIER(replace);

    /* Get the short name (substring after last dot) */
    name_len = PyUnicode_GetLength(name);
    lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1);
    if (lastdot < -1) {
        return NULL;
    } else if (lastdot >= 0) {
        tmp = PyUnicode_Substring(name, lastdot + 1, name_len);
        if (tmp == NULL)
            return NULL;
        name = tmp;
        /* "name" now holds a new reference to the substring */
    } else {
        Py_INCREF(name);
    }

    /* Encode to ASCII or Punycode, as needed */
    encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
    if (encoded != NULL) {
        *hook_prefix = ascii_only_prefix;
    } else {
        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
            PyErr_Clear();
            encoded = PyUnicode_AsEncodedString(name, "punycode", NULL);
            if (encoded == NULL) {
                goto error;
            }
            *hook_prefix = nonascii_prefix;
        } else {
            goto error;
        }
    }

    /* Replace '-' by '_' */
    modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_');
    if (modname == NULL)
        goto error;

    Py_DECREF(name);
    Py_DECREF(encoded);
    return modname;
error:
    Py_DECREF(name);
    Py_XDECREF(encoded);
    return NULL;
}
Ejemplo n.º 3
0
/* return fullname.split(".")[-1] */
static PyObject *
get_subname(PyObject *fullname)
{
    Py_ssize_t len, dot;
    if (PyUnicode_READY(fullname) < 0)
        return NULL;
    len = PyUnicode_GET_LENGTH(fullname);
    dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
    if (dot == -1) {
        Py_INCREF(fullname);
        return fullname;
    } else
        return PyUnicode_Substring(fullname, dot+1, len);
}
Ejemplo n.º 4
0
static PyObject *
zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path)
/*[clinic end generated code: output=65dc506aaa268436 input=fa6428b74843c4ae]*/
{
    PyObject *key;
    PyObject *toc_entry;
    Py_ssize_t path_start, path_len, len;

    if (self->archive == NULL) {
        PyErr_SetString(PyExc_ValueError,
                        "zipimporter.__init__() wasn't called");
        return NULL;
    }

#ifdef ALTSEP
    path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace,
                                  "OCC", path, ALTSEP, SEP);
    if (!path)
        return NULL;
#else
    Py_INCREF(path);
#endif
    if (PyUnicode_READY(path) == -1)
        goto error;

    path_len = PyUnicode_GET_LENGTH(path);

    len = PyUnicode_GET_LENGTH(self->archive);
    path_start = 0;
    if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
        && PyUnicode_READ_CHAR(path, len) == SEP) {
        path_start = len + 1;
    }

    key = PyUnicode_Substring(path, path_start, path_len);
    if (key == NULL)
        goto error;
    toc_entry = PyDict_GetItem(self->files, key);
    if (toc_entry == NULL) {
        PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, key);
        Py_DECREF(key);
        goto error;
    }
    Py_DECREF(key);
    Py_DECREF(path);
    return get_data(self->archive, toc_entry);
  error:
    Py_DECREF(path);
    return NULL;
}
Ejemplo n.º 5
0
static PyObject *
zipimporter_get_data(PyObject *obj, PyObject *args)
{
    ZipImporter *self = (ZipImporter *)obj;
    PyObject *path, *key;
#ifdef ALTSEP
    _Py_IDENTIFIER(replace);
#endif
    PyObject *toc_entry;
    Py_ssize_t path_start, path_len, len;

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

#ifdef ALTSEP
    path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
    if (!path)
        return NULL;
#else
    Py_INCREF(path);
#endif
    if (PyUnicode_READY(path) == -1)
        goto error;

    path_len = PyUnicode_GET_LENGTH(path);

    len = PyUnicode_GET_LENGTH(self->archive);
    path_start = 0;
    if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
        && PyUnicode_READ_CHAR(path, len) == SEP) {
        path_start = len + 1;
    }

    key = PyUnicode_Substring(path, path_start, path_len);
    if (key == NULL)
        goto error;
    toc_entry = PyDict_GetItem(self->files, key);
    if (toc_entry == NULL) {
        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
        Py_DECREF(key);
        goto error;
    }
    Py_DECREF(key);
    Py_DECREF(path);
    return get_data(self->archive, toc_entry);
  error:
    Py_DECREF(path);
    return NULL;
}
Ejemplo n.º 6
0
static PyObject *
syslog_get_argv(void)
{
    /* Figure out what to use for as the program "ident" for openlog().
     * This swallows exceptions and continues rather than failing out,
     * because the syslog module can still be used because openlog(3)
     * is optional.
     */

    Py_ssize_t argv_len, scriptlen;
    PyObject *scriptobj;
    Py_ssize_t slash;
    PyObject *argv = PySys_GetObject("argv");

    if (argv == NULL) {
        return(NULL);
    }

    argv_len = PyList_Size(argv);
    if (argv_len == -1) {
        PyErr_Clear();
        return(NULL);
    }
    if (argv_len == 0) {
        return(NULL);
    }

    scriptobj = PyList_GetItem(argv, 0);
    if (!PyUnicode_Check(scriptobj)) {
        return(NULL);
    }
    scriptlen = PyUnicode_GET_LENGTH(scriptobj);
    if (scriptlen == 0) {
        return(NULL);
    }

    slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1);
    if (slash == -2)
        return NULL;
    if (slash != -1) {
        return PyUnicode_Substring(scriptobj, slash, scriptlen);
    } else {
        Py_INCREF(scriptobj);
        return(scriptobj);
    }

    return(NULL);
}
Ejemplo n.º 7
0
/* Returns 0 on error (no new refs), 1 on success */
static int
setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
              PyObject **module, PyObject **registry)
{
    PyObject *globals;

    /* Setup globals and lineno. */
    PyFrameObject *f = PyThreadState_GET()->frame;
    // Stack level comparisons to Python code is off by one as there is no
    // warnings-related stack level to avoid.
    if (stack_level <= 0 || is_internal_frame(f)) {
        while (--stack_level > 0 && f != NULL) {
            f = f->f_back;
        }
    }
    else {
        while (--stack_level > 0 && f != NULL) {
            f = next_external_frame(f);
        }
    }

    if (f == NULL) {
        globals = PyThreadState_Get()->interp->sysdict;
        *lineno = 1;
    }
    else {
        globals = f->f_globals;
        *lineno = PyFrame_GetLineNumber(f);
    }

    *module = NULL;

    /* Setup registry. */
    assert(globals != NULL);
    assert(PyDict_Check(globals));
    *registry = PyDict_GetItemString(globals, "__warningregistry__");
    if (*registry == NULL) {
        int rc;

        *registry = PyDict_New();
        if (*registry == NULL)
            return 0;

         rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
         if (rc < 0)
            goto handle_error;
    }
    else
        Py_INCREF(*registry);

    /* Setup module. */
    *module = PyDict_GetItemString(globals, "__name__");
    if (*module == NULL) {
        *module = PyUnicode_FromString("<string>");
        if (*module == NULL)
            goto handle_error;
    }
    else
        Py_INCREF(*module);

    /* Setup filename. */
    *filename = PyDict_GetItemString(globals, "__file__");
    if (*filename != NULL && PyUnicode_Check(*filename)) {
        Py_ssize_t len;
        int kind;
        void *data;

        if (PyUnicode_READY(*filename))
            goto handle_error;

        len = PyUnicode_GetLength(*filename);
        kind = PyUnicode_KIND(*filename);
        data = PyUnicode_DATA(*filename);

#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
        /* if filename.lower().endswith(".pyc"): */
        if (len >= 4 &&
            PyUnicode_READ(kind, data, len-4) == '.' &&
            ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
            ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
            ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
        {
            *filename = PyUnicode_Substring(*filename, 0,
                                            PyUnicode_GET_LENGTH(*filename)-1);
            if (*filename == NULL)
                goto handle_error;
        }
        else
            Py_INCREF(*filename);
    }
    else {
        *filename = NULL;
        if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) {
            PyObject *argv = _PySys_GetObjectId(&PyId_argv);
            /* PyList_Check() is needed because sys.argv is set to None during
               Python finalization */
            if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
                int is_true;
                *filename = PyList_GetItem(argv, 0);
                Py_INCREF(*filename);
                /* If sys.argv[0] is false, then use '__main__'. */
                is_true = PyObject_IsTrue(*filename);
                if (is_true < 0) {
                    Py_DECREF(*filename);
                    goto handle_error;
                }
                else if (!is_true) {
                    Py_XSETREF(*filename, PyUnicode_FromString("__main__"));
                    if (*filename == NULL)
                        goto handle_error;
                }
            }
            else {
                /* embedded interpreters don't have sys.argv, see bug #839151 */
                *filename = PyUnicode_FromString("__main__");
                if (*filename == NULL)
                    goto handle_error;
            }
        }
        if (*filename == NULL) {
            *filename = *module;
            Py_INCREF(*filename);
        }
    }

    return 1;

 handle_error:
    /* filename not XDECREF'ed here as there is no way to jump here with a
       dangling reference. */
    Py_XDECREF(*registry);
    Py_XDECREF(*module);
    return 0;
}
Ejemplo n.º 8
0
static void
show_warning(PyObject *filename, int lineno, PyObject *text,
             PyObject *category, PyObject *sourceline)
{
    PyObject *f_stderr;
    PyObject *name;
    char lineno_str[128];
    _Py_IDENTIFIER(__name__);

    PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);

    name = _PyObject_GetAttrId(category, &PyId___name__);
    if (name == NULL)  /* XXX Can an object lack a '__name__' attribute? */
        goto error;

    f_stderr = _PySys_GetObjectId(&PyId_stderr);
    if (f_stderr == NULL) {
        fprintf(stderr, "lost sys.stderr\n");
        goto error;
    }

    /* Print "filename:lineno: category: text\n" */
    if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
        goto error;
    if (PyFile_WriteString(lineno_str, f_stderr) < 0)
        goto error;
    if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
        goto error;
    if (PyFile_WriteString(": ", f_stderr) < 0)
        goto error;
    if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
        goto error;
    if (PyFile_WriteString("\n", f_stderr) < 0)
        goto error;
    Py_CLEAR(name);

    /* Print "  source_line\n" */
    if (sourceline) {
        int kind;
        void *data;
        Py_ssize_t i, len;
        Py_UCS4 ch;
        PyObject *truncated;

        if (PyUnicode_READY(sourceline) < 1)
            goto error;

        kind = PyUnicode_KIND(sourceline);
        data = PyUnicode_DATA(sourceline);
        len = PyUnicode_GET_LENGTH(sourceline);
        for (i=0; i<len; i++) {
            ch = PyUnicode_READ(kind, data, i);
            if (ch != ' ' && ch != '\t' && ch != '\014')
                break;
        }

        truncated = PyUnicode_Substring(sourceline, i, len);
        if (truncated == NULL)
            goto error;

        PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
        Py_DECREF(truncated);
        PyFile_WriteString("\n", f_stderr);
    }
    else {
        _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
    }

error:
    Py_XDECREF(name);
    PyErr_Clear();
}
Ejemplo n.º 9
0
int
_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
{
    int err = 0;
    int fd;
    int i;
    char *found_encoding;
    char *encoding;
    PyObject *io;
    PyObject *binary;
    PyObject *fob = NULL;
    PyObject *lineobj = NULL;
    PyObject *res;
    char buf[MAXPATHLEN+1];
    int kind;
    void *data;

    /* open the file */
    if (filename == NULL)
        return 0;

    io = PyImport_ImportModuleNoBlock("io");
    if (io == NULL)
        return -1;
    binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");

    if (binary == NULL) {
        PyErr_Clear();

        binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
        if (binary == NULL) {
            Py_DECREF(io);
            return -1;
        }
    }

    /* use the right encoding to decode the file as unicode */
    fd = PyObject_AsFileDescriptor(binary);
    if (fd < 0) {
        Py_DECREF(io);
        Py_DECREF(binary);
        return 0;
    }
    found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
    if (found_encoding == NULL)
        PyErr_Clear();
    encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
    /* Reset position */
    if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
        Py_DECREF(io);
        Py_DECREF(binary);
        PyMem_FREE(found_encoding);
        return 0;
    }
    fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
    Py_DECREF(io);
    Py_DECREF(binary);
    PyMem_FREE(found_encoding);

    if (fob == NULL) {
        PyErr_Clear();
        return 0;
    }

    /* get the line number lineno */
    for (i = 0; i < lineno; i++) {
        Py_XDECREF(lineobj);
        lineobj = PyFile_GetLine(fob, -1);
        if (!lineobj) {
            err = -1;
            break;
        }
    }
    res = _PyObject_CallMethodId(fob, &PyId_close, "");
    if (res)
        Py_DECREF(res);
    else
        PyErr_Clear();
    Py_DECREF(fob);
    if (!lineobj || !PyUnicode_Check(lineobj)) {
        Py_XDECREF(lineobj);
        return err;
    }

    /* remove the indentation of the line */
    kind = PyUnicode_KIND(lineobj);
    data = PyUnicode_DATA(lineobj);
    for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) {
        Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        if (ch != ' ' && ch != '\t' && ch != '\014')
            break;
    }
    if (i) {
        PyObject *truncated;
        truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj));
        if (truncated) {
            Py_DECREF(lineobj);
            lineobj = truncated;
        } else {
            PyErr_Clear();
        }
    }

    /* Write some spaces before the line */
    strcpy(buf, "          ");
    assert (strlen(buf) == 10);
    while (indent > 0) {
        if (indent < 10)
            buf[indent] = '\0';
        err = PyFile_WriteString(buf, f);
        if (err != 0)
            break;
        indent -= 10;
    }

    /* finally display the line */
    if (err == 0)
        err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW);
    Py_DECREF(lineobj);
    if  (err == 0)
        err = PyFile_WriteString("\n", f);
    return err;
}
Ejemplo n.º 10
0
PyObject *
PyFile_GetLine(PyObject *f, int n)
{
    PyObject *result;

    if (f == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }

    {
        PyObject *reader;
        PyObject *args;
        _Py_IDENTIFIER(readline);

        reader = _PyObject_GetAttrId(f, &PyId_readline);
        if (reader == NULL)
            return NULL;
        if (n <= 0)
            args = PyTuple_New(0);
        else
            args = Py_BuildValue("(i)", n);
        if (args == NULL) {
            Py_DECREF(reader);
            return NULL;
        }
        result = PyEval_CallObject(reader, args);
        Py_DECREF(reader);
        Py_DECREF(args);
        if (result != NULL && !PyBytes_Check(result) &&
            !PyUnicode_Check(result)) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_TypeError,
                       "object.readline() returned non-string");
        }
    }

    if (n < 0 && result != NULL && PyBytes_Check(result)) {
        char *s = PyBytes_AS_STRING(result);
        Py_ssize_t len = PyBytes_GET_SIZE(result);
        if (len == 0) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_EOFError,
                            "EOF when reading a line");
        }
        else if (s[len-1] == '\n') {
            if (result->ob_refcnt == 1)
                _PyBytes_Resize(&result, len-1);
            else {
                PyObject *v;
                v = PyBytes_FromStringAndSize(s, len-1);
                Py_DECREF(result);
                result = v;
            }
        }
    }
    if (n < 0 && result != NULL && PyUnicode_Check(result)) {
        Py_ssize_t len = PyUnicode_GET_LENGTH(result);
        if (len == 0) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_EOFError,
                            "EOF when reading a line");
        }
        else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
            PyObject *v;
            v = PyUnicode_Substring(result, 0, len-1);
            Py_DECREF(result);
            result = v;
        }
    }
    return result;
}
Ejemplo n.º 11
0
/* zipimporter.__init__
   Split the "subdirectory" from the Zip archive path, lookup a matching
   entry in sys.path_importer_cache, fetch the file directory from there
   if found, or else read it from the archive. */
static int
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
{
    PyObject *path, *files, *tmp;
    PyObject *filename = NULL;
    Py_ssize_t len, flen;

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

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

    if (PyUnicode_READY(path) == -1)
        return -1;

    len = PyUnicode_GET_LENGTH(path);
    if (len == 0) {
        PyErr_SetString(ZipImportError, "archive path is empty");
        goto error;
    }

#ifdef ALTSEP
    tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
    if (!tmp)
        goto error;
    Py_DECREF(path);
    path = tmp;
#endif

    filename = path;
    Py_INCREF(filename);
    flen = len;
    for (;;) {
        struct stat statbuf;
        int rv;

        rv = _Py_stat(filename, &statbuf);
        if (rv == -2)
            goto error;
        if (rv == 0) {
            /* it exists */
            if (!S_ISREG(statbuf.st_mode))
                /* it's a not file */
                Py_CLEAR(filename);
            break;
        }
        Py_CLEAR(filename);
        /* back up one path element */
        flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
        if (flen == -1)
            break;
        filename = PyUnicode_Substring(path, 0, flen);
        if (filename == NULL)
            goto error;
    }
    if (filename == NULL) {
        PyErr_SetString(ZipImportError, "not a Zip file");
        goto error;
    }

    if (PyUnicode_READY(filename) < 0)
        goto error;

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

    /* Transfer reference */
    self->archive = filename;
    filename = NULL;

    /* Check if there is a prefix directory following the filename. */
    if (flen != len) {
        tmp = PyUnicode_Substring(path, flen+1,
                                  PyUnicode_GET_LENGTH(path));
        if (tmp == NULL)
            goto error;
        self->prefix = tmp;
        if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
            /* add trailing SEP */
            tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
            if (tmp == NULL)
                goto error;
            Py_SETREF(self->prefix, tmp);
        }
    }
    else
        self->prefix = PyUnicode_New(0, 0);
    Py_DECREF(path);
    return 0;

error:
    Py_DECREF(path);
    Py_XDECREF(filename);
    return -1;
}
Ejemplo n.º 12
0
static int
zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)
/*[clinic end generated code: output=141558fefdb46dc8 input=92b9ebeed1f6a704]*/
{
    PyObject *files, *tmp;
    PyObject *filename = NULL;
    Py_ssize_t len, flen;

    if (PyUnicode_READY(path) == -1)
        return -1;

    len = PyUnicode_GET_LENGTH(path);
    if (len == 0) {
        PyErr_SetString(ZipImportError, "archive path is empty");
        goto error;
    }

#ifdef ALTSEP
    tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
    if (!tmp)
        goto error;
    Py_DECREF(path);
    path = tmp;
#endif

    filename = path;
    Py_INCREF(filename);
    flen = len;
    for (;;) {
        struct stat statbuf;
        int rv;

        rv = _Py_stat(filename, &statbuf);
        if (rv == -2)
            goto error;
        if (rv == 0) {
            /* it exists */
            if (!S_ISREG(statbuf.st_mode))
                /* it's a not file */
                Py_CLEAR(filename);
            break;
        }
        Py_CLEAR(filename);
        /* back up one path element */
        flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
        if (flen == -1)
            break;
        filename = PyUnicode_Substring(path, 0, flen);
        if (filename == NULL)
            goto error;
    }
    if (filename == NULL) {
        PyErr_SetString(ZipImportError, "not a Zip file");
        goto error;
    }

    if (PyUnicode_READY(filename) < 0)
        goto error;

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

    /* Transfer reference */
    Py_XSETREF(self->archive, filename);
    filename = NULL;

    /* Check if there is a prefix directory following the filename. */
    if (flen != len) {
        tmp = PyUnicode_Substring(path, flen+1,
                                  PyUnicode_GET_LENGTH(path));
        if (tmp == NULL)
            goto error;
        Py_XSETREF(self->prefix, tmp);
        if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
            /* add trailing SEP */
            tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
            if (tmp == NULL)
                goto error;
            Py_SETREF(self->prefix, tmp);
        }
    }
    else {
        Py_XSETREF(self->prefix, PyUnicode_New(0, 0));
    }
    Py_DECREF(path);
    return 0;

error:
    Py_DECREF(path);
    Py_XDECREF(filename);
    return -1;
}