10000 Ignore PermissionError during import from cwd · python/cpython@f2f5e1c · GitHub
[go: up one dir, main page]

Skip to content

Commit f2f5e1c

Browse files
committed
Ignore PermissionError during import from cwd
On macOS `getcwd(3)` can return EACCES if a path component isn't readable, resulting in PermissionError. `PathFinder.find_spec()` now catches these and ignores them - the same treatment as a missing/deleted cwd.
1 parent 9c15202 commit f2f5e1c

File tree

5 files changed

+39
-5
lines changed
  • Doc/reference
  • Lib
  • Misc/NEWS.d/next/Core and Builtins
  • 5 files changed

    +39
    -5
    lines changed

    Doc/reference/import.rst

    Lines changed: 4 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -871,10 +871,10 @@ module.
    871871

    872872
    The current working directory -- denoted by an empty string -- is handled
    873873
    slightly differently from other entries on :data:`sys.path`. First, if the
    874-
    current working directory is found to not exist, no value is stored in
    875-
    :data:`sys.path_importer_cache`. Second, the value for the current working
    876-
    directory is looked up fresh for each module lookup. Third, the path used for
    877-
    :data:`sys.path_importer_cache` and returned by
    874+
    current working directory cannot be determined or is found to not exist, no
    875+
    value is stored in :data:`sys.path_importer_cache`. Second, the value for the
    876+
    current working directory is looked up fresh for each module lookup. Third,
    877+
    the path used for :data:`sys.path_importer_cache` and returned by
    878878
    :meth:`importlib.machinery.PathFinder.find_spec` will be the actual current
    879879
    working directory and not the empty string.
    880880

    Lib/importlib/_bootstrap_external.py

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -1503,7 +1503,7 @@ def _path_importer_cache(cls, path):
    15031503
    if path == '':
    15041504
    try:
    15051505
    path = _os.getcwd()
    1506-
    except FileNotFoundError:
    1506+
    except (FileNotFoundError, PermissionError):
    15071507
    # Don't cache the failure as the cwd can easily change to
    15081508
    # a valid directory later on.
    15091509
    return None

    Lib/test/test_importlib/import_/test_path.py

    Lines changed: 21 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,3 +1,5 @@
    1+
    from test.support import os_helper
    2+
    from test.test_importlib import fixtures
    13
    from test.test_importlib import util
    24

    35
    importlib = util.import_importlib('importlib')
    @@ -153,6 +155,25 @@ def test_deleted_cwd(self):
    153155
    # Do not want FileNotFoundError raised.
    154156
    self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
    155157

    158+
    @os_helper.skip_unless_working_chmod
    159+
    def test_permission_error_cwd(self):
    160+
    # gh-115911
    161+
    with (
    162+
    fixtures.tempdir() as new_dir,
    163+
    fixtures.save_mode(new_dir),
    164+
    fixtures.save_cwd(),
    165+
    util.import_state(path=['']),
    166+
    ):
    167+
    os.chdir(new_dir)
    168+
    try:
    169+
    os.chmod(new_dir, 0o000)
    170+
    except OSError:
    171+
    self.skipTest("platform does not allow "
    172+
    "changing mode of the cwd")
    173+
    174+
    # Do not want PermissionError raised.
    175+
    self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
    176+
    156177
    def test_invalidate_caches_finders(self):
    157178
    # Finders with an invalidate_caches() method have it called.
    158179
    class FakeFinder:

    Lib/test/test_importlib/metadata/fixtures.py

    Lines changed: 10 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -44,6 +44,16 @@ def save_cwd():
    4444
    os.chdir(orig)
    4545

    4646

    47+
    @contextlib.contextmanager
    48+
    def save_mode(path, *, follow_symlinks=True):
    49+
    path = pathlib.Path(path)
    50+
    orig = path.stat(follow_symlinks=follow_symlinks)
    51+
    try:
    52+
    yield
    53+
    finally:
    54+
    path.chmod(orig.st_mode, follow_symlinks=follow_symlinks)
    55+
    56+
    4757
    @contextlib.contextmanager
    4858
    def tempdir_as_cwd():
    4959
    with tempdir() as tmp:
    Lines changed: 3 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,3 @@
    1+
    If the current working directory cannot be determined due to permissions,
    2+
    then import will no longer raise :exc:`PermissionError`. Patch by Alex
    3+
    Willmer.

    0 commit comments

    Comments
     (0)
    0