[Python-checkins] cpython: Issue #22834: Have import suppress FileNotFoundError when the current

brett.cannon python-checkins at python.org
Fri Nov 21 18:19:38 CET 2014


https://hg.python.org/cpython/rev/8558fff73032
changeset:   93528:8558fff73032
parent:      93525:31fd106bb68a
user:        Brett Cannon <brett at python.org>
date:        Fri Nov 21 12:19:28 2014 -0500
summary:
  Issue #22834: Have import suppress FileNotFoundError when the current
working directory no longer exists.

Thanks to Martin Panter for the bug report.

files:
  Doc/library/importlib.rst                    |     5 +
  Doc/reference/import.rst                     |     9 +
  Doc/whatsnew/3.5.rst                         |     6 +
  Lib/importlib/_bootstrap.py                  |     7 +-
  Lib/test/test_importlib/import_/test_path.py |    12 +
  Misc/NEWS                                    |     5 +-
  Python/importlib.h                           |  2002 +++++----
  7 files changed, 1044 insertions(+), 1002 deletions(-)


diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -794,6 +794,11 @@
 
       .. versionadded:: 3.4
 
+      .. versionchanged:: 3.5
+         If the current working directory -- represented by an empty string --
+         is no longer valid then ``None`` is returned but no value is cached
+         in :data:`sys.path_importer_cache`.
+
    .. classmethod:: find_module(fullname, path=None)
 
       A legacy wrapper around :meth:`find_spec`.
diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst
--- a/Doc/reference/import.rst
+++ b/Doc/reference/import.rst
@@ -754,6 +754,15 @@
 to ask the finder for a module spec, which is then used when loading the
 module.
 
+The current working directory -- denoted by an empty string -- is handled
+slightly differently from other entries on :data:`sys.path`. First, if the
+current working directory is found to not exist, no value is stored in
+:data:`sys.path_importer_cache`. Second, the value for the current working
+directory is looked up fresh for each module lookup. Third, the path used for
+:data:`sys.path_importer_cache` and returned by
+:meth:`importlib.machinery.PathFinder.find_spec` will be the actual current
+working directory and not the empty string.
+
 Path entry finder protocol
 --------------------------
 
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -436,6 +436,12 @@
   bytes-like object is required, not 'sometype'".  (Contributed by Ezio Melotti
   in :issue:`16518`.)
 
+* If the current directory is set to a directory that no longer exists then
+  :exc:`FileNotFoundError` will no longer be raised and instead
+  :meth:`~importlib.machinery.FileFinder.find_spec` will return ``None``
+  **without** caching ``None`` in :data:`sys.path_importer_cache` which is
+  different than the typical case (:issue:`22834`).
+
 Changes in the C API
 --------------------
 
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -1825,7 +1825,12 @@
 
         """
         if path == '':
-            path = _os.getcwd()
+            try:
+                path = _os.getcwd()
+            except FileNotFoundError:
+                # Don't cache the failure as the cwd can easily change to
+                # a valid directory later on.
+                return None
         try:
             finder = sys.path_importer_cache[path]
         except KeyError:
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
@@ -5,6 +5,7 @@
 
 import os
 import sys
+import tempfile
 from types import ModuleType
 import unittest
 import warnings
@@ -158,6 +159,17 @@
             got = self.machinery.PathFinder.find_spec('whatever', [path])
         self.assertEqual(got, success_finder.spec)
 
+    def test_deleted_cwd(self):
+        # Issue #22834
+        self.addCleanup(os.chdir, os.getcwd())
+        with tempfile.TemporaryDirectory() as path:
+            os.chdir(path)
+        with util.import_state(path=['']):
+            # Do not want FileNotFoundError raised.
+            self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
+
+
+
 
 (Frozen_FinderTests,
  Source_FinderTests
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #22834: If the current working directory ends up being set to a
+  non-existent directory then import will no longer raise FileNotFoundError.
+
 - Issue #22869: Move the interpreter startup & shutdown code to a new
   dedicated pylifecycle.c module
 
@@ -235,7 +238,7 @@
 
 - Issue #22776: Brought excluded code into the scope of a try block in
   SysLogHandler.emit().
- 
+
 - Issue #22665: Add missing get_terminal_size and SameFileError to
   shutil.__all__.
 
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

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


More information about the Python-checkins mailing list