@@ -64,7 +64,7 @@ from typing.io import BinaryIO
6464
6565
6666Package = Union[str , types.ModuleType]
67- Path = Union[str , os.PathLike]
67+ FileName = Union[str , os.PathLike]
6868
6969
7070def _get_package (package ):
@@ -82,35 +82,34 @@ def _get_package(package):
8282
8383
8484def _normalize_path (path ):
85- if os.path.isabs(path):
86- raise ValueError (f " { path!r } is absolute " )
87- normalized_path = os.path.normpath(path)
88- if normalized_path.startswith(" .." ):
89- raise ValueError (f " { path!r } attempts to traverse past package " )
85+ directory, file_name = os.path.split(path)
86+ if directory:
87+ raise ValueError (f " { path!r } is not just a file name " )
9088 else :
91- return normalized_path
89+ return file_name
9290
9391
94- def open (module_name : Package, path : Path ) -> BinaryIO:
92+ def open (module_name : Package, file_name : FileName ) -> BinaryIO:
9593 """ Return a file-like object opened for binary-reading of the resource."""
96- normalized_path = _normalize_path(path )
94+ normalized_path = _normalize_path(file_name )
9795 module = _get_package(module_name)
9896 return module.__spec__ .loader.open_resource(normalized_path)
9997
10098
101- def read (module_name : Package, path : Path , encoding : str = " utf-8" ,
99+ def read (module_name : Package, file_name : FileName , encoding : str = " utf-8" ,
102100 errors : str = " strict" ) -> str :
103101 """ Return the decoded string of the resource.
104102
105103 The decoding-related arguments have the same semantics as those of
106104 bytes.decode().
107105 """
108- with open (module_name, path) as file :
106+ # Note this is **not** builtins.open()!
107+ with open (module_name, file_name) as file :
109108 return file .read().decode(encoding = encoding, errors = errors)
110109
111110
112111@contextlib.contextmanager
113- def path (module_name : Package, path : Path ) -> Iterator[pathlib.Path]:
112+ def path (module_name : Package, file_name : FileName ) -> Iterator[pathlib.Path]:
114113 """ A context manager providing a file path object to the resource.
115114
116115 If the resource does not already exist on its own on the file system,
@@ -119,7 +118,7 @@ def path(module_name: Package, path: Path) -> Iterator[pathlib.Path]:
119118 raised if the file was deleted prior to the context manager
120119 exiting).
121120 """
122- normalized_path = _normalize_path(path )
121+ normalized_path = _normalize_path(file_name )
123122 module = _get_package(module_name)
124123 try :
125124 yield pathlib.Path(module.__spec__ .resource_path(normalized_path))
@@ -143,12 +142,10 @@ side-effect of the call. The specified module is expected to be a
143142package, otherwise ` TypeError ` is raised. The module is expected to
144143have a loader specified on ` __spec__.loader ` which
145144
146- For the * path* argument, it is expected to be a relative path. If
147- there are implicit references to the parent directory (i.e. ` .. ` ), they
148- will be resolved. If the normalized, relative path attempts to reference
149- beyond the location of the specified module, a ` ValueError ` will be
150- raised. The provided path is expected to be UNIX-style (i.e. to use
151- ` / ` as its path separator). Bytes-based paths are not supported.
145+ For the * file_name* argument, it is expected to be only a file name with
146+ no other path parts. If any parts beyond a file name are found, a ` ValueError `
147+ will be raised. The expectation is that all data files will exist within
148+ a directory that can be imported by Python as a package.
152149
153150All functions raise ` FileNotFoundError ` if the resource does not exist.
154151
0 commit comments