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

Skip to content

Commit 27e27f7

Browse files
committed
Issue #18416: Have importlib.machinery.PathFinder treat '' as the cwd
and stop importlib.machinery.FileFinder treating '' as '.'. Previous PathFinder transformed '' into '.' which led to __file__ for modules imported from the cwd to always be relative paths. This meant the values of the attribute were wrong as soon as the cwd changed. This change now means that as long as the site module is run (which makes all entries in sys.path absolute) then all values for __file__ will also be absolute unless it's for __main__ when specified by file path in a relative way (modules imported by runpy will have an absolute path). Now that PathFinder is no longer treating '' as '.' it only makes sense for FileFinder to stop doing so as well. Now no transformation is performed for the directory given to the __init__ method. Thanks to Madison May for the initial patch.
1 parent 40b22d0 commit 27e27f7

6 files changed

Lines changed: 3471 additions & 3223 deletions

File tree

Doc/library/importlib.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,10 @@ find and load modules.
722722
Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all
723723
finders stored in :attr:`sys.path_importer_cache`.
724724

725+
.. versionchanged:: 3.4
726+
Calls objects in :data:sys.path_hooks with the current working directory
727+
for ``''`` (i.e. the empty string).
728+
725729

726730
.. class:: FileFinder(path, \*loader_details)
727731

@@ -748,6 +752,9 @@ find and load modules.
748752

749753
.. versionadded:: 3.3
750754

755+
.. versionchange:: 3.4
756+
The empty string is no longer special-cased to be changed into ``'.'``.
757+
751758
.. attribute:: path
752759

753760
The path the finder will search in.

Doc/whatsnew/3.4.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,14 @@ that may require changes to your code.
675675
:c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a
676676
string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`.
677677

678+
* :cls:`importlib.machinery.PathFinder` now passes on the current working
679+
directory to objects in :data:`sys.path_hooks` for the empty string. This
680+
results in :data:`sys.path_importer_cache` never containing ``''``, thus
681+
iterating through :data:`sys.path_importer_cache` based on :data:`sys.path`
682+
will not find all keys. A module's ``__file__`` when imported in the current
683+
working directory will also now have an absolute path, including when using
684+
``-m`` with the interpreter (this does not influence when the path to a file
685+
is specified on the command-line).
686+
687+
* :cls:`importlib.machinery.FileFinder` no longer special-cases the empty string
688+
to be changed to ``'.'``.

Lib/importlib/_bootstrap.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ def _path_importer_cache(cls, path):
13021302
13031303
"""
13041304
if path == '':
1305-
path = '.'
1305+
path = _os.getcwd()
13061306
try:
13071307
finder = sys.path_importer_cache[path]
13081308
except KeyError:
@@ -1373,7 +1373,7 @@ def __init__(self, path, *loader_details):
13731373
loaders.extend((suffix, loader) for suffix in suffixes)
13741374
self._loaders = loaders
13751375
# Base (directory) path
1376-
self.path = path or '.'
1376+
self.path = path
13771377
self._path_mtime = -1
13781378
self._path_cache = set()
13791379
self._relaxed_path_cache = set()

Lib/test/test_importlib/import_/test_path.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ def test_path_importer_cache_empty_string(self):
8282
path = ''
8383
module = '<test module>'
8484
importer = util.mock_modules(module)
85-
hook = import_util.mock_path_hook(os.curdir, importer=importer)
85+
hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
8686
with util.import_state(path=[path], path_hooks=[hook]):
8787
loader = machinery.PathFinder.find_module(module)
8888
self.assertIs(loader, importer)
89-
self.assertIn(os.curdir, sys.path_importer_cache)
89+
self.assertIn(os.getcwd(), sys.path_importer_cache)
9090

9191
def test_None_on_sys_path(self):
9292
# Putting None in sys.path[0] caused an import regression from Python

Misc/NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ Projected release date: 2013-10-20
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #18416: importlib.machinery.PathFinder now treats '' as the cwd and
14+
importlib.machinery.FileFinder no longer special-cases '' to '.'. This leads
15+
to modules imported from cwd to now possess an absolute file path for
16+
__file__ (this does not affect modules specified by path on the CLI but it
17+
does affect -m/runpy). It also allows FileFinder to be more consistent by not
18+
having an edge case.
19+
1320
- Issue #4555: All exported C symbols are now prefixed with either
1421
"Py" or "_Py".
1522

0 commit comments

Comments
 (0)