test_files.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import typing
  2. import textwrap
  3. import unittest
  4. import warnings
  5. import importlib
  6. import contextlib
  7. import importlib_resources as resources
  8. from ..abc import Traversable
  9. from . import data01
  10. from . import util
  11. from . import _path
  12. from ._compat import os_helper, import_helper
  13. @contextlib.contextmanager
  14. def suppress_known_deprecation():
  15. with warnings.catch_warnings(record=True) as ctx:
  16. warnings.simplefilter('default', category=DeprecationWarning)
  17. yield ctx
  18. class FilesTests:
  19. def test_read_bytes(self):
  20. files = resources.files(self.data)
  21. actual = files.joinpath('utf-8.file').read_bytes()
  22. assert actual == b'Hello, UTF-8 world!\n'
  23. def test_read_text(self):
  24. files = resources.files(self.data)
  25. actual = files.joinpath('utf-8.file').read_text(encoding='utf-8')
  26. assert actual == 'Hello, UTF-8 world!\n'
  27. @unittest.skipUnless(
  28. hasattr(typing, 'runtime_checkable'),
  29. "Only suitable when typing supports runtime_checkable",
  30. )
  31. def test_traversable(self):
  32. assert isinstance(resources.files(self.data), Traversable)
  33. def test_old_parameter(self):
  34. """
  35. Files used to take a 'package' parameter. Make sure anyone
  36. passing by name is still supported.
  37. """
  38. with suppress_known_deprecation():
  39. resources.files(package=self.data)
  40. class OpenDiskTests(FilesTests, unittest.TestCase):
  41. def setUp(self):
  42. self.data = data01
  43. class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
  44. pass
  45. class OpenNamespaceTests(FilesTests, unittest.TestCase):
  46. def setUp(self):
  47. from . import namespacedata01
  48. self.data = namespacedata01
  49. class SiteDir:
  50. def setUp(self):
  51. self.fixtures = contextlib.ExitStack()
  52. self.addCleanup(self.fixtures.close)
  53. self.site_dir = self.fixtures.enter_context(os_helper.temp_dir())
  54. self.fixtures.enter_context(import_helper.DirsOnSysPath(self.site_dir))
  55. self.fixtures.enter_context(import_helper.CleanImport())
  56. class ModulesFilesTests(SiteDir, unittest.TestCase):
  57. def test_module_resources(self):
  58. """
  59. A module can have resources found adjacent to the module.
  60. """
  61. spec = {
  62. 'mod.py': '',
  63. 'res.txt': 'resources are the best',
  64. }
  65. _path.build(spec, self.site_dir)
  66. import mod
  67. actual = resources.files(mod).joinpath('res.txt').read_text(encoding='utf-8')
  68. assert actual == spec['res.txt']
  69. class ImplicitContextFilesTests(SiteDir, unittest.TestCase):
  70. def test_implicit_files(self):
  71. """
  72. Without any parameter, files() will infer the location as the caller.
  73. """
  74. spec = {
  75. 'somepkg': {
  76. '__init__.py': textwrap.dedent(
  77. """
  78. import importlib_resources as res
  79. val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
  80. """
  81. ),
  82. 'res.txt': 'resources are the best',
  83. },
  84. }
  85. _path.build(spec, self.site_dir)
  86. assert importlib.import_module('somepkg').val == 'resources are the best'
  87. if __name__ == '__main__':
  88. unittest.main()