1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
from .. import util
importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery')
import os
import sys
import tempfile
from types import ModuleType
import unittest
import warnings
import zipimport
class FinderTests:
"""Tests for PathFinder."""
def test_failure(self):
# Test None returned upon not finding a suitable loader.
module = '<test module>'
with util.import_state():
self.assertIsNone(self.machinery.PathFinder.find_module(module))
def test_sys_path(self):
# Test that sys.path is used when 'path' is None.
# Implicitly tests that sys.path_importer_cache is used.
module = '<test module>'
path = '<test path>'
importer = util.mock_spec(module)
with util.import_state(path_importer_cache={path: importer},
path=[path]):
loader = self.machinery.PathFinder.find_module(module)
self.assertIs(loader, importer)
def test_path(self):
# Test that 'path' is used when set.
# Implicitly tests that sys.path_importer_cache is used.
module = '<test module>'
path = '<test path>'
importer = util.mock_spec(module)
with util.import_state(path_importer_cache={path: importer}):
loader = self.machinery.PathFinder.find_module(module, [path])
self.assertIs(loader, importer)
def test_empty_list(self):
# An empty list should not count as asking for sys.path.
module = 'module'
path = '<test path>'
importer = util.mock_spec(module)
with util.import_state(path_importer_cache={path: importer},
path=[path]):
self.assertIsNone(self.machinery.PathFinder.find_module('module', []))
def test_path_hooks(self):
# Test that sys.path_hooks is used.
# Test that sys.path_importer_cache is set.
module = '<test module>'
path = '<test path>'
importer = util.mock_spec(module)
hook = util.mock_path_hook(path, importer=importer)
with util.import_state(path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module, [path])
self.assertIs(loader, importer)
self.assertIn(path, sys.path_importer_cache)
self.assertIs(sys.path_importer_cache[path], importer)
def test_empty_path_hooks(self):
# Test that if sys.path_hooks is empty a warning is raised,
# sys.path_importer_cache gets None set, and PathFinder returns None.
path_entry = 'bogus_path'
with util.import_state(path_importer_cache={}, path_hooks=[],
path=[path_entry]):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
self.assertIsNone(self.machinery.PathFinder.find_module('os'))
self.assertIsNone(sys.path_importer_cache[path_entry])
self.assertEqual(len(w), 1)
self.assertTrue(issubclass(w[-1].category, ImportWarning))
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_spec(module)
hook = util.mock_path_hook(os.getcwd(), importer=importer)
with util.import_state(path=[path], path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module)
self.assertIs(loader, importer)
self.assertIn(os.getcwd(), sys.path_importer_cache)
def test_None_on_sys_path(self):
# Putting None in sys.path[0] caused an import regression from Python
# 3.2: http://bugs.python.org/issue16514
new_path = sys.path[:]
new_path.insert(0, None)
new_path_importer_cache = sys.path_importer_cache.copy()
new_path_importer_cache.pop(None, None)
new_path_hooks = [zipimport.zipimporter,
self.machinery.FileFinder.path_hook(
*self.importlib._bootstrap_external._get_supported_file_loaders())]
missing = object()
email = sys.modules.pop('email', missing)
try:
with util.import_state(meta_path=sys.meta_path[:],
path=new_path,
path_importer_cache=new_path_importer_cache,
path_hooks=new_path_hooks):
module = self.importlib.import_module('email')
self.assertIsInstance(module, ModuleType)
finally:
if email is not missing:
sys.modules['email'] = email
def test_finder_with_find_module(self):
class TestFinder:
def find_module(self, fullname):
return self.to_return
failing_finder = TestFinder()
failing_finder.to_return = None
path = 'testing path'
with util.import_state(path_importer_cache={path: failing_finder}):
self.assertIsNone(
self.machinery.PathFinder.find_spec('whatever', [path]))
success_finder = TestFinder()
success_finder.to_return = __loader__
with util.import_state(path_importer_cache={path: success_finder}):
spec = self.machinery.PathFinder.find_spec('whatever', [path])
self.assertEqual(spec.loader, __loader__)
def test_finder_with_find_loader(self):
class TestFinder:
loader = None
portions = []
def find_loader(self, fullname):
return self.loader, self.portions
path = 'testing path'
with util.import_state(path_importer_cache={path: TestFinder()}):
self.assertIsNone(
self.machinery.PathFinder.find_spec('whatever', [path]))
success_finder = TestFinder()
success_finder.loader = __loader__
with util.import_state(path_importer_cache={path: success_finder}):
spec = self.machinery.PathFinder.find_spec('whatever', [path])
self.assertEqual(spec.loader, __loader__)
def test_finder_with_find_spec(self):
class TestFinder:
spec = None
def find_spec(self, fullname, target=None):
return self.spec
path = 'testing path'
with util.import_state(path_importer_cache={path: TestFinder()}):
self.assertIsNone(
self.machinery.PathFinder.find_spec('whatever', [path]))
success_finder = TestFinder()
success_finder.spec = self.machinery.ModuleSpec('whatever', __loader__)
with util.import_state(path_importer_cache={path: success_finder}):
got = self.machinery.PathFinder.find_spec('whatever', [path])
self.assertEqual(got, success_finder.spec)
def test_deleted_cwd(self):
# Issue #22834
old_dir = os.getcwd()
self.addCleanup(os.chdir, old_dir)
new_dir = tempfile.mkdtemp()
try:
os.chdir(new_dir)
try:
os.rmdir(new_dir)
except OSError:
# EINVAL on Solaris, EBUSY on AIX, ENOTEMPTY on Windows
self.skipTest("platform does not allow "
"the deletion of the cwd")
except:
os.chdir(old_dir)
os.rmdir(new_dir)
raise
with util.import_state(path=['']):
# Do not want FileNotFoundError raised.
self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
(Frozen_FinderTests,
Source_FinderTests
) = util.test_both(FinderTests, importlib=importlib, machinery=machinery)
class PathEntryFinderTests:
def test_finder_with_failing_find_module(self):
# PathEntryFinder with find_module() defined should work.
# Issue #20763.
class Finder:
path_location = 'test_finder_with_find_module'
def __init__(self, path):
if path != self.path_location:
raise ImportError
@staticmethod
def find_module(fullname):
return None
with util.import_state(path=[Finder.path_location]+sys.path[:],
path_hooks=[Finder]):
self.machinery.PathFinder.find_spec('importlib')
(Frozen_PEFTests,
Source_PEFTests
) = util.test_both(PathEntryFinderTests, machinery=machinery)
if __name__ == '__main__':
unittest.main()
|