/* 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; }
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; }