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

58 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

1# flake8: noqa 

2 

3import abc 

4import os 

5import sys 

6import pathlib 

7import warnings 

8from contextlib import suppress 

9from typing import Union 

10 

11 

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

13 from zipfile import Path as ZipPath # type: ignore 

14else: 

15 from zipp import Path as ZipPath # type: ignore 

16 

17 

18try: 

19 from typing import runtime_checkable # type: ignore 

20except ImportError: 

21 

22 def runtime_checkable(cls): # type: ignore 

23 return cls 

24 

25 

26try: 

27 from typing import Protocol # type: ignore 

28except ImportError: 

29 Protocol = abc.ABC # type: ignore 

30 

31 

32class TraversableResourcesLoader: 

33 """ 

34 Adapt loaders to provide TraversableResources and other 

35 compatibility. 

36 

37 Used primarily for Python 3.9 and earlier where the native 

38 loaders do not yet implement TraversableResources. 

39 """ 

40 

41 def __init__(self, spec): 

42 self.spec = spec 

43 

44 @property 

45 def path(self): 

46 return self.spec.origin 

47 

48 def get_resource_reader(self, name): 

49 from . import readers, _adapters 

50 

51 def _zip_reader(spec): 

52 with suppress(AttributeError): 

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

54 

55 def _namespace_reader(spec): 

56 with suppress(AttributeError, ValueError): 

57 return readers.NamespaceReader(spec.submodule_search_locations) 

58 

59 def _available_reader(spec): 

60 with suppress(AttributeError): 

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

62 

63 def _native_reader(spec): 

64 reader = _available_reader(spec) 

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

66 

67 def _file_reader(spec): 

68 try: 

69 path = pathlib.Path(self.path) 

70 except TypeError: 

71 return None 

72 if path.exists(): 

73 return readers.FileReader(self) 

74 

75 return ( 

76 # local ZipReader if a zip module 

77 _zip_reader(self.spec) 

78 or 

79 # local NamespaceReader if a namespace module 

80 _namespace_reader(self.spec) 

81 or 

82 # local FileReader 

83 _file_reader(self.spec) 

84 or 

85 # native reader if it supplies 'files' 

86 _native_reader(self.spec) 

87 or 

88 # fallback - adapt the spec ResourceReader to TraversableReader 

89 _adapters.CompatibilityFiles(self.spec) 

90 ) 

91 

92 

93def wrap_spec(package): 

94 """ 

95 Construct a package spec with traversable compatibility 

96 on the spec/loader/reader. 

97 

98 Supersedes _adapters.wrap_spec to use TraversableResourcesLoader 

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

100 """ 

101 from . import _adapters 

102 

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

104 

105 

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

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

108else: 

109 # PathLike is only subscriptable at runtime in 3.9+ 

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

111 

112 

113def ensure_traversable(path): 

114 """ 

115 Convert deprecated string arguments to traversables (pathlib.Path). 

116 """ 

117 if not isinstance(path, str): 

118 return path 

119 

120 warnings.warn( 

121 "String arguments are deprecated. Pass a Traversable instead.", 

122 DeprecationWarning, 

123 stacklevel=3, 

124 ) 

125 

126 return pathlib.Path(path)