77from functools import lru_cache
88from numbers import Integral
99
10+ import attr
1011import numpy as np
1112import yaml
1213from jsonschema import validators as mvalidators
13- from jsonschema .exceptions import ValidationError
14+ from jsonschema .exceptions import RefResolutionError , ValidationError
1415
1516from . import constants , extension , generic_io , reference , tagged , treeutil , util , versioning , yamlutil
1617from .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
589578def _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 )
0 commit comments