Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 10ebce0

Browse filesBrowse 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 7b47943 commit 10ebce0
Copy full SHA for 10ebce0

File tree

5 files changed

+39
-5
lines changed
Filter options

5 files changed

+39
-5
lines changed

‎Doc/reference/import.rst

Copy file name to clipboardExpand all lines: Doc/reference/import.rst
+4-4Lines 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

Copy file name to clipboardExpand all lines: Lib/importlib/_bootstrap_external.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ def _path_importer_cache(cls, path):
14931493
if path == '':
14941494
try:
14951495
path = _os.getcwd()
1496-
except FileNotFoundError:
1496+
except (FileNotFoundError, PermissionError):
14971497
# Don't cache the failure as the cwd can easily change to
14981498
# a valid directory later on.
14991499
return None

‎Lib/test/test_importlib/fixtures.py

Copy file name to clipboardExpand all lines: Lib/test/test_importlib/fixtures.py
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ def save_cwd():
4343
os.chdir(orig)
4444

4545

46+
@contextlib.contextmanager
47+
def save_mode(path, *, follow_symlinks=True):
48+
path = pathlib.Path(path)
49+
orig = path.stat(follow_symlinks=follow_symlinks)
50+
try:
51+
yield
52+
finally:
53+
path.chmod(orig.st_mode, follow_symlinks=follow_symlinks)
54+
55+
4656
@contextlib.contextmanager
4757
def tempdir_as_cwd():
4858
with tempdir() as tmp:

‎Lib/test/test_importlib/import_/test_path.py

Copy file name to clipboardExpand all lines: Lib/test/test_importlib/import_/test_path.py
+21Lines 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:
+3Lines 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.