Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b6e2556

Browse files
committed
Issue #22834: Have import suppress FileNotFoundError when the current
working directory no longer exists. Thanks to Martin Panter for the bug report.
1 parent 8314690 commit b6e2556

7 files changed

Lines changed: 1042 additions & 1000 deletions

File tree

Doc/library/importlib.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,11 @@ find and load modules.
794794

795795
.. versionadded:: 3.4
796796

797+
.. versionchanged:: 3.5
798+
If the current working directory -- represented by an empty string --
799+
is no longer valid then ``None`` is returned but no value is cached
800+
in :data:`sys.path_importer_cache`.
801+
797802
.. classmethod:: find_module(fullname, path=None)
798803

799804
A legacy wrapper around :meth:`find_spec`.

Doc/reference/import.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,15 @@ hook` callables on :data:`sys.path_hooks`, then the following protocol is used
754754
to ask the finder for a module spec, which is then used when loading the
755755
module.
756756

757+
The current working directory -- denoted by an empty string -- is handled
758+
slightly differently from other entries on :data:`sys.path`. First, if the
759+
current working directory is found to not exist, no value is stored in
760+
:data:`sys.path_importer_cache`. Second, the value for the current working
761+
directory is looked up fresh for each module lookup. Third, the path used for
762+
:data:`sys.path_importer_cache` and returned by
763+
:meth:`importlib.machinery.PathFinder.find_spec` will be the actual current
764+
working directory and not the empty string.
765+
757766
Path entry finder protocol
758767
--------------------------
759768

Doc/whatsnew/3.5.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ Changes in the Python API
436436
bytes-like object is required, not 'sometype'". (Contributed by Ezio Melotti
437437
in :issue:`16518`.)
438438

439+
* If the current directory is set to a directory that no longer exists then
440+
:exc:`FileNotFoundError` will no longer be raised and instead
441+
:meth:`~importlib.machinery.FileFinder.find_spec` will return ``None``
442+
**without** caching ``None`` in :data:`sys.path_importer_cache` which is
443+
different than the typical case (:issue:`22834`).
444+
439445
Changes in the C API
440446
--------------------
441447

Lib/importlib/_bootstrap.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,12 @@ def _path_importer_cache(cls, path):
18251825
18261826
"""
18271827
if path == '':
1828-
path = _os.getcwd()
1828+
try:
1829+
path = _os.getcwd()
1830+
except FileNotFoundError:
1831+
# Don't cache the failure as the cwd can easily change to
1832+
# a valid directory later on.
1833+
return None
18291834
try:
18301835
finder = sys.path_importer_cache[path]
18311836
except KeyError:

Lib/test/test_importlib/import_/test_path.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import os
77
import sys
8+
import tempfile
89
from types import ModuleType
910
import unittest
1011
import warnings
@@ -158,6 +159,17 @@ def find_spec(self, fullname, target=None):
158159
got = self.machinery.PathFinder.find_spec('whatever', [path])
159160
self.assertEqual(got, success_finder.spec)
160161

162+
def test_deleted_cwd(self):
163+
# Issue #22834
164+
self.addCleanup(os.chdir, os.getcwd())
165+
with tempfile.TemporaryDirectory() as path:
166+
os.chdir(path)
167+
with util.import_state(path=['']):
168+
# Do not want FileNotFoundError raised.
169+
self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
170+
171+
172+
161173

162174
(Frozen_FinderTests,
163175
Source_FinderTests

Misc/NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Release date: TBA
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #22834: If the current working directory ends up being set to a
14+
non-existent directory then import will no longer raise FileNotFoundError.
15+
1316
- Issue #22869: Move the interpreter startup & shutdown code to a new
1417
dedicated pylifecycle.c module
1518

@@ -235,7 +238,7 @@ Library
235238

236239
- Issue #22776: Brought excluded code into the scope of a try block in
237240
SysLogHandler.emit().
238-
241+
239242
- Issue #22665: Add missing get_terminal_size and SameFileError to
240243
shutil.__all__.
241244

0 commit comments

Comments
 (0)