diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8c52652..f730e29 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -35,3 +35,4 @@ jobs: run: hatch publish -y env: HATCH_INDEX_AUTH: ${{ secrets.HATCH_INDEX_AUTH }} + HATCH_INDEX_USER: ${{ secrets.HATCH_INDEX_USER }} diff --git a/pyproject.toml b/pyproject.toml index abe62a3..d3efec0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,7 @@ dependencies = ["mypy>=1.8.0", "pydocstyle>=6.3.0", "ruff>=0.2.2"] features = ["cloud", "file-formats", "validation"] [tool.hatch.envs.lint.scripts] -lint = "ruff src" +lint = "ruff check src" typing = "mypy src" docs = "pydocstyle src" diff --git a/src/config/configuration.py b/src/config/configuration.py index bd4c11e..30eb299 100644 --- a/src/config/configuration.py +++ b/src/config/configuration.py @@ -402,6 +402,7 @@ def validate( self, schema: Any, raise_on_error: bool = False, + nested: bool = False, **kwargs: Mapping[str, Any], ) -> bool: """Validate the current config using JSONSchema.""" @@ -412,7 +413,7 @@ def validate( "Validation requires the `jsonschema` library.", ) from None try: - validate(self.as_dict(), schema, **kwargs) + validate(self.as_attrdict() if nested else self.as_dict(), schema, **kwargs) except ValidationError as err: if raise_on_error: raise err diff --git a/tests/test_validation.py b/tests/test_validation.py index 9c2a7ad..d6bc264 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -1,11 +1,11 @@ +"""Validation tests.""" + +# ruff: noqa: D103 + +import pytest from config import ( - Configuration, - ConfigurationSet, - EnvConfiguration, - config, config_from_dict, ) -import pytest try: import jsonschema @@ -25,7 +25,7 @@ def test_validation_ok(): # type: ignore "type": "array", "items": {"enum": [1, 2, 3]}, "maxItems": 2, - } + }, }, } @@ -43,7 +43,7 @@ def test_validation_fail(): # type: ignore "type": "array", "items": {"enum": [1, 2, 3]}, "maxItems": 2, - } + }, }, } @@ -89,5 +89,36 @@ def test_validation_format(): # type: ignore raise_on_error=True, format_checker=Draft202012Validator.FORMAT_CHECKER, ) - print(str(err)) assert "'10' is not a 'ipv4'" in str(err) + + +@pytest.mark.skipif("jsonschema is None") +def test_validation_nested(): # type: ignore + d = {"item": {"sub1": 1, "sub2": "abc"}} + cfg = config_from_dict(d) + + schema = { + "type": "object", + "properties": { + "item.sub1": {"type": "number"}, + "item.sub2": {"type": "string"}, + }, + "required": ["item.sub1", "item.sub2"], + } + assert cfg.validate(schema) + + schema = { + "type": "object", + "properties": { + "item": { + "type": "object", + "properties": { + "sub1": {"type": "number"}, + "sub2": {"type": "string"}, + }, + "required": ["sub1", "sub2"], + }, + }, + "required": ["item"], + } + assert cfg.validate(schema, nested=True)