• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
82