fix initial module registration for (nested) packages
authorStefan Behnel <stefan_ml@behnel.de>
Mon, 5 Nov 2012 21:14:50 +0000 (22:14 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Mon, 5 Nov 2012 21:14:50 +0000 (22:14 +0100)
--HG--
extra : transplant_source : 1%92%CA%A14x%08H%1D%3A%F3z%E7%E22%BF%CA%D2%1B%10

Cython/Compiler/ModuleNode.py
tests/run/initial_file_path.srctree

index 6778e2e..9b605fe 100644 (file)
@@ -2090,17 +2090,22 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 Naming.pymoduledef_cname))
         code.putln("#endif")
         code.putln(code.error_goto_if_null(env.module_cname, self.pos))
+
         # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
+        fq_module_name = env.qualified_name
+        if fq_module_name.endswith('.__init__'):
+            fq_module_name = fq_module_name[:-len('.__init__')]
         code.putln("#if PY_MAJOR_VERSION >= 3")
         code.putln("{")
         code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" %
                    code.error_goto_if_null("modules", self.pos))
-        code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % env.qualified_name)
+        code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name)
         code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % (
-            env.qualified_name, env.module_cname), self.pos))
+            fq_module_name, env.module_cname), self.pos))
         code.putln("}")
         code.putln("}")
         code.putln("#endif")
+
         code.putln(
             '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); %s' % (
                 Naming.builtins_cname,
index b319347..4f92756 100644 (file)
@@ -1,6 +1,8 @@
 PYTHON setup.py build_ext --inplace
-PYTHON -c "import my_test_package; assert not my_test_package.__file__.rstrip('co').endswith('.py'), my_test_package.__file__; my_test_package.test()"
-PYTHON -c "import my_test_package.a; my_test_package.a.test()"
+PYTHON -c "import my_test_package as p; assert not p.__file__.rstrip('co').endswith('.py'), p.__file__; m.test()"
+PYTHON -c "import my_test_package.a as a; a.test()"
+PYTHON -c "import my_test_package.another as p; assert not p.__file__.rstrip('co').endswith('.py'), p.__file__; p.test()"
+PYTHON -c "import my_test_package.another.a as a; a.test()"
 
 ######## setup.py ########
 
@@ -8,7 +10,7 @@ from Cython.Build.Dependencies import cythonize
 from distutils.core import setup
 
 setup(
-    ext_modules = cythonize("my_test_package/*.py"),
+    ext_modules = cythonize(["my_test_package/**/*.py"]),
 )
 
 ######## my_test_package/__init__.py ########
@@ -33,6 +35,28 @@ def test():
     assert initial_file.endswith('__init__.py'), initial_file
     assert import_error is None, import_error
 
+######## my_test_package/another/__init__.py ########
+
+# cython: set_initial_path=SOURCEFILE
+
+initial_path = __path__
+initial_file = __file__
+
+try:
+    from . import a
+    import_error = None
+except ImportError as e:
+    import_error = e
+    import traceback
+    traceback.print_exc()
+
+def test():
+    print "FILE: ", initial_file
+    print "PATH: ", initial_path
+    assert initial_path[0].endswith('another'), initial_path
+    assert initial_file.endswith('__init__.py'), initial_file
+    assert import_error is None, import_error
+
 ######## my_test_package/a.py ########
 
 # cython: set_initial_path=SOURCEFILE
@@ -49,3 +73,20 @@ else:
 def test():
     assert initial_file.endswith('a.py'), initial_file
     assert got_name_error, "looks like __path__ was set at module init time: " + initial_path
+
+######## my_test_package/another/a.py ########
+
+# cython: set_initial_path=SOURCEFILE
+
+initial_file = __file__
+
+try:
+    initial_path = __path__
+except NameError:
+    got_name_error = True
+else:
+    got_name_error = False
+
+def test():
+    assert initial_file.endswith('a.py'), initial_file
+    assert got_name_error, "looks like __path__ was set at module init time: " + initial_path