summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_importlib
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2021-07-30 01:05:05 (GMT)
committerGitHub <noreply@github.com>2021-07-30 01:05:05 (GMT)
commitaaa83cdfab6817446285e631232f64b394ac6791 (patch)
treed41195f1412a533b1c7333b99adcc77f171329a1 /Lib/test/test_importlib
parent851cca8c22795a2f143ad5ebc10adab3c7784ad0 (diff)
downloadcpython-aaa83cdfab6817446285e631232f64b394ac6791.zip
cpython-aaa83cdfab6817446285e631232f64b394ac6791.tar.gz
cpython-aaa83cdfab6817446285e631232f64b394ac6791.tar.bz2
bpo-44771: Apply changes from importlib_resources 5.2.1 (GH-27436)
* bpo-44771: Apply changes from importlib_resources@3b24bd6307 * Add blurb * Exclude namespacedata01 from eol conversion.
Diffstat (limited to 'Lib/test/test_importlib')
-rw-r--r--Lib/test/test_importlib/resources/__init__.py0
-rw-r--r--Lib/test/test_importlib/resources/util.py190
-rw-r--r--Lib/test/test_importlib/test_compatibilty_files.py102
-rw-r--r--Lib/test/test_importlib/test_contents.py42
-rw-r--r--Lib/test/test_importlib/test_files.py9
-rw-r--r--Lib/test/test_importlib/test_open.py6
-rw-r--r--Lib/test/test_importlib/test_path.py4
-rw-r--r--Lib/test/test_importlib/test_read.py13
-rw-r--r--Lib/test/test_importlib/test_resource.py12
-rw-r--r--Lib/test/test_importlib/util.py172
10 files changed, 363 insertions, 187 deletions
diff --git a/Lib/test/test_importlib/resources/__init__.py b/Lib/test/test_importlib/resources/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Lib/test/test_importlib/resources/__init__.py
diff --git a/Lib/test/test_importlib/resources/util.py b/Lib/test/test_importlib/resources/util.py
new file mode 100644
index 0000000..d7a049b
--- /dev/null
+++ b/Lib/test/test_importlib/resources/util.py
@@ -0,0 +1,190 @@
+import abc
+import importlib
+import io
+import sys
+import types
+from pathlib import Path, PurePath
+
+from .. import data01
+from .. import zipdata01
+from importlib.abc import ResourceReader
+from test.support import import_helper
+
+
+from importlib.machinery import ModuleSpec
+
+
+class Reader(ResourceReader):
+ def __init__(self, **kwargs):
+ vars(self).update(kwargs)
+
+ def get_resource_reader(self, package):
+ return self
+
+ def open_resource(self, path):
+ self._path = path
+ if isinstance(self.file, Exception):
+ raise self.file
+ return self.file
+
+ def resource_path(self, path_):
+ self._path = path_
+ if isinstance(self.path, Exception):
+ raise self.path
+ return self.path
+
+ def is_resource(self, path_):
+ self._path = path_
+ if isinstance(self.path, Exception):
+ raise self.path
+
+ def part(entry):
+ return entry.split('/')
+
+ return any(
+ len(parts) == 1 and parts[0] == path_ for parts in map(part, self._contents)
+ )
+
+ def contents(self):
+ if isinstance(self.path, Exception):
+ raise self.path
+ yield from self._contents
+
+
+def create_package_from_loader(loader, is_package=True):
+ name = 'testingpackage'
+ module = types.ModuleType(name)
+ spec = ModuleSpec(name, loader, origin='does-not-exist', is_package=is_package)
+ module.__spec__ = spec
+ module.__loader__ = loader
+ return module
+
+
+def create_package(file=None, path=None, is_package=True, contents=()):
+ return create_package_from_loader(
+ Reader(file=file, path=path, _contents=contents),
+ is_package,
+ )
+
+
+class CommonTests(metaclass=abc.ABCMeta):
+ """
+ Tests shared by test_open, test_path, and test_read.
+ """
+
+ @abc.abstractmethod
+ def execute(self, package, path):
+ """
+ Call the pertinent legacy API function (e.g. open_text, path)
+ on package and path.
+ """
+
+ def test_package_name(self):
+ # Passing in the package name should succeed.
+ self.execute(data01.__name__, 'utf-8.file')
+
+ def test_package_object(self):
+ # Passing in the package itself should succeed.
+ self.execute(data01, 'utf-8.file')
+
+ def test_string_path(self):
+ # Passing in a string for the path should succeed.
+ path = 'utf-8.file'
+ self.execute(data01, path)
+
+ def test_pathlib_path(self):
+ # Passing in a pathlib.PurePath object for the path should succeed.
+ path = PurePath('utf-8.file')
+ self.execute(data01, path)
+
+ def test_absolute_path(self):
+ # An absolute path is a ValueError.
+ path = Path(__file__)
+ full_path = path.parent / 'utf-8.file'
+ with self.assertRaises(ValueError):
+ self.execute(data01, full_path)
+
+ def test_relative_path(self):
+ # A reative path is a ValueError.
+ with self.assertRaises(ValueError):
+ self.execute(data01, '../data01/utf-8.file')
+
+ def test_importing_module_as_side_effect(self):
+ # The anchor package can already be imported.
+ del sys.modules[data01.__name__]
+ self.execute(data01.__name__, 'utf-8.file')
+
+ def test_non_package_by_name(self):
+ # The anchor package cannot be a module.
+ with self.assertRaises(TypeError):
+ self.execute(__name__, 'utf-8.file')
+
+ def test_non_package_by_package(self):
+ # The anchor package cannot be a module.
+ with self.assertRaises(TypeError):
+ module = sys.modules['test.test_importlib.resources.util']
+ self.execute(module, 'utf-8.file')
+
+ def test_missing_path(self):
+ # Attempting to open or read or request the path for a
+ # non-existent path should succeed if open_resource
+ # can return a viable data stream.
+ bytes_data = io.BytesIO(b'Hello, world!')
+ package = create_package(file=bytes_data, path=FileNotFoundError())
+ self.execute(package, 'utf-8.file')
+ self.assertEqual(package.__loader__._path, 'utf-8.file')
+
+ def test_extant_path(self):
+ # Attempting to open or read or request the path when the
+ # path does exist should still succeed. Does not assert
+ # anything about the result.
+ bytes_data = io.BytesIO(b'Hello, world!')
+ # any path that exists
+ path = __file__
+ package = create_package(file=bytes_data, path=path)
+ self.execute(package, 'utf-8.file')
+ self.assertEqual(package.__loader__._path, 'utf-8.file')
+
+ def test_useless_loader(self):
+ package = create_package(file=FileNotFoundError(), path=FileNotFoundError())
+ with self.assertRaises(FileNotFoundError):
+ self.execute(package, 'utf-8.file')
+
+
+class ZipSetupBase:
+ ZIP_MODULE = None
+
+ @classmethod
+ def setUpClass(cls):
+ data_path = Path(cls.ZIP_MODULE.__file__)
+ data_dir = data_path.parent
+ cls._zip_path = str(data_dir / 'ziptestdata.zip')
+ sys.path.append(cls._zip_path)
+ cls.data = importlib.import_module('ziptestdata')
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ sys.path.remove(cls._zip_path)
+ except ValueError:
+ pass
+
+ try:
+ del sys.path_importer_cache[cls._zip_path]
+ del sys.modules[cls.data.__name__]
+ except KeyError:
+ pass
+
+ try:
+ del cls.data
+ del cls._zip_path
+ except AttributeError:
+ pass
+
+ def setUp(self):
+ modules = import_helper.modules_setup()
+ self.addCleanup(import_helper.modules_cleanup, *modules)
+
+
+class ZipSetup(ZipSetupBase):
+ ZIP_MODULE = zipdata01 # type: ignore
diff --git a/Lib/test/test_importlib/test_compatibilty_files.py b/Lib/test/test_importlib/test_compatibilty_files.py
new file mode 100644
index 0000000..d703c06
--- /dev/null
+++ b/Lib/test/test_importlib/test_compatibilty_files.py
@@ -0,0 +1,102 @@
+import io
+import unittest
+
+from importlib import resources
+
+from importlib._adapters import (
+ CompatibilityFiles,
+ wrap_spec,
+)
+
+from .resources import util
+
+
+class CompatibilityFilesTests(unittest.TestCase):
+ @property
+ def package(self):
+ bytes_data = io.BytesIO(b'Hello, world!')
+ return util.create_package(
+ file=bytes_data,
+ path='some_path',
+ contents=('a', 'b', 'c'),
+ )
+
+ @property
+ def files(self):
+ return resources.files(self.package)
+
+ def test_spec_path_iter(self):
+ self.assertEqual(
+ sorted(path.name for path in self.files.iterdir()),
+ ['a', 'b', 'c'],
+ )
+
+ def test_child_path_iter(self):
+ self.assertEqual(list((self.files / 'a').iterdir()), [])
+
+ def test_orphan_path_iter(self):
+ self.assertEqual(list((self.files / 'a' / 'a').iterdir()), [])
+ self.assertEqual(list((self.files / 'a' / 'a' / 'a').iterdir()), [])
+
+ def test_spec_path_is(self):
+ self.assertFalse(self.files.is_file())
+ self.assertFalse(self.files.is_dir())
+
+ def test_child_path_is(self):
+ self.assertTrue((self.files / 'a').is_file())
+ self.assertFalse((self.files / 'a').is_dir())
+
+ def test_orphan_path_is(self):
+ self.assertFalse((self.files / 'a' / 'a').is_file())
+ self.assertFalse((self.files / 'a' / 'a').is_dir())
+ self.assertFalse((self.files / 'a' / 'a' / 'a').is_file())
+ self.assertFalse((self.files / 'a' / 'a' / 'a').is_dir())
+
+ def test_spec_path_name(self):
+ self.assertEqual(self.files.name, 'testingpackage')
+
+ def test_child_path_name(self):
+ self.assertEqual((self.files / 'a').name, 'a')
+
+ def test_orphan_path_name(self):
+ self.assertEqual((self.files / 'a' / 'b').name, 'b')
+ self.assertEqual((self.files / 'a' / 'b' / 'c').name, 'c')
+
+ def test_spec_path_open(self):
+ self.assertEqual(self.files.read_bytes(), b'Hello, world!')
+ self.assertEqual(self.files.read_text(), 'Hello, world!')
+
+ def test_child_path_open(self):
+ self.assertEqual((self.files / 'a').read_bytes(), b'Hello, world!')
+ self.assertEqual((self.files / 'a').read_text(), 'Hello, world!')
+
+ def test_orphan_path_open(self):
+ with self.assertRaises(FileNotFoundError):
+ (self.files / 'a' / 'b').read_bytes()
+ with self.assertRaises(FileNotFoundError):
+ (self.files / 'a' / 'b' / 'c').read_bytes()
+
+ def test_open_invalid_mode(self):
+ with self.assertRaises(ValueError):
+ self.files.open('0')
+
+ def test_orphan_path_invalid(self):
+ with self.assertRaises(ValueError):
+ CompatibilityFiles.OrphanPath()
+
+ def test_wrap_spec(self):
+ spec = wrap_spec(self.package)
+ self.assertIsInstance(spec.loader.get_resource_reader(None), CompatibilityFiles)
+
+
+class CompatibilityFilesNoReaderTests(unittest.TestCase):
+ @property
+ def package(self):
+ return util.create_package_from_loader(None)
+
+ @property
+ def files(self):
+ return resources.files(self.package)
+
+ def test_spec_path_joinpath(self):
+ self.assertIsInstance(self.files / 'a', CompatibilityFiles.OrphanPath)
diff --git a/Lib/test/test_importlib/test_contents.py b/Lib/test/test_importlib/test_contents.py
new file mode 100644
index 0000000..0f3aa84
--- /dev/null
+++ b/Lib/test/test_importlib/test_contents.py
@@ -0,0 +1,42 @@
+import unittest
+from importlib import resources
+
+from . import data01
+from .resources import util
+
+
+class ContentsTests:
+ expected = {
+ '__init__.py',
+ 'binary.file',
+ 'subdirectory',
+ 'utf-16.file',
+ 'utf-8.file',
+ }
+
+ def test_contents(self):
+ assert self.expected <= set(resources.contents(self.data))
+
+
+class ContentsDiskTests(ContentsTests, unittest.TestCase):
+ def setUp(self):
+ self.data = data01
+
+
+class ContentsZipTests(ContentsTests, util.ZipSetup, unittest.TestCase):
+ pass
+
+
+class ContentsNamespaceTests(ContentsTests, unittest.TestCase):
+ expected = {
+ # no __init__ because of namespace design
+ # no subdirectory as incidental difference in fixture
+ 'binary.file',
+ 'utf-16.file',
+ 'utf-8.file',
+ }
+
+ def setUp(self):
+ from . import namespacedata01
+
+ self.data = namespacedata01
diff --git a/Lib/test/test_importlib/test_files.py b/Lib/test/test_importlib/test_files.py
index 481829b..b9170d8 100644
--- a/Lib/test/test_importlib/test_files.py
+++ b/Lib/test/test_importlib/test_files.py
@@ -4,7 +4,7 @@ import unittest
from importlib import resources
from importlib.abc import Traversable
from . import data01
-from . import util
+from .resources import util
class FilesTests:
@@ -35,5 +35,12 @@ class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
pass
+class OpenNamespaceTests(FilesTests, unittest.TestCase):
+ def setUp(self):
+ from . import namespacedata01
+
+ self.data = namespacedata01
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_importlib/test_open.py b/Lib/test/test_importlib/test_open.py
index b75675f..6f88ff7 100644
--- a/Lib/test/test_importlib/test_open.py
+++ b/Lib/test/test_importlib/test_open.py
@@ -2,16 +2,16 @@ import unittest
from importlib import resources
from . import data01
-from . import util
+from .resources import util
-class CommonBinaryTests(util.CommonResourceTests, unittest.TestCase):
+class CommonBinaryTests(util.CommonTests, unittest.TestCase):
def execute(self, package, path):
with resources.open_binary(package, path):
pass
-class CommonTextTests(util.CommonResourceTests, unittest.TestCase):
+class CommonTextTests(util.CommonTests, unittest.TestCase):
def execute(self, package, path):
with resources.open_text(package, path):
pass
diff --git a/Lib/test/test_importlib/test_path.py b/Lib/test/test_importlib/test_path.py
index d6ed09a..4436d7f 100644
--- a/Lib/test/test_importlib/test_path.py
+++ b/Lib/test/test_importlib/test_path.py
@@ -3,10 +3,10 @@ import unittest
from importlib import resources
from . import data01
-from . import util
+from .resources import util
-class CommonTests(util.CommonResourceTests, unittest.TestCase):
+class CommonTests(util.CommonTests, unittest.TestCase):
def execute(self, package, path):
with resources.path(package, path):
pass
diff --git a/Lib/test/test_importlib/test_read.py b/Lib/test/test_importlib/test_read.py
index f6ec13a..3579801 100644
--- a/Lib/test/test_importlib/test_read.py
+++ b/Lib/test/test_importlib/test_read.py
@@ -2,15 +2,15 @@ import unittest
from importlib import import_module, resources
from . import data01
-from . import util
+from .resources import util
-class CommonBinaryTests(util.CommonResourceTests, unittest.TestCase):
+class CommonBinaryTests(util.CommonTests, unittest.TestCase):
def execute(self, package, path):
resources.read_binary(package, path)
-class CommonTextTests(util.CommonResourceTests, unittest.TestCase):
+class CommonTextTests(util.CommonTests, unittest.TestCase):
def execute(self, package, path):
resources.read_text(package, path)
@@ -55,5 +55,12 @@ class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
self.assertEqual(result, b'\0\1\2\3')
+class ReadNamespaceTests(ReadTests, unittest.TestCase):
+ def setUp(self):
+ from . import namespacedata01
+
+ self.data = namespacedata01
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_importlib/test_resource.py b/Lib/test/test_importlib/test_resource.py
index 003f7e9..612bada 100644
--- a/Lib/test/test_importlib/test_resource.py
+++ b/Lib/test/test_importlib/test_resource.py
@@ -5,7 +5,7 @@ import pathlib
from . import data01
from . import zipdata01, zipdata02
-from . import util
+from .resources import util
from importlib import resources, import_module
from test.support import import_helper
from test.support.os_helper import unlink
@@ -33,14 +33,14 @@ class ResourceTests:
# are not germane to this test, so just filter them out.
contents.discard('__pycache__')
self.assertEqual(
- contents,
- {
+ sorted(contents),
+ [
'__init__.py',
- 'subdirectory',
- 'utf-8.file',
'binary.file',
+ 'subdirectory',
'utf-16.file',
- },
+ 'utf-8.file',
+ ],
)
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
index ca0d8c9..c07ac2a 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -1,17 +1,11 @@
-import abc
import builtins
import contextlib
import errno
import functools
-import importlib
from importlib import machinery, util, invalidate_caches
-from importlib.abc import ResourceReader
-import io
import marshal
import os
import os.path
-from pathlib import Path, PurePath
-from test import support
from test.support import import_helper
from test.support import os_helper
import unittest
@@ -19,9 +13,6 @@ import sys
import tempfile
import types
-from . import data01
-from . import zipdata01
-
BUILTINS = types.SimpleNamespace()
BUILTINS.good_name = None
@@ -417,166 +408,3 @@ class CASEOKTestBase:
if any(x in self.importlib._bootstrap_external._os.environ
for x in possibilities) != should_exist:
self.skipTest('os.environ changes not reflected in _os.environ')
-
-
-def create_package(file, path, is_package=True, contents=()):
- class Reader(ResourceReader):
- def get_resource_reader(self, package):
- return self
-
- def open_resource(self, path):
- self._path = path
- if isinstance(file, Exception):
- raise file
- else:
- return file
-
- def resource_path(self, path_):
- self._path = path_
- if isinstance(path, Exception):
- raise path
- else:
- return path
-
- def is_resource(self, path_):
- self._path = path_
- if isinstance(path, Exception):
- raise path
- for entry in contents:
- parts = entry.split('/')
- if len(parts) == 1 and parts[0] == path_:
- return True
- return False
-
- def contents(self):
- if isinstance(path, Exception):
- raise path
- # There's no yield from in baseball, er, Python 2.
- for entry in contents:
- yield entry
-
- name = 'testingpackage'
- # Unfortunately importlib.util.module_from_spec() was not introduced until
- # Python 3.5.
- module = types.ModuleType(name)
- loader = Reader()
- spec = machinery.ModuleSpec(
- name, loader,
- origin='does-not-exist',
- is_package=is_package)
- module.__spec__ = spec
- module.__loader__ = loader
- return module
-
-
-class CommonResourceTests(abc.ABC):
- @abc.abstractmethod
- def execute(self, package, path):
- raise NotImplementedError
-
- def test_package_name(self):
- # Passing in the package name should succeed.
- self.execute(data01.__name__, 'utf-8.file')
-
- def test_package_object(self):
- # Passing in the package itself should succeed.
- self.execute(data01, 'utf-8.file')
-
- def test_string_path(self):
- # Passing in a string for the path should succeed.
- path = 'utf-8.file'
- self.execute(data01, path)
-
- @unittest.skipIf(sys.version_info < (3, 6), 'requires os.PathLike support')
- def test_pathlib_path(self):
- # Passing in a pathlib.PurePath object for the path should succeed.
- path = PurePath('utf-8.file')
- self.execute(data01, path)
-
- def test_absolute_path(self):
- # An absolute path is a ValueError.
- path = Path(__file__)
- full_path = path.parent/'utf-8.file'
- with self.assertRaises(ValueError):
- self.execute(data01, full_path)
-
- def test_relative_path(self):
- # A relative path is a ValueError.
- with self.assertRaises(ValueError):
- self.execute(data01, '../data01/utf-8.file')
-
- def test_importing_module_as_side_effect(self):
- # The anchor package can already be imported.
- del sys.modules[data01.__name__]
- self.execute(data01.__name__, 'utf-8.file')
-
- def test_non_package_by_name(self):
- # The anchor package cannot be a module.
- with self.assertRaises(TypeError):
- self.execute(__name__, 'utf-8.file')
-
- def test_non_package_by_package(self):
- # The anchor package cannot be a module.
- with self.assertRaises(TypeError):
- module = sys.modules['test.test_importlib.util']
- self.execute(module, 'utf-8.file')
-
- @unittest.skipIf(sys.version_info < (3,), 'No ResourceReader in Python 2')
- def test_resource_opener(self):
- bytes_data = io.BytesIO(b'Hello, world!')
- package = create_package(file=bytes_data, path=FileNotFoundError())
- self.execute(package, 'utf-8.file')
- self.assertEqual(package.__loader__._path, 'utf-8.file')
-
- @unittest.skipIf(sys.version_info < (3,), 'No ResourceReader in Python 2')
- def test_resource_path(self):
- bytes_data = io.BytesIO(b'Hello, world!')
- path = __file__
- package = create_package(file=bytes_data, path=path)
- self.execute(package, 'utf-8.file')
- self.assertEqual(package.__loader__._path, 'utf-8.file')
-
- def test_useless_loader(self):
- package = create_package(file=FileNotFoundError(),
- path=FileNotFoundError())
- with self.assertRaises(FileNotFoundError):
- self.execute(package, 'utf-8.file')
-
-
-class ZipSetupBase:
- ZIP_MODULE = None
-
- @classmethod
- def setUpClass(cls):
- data_path = Path(cls.ZIP_MODULE.__file__)
- data_dir = data_path.parent
- cls._zip_path = str(data_dir / 'ziptestdata.zip')
- sys.path.append(cls._zip_path)
- cls.data = importlib.import_module('ziptestdata')
-
- @classmethod
- def tearDownClass(cls):
- try:
- sys.path.remove(cls._zip_path)
- except ValueError:
- pass
-
- try:
- del sys.path_importer_cache[cls._zip_path]
- del sys.modules[cls.data.__name__]
- except KeyError:
- pass
-
- try:
- del cls.data
- del cls._zip_path
- except AttributeError:
- pass
-
- def setUp(self):
- modules = import_helper.modules_setup()
- self.addCleanup(import_helper.modules_cleanup, *modules)
-
-
-class ZipSetup(ZipSetupBase):
- ZIP_MODULE = zipdata01 # type: ignore