1"""Simplified function-based API for importlib.resources"""
2
3import warnings
4
5from ._common import as_file, files
6from .abc import TraversalError
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 try:
46 return _get_resource(anchor, path_names).is_file()
47 except TraversalError:
48 return False
49
50
51def contents(anchor, *path_names):
52 """Return an iterable over the named resources within the package.
53
54 The iterable returns :class:`str` resources (e.g. files).
55 The iterable does not recurse into subdirectories.
56 """
57 warnings.warn(
58 "importlib.resources.contents is deprecated. "
59 "Use files(anchor).iterdir() instead.",
60 DeprecationWarning,
61 stacklevel=1,
62 )
63 return (resource.name for resource in _get_resource(anchor, path_names).iterdir())
64
65
66def _get_encoding_arg(path_names, encoding):
67 # For compatibility with versions where *encoding* was a positional
68 # argument, it needs to be given explicitly when there are multiple
69 # *path_names*.
70 # This limitation can be removed in Python 3.15.
71 if encoding is _MISSING:
72 if len(path_names) > 1:
73 raise TypeError(
74 "'encoding' argument required with multiple path names",
75 )
76 else:
77 return 'utf-8'
78 return encoding
79
80
81def _get_resource(anchor, path_names):
82 if anchor is None:
83 raise TypeError("anchor must be module or string, got None")
84 return files(anchor).joinpath(*path_names)