Commits

Ronald Oussoren committed 5bf1630 Merge

merge

Comments (0)

Files changed (6)

doc/changelog.rst

   lxml performs a number of imports from an extension and those cannot
   be detected automaticly by modulegraph.
 
+- Issue #94: The site-packages zipfile in the application bundle now contains
+  zipfile entries for directories as well. This is needed to work around
+  a bug in the zipimporter for Python 3.3: it won't consider 'pkg/foo.py' to be
+  in namespace package 'pkg' unless there is a zipfile entry for the 'pkg'
+  folder (or there is a 'pkg/__init__.py' entry).
+
 
 py2app 0.7.3
 ------------

py2app/build_app.py

     def finalize_modulefinder(self, mf):
         for item in mf.flatten():
             if isinstance(item, Package) and item.filename == '-':
-                fn = os.path.join(self.temp_dir, 'empty_package', '__init__.py')
-                if not os.path.exists(fn):
-                    dn = os.path.dirname(fn)
-                    if not os.path.exists(dn):
-                        os.makedirs(dn)
-                    with open(fn, 'w') as fp:
-                        pass
+                if sys.version_info[:2] <= (3,3):
+                    fn = os.path.join(self.temp_dir, 'empty_package', '__init__.py')
+                    if not os.path.exists(fn):
+                        dn = os.path.dirname(fn)
+                        if not os.path.exists(dn):
+                            os.makedirs(dn)
+                        with open(fn, 'w') as fp:
+                            pass
 
-                item.filename = fn
+                    item.filename = fn
 
         py_files, extensions = parse_mf_results(mf)
 
             save_cwd = os.getcwd()
             os.chdir(base_dir)
             for dirpath, dirnames, filenames in os.walk('.'):
+                if filenames:
+                    # Ensure that there are directory entries for
+                    # all directories in the zipfile. This is a
+                    # workaround for <http://bugs.python.org/issue14905>:
+                    # zipimport won't consider 'pkg/foo.py' to be in
+                    # namespace package 'pkg' unless there is an
+                    # entry for the directory (or there is a
+                    # pkg/__init__.py file as well)
+                    z.write(dirpath, dirpath)
+
                 for fn in filenames:
                     path = os.path.normpath(os.path.join(dirpath, fn))
                     if os.path.isfile(path):
                         z.write(path, path)
+
             os.chdir(save_cwd)
             z.close()
 

py2app_tests/app_with_sharedlib/mod.c

 #define INITERROR() return NULL
 #define INITDONE() return m
 
-#define INITFUNC PyInt_ ## NAME
-
 PyObject* INITFUNC(void);
 
 PyObject*

py2app_tests/app_with_sharedlib/setup.py

 import platform
 import shlex
 import re
+import sys
 
 class sharedlib (Command):
     description = "build a shared library"
 
 
         mod_build_ext.build_ext.run(self)
-        
+
         subprocess.check_call([
-            'install_name_tool', '-change', 
+            'install_name_tool', '-change',
                os.path.abspath('lib/libshared.1.dylib'),
                os.path.abspath('lib/libshared.dylib'),
                'square.so'
         build_ext=my_build_ext
     ),
     ext_modules=[
-        Extension("double", [ "mod.c" ], 
-            extra_compile_args=["-Isrc", '-DNAME=double', '-DFUNC_NAME=doubled', '-DINITFUNC=initdouble'],
+        Extension("double", [ "mod.c" ],
+            extra_compile_args=["-Isrc", '-DNAME=double', '-DFUNC_NAME=doubled', ('-DINITFUNC=initdouble' if sys.maxsize == 2 else '-DINITFUNC=PyInit_double')],
             extra_link_args=["-Llib", "-lshared"]),
-        Extension("square", [ "mod.c" ], 
-            extra_compile_args=["-Isrc", '-DNAME=square', '-DFUNC_NAME=squared', '-DINITFUNC=initsquare'],
+        Extension("square", [ "mod.c" ],
+            extra_compile_args=["-Isrc", '-DNAME=square', '-DFUNC_NAME=squared', ('-DINITFUNC=initsquare' if sys.maxsize == 2 else '-DINITFUNC=PyInit_square')],
             extra_link_args=["-Llib", "-lshared.1"]),
-        Extension("half", [ "mod.c" ], 
-            extra_compile_args=["-Isrc", '-DNAME=half', '-DFUNC_NAME=half', '-DINITFUNC=inithalf'],
+        Extension("half", [ "mod.c" ],
+            extra_compile_args=["-Isrc", '-DNAME=half', '-DFUNC_NAME=half', ('-DINITFUNC=inithalf' if sys.maxsize == 2 else '-DINITFUNC=PyInit_half')],
             extra_link_args=["-Llib", "-lhalf"]),
     ],
     options=dict(

py2app_tests/basic_app/package3/mod.py

+""" package3.mod """

py2app_tests/test_explicit_includes.py

 
 class TestExplicitIncludes (unittest.TestCase):
     py2app_args = [ '--includes=package1.subpackage.module' ]
+    if sys.version_info[:2] >= (3,3):
+        py2app_args = [ '--includes=package1.subpackage.module,package3.mod' ]
+
     python_args = []
     app_dir = os.path.join(DIR_NAME, 'basic_app')
 
         ln = p.stdout.readline()
         self.assertEqual(ln.strip(), b"package1.subpackage.module")
 
+        if sys.version_info[:2] >= (3,3):
+            p.stdin.write('import_module("package3.mod")\n'.encode('latin1'))
+            p.stdin.flush()
+            ln = p.stdout.readline()
+            self.assertEqual(ln.strip(), b"package3.mod")
+
+
 if __name__ == "__main__":
     unittest.main()