1"""Simplified function-based API for importlib.resources"""
2
3import warnings
4
5from ._common import files, as_file
6
7
8_MISSING = object()
9
10
11def open_binary(anchor, *path_names):
12 """Open for binary reading the *resource* within *package*."""
13 return _get_resource(anchor, path_names).open('rb')
14
15
16def open_text(anchor, *path_names, encoding=_MISSING, errors='strict'):
17 """Open for text reading the *resource* within *package*."""
18 encoding = _get_encoding_arg(path_names, encoding)
19 resource = _get_resource(anchor, path_names)
20 return resource.open('r', encoding=encoding, errors=errors)
21
22
23def read_binary(anchor, *path_names):
24 """Read and return contents of *resource* within *package* as bytes."""
25 return _get_resource(anchor, path_names).read_bytes()
26
27
28def read_text(anchor, *path_names, encoding=_MISSING, errors='strict'):
29 """Read and return contents of *resource* within *package* as str."""
30 encoding = _get_encoding_arg(path_names, encoding)
31 resource = _get_resource(anchor, path_names)
32 return resource.read_text(encoding=encoding, errors=errors)
33
34
35def path(anchor, *path_names):
36 """Return the path to the *resource* as an actual file system path."""
37 return as_file(_get_resource(anchor, path_names))
38
39
40def is_resource(anchor, *path_names):
41 """Return ``True`` if there is a resource named *name* in the package,
42
43 Otherwise returns ``False``.
44 """
45 return _get_resource(anchor, path_names).is_file()
46
47
48def contents(anchor, *path_names):
49 """Return an iterable over the named resources within the package.
50
51 The iterable returns :class:`str` resources (e.g. files).
52 The iterable does not recurse into subdirectories.
53 """
54 warnings.warn(
55 "importlib.resources.contents is deprecated. "
56 "Use files(anchor).iterdir() instead.",
57 DeprecationWarning,
58 stacklevel=1,
59 )
60 return (resource.name for resource in _get_resource(anchor, path_names).iterdir())
61
62
63def _get_encoding_arg(path_names, encoding):
64 # For compatibility with versions where *encoding* was a positional
65 # argument, it needs to be given explicitly when there are multiple
66 # *path_names*.
67 # This limitation can be removed in Python 3.15.
68 if encoding is _MISSING:
69 if len(path_names) > 1:
70 raise TypeError(
71 "'encoding' argument required with multiple path names",
72 )
73 else:
74 return 'utf-8'
75 return encoding
76
77
78def _get_resource(anchor, path_names):
79 if anchor is None:
80 raise TypeError("anchor must be module or string, got None")
81 return files(anchor).joinpath(*path_names)