diff --git a/docs/requirements.txt b/docs/requirements.txt index 38c691c..65092db 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -39,13 +39,13 @@ pygments==2.17.2 # sphinx pygments-github-lexers==0.0.5 # via -r docs/requirements.in -referencing==0.31.1 +referencing==0.32.0 # via referencing-loaders file:.#egg=referencing-loaders # via -r docs/requirements.in requests==2.31.0 # via sphinx -rpds-py==0.13.1 +rpds-py==0.13.2 # via referencing snowballstemmer==2.2.0 # via sphinx diff --git a/pyproject.toml b/pyproject.toml index fbaf583..c0ce63d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ classifiers = [ ] dynamic = ["version"] dependencies = [ - "referencing>=0.31.1", + "referencing>=0.32.0", ] [project.urls] diff --git a/referencing_loaders/__init__.py b/referencing_loaders/__init__.py index fb78479..ee4398d 100644 --- a/referencing_loaders/__init__.py +++ b/referencing_loaders/__init__.py @@ -8,21 +8,29 @@ import json import os -from referencing import Resource +from referencing import Resource, Specification if TYPE_CHECKING: from referencing.typing import URI -def from_path(path: Path) -> Iterable[tuple[URI, Resource[Any]]]: +def from_path(root: Path) -> Iterable[tuple[URI, Resource[Any]]]: """ Load some resources recursively from a given directory path. + + Subdirectories are defaulted to the first version seen (starting from + the root) -- though it still is often a good idea to explicitly indicate + what specification every resource is written for internally. """ - for root, _, files in _walk(path): + specification: Specification[Any] | None = None + for dir, _, files in _walk(root): for file in files: - path = root / file + path = dir / file contents = json.loads(path.read_text()) - yield path.as_uri(), Resource.from_contents(contents) + if specification is None: + specification = Specification.detect(contents) # type: ignore[reportUnknownMemberType] + resource = specification.detect(contents).create_resource(contents) + yield path.as_uri(), resource def _walk(path: Path) -> Iterable[tuple[Path, Iterable[str], Iterable[str]]]: diff --git a/referencing_loaders/tests/test_loaders.py b/referencing_loaders/tests/test_loaders.py index e4bfcd9..9197a90 100644 --- a/referencing_loaders/tests/test_loaders.py +++ b/referencing_loaders/tests/test_loaders.py @@ -1,7 +1,7 @@ import json from referencing import Registry -from referencing.jsonschema import EMPTY_REGISTRY +from referencing.jsonschema import DRAFT202012, EMPTY_REGISTRY import referencing_loaders as loaders @@ -44,6 +44,43 @@ def test_absolute_internally_identified(tmp_path): assert registry.crawl() == expected.crawl() +def test_schema_is_inherited_downwards(tmp_path): + root_path, root = tmp_path / "schema.json", { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "http://example.com/", + } + son_path, son = tmp_path / "child/son.json", { + "$id": "http://example.com/son", + } + daughter_path, daughter = tmp_path / "child/daughter.json", { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "http://example.com/random/daughter", + } + grandchild_path, grandchild = tmp_path / "child/more/gc.json", { + "$id": "http://example.com/also/a/grandchild", + } + + tmp_path.joinpath("child/more").mkdir(parents=True) + root_path.write_text(json.dumps(root)) + son_path.write_text(json.dumps(son)) + daughter_path.write_text(json.dumps(daughter)) + grandchild_path.write_text(json.dumps(grandchild)) + + expected = Registry().with_resources( + (each, DRAFT202012.create_resource(contents)) + for each, contents in [ + (root_path.as_uri(), root), + (son_path.as_uri(), son), + (daughter_path.as_uri(), daughter), + (grandchild_path.as_uri(), grandchild), + ] + ) + + resources = loaders.from_path(tmp_path) + registry = EMPTY_REGISTRY.with_resources(resources) + assert registry.crawl() == expected.crawl() + + def test_empty(tmp_path): registry = EMPTY_REGISTRY.with_resources(loaders.from_path(tmp_path)) assert registry == EMPTY_REGISTRY diff --git a/test-requirements.txt b/test-requirements.txt index 33858f1..8947d81 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -14,9 +14,9 @@ pluggy==1.3.0 # via pytest pytest==7.4.3 # via -r test-requirements.in -referencing==0.31.1 +referencing==0.32.0 # via referencing-loaders file:.#egg=referencing-loaders # via -r test-requirements.in -rpds-py==0.13.1 +rpds-py==0.13.2 # via referencing