Skip to content

Commit d2d1c43

Browse files
Merge pull request #1105 from eslavich/update-jsonschema-to-4.x
Update jsonschema to 4.x
2 parents 9f239c0 + 60f7262 commit d2d1c43

5 files changed

Lines changed: 35 additions & 38 deletions

File tree

CHANGES.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
2.10.2 (unreleased)
1+
2.11.0 (unreleased)
22
-------------------
33

4+
- Update minimum jsonschema version to 4.0.1. [#1105]
5+
46
2.10.1 (2022-03-02)
57
-------------------
68

asdf/schema.py

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
from functools import lru_cache
88
from numbers import Integral
99

10+
import attr
1011
import numpy as np
1112
import yaml
1213
from jsonschema import validators as mvalidators
13-
from jsonschema.exceptions import ValidationError
14+
from jsonschema.exceptions import RefResolutionError, ValidationError
1415

1516
from . import constants, extension, generic_io, reference, tagged, treeutil, util, versioning, yamlutil
1617
from .config import get_config
@@ -258,34 +259,30 @@ def _create_validator(validators=YAML_VALIDATORS, visit_repeat_nodes=False):
258259
meta_schema=meta_schema, validators=validators, type_checker=type_checker, id_of=id_of
259260
)
260261

262+
@attr.s
261263
class ASDFValidator(base_cls):
262-
def __init__(self, *args, **kwargs):
263-
super().__init__(*args, **kwargs)
264-
self._context = _ValidationContext()
264+
_context = attr.ib(factory=lambda: _ValidationContext())
265+
ctx = attr.ib(default=None)
266+
serialization_context = attr.ib(default=None)
265267

266-
def iter_errors(self, instance, _schema=None):
268+
def iter_errors(self, instance, *args, **kwargs):
267269
# We can't validate anything that looks like an external reference,
268270
# since we don't have the actual content, so we just have to defer
269271
# it for now. If the user cares about complete validation, they
270272
# can call `AsdfFile.resolve_references`.
271273
with self._context:
272-
if _schema is None:
273-
schema = self.schema
274-
else:
275-
schema = _schema
276-
277-
if self._context.seen(instance, schema):
274+
if self._context.seen(instance, self.schema):
278275
# We've already validated this instance against this schema,
279276
# no need to do it again.
280277
return
281278

282279
if not visit_repeat_nodes:
283-
self._context.add(instance, schema)
280+
self._context.add(instance, self.schema)
284281

285282
if (isinstance(instance, dict) and "$ref" in instance) or isinstance(instance, reference.Reference):
286283
return
287284

288-
if _schema is None:
285+
if not self.schema:
289286
tag = getattr(instance, "_tag", None)
290287
if tag is not None:
291288
if self.serialization_context.extension_manager.handles_tag_definition(tag):
@@ -299,15 +296,11 @@ def iter_errors(self, instance, _schema=None):
299296
# Must validate against all schema_uris
300297
for schema_uri in schema_uris:
301298
try:
302-
s = _load_schema_cached(schema_uri, self.ctx.resolver, False, False)
303-
except FileNotFoundError:
299+
with self.resolver.resolving(schema_uri) as resolved:
300+
yield from self.descend(instance, resolved)
301+
except RefResolutionError:
304302
msg = "Unable to locate schema file for '{}': '{}'"
305303
warnings.warn(msg.format(tag, schema_uri), AsdfWarning)
306-
s = {}
307-
if s:
308-
with self.resolver.in_scope(schema_uri):
309-
for x in super(ASDFValidator, self).iter_errors(instance, s):
310-
yield x
311304

312305
if isinstance(instance, dict):
313306
for val in instance.values():
@@ -319,8 +312,7 @@ def iter_errors(self, instance, _schema=None):
319312
for x in self.iter_errors(val):
320313
yield x
321314
else:
322-
for x in super(ASDFValidator, self).iter_errors(instance, _schema=schema):
323-
yield x
315+
yield from super(ASDFValidator, self).iter_errors(instance)
324316

325317
return ASDFValidator
326318

@@ -580,10 +572,7 @@ def get_validator(
580572
# test suite!!!). Instead, we assume that the schemas are valid
581573
# through the running of the unit tests, not at run time.
582574
cls = _create_validator(validators=validators, visit_repeat_nodes=_visit_repeat_nodes)
583-
validator = cls(schema, *args, **kwargs)
584-
validator.ctx = ctx
585-
validator.serialization_context = _serialization_context
586-
return validator
575+
return cls(schema, *args, ctx=ctx, serialization_context=_serialization_context, **kwargs)
587576

588577

589578
def _validate_large_literals(instance, reading):
@@ -670,7 +659,7 @@ def validate(instance, ctx=None, schema={}, validators=None, reading=False, *arg
670659
ctx = AsdfFile()
671660

672661
validator = get_validator(schema, ctx, validators, ctx.resolver, *args, **kwargs)
673-
validator.validate(instance, _schema=(schema or None))
662+
validator.validate(instance)
674663

675664
additional_validators = [_validate_large_literals]
676665
if ctx.version >= versioning.RESTRICTED_KEYS_MIN_VERSION:
@@ -742,9 +731,11 @@ def _validate_default(validator, default, instance, schema):
742731
return
743732

744733
if "default" in instance:
745-
with instance_validator.resolver.in_scope(instance_scope):
746-
for err in instance_validator.iter_errors(instance["default"], instance):
747-
yield err
734+
instance_validator.resolver.push_scope(instance_scope)
735+
try:
736+
yield from instance_validator.descend(instance["default"], instance)
737+
finally:
738+
instance_validator.resolver.pop_scope()
748739

749740
validators.update({"default": _validate_default})
750741

@@ -760,4 +751,4 @@ def _validate_default(validator, default, instance, schema):
760751
id_of=mvalidators.Draft4Validator.ID_OF,
761752
)
762753
validator = cls(meta_schema, resolver=resolver)
763-
validator.validate(schema, _schema=meta_schema)
754+
validator.validate(schema)

asdf/tests/test_schema.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,13 @@ def test_defaults():
401401

402402
cls = schema._create_validator(schema.FILL_DEFAULTS)
403403
validator = cls(s)
404-
validator.validate(t, _schema=s)
404+
validator.validate(t)
405405

406406
assert t["a"] == 42
407407

408408
cls = schema._create_validator(schema.REMOVE_DEFAULTS)
409409
validator = cls(s)
410-
validator.validate(t, _schema=s)
410+
validator.validate(t)
411411

412412
assert t == {}
413413

@@ -1070,9 +1070,9 @@ def test_nonexistent_tag(tmpdir):
10701070
)
10711071
def test_numpy_scalar_type_validation(numpy_value, valid_types):
10721072
def _assert_validation(jsonschema_type, expected_valid):
1073-
validator = schema.get_validator()
1073+
validator = schema.get_validator(schema={"type": jsonschema_type})
10741074
try:
1075-
validator.validate(numpy_value, _schema={"type": jsonschema_type})
1075+
validator.validate(numpy_value)
10761076
except ValidationError:
10771077
valid = False
10781078
else:

setup.cfg

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ setup_requires = setuptools_scm
2828
install_requires =
2929
importlib_resources>=3;python_version<"3.9"
3030
jmespath>=0.6.2
31-
jsonschema>=3.0.2,<4
31+
jsonschema>=4.0.1
3232
numpy>=1.10
3333
packaging>=16.0
3434
pyyaml>=3.10
3535
semantic_version>=2.8
3636
asdf-standard>=1.0.1
3737
asdf-transform-schemas>=0.2.2
38+
# Multiple downstream packages accidentally depend on asdf to
39+
# install six. As a friendly gesture we list six as a dependency
40+
# for older Python versions.
41+
six;python_version<"3.8"
3842

3943
[options.extras_require]
4044
all =

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ deps=
1818
legacy: gwcs==0.9.1
1919
legacy: semantic_version==2.8
2020
legacy: pyyaml==3.13
21-
legacy: jsonschema==3.0.2
21+
legacy: jsonschema==4.0.1
2222
legacy: numpy~=1.14.6
2323
legacy: pytest~=4.6.11
2424
legacy: astropy~=3.0.0

0 commit comments

Comments
 (0)