Issue #22834: Have import suppress FileNotFoundError when the current
working directory no longer exists. Thanks to Martin Panter for the bug report.
This commit is contained in:
parent
8314690a26
commit
b6e2556d8f
|
@ -794,6 +794,11 @@ find and load modules.
|
|||
|
||||
.. 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`.
|
||||
|
|
|
@ -754,6 +754,15 @@ hook` callables on :data:`sys.path_hooks`, then the following protocol is used
|
|||
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
|
||||
--------------------------
|
||||
|
||||
|
|
|
@ -436,6 +436,12 @@ Changes in the Python API
|
|||
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
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -1825,7 +1825,12 @@ class PathFinder:
|
|||
|
||||
"""
|
||||
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:
|
||||
|
|
|
@ -5,6 +5,7 @@ machinery = util.import_importlib('importlib.machinery')
|
|||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from types import ModuleType
|
||||
import unittest
|
||||
import warnings
|
||||
|
@ -158,6 +159,17 @@ class FinderTests:
|
|||
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
|
||||
|
|
|
@ -10,6 +10,9 @@ Release date: TBA
|
|||
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 @@ Library
|
|||
|
||||
- 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__.
|
||||
|
||||
|
|
2000
Python/importlib.h
2000
Python/importlib.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue