Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/importlib_resources/_compat.py: 81%

52 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1# flake8: noqa 

2 

3import abc 

4import os 

5import sys 

6import pathlib 

7from contextlib import suppress 

8from typing import Union 

9 

10 

11if sys.version_info >= (3, 10): 

12 from zipfile import Path as ZipPath # type: ignore 

13else: 

14 from zipp import Path as ZipPath # type: ignore 

15 

16 

17try: 

18 from typing import runtime_checkable # type: ignore 

19except ImportError: 

20 

21 def runtime_checkable(cls): # type: ignore 

22 return cls 

23 

24 

25try: 

26 from typing import Protocol # type: ignore 

27except ImportError: 

28 Protocol = abc.ABC # type: ignore 

29 

30 

31class TraversableResourcesLoader: 

32 """ 

33 Adapt loaders to provide TraversableResources and other 

34 compatibility. 

35 

36 Used primarily for Python 3.9 and earlier where the native 

37 loaders do not yet implement TraversableResources. 

38 """ 

39 

40 def __init__(self, spec): 

41 self.spec = spec 

42 

43 @property 

44 def path(self): 

45 return self.spec.origin 

46 

47 def get_resource_reader(self, name): 

48 from . import readers, _adapters 

49 

50 def _zip_reader(spec): 

51 with suppress(AttributeError): 

52 return readers.ZipReader(spec.loader, spec.name) 

53 

54 def _namespace_reader(spec): 

55 with suppress(AttributeError, ValueError): 

56 return readers.NamespaceReader(spec.submodule_search_locations) 

57 

58 def _available_reader(spec): 

59 with suppress(AttributeError): 

60 return spec.loader.get_resource_reader(spec.name) 

61 

62 def _native_reader(spec): 

63 reader = _available_reader(spec) 

64 return reader if hasattr(reader, 'files') else None 

65 

66 def _file_reader(spec): 

67 try: 

68 path = pathlib.Path(self.path) 

69 except TypeError: 

70 return None 

71 if path.exists(): 

72 return readers.FileReader(self) 

73 

74 return ( 

75 # local ZipReader if a zip module 

76 _zip_reader(self.spec) 

77 or 

78 # local NamespaceReader if a namespace module 

79 _namespace_reader(self.spec) 

80 or 

81 # local FileReader 

82 _file_reader(self.spec) 

83 or 

84 # native reader if it supplies 'files' 

85 _native_reader(self.spec) 

86 or 

87 # fallback - adapt the spec ResourceReader to TraversableReader 

88 _adapters.CompatibilityFiles(self.spec) 

89 ) 

90 

91 

92def wrap_spec(package): 

93 """ 

94 Construct a package spec with traversable compatibility 

95 on the spec/loader/reader. 

96 

97 Supersedes _adapters.wrap_spec to use TraversableResourcesLoader 

98 from above for older Python compatibility (<3.10). 

99 """ 

100 from . import _adapters 

101 

102 return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) 

103 

104 

105if sys.version_info >= (3, 9): 

106 StrPath = Union[str, os.PathLike[str]] 

107else: 

108 # PathLike is only subscriptable at runtime in 3.9+ 

109 StrPath = Union[str, "os.PathLike[str]"]