diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 0a458e9d58..496ea05632 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -620,6 +620,19 @@ def _get_mtime_of_source(self, path): except (KeyError, IndexError, TypeError): return 0 +# Select code origin for unmarshalled code. +def _select_code_origin(self, code, toc_entry): + path = code.co_filename.replace('/', path_sep) + toc_origin = self._files.get(path, toc_entry) + return toc_origin[0] + +def _overwrite_code_origin(code, code_origin): + code.co_filename = code_origin + # Iterate nested code objects to fix 'co_filename' as well. + for item in code.co_consts: + if isinstance(item, _code_type): + _overwrite_code_origin(item, code_origin) + # Get the code object associated with the module specified by # 'fullname'. def _get_module_code(self, fullname): @@ -637,6 +650,9 @@ def _get_module_code(self, fullname): if isbytecode: mtime = _get_mtime_of_source(self, fullpath) code = _unmarshal_code(modpath, data, mtime) + if code is not None: + code_origin = _select_code_origin(self, code, toc_entry) + _overwrite_code_origin(code, code_origin) else: code = _compile_source(modpath, data) if code is None: diff --git a/Objects/codeobject.c b/Objects/codeobject.c index cedf11ee8a..eac9848baa 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -284,7 +284,7 @@ static PyMemberDef code_memberlist[] = { {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), 0}, {"co_name", T_OBJECT, OFF(co_name), READONLY}, {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},