@@ -101,12 +101,20 @@ def _validate(
101101 if 'contains' in vars (cls_schema ):
102102 contains_qty = _get_contains_qty (
103103 arg ,
104- json_schema_data ['contains' ],
104+ vars ( cls_schema ) ['contains' ],
105105 validation_metadata ,
106106 path_to_schemas
107107 )
108+ prefix_items_length = 0
109+ if 'prefix_items' in vars (cls_schema ):
110+ prefix_items_length = len (vars (cls_schema )['prefix_items' ])
108111 for keyword , val in json_schema_data .items ():
109- used_val = (val , contains_qty ) if keyword in {'contains' , 'min_contains' , 'max_contains' } else val
112+ if keyword in {'contains' , 'min_contains' , 'max_contains' }:
113+ used_val = (val , contains_qty )
114+ elif keyword == 'items' :
115+ used_val = (val , prefix_items_length )
116+ else :
117+ used_val = val
110118 validator = json_schema_keyword_to_validator [keyword ]
111119
112120 other_path_to_schemas = validator (
@@ -660,15 +668,17 @@ def validate_required(
660668
661669def validate_items (
662670 arg : typing .Any ,
663- item_cls : typing .Type [SchemaValidator ],
671+ item_cls_prefix_items_length : typing .Tuple [ typing . Type [SchemaValidator ], int ],
664672 cls : typing .Type ,
665673 validation_metadata : ValidationMetadata ,
666674) -> typing .Optional [PathToSchemasType ]:
667675 if not isinstance (arg , tuple ):
668676 return None
669- item_cls = _get_class (item_cls )
677+ item_cls = _get_class (item_cls_prefix_items_length [0 ])
678+ prefix_items_length = item_cls_prefix_items_length [1 ]
670679 path_to_schemas : PathToSchemasType = {}
671- for i , value in enumerate (arg ):
680+ for i in range (prefix_items_length , len (arg )):
681+ value = arg [i ]
672682 item_validation_metadata = ValidationMetadata (
673683 path_to_item = validation_metadata .path_to_item + (i ,),
674684 configuration = validation_metadata .configuration ,
@@ -1154,6 +1164,34 @@ def validate_pattern_properties(
11541164 return path_to_schemas
11551165
11561166
1167+ def validate_prefix_items (
1168+ arg : typing .Any ,
1169+ prefix_items : typing .Tuple [typing .Type [SchemaValidator ], ...],
1170+ cls : typing .Type ,
1171+ validation_metadata : ValidationMetadata ,
1172+ ) -> typing .Optional [PathToSchemasType ]:
1173+ if not isinstance (arg , tuple ):
1174+ return None
1175+ path_to_schemas : PathToSchemasType = {}
1176+ module_namespace = vars (sys .modules [cls .__module__ ])
1177+ for i , val in enumerate (arg ):
1178+ if i >= len (prefix_items ):
1179+ break
1180+ schema = _get_class (prefix_items [i ], module_namespace )
1181+ path_to_item = validation_metadata .path_to_item + (i ,)
1182+ item_validation_metadata = ValidationMetadata (
1183+ path_to_item = path_to_item ,
1184+ configuration = validation_metadata .configuration ,
1185+ validated_path_to_schemas = validation_metadata .validated_path_to_schemas
1186+ )
1187+ if item_validation_metadata .validation_ran_earlier (schema ):
1188+ add_deeper_validated_schemas (validation_metadata , path_to_schemas )
1189+ continue
1190+ other_path_to_schemas = schema ._validate (val , validation_metadata = item_validation_metadata )
1191+ update (path_to_schemas , other_path_to_schemas )
1192+ return path_to_schemas
1193+
1194+
11571195validator_type = typing .Callable [[typing .Any , typing .Any , type , ValidationMetadata ], typing .Optional [PathToSchemasType ]]
11581196json_schema_keyword_to_validator : typing .Mapping [str , validator_type ] = {
11591197 'types' : validate_types ,
@@ -1188,5 +1226,6 @@ def validate_pattern_properties(
11881226 'dependent_required' : validate_dependent_required ,
11891227 'dependent_schemas' : validate_dependent_schemas ,
11901228 'property_names' : validate_property_names ,
1191- 'pattern_properties' : validate_pattern_properties
1229+ 'pattern_properties' : validate_pattern_properties ,
1230+ 'prefix_items' : validate_prefix_items
11921231}
0 commit comments