summaryrefslogtreecommitdiffstats
path: root/Lib/importlib
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2024-04-05 11:55:59 (GMT)
committerGitHub <noreply@github.com>2024-04-05 11:55:59 (GMT)
commit9ceaee74db7da0e71042ab0b385d844e9f282adb (patch)
tree45962fae62f0e15e0921ccf894b97aaa8029f87b /Lib/importlib
parent757b62493b47c6d2f07fc8ecaa2278a7c8a3bea6 (diff)
downloadcpython-9ceaee74db7da0e71042ab0b385d844e9f282adb.zip
cpython-9ceaee74db7da0e71042ab0b385d844e9f282adb.tar.gz
cpython-9ceaee74db7da0e71042ab0b385d844e9f282adb.tar.bz2
gh-116608: importlib.resources: Un-deprecate functional API & add subdirectory support (GH-116609)
Diffstat (limited to 'Lib/importlib')
-rw-r--r--Lib/importlib/resources/__init__.py17
-rw-r--r--Lib/importlib/resources/_functional.py85
2 files changed, 102 insertions, 0 deletions
diff --git a/Lib/importlib/resources/__init__.py b/Lib/importlib/resources/__init__.py
index ae83cd0..ec4441c 100644
--- a/Lib/importlib/resources/__init__.py
+++ b/Lib/importlib/resources/__init__.py
@@ -7,6 +7,16 @@ from ._common import (
Anchor,
)
+from ._functional import (
+ contents,
+ is_resource,
+ open_binary,
+ open_text,
+ path,
+ read_binary,
+ read_text,
+)
+
from .abc import ResourceReader
@@ -16,4 +26,11 @@ __all__ = [
'ResourceReader',
'as_file',
'files',
+ 'contents',
+ 'is_resource',
+ 'open_binary',
+ 'open_text',
+ 'path',
+ 'read_binary',
+ 'read_text',
]
diff --git a/Lib/importlib/resources/_functional.py b/Lib/importlib/resources/_functional.py
new file mode 100644
index 0000000..9e3ea15
--- /dev/null
+++ b/Lib/importlib/resources/_functional.py
@@ -0,0 +1,85 @@
+"""Simplified function-based API for importlib.resources"""
+
+import warnings
+
+from ._common import files, as_file
+
+
+_MISSING = object()
+
+
+def open_binary(anchor, *path_names):
+ """Open for binary reading the *resource* within *package*."""
+ return _get_resource(anchor, path_names).open('rb')
+
+
+def open_text(anchor, *path_names, encoding=_MISSING, errors='strict'):
+ """Open for text reading the *resource* within *package*."""
+ encoding = _get_encoding_arg(path_names, encoding)
+ resource = _get_resource(anchor, path_names)
+ return resource.open('r', encoding=encoding, errors=errors)
+
+
+def read_binary(anchor, *path_names):
+ """Read and return contents of *resource* within *package* as bytes."""
+ return _get_resource(anchor, path_names).read_bytes()
+
+
+def read_text(anchor, *path_names, encoding=_MISSING, errors='strict'):
+ """Read and return contents of *resource* within *package* as str."""
+ encoding = _get_encoding_arg(path_names, encoding)
+ resource = _get_resource(anchor, path_names)
+ return resource.read_text(encoding=encoding, errors=errors)
+
+
+def path(anchor, *path_names):
+ """Return the path to the *resource* as an actual file system path."""
+ return as_file(_get_resource(anchor, path_names))
+
+
+def is_resource(anchor, *path_names):
+ """Return ``True`` if there is a resource named *name* in the package,
+
+ Otherwise returns ``False``.
+ """
+ return _get_resource(anchor, path_names).is_file()
+
+
+def contents(anchor, *path_names):
+ """Return an iterable over the named resources within the package.
+
+ The iterable returns :class:`str` resources (e.g. files).
+ The iterable does not recurse into subdirectories.
+ """
+ warnings.warn(
+ "importlib.resources.contents is deprecated. "
+ "Use files(anchor).iterdir() instead.",
+ DeprecationWarning,
+ stacklevel=1,
+ )
+ return (
+ resource.name
+ for resource
+ in _get_resource(anchor, path_names).iterdir()
+ )
+
+
+def _get_encoding_arg(path_names, encoding):
+ # For compatibility with versions where *encoding* was a positional
+ # argument, it needs to be given explicitly when there are multiple
+ # *path_names*.
+ # This limitation can be removed in Python 3.15.
+ if encoding is _MISSING:
+ if len(path_names) > 1:
+ raise TypeError(
+ "'encoding' argument required with multiple path names",
+ )
+ else:
+ return 'utf-8'
+ return encoding
+
+
+def _get_resource(anchor, path_names):
+ if anchor is None:
+ raise TypeError("anchor must be module or string, got None")
+ return files(anchor).joinpath(*path_names)