summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-02-08 23:52:56 (GMT)
committerBrett Cannon <brett@python.org>2012-02-08 23:52:56 (GMT)
commitb4e63b3177f50d519aeac2f59d38af4503b82d62 (patch)
treeb94d1946b9b4889ed9d679667afe0a0bc517e819
parent354c26ecd6d1f6341bb1f65ea099d6952a29abd8 (diff)
downloadcpython-b4e63b3177f50d519aeac2f59d38af4503b82d62.zip
cpython-b4e63b3177f50d519aeac2f59d38af4503b82d62.tar.gz
cpython-b4e63b3177f50d519aeac2f59d38af4503b82d62.tar.bz2
Use the cwd when the empty string is found in sys.path. This leads to
__file__ being an absolute path when the module is found in the current directory.
-rw-r--r--Lib/importlib/_bootstrap.py46
-rw-r--r--Lib/importlib/test/import_/test_path.py10
-rw-r--r--Misc/NEWS3
3 files changed, 58 insertions, 1 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index e5a9580..2569284 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -718,7 +718,7 @@ class PathFinder:
try:
finder = sys.path_importer_cache[path]
except KeyError:
- finder = cls._path_hooks(path)
+ finder = cls._path_hooks(path if path != '' else _os.getcwd())
sys.path_importer_cache[path] = finder
else:
if finder is None and default:
@@ -1039,3 +1039,47 @@ def _setup(sys_module, imp_module):
setattr(self_module, '_os', os_module)
setattr(self_module, 'path_sep', path_sep)
+
+
+def _setup(sys_module, imp_module):
+ """Setup importlib by importing needed built-in modules and injecting them
+ into the global namespace.
+
+ As sys is needed for sys.modules access and imp is needed to load built-in
+ modules those two modules must be explicitly passed in.
+
+ """
+ global imp, sys
+ imp = imp_module
+ sys = sys_module
+
+ for module in (imp, sys):
+ if not hasattr(module, '__loader__'):
+ module.__loader__ = BuiltinImporter
+
+ self_module = sys.modules[__name__]
+ for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'):
+ if builtin_name not in sys.modules:
+ builtin_module = BuiltinImporter.load_module(builtin_name)
+ else:
+ builtin_module = sys.modules[builtin_name]
+ setattr(self_module, builtin_name, builtin_module)
+
+ for builtin_os, path_sep in [('posix', '/'), ('nt', '\\'), ('os2', '\\')]:
+ if builtin_os in sys.modules:
+ os_module = sys.modules[builtin_os]
+ break
+ else:
+ try:
+ os_module = BuiltinImporter.load_module(builtin_os)
+ # TODO: rip out os2 code after 3.3 is released as per PEP 11
+ if builtin_os == 'os2' and 'EMX GCC' in sys.version:
+ path_sep = '/'
+ break
+ except ImportError:
+ continue
+ else:
+ raise ImportError('importlib requires posix or nt')
+ setattr(self_module, '_os', os_module)
+ setattr(self_module, 'path_sep', path_sep)
+
diff --git a/Lib/importlib/test/import_/test_path.py b/Lib/importlib/test/import_/test_path.py
index 2faa231..b28f25d 100644
--- a/Lib/importlib/test/import_/test_path.py
+++ b/Lib/importlib/test/import_/test_path.py
@@ -73,6 +73,16 @@ class FinderTests(unittest.TestCase):
loader = machinery.PathFinder.find_module(module)
self.assertTrue(loader is importer)
+ def test_path_importer_cache_empty_string(self):
+ # The empty string should create a finder using the cwd.
+ path = ''
+ module = '<test module>'
+ importer = util.mock_modules(module)
+ hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
+ with util.import_state(path=[path], path_hooks=[hook]):
+ loader = machinery.PathFinder.find_module(module)
+ self.assertIs(loader, importer)
+ self.assertIn('', sys.path_importer_cache)
class DefaultPathFinderTests(unittest.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 55940e5..6ec3df8 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -466,6 +466,9 @@ Core and Builtins
Library
-------
+- When '' is a path (e.g. in sys.path), make sure __file__ uses the current
+ working directory instead of ''.
+
- Issue #13609: Add two functions to query the terminal size:
os.get_terminal_size (low level) and shutil.get_terminal_size (high level).
Patch by Zbigniew Jędrzejewski-Szmek.