[pypy-svn] pypy default: make sure that the co_filename attribute of code objects inside zip files is in the form myfile.zip/mymodule.py

antocuni commits-noreply at bitbucket.org
Wed Feb 16 11:50:44 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: 
Changeset: r42032:f1f804016710
Date: 2011-02-16 11:16 +0100
http://bitbucket.org/pypy/pypy/changeset/f1f804016710/

Log:	make sure that the co_filename attribute of code objects inside zip
	files is in the form myfile.zip/mymodule.py

diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -149,7 +149,8 @@
         real_name = self.filename + os.path.sep + self.corr_zname(filename)
         space.setattr(w_mod, w('__loader__'), space.wrap(self))
         importing._prepare_module(space, w_mod, real_name, pkgpath)
-        code_w = importing.parse_source_module(space, filename, buf)
+        co_filename = self.make_co_filename(filename)
+        code_w = importing.parse_source_module(space, co_filename, buf)
         importing.exec_code_module(space, w_mod, code_w)
         return w_mod
 
@@ -231,6 +232,14 @@
         subname = fullname[startpos:]
         return self.prefix + subname.replace('.', '/')
 
+    def make_co_filename(self, filename):
+        """
+        Return the filename to be used for compiling the module, i.e. what
+        gets in code_object.co_filename. Something like
+        'myfile.zip/mymodule.py'
+        """
+        return self.filename + os.path.sep + filename
+
     def load_module(self, space, fullname):
         w = space.wrap
         filename = self.make_filename(fullname)
@@ -297,8 +306,9 @@
                     code_w = importing.read_compiled_module(
                         space, filename + ext, source[8:])
                 else:
+                    co_filename = self.make_co_filename(filename+ext)
                     code_w = importing.parse_source_module(
-                        space, filename + ext, source)
+                        space, co_filename, source)
                 return space.wrap(code_w)
         raise operationerrfmt(self.w_ZipImportError,
             "Cannot find source or code for %s in %s", filename, self.name)

diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -34,6 +34,10 @@
         return pyc
     make_pyc = classmethod(make_pyc)
     def make_class(cls):
+        # XXX: this is (mostly) wrong: .compile() compiles the code object
+        # using the host python compiler, but then in the tests we load it
+        # with py.py. It works (mostly by chance) because the two functions
+        # are very simple and the bytecodes are compatible enough.
         co = py.code.Source("""
         def get_name():
             return __name__
@@ -338,6 +342,25 @@
         import zipimport
         assert sys.path_hooks.count(zipimport.zipimporter) == 1
 
+    def test_co_filename(self):
+        self.writefile('mymodule.py', """
+def get_co_filename():
+    return get_co_filename.func_code.co_filename
+""")
+        import os
+        expected = self.zipfile + os.sep + 'mymodule.py'
+        #
+        import mymodule
+        co_filename = mymodule.get_co_filename()
+        assert co_filename == expected
+        #
+        import zipimport
+        z = zipimport.zipimporter(self.zipfile)
+        code = z.get_code('mymodule')
+        co_filename = code.co_filename
+        assert co_filename == expected
+
+
 class AppTestZipimportDeflated(AppTestZipimport):
     compression = ZIP_DEFLATED
 


More information about the Pypy-commit mailing list