{"id":5835,"library":"acres","title":"acres: Access Resources on Your Terms","description":"acres is a Python library designed to simplify access to package resources, offering a consistent API for reading, filesystem access, and cached filesystem access. It addresses common pitfalls associated with `importlib.resources` by clearly delineating resource scopes and capabilities. The current version is 0.5.0, with releases occurring periodically, typically every few months, for new features, improvements, and bug fixes.","status":"active","version":"0.5.0","language":"en","source_language":"en","source_url":"https://github.com/nipreps/acres","tags":["resource management","package resources","data loading","files","importlib.resources"],"install":[{"cmd":"pip install acres","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"Loader","correct":"from acres import Loader"},{"note":"Use `acres.typ.Traversable` for type annotations to simplify usage and avoid Python version compatibility issues with `importlib.resources.abc.Traversable` (moved from `importlib.abc` in Python 3.10 to `importlib.resources.abc` in Python 3.11).","wrong":"from importlib.resources.abc import Traversable","symbol":"Traversable","correct":"import acres.typ as at\n# then use at.Traversable"}],"quickstart":{"code":"from acres import Loader\nimport os\n\n# Assuming a package structure like:\n# my_package/\n#   __init__.py\n#   data/\n#     resource.txt\n\n# Create dummy package for demonstration\nif not os.path.exists('my_package/data'):\n    os.makedirs('my_package/data')\nwith open('my_package/data/resource.txt', 'w') as f:\n    f.write('Hello from acres!')\nwith open('my_package/__init__.py', 'w') as f: # Ensure it's a package\n    f.write('')\n\n# The recommended way to anchor the Loader is with __spec__.name\n# For a real package, you would pass `__spec__.name` from within that package.\n# For this example, we'll simulate it with a string.\npackage_name = 'my_package'\n\nloader = Loader(package_name)\n\n# Read a text resource\ntext_content = loader.readable('data/resource.txt').read_text()\nprint(f\"Text resource content: {text_content}\")\n\n# Access a resource as a temporary file path using a context manager\nwith loader.as_path('data/resource.txt') as resource_path:\n    print(f\"Resource path (temporary): {resource_path}\")\n    print(f\"Content from path: {resource_path.read_text()}\")\n\n# Access a resource that exists for the interpreter's lifetime\ncached_path = loader.cached('data/resource.txt')\nprint(f\"Resource path (cached, interpreter lifetime): {cached_path}\")\nprint(f\"Content from cached path: {cached_path.read_text()}\")\n\n# Clean up dummy package\nos.remove('my_package/data/resource.txt')\nos.rmdir('my_package/data')\nos.remove('my_package/__init__.py')\nos.rmdir('my_package')","lang":"python","description":"The quickstart demonstrates how to use `acres.Loader` to access package resources. It shows how to read text content, get a temporary file path using `as_path` (useful for operations requiring a real filesystem path), and retrieve a cached path that persists for the interpreter's lifetime. The example uses a simulated package structure."},"warnings":[{"fix":"Update `Loader(__package__)` to `Loader(__spec__.name)` when instantiating `Loader`.","message":"The recommended anchor for `Loader` changed from `Loader(__package__)` to `Loader(__spec__.name)` in version 0.2.0. `__package__` can be `None` during zip imports before Python 3.10 and is deprecated in Python 3.13 (to be removed in 3.15).","severity":"breaking","affected_versions":">=0.2.0"},{"fix":"Upgrade to Python 3.9 or newer.","message":"Support for Python 3.8 was dropped in version 0.3.0.","severity":"breaking","affected_versions":">=0.3.0"},{"fix":"Remove `importlib_resources` from your project's dependencies if it was only included for `acres`.","message":"The `importlib_resources` backport is no longer a dependency, even for older Python versions, as of version 0.4.0.","severity":"deprecated","affected_versions":">=0.4.0"},{"fix":"If you relied on automatic listing of top-level package contents, you must now explicitly set `list_contents=True` when initializing the `Loader`.","message":"`Loader(..., list_contents=True)` is now opt-in as of version 0.5.0 to list top-level package contents.","severity":"gotcha","affected_versions":">=0.5.0"},{"fix":"Always use `Loader.as_path()` within a `with` statement for operations requiring a temporary, guaranteed-to-exist `pathlib.Path`. Use `Loader.cached()` when a longer-lived `pathlib.Path` is needed. For simple reads, `Loader.readable().read_text()` or `.read_bytes()` are sufficient without needing a disk path.","message":"When working with resource paths, be mindful of their lifetime. `Loader.readable()` returns a `Traversable` object (which may not represent an actual file on disk), `Loader.as_path()` provides a temporary `pathlib.Path` within a `with` block, and `Loader.cached()` provides a `pathlib.Path` that exists for the interpreter's lifetime. Misunderstanding these can lead to `Path` objects pointing to non-existent files, especially with zipped packages.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}