summaryrefslogtreecommitdiff
path: root/Modules/zipimport.c
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2016-01-20 22:07:43 -0800
committerBenjamin Peterson <benjamin@python.org>2016-01-20 22:07:43 -0800
commitefd66823ecd8a4cd118cc01a9e391603562ab95e (patch)
tree3842fee7c14c607d0d3cfb82e824b9d3bf2042f9 /Modules/zipimport.c
parentb4858f2a3459bfb7f37164c1a1b746022053c42c (diff)
parentb3aee159546a73b97134fd0873a868f83fb1a9a7 (diff)
downloadcpython-efd66823ecd8a4cd118cc01a9e391603562ab95e.tar.gz
merge 3.4
Diffstat (limited to 'Modules/zipimport.c')
-rw-r--r--Modules/zipimport.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 55bfb5d7cf..42f8f16185 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -20,15 +20,13 @@ _Py_IDENTIFIER(replace);
/* zip_searchorder defines how we search for a module in the Zip
archive: we first search for a package __init__, then for
- non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
+ non-package .pyc, and .py entries. The .pyc entries
are swapped by initzipimport() if we run in optimized mode. Also,
'/' is replaced by SEP there. */
static struct st_zip_searchorder zip_searchorder[] = {
{"/__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}
};
@@ -157,8 +155,7 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
if (tmp == NULL)
goto error;
- Py_DECREF(self->prefix);
- self->prefix = tmp;
+ Py_SETREF(self->prefix, tmp);
}
}
else
@@ -327,17 +324,14 @@ get_module_info(ZipImporter *self, PyObject *fullname)
}
typedef enum {
- FL_ERROR,
- FL_NOT_FOUND,
- FL_MODULE_FOUND,
- FL_NS_FOUND
+ FL_ERROR = -1, /* error */
+ FL_NOT_FOUND, /* no loader or namespace portions found */
+ FL_MODULE_FOUND, /* module/package found */
+ FL_NS_FOUND /* namespace portion found: */
+ /* *namespace_portion will point to the name */
} find_loader_result;
-/* The guts of "find_loader" and "find_module". Return values:
- -1: error
- 0: no loader or namespace portions found
- 1: module/package found
- 2: namespace portion found: *namespace_portion will point to the name
+/* The guts of "find_loader" and "find_module".
*/
static find_loader_result
find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
@@ -352,21 +346,34 @@ find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
if (mi == MI_NOT_FOUND) {
/* Not a module or regular package. See if this is a directory, and
therefore possibly a portion of a namespace package. */
- int is_dir = check_is_directory(self, self->prefix, fullname);
+ find_loader_result result = FL_NOT_FOUND;
+ PyObject *subname;
+ int is_dir;
+
+ /* We're only interested in the last path component of fullname;
+ earlier components are recorded in self->prefix. */
+ subname = get_subname(fullname);
+ if (subname == NULL) {
+ return FL_ERROR;
+ }
+
+ is_dir = check_is_directory(self, self->prefix, subname);
if (is_dir < 0)
- return -1;
- if (is_dir) {
+ result = FL_ERROR;
+ else if (is_dir) {
/* This is possibly a portion of a namespace
package. Return the string representing its path,
without a trailing separator. */
*namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
self->archive, SEP,
- self->prefix, fullname);
+ self->prefix, subname);
if (*namespace_portion == NULL)
- return FL_ERROR;
- return FL_NS_FOUND;
+ result = FL_ERROR;
+ else
+ result = FL_NS_FOUND;
}
- return FL_NOT_FOUND;
+ Py_DECREF(subname);
+ return result;
}
/* This is a module or package. */
return FL_MODULE_FOUND;
@@ -400,6 +407,9 @@ zipimporter_find_module(PyObject *obj, PyObject *args)
case FL_MODULE_FOUND:
result = (PyObject *)self;
break;
+ default:
+ PyErr_BadInternalCall();
+ return NULL;
}
Py_INCREF(result);
return result;
@@ -436,6 +446,9 @@ zipimporter_find_loader(PyObject *obj, PyObject *args)
result = Py_BuildValue("O[O]", Py_None, namespace_portion);
Py_DECREF(namespace_portion);
return result;
+ default:
+ PyErr_BadInternalCall();
+ return NULL;
}
return result;
}
@@ -875,8 +888,12 @@ read_directory(PyObject *archive)
fp = _Py_fopen_obj(archive, "rb");
if (fp == NULL) {
- if (!PyErr_Occurred())
+ if (PyErr_ExceptionMatches(PyExc_OSError)) {
+ PyObject *exc, *val, *tb;
+ PyErr_Fetch(&exc, &val, &tb);
PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
+ _PyErr_ChainExceptions(exc, val, tb);
+ }
return NULL;
}
@@ -939,6 +956,9 @@ read_directory(PyObject *archive)
header_size = name_size +
PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp);
+ if (PyErr_Occurred())
+ goto error;
+
if (fread(dummy, 1, 8, fp) != 8) /* Skip unused fields, avoid fseek */
goto file_error;
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
@@ -1073,12 +1093,8 @@ get_data(PyObject *archive, PyObject *toc_entry)
}
fp = _Py_fopen_obj(archive, "rb");
- if (!fp) {
- if (!PyErr_Occurred())
- PyErr_Format(PyExc_IOError,
- "zipimport: can not open file %U", archive);
+ if (!fp)
return NULL;
- }
/* Check to make sure the local file header is correct */
if (fseek(fp, file_offset, 0) == -1) {
@@ -1316,7 +1332,7 @@ parse_dostime(int dostime, int dosdate)
return mktime(&stm);
}
-/* Given a path to a .pyc or .pyo file in the archive, return the
+/* Given a path to a .pyc file in the archive, return the
modification time of the matching .py file, or 0 if no source
is available. */
static time_t
@@ -1479,17 +1495,6 @@ PyInit_zipimport(void)
/* 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)