diff --git a/CHANGES.rst b/CHANGES.rst index a75607cf9044699f6af5f580c2ffa48fb29a93ab..e3d211fc41140a2a4f125148dd642bf5a9252c13 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -96,6 +96,9 @@ Bugs fixed * C unions use a saner way to coerce from and to Python dicts. +* When compiling a module ``foo.pyx``, the directories in ``sys.path`` + are no longer searched when looking for ``foo.pxd``. + Other changes ------------- diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index 27963f210bd0d5823ec347bdb55021b827fefbbb..5f1a3e9b7e4feb850037b540f3e9c759ba3dd559 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -187,20 +187,25 @@ class Context(object): if not scope.pxd_file_loaded: if debug_find_module: print("...pxd not loaded") - scope.pxd_file_loaded = 1 if not pxd_pathname: if debug_find_module: print("...looking for pxd file") - pxd_pathname = self.find_pxd_file(qualified_name, pos) + # Only look in sys.path if we are explicitly looking + # for a .pxd file. + pxd_pathname = self.find_pxd_file(qualified_name, pos, sys_path=need_pxd) if debug_find_module: print("......found %s" % pxd_pathname) if not pxd_pathname and need_pxd: + # Set pxd_file_loaded such that we don't need to + # look for the non-existing pxd file next time. + scope.pxd_file_loaded = True package_pathname = self.search_include_directories(qualified_name, ".py", pos) if package_pathname and package_pathname.endswith('__init__.py'): pass else: error(pos, "'%s.pxd' not found" % qualified_name.replace('.', os.sep)) if pxd_pathname: + scope.pxd_file_loaded = True try: if debug_find_module: print("Context.find_module: Parsing %s" % pxd_pathname) @@ -217,15 +222,16 @@ class Context(object): pass return scope - def find_pxd_file(self, qualified_name, pos): - # Search include path for the .pxd file corresponding to the - # given fully-qualified module name. + def find_pxd_file(self, qualified_name, pos, sys_path=True): + # Search include path (and sys.path if sys_path is True) for + # the .pxd file corresponding to the given fully-qualified + # module name. # Will find either a dotted filename or a file in a # package directory. If a source file position is given, # the directory containing the source file is searched first # for a dotted filename, and its containing package root # directory is searched first for a non-dotted filename. - pxd = self.search_include_directories(qualified_name, ".pxd", pos, sys_path=True) + pxd = self.search_include_directories(qualified_name, ".pxd", pos, sys_path=sys_path) if pxd is None: # XXX Keep this until Includes/Deprecated is removed if (qualified_name.startswith('python') or qualified_name in ('stdlib', 'stdio', 'stl')): diff --git a/docs/src/userguide/sharing_declarations.rst b/docs/src/userguide/sharing_declarations.rst index f30234de6abcb699fbdfa91c273c0c8506400e92..838d8134ba511529aa6aa7a41bbc33d5746da2c4 100644 --- a/docs/src/userguide/sharing_declarations.rst +++ b/docs/src/userguide/sharing_declarations.rst @@ -123,12 +123,15 @@ Search paths for definition files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you :keyword:`cimport` a module called ``modulename``, the Cython -compiler searches for a file called :file:`modulename.pxd` along the search -path for include files, as specified by ``-I`` command line options. +compiler searches for a file called :file:`modulename.pxd`. +It searches for this file along the path for include files +(as specified by ``-I`` command line options or the ``include_path`` +option to ``cythonize()``), as well as ``sys.path``. Also, whenever you compile a file :file:`modulename.pyx`, the corresponding -definition file :file:`modulename.pxd` is first searched for along the same -path, and if found, it is processed before processing the ``.pyx`` file. +definition file :file:`modulename.pxd` is first searched for along the +include path (but not ``sys.path``), and if found, it is processed before +processing the ``.pyx`` file. Using cimport to resolve naming conflicts diff --git a/tests/compile/find_pxd.srctree b/tests/compile/find_pxd.srctree new file mode 100644 index 0000000000000000000000000000000000000000..1d7885fe88128787fb550360680c2250a521beb0 --- /dev/null +++ b/tests/compile/find_pxd.srctree @@ -0,0 +1,39 @@ +PYTHON setup.py build_ext --inplace + +######## setup.py ######## + +from Cython.Build import cythonize +from Cython.Distutils.extension import Extension + +import sys +sys.path.append("path") + +ext_modules = [ + Extension("a", ["a.pyx"]), + Extension("b", ["b.pyx"]), + Extension("c", ["c.pyx"]), +] + +ext_modules = cythonize(ext_modules, include_path=["include"]) + + +######## a.pyx ######## +# Implicit cimport looking in include_path +cdef my_type foo + +######## include/a.pxd ######## +ctypedef int my_type + +######## b.pyx ######## +# Explicit cimport looking in sys.path +from b cimport * +cdef my_type foo + +######## path/b.pxd ######## +ctypedef int my_type + +######## c.pyx ######## +# Implicit cimport NOT looking in sys.path + +######## path/c.pxd ######## ++++syntax error just to show that this file is not actually cimported+++