[Python-checkins] cpython: Issue #18416: Have importlib.machinery.PathFinder treat '' as the cwd

brett.cannon python-checkins at python.org
Fri Oct 18 17:39:44 CEST 2013


http://hg.python.org/cpython/rev/76184b5339f2
changeset:   86436:76184b5339f2
parent:      86433:9d96a3163dbf
user:        Brett Cannon <brett at python.org>
date:        Fri Oct 18 11:39:04 2013 -0400
summary:
  Issue #18416: Have importlib.machinery.PathFinder treat '' as the cwd
and stop importlib.machinery.FileFinder treating '' as '.'.

Previous PathFinder transformed '' into '.' which led to __file__ for
modules imported from the cwd to always be relative paths. This meant
the values of the attribute were wrong as soon as the cwd changed.
This change now means that as long as the site module is run (which
makes all entries in sys.path absolute) then all values for __file__
will also be absolute unless it's for __main__ when specified by file
path in a relative way (modules imported by runpy will have an
absolute path).

Now that PathFinder is no longer treating '' as '.' it only makes
sense for FileFinder to stop doing so as well. Now no transformation
is performed for the directory given to the __init__ method.

Thanks to Madison May for the initial patch.

files:
  Doc/library/importlib.rst                    |     7 +
  Doc/whatsnew/3.4.rst                         |    11 +
  Lib/importlib/_bootstrap.py                  |     4 +-
  Lib/test/test_importlib/import_/test_path.py |     4 +-
  Misc/NEWS                                    |     7 +
  Python/importlib.h                           |  6665 +++++----
  6 files changed, 3473 insertions(+), 3225 deletions(-)


diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -722,6 +722,10 @@
      Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all
      finders stored in :attr:`sys.path_importer_cache`.
 
+  .. versionchanged:: 3.4
+     Calls objects in :data:sys.path_hooks with the current working directory
+     for ``''`` (i.e. the empty string).
+
 
 .. class:: FileFinder(path, \*loader_details)
 
@@ -748,6 +752,9 @@
 
    .. versionadded:: 3.3
 
+   .. versionchange:: 3.4
+      The empty string is no longer special-cased to be changed into ``'.'``.
+
    .. attribute:: path
 
       The path the finder will search in.
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -675,3 +675,14 @@
   :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a
   string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`.
 
+* :cls:`importlib.machinery.PathFinder` now passes on the current working
+  directory to objects in :data:`sys.path_hooks` for the empty string. This
+  results in :data:`sys.path_importer_cache` never containing ``''``, thus
+  iterating through :data:`sys.path_importer_cache` based on :data:`sys.path`
+  will not find all keys. A module's ``__file__`` when imported in the current
+  working directory will also now have an absolute path, including when using
+  ``-m`` with the interpreter (this does not influence when the path to a file
+  is specified on the command-line).
+
+* :cls:`importlib.machinery.FileFinder` no longer special-cases the empty string
+  to be changed to ``'.'``.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -1302,7 +1302,7 @@
 
         """
         if path == '':
-            path = '.'
+            path = _os.getcwd()
         try:
             finder = sys.path_importer_cache[path]
         except KeyError:
@@ -1373,7 +1373,7 @@
             loaders.extend((suffix, loader) for suffix in suffixes)
         self._loaders = loaders
         # Base (directory) path
-        self.path = path or '.'
+        self.path = path
         self._path_mtime = -1
         self._path_cache = set()
         self._relaxed_path_cache = set()
diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -82,11 +82,11 @@
         path = ''
         module = '<test module>'
         importer = util.mock_modules(module)
-        hook = import_util.mock_path_hook(os.curdir, importer=importer)
+        hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
         with util.import_state(path=[path], path_hooks=[hook]):
             loader = machinery.PathFinder.find_module(module)
             self.assertIs(loader, importer)
-            self.assertIn(os.curdir, sys.path_importer_cache)
+            self.assertIn(os.getcwd(), sys.path_importer_cache)
 
     def test_None_on_sys_path(self):
         # Putting None in sys.path[0] caused an import regression from Python
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,13 @@
 Core and Builtins
 -----------------
 
+- Issue #18416: importlib.machinery.PathFinder now treats '' as the cwd and
+  importlib.machinery.FileFinder no longer special-cases '' to '.'. This leads
+  to modules imported from cwd to now possess an absolute file path for
+  __file__ (this does not affect modules specified by path on the CLI but it
+  does affect -m/runpy). It also allows FileFinder to be more consistent by not
+  having an edge case.
+
 - Issue #4555: All exported C symbols are now prefixed with either
   "Py" or "_Py".
 
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list