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