Skip to content

Commit 7cf789b

Browse files
committed
rf: Use acres data loader uniformly
1 parent 55ff88f commit 7cf789b

File tree

13 files changed

+49
-128
lines changed

13 files changed

+49
-128
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ repos:
7272
- id: mypy
7373
# Sync with project.optional-dependencies.typing
7474
additional_dependencies:
75+
- acres
7576
- click
7677
- markdown-it-py
7778
- importlib_resources

tools/schemacode/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ license = {text = "MIT"}
1111
readme = "README.md"
1212
requires-python = ">=3.9"
1313
dependencies = [
14+
"acres",
1415
"click",
1516
"pyyaml",
1617
"jsonschema",

tools/schemacode/src/bidsschematools/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414

1515
def __getattr__(attr):
16-
from .data import load_resource
16+
from .data import load
1717

1818
if attr == "__version__":
1919
global __version__
20-
__version__ = load_resource("schema/SCHEMA_VERSION").read_text().strip()
20+
__version__ = load.readable("schema/SCHEMA_VERSION").read_text().strip()
2121
return __version__
2222
elif attr == "__bids_version__":
2323
global __bids_version__
24-
__bids_version__ = load_resource("schema/BIDS_VERSION").read_text().strip()
24+
__bids_version__ = load.readable("schema/BIDS_VERSION").read_text().strip()
2525
return __bids_version__
2626

2727
raise AttributeError(f"module {__spec__.name!r} has no attribute {attr!r}")

tools/schemacode/src/bidsschematools/__main__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import click
99

10-
from .data import load_resource
1110
from .rules import regexify_filename_rules
1211
from .schema import export_schema, load_schema
1312
from .utils import configure_logger, get_logger
@@ -48,7 +47,9 @@ def export(ctx, schema, output):
4847
@click.pass_context
4948
def export_metaschema(ctx, output):
5049
"""Export BIDS schema to JSON document"""
51-
metaschema = load_resource("metaschema.json").read_text()
50+
from .data import load
51+
52+
metaschema = load.readable("metaschema.json").read_text()
5253
if output == "-":
5354
print(metaschema, end="")
5455
else:

tools/schemacode/src/bidsschematools/conftest.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
import tempfile
33
from pathlib import Path
44
from subprocess import run
5+
from typing import Generator
56

67
import pytest
78

9+
from . import data
10+
811
lgr = logging.getLogger()
912

1013
# This selects a subset of the bids-examples collection to run the test suite on.
@@ -90,12 +93,10 @@ def fixture(tests_data_dir):
9093

9194

9295
@pytest.fixture(scope="session")
93-
def schema_dir():
96+
def schema_dir() -> Generator[str, None, None]:
9497
"""Path to the schema housed in the bids-specification repo."""
95-
from bidsschematools import utils
96-
97-
bids_schema = utils.get_bundled_schema_path()
98-
return bids_schema
98+
with data.load.as_path("schema") as schema_path:
99+
yield str(schema_path)
99100

100101

101102
@pytest.fixture(scope="session")
Lines changed: 7 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,14 @@
11
"""Module containing data files, including the schema source files
22
3-
.. autofunction:: load_resource
4-
"""
5-
6-
import atexit
7-
import os
8-
from contextlib import ExitStack
9-
from functools import cache, cached_property
10-
from importlib.resources import as_file, files
11-
from pathlib import Path
12-
from types import ModuleType
13-
from typing import Union
14-
15-
__all__ = ["load_resource"]
16-
17-
18-
class Loader:
19-
"""A loader for package files relative to a module
20-
21-
This class wraps :mod:`importlib.resources` to provide a getter
22-
function with an interpreter-lifetime scope. For typical packages
23-
it simply passes through filesystem paths as :class:`~pathlib.Path`
24-
objects. For zipped distributions, it will unpack the files into
25-
a temporary directory that is cleaned up on interpreter exit.
26-
27-
This loader accepts a fully-qualified module name or a module
28-
object.
29-
30-
Expected usage::
31-
32-
'''Data package
3+
.. autofunction:: load
334
34-
.. autofunction:: load_data
35-
'''
5+
.. automethod:: load.readable
366
37-
from bidsschematools.data import Loader
7+
.. automethod:: load.as_path
388
39-
load_data = Loader(__package__)
40-
41-
:class:`~Loader` objects implement the :func:`callable` interface
42-
and generate a docstring, and are intended to be treated and documented
43-
as functions.
44-
"""
45-
46-
def __init__(self, anchor: Union[str, ModuleType]):
47-
self._anchor = anchor
48-
self.files = files(anchor)
49-
self.exit_stack = ExitStack()
50-
atexit.register(self.exit_stack.close)
51-
# Allow class to have a different docstring from instances
52-
self.__doc__ = self._doc
53-
54-
@cached_property
55-
def _doc(self):
56-
"""Construct docstring for instances
57-
58-
Lists the public top-level paths inside the location, where
59-
non-public means has a `.` or `_` prefix or is a 'tests'
60-
directory.
61-
"""
62-
top_level = sorted(
63-
os.path.relpath(p, self.files) + "/"[: p.is_dir()]
64-
for p in self.files.iterdir()
65-
if p.name[0] not in (".", "_") and p.name != "tests"
66-
)
67-
doclines = [
68-
f"Load package files relative to ``{self._anchor}``.",
69-
"",
70-
"This package contains the following (top-level) files/directories:",
71-
"",
72-
*(f"* ``{path}``" for path in top_level),
73-
]
74-
75-
return "\n".join(doclines)
76-
77-
@cache
78-
def __call__(self, *segments) -> Path:
79-
"""Ensure data is available as a :class:`~pathlib.Path`.
80-
81-
Any temporary files that are created remain available throughout
82-
the duration of the program, and are deleted when Python exits.
83-
84-
Results are cached so that multiple calls do not unpack the same
85-
data multiple times, but the cache is sensitive to the specific
86-
argument(s) passed.
87-
"""
88-
return self.exit_stack.enter_context(as_file(self.files.joinpath(*segments)))
9+
.. automethod:: load.cached
10+
"""
8911

12+
from acres import Loader
9013

91-
load_resource = Loader(__package__)
14+
load = Loader(__spec__.name)

tools/schemacode/src/bidsschematools/schema.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010

1111
from jsonschema import ValidationError, validate
1212

13-
from . import __bids_version__, __version__, utils
14-
from .data import load_resource
13+
from . import __bids_version__, __version__, data, utils
1514
from .types import Namespace
1615

1716
lgr = utils.get_logger()
@@ -204,7 +203,7 @@ def load_schema(schema_path=None):
204203
This function is cached, so it will only be called once per schema path.
205204
"""
206205
if schema_path is None:
207-
schema_path = utils.get_bundled_schema_path()
206+
schema_path = data.load.readable("schema")
208207
lgr.info("No schema path specified, defaulting to the bundled schema, `%s`.", schema_path)
209208
schema = Namespace.from_directory(schema_path)
210209
if not schema.objects:
@@ -293,7 +292,9 @@ def filter_schema(schema, **kwargs):
293292

294293
def validate_schema(schema: Namespace):
295294
"""Validate a schema against the BIDS metaschema."""
296-
metaschema = json.loads(load_resource("metaschema.json").read_text())
295+
from .data import load
296+
297+
metaschema = json.loads(load.readable("metaschema.json").read_text())
297298

298299
# validate is put in this try/except clause because the error is sometimes too long to
299300
# print in the terminal
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
"""Test data module
22
33
.. autofunction:: load_test_data
4+
5+
.. automethod:: load_test_data.readable
6+
7+
.. automethod:: load_test_data.as_path
8+
9+
.. automethod:: load_test_data.cached
410
"""
511

6-
from ...data import Loader
12+
from acres import Loader
713

814
__all__ = ("load_test_data",)
915

10-
load_test_data = Loader(__package__)
16+
load_test_data = Loader(__spec__.name)

tools/schemacode/src/bidsschematools/tests/test_schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
from bidsschematools import __bids_version__, schema, types
1010

11-
from ..data import load_resource
11+
from ..data import load
1212

1313

1414
def test__get_bids_version(tmp_path):
1515
# Is the version being read in correctly?
16-
schema_path = str(load_resource("schema"))
16+
schema_path = str(load("schema"))
1717
bids_version = schema._get_bids_version(schema_path)
1818
assert bids_version == __bids_version__
1919

tools/schemacode/src/bidsschematools/tests/test_validator.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from bidsschematools.conftest import BIDS_ERROR_SELECTION, BIDS_SELECTION
77
from bidsschematools.validator import select_schema_path, validate_bids
88

9-
from ..data import load_resource
9+
from ..data import load
1010
from .data import load_test_data
1111

1212

@@ -155,9 +155,8 @@ def test_validate_bids(bids_examples, tmp_path):
155155
assert len(result["path_tracking"]) == 0
156156

157157
# Is the schema version recorded correctly?
158-
schema_path = load_resource("schema")
159-
with open(os.path.join(schema_path, "BIDS_VERSION")) as f:
160-
expected_version = f.readline().rstrip()
158+
schema_path = load.readable("schema")
159+
expected_version = schema_path.joinpath("BIDS_VERSION").read_text().rstrip()
161160
assert result["bids_version"] == expected_version
162161

163162

@@ -279,9 +278,7 @@ def test_bids_schema_versioncheck(monkeypatch):
279278
"""Test incompatible version."""
280279
import bidsschematools as bst
281280

282-
from ..utils import get_bundled_schema_path
283-
284-
schema_dir = get_bundled_schema_path()
281+
schema_dir = bst.data.load.readable("schema")
285282
assert bst.validator._bids_schema_versioncheck(schema_dir)
286283
monkeypatch.setattr(bst, "__version__", "99.99.99")
287284
assert not bst.validator._bids_schema_versioncheck(schema_dir)

0 commit comments

Comments
 (0)