Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/jsonschema/_legacy_validators.py: 12%
179 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1from jsonschema import _utils
2from jsonschema.exceptions import ValidationError
5def id_of_ignore_ref(property="$id"):
6 def id_of(schema):
7 """
8 Ignore an ``$id`` sibling of ``$ref`` if it is present.
10 Otherwise, return the ID of the given schema.
11 """
12 if schema is True or schema is False or "$ref" in schema:
13 return ""
14 return schema.get(property, "")
15 return id_of
18def ignore_ref_siblings(schema):
19 """
20 Ignore siblings of ``$ref`` if it is present.
22 Otherwise, return all keywords.
24 Suitable for use with `create`'s ``applicable_validators`` argument.
25 """
26 ref = schema.get("$ref")
27 if ref is not None:
28 return [("$ref", ref)]
29 else:
30 return schema.items()
33def dependencies_draft3(validator, dependencies, instance, schema):
34 if not validator.is_type(instance, "object"):
35 return
37 for property, dependency in dependencies.items():
38 if property not in instance:
39 continue
41 if validator.is_type(dependency, "object"):
42 yield from validator.descend(
43 instance, dependency, schema_path=property,
44 )
45 elif validator.is_type(dependency, "string"):
46 if dependency not in instance:
47 message = f"{dependency!r} is a dependency of {property!r}"
48 yield ValidationError(message)
49 else:
50 for each in dependency:
51 if each not in instance:
52 message = f"{each!r} is a dependency of {property!r}"
53 yield ValidationError(message)
56def dependencies_draft4_draft6_draft7(
57 validator,
58 dependencies,
59 instance,
60 schema,
61):
62 """
63 Support for the ``dependencies`` keyword from pre-draft 2019-09.
65 In later drafts, the keyword was split into separate
66 ``dependentRequired`` and ``dependentSchemas`` validators.
67 """
68 if not validator.is_type(instance, "object"):
69 return
71 for property, dependency in dependencies.items():
72 if property not in instance:
73 continue
75 if validator.is_type(dependency, "array"):
76 for each in dependency:
77 if each not in instance:
78 message = f"{each!r} is a dependency of {property!r}"
79 yield ValidationError(message)
80 else:
81 yield from validator.descend(
82 instance, dependency, schema_path=property,
83 )
86def disallow_draft3(validator, disallow, instance, schema):
87 for disallowed in _utils.ensure_list(disallow):
88 if validator.evolve(schema={"type": [disallowed]}).is_valid(instance):
89 message = f"{disallowed!r} is disallowed for {instance!r}"
90 yield ValidationError(message)
93def extends_draft3(validator, extends, instance, schema):
94 if validator.is_type(extends, "object"):
95 yield from validator.descend(instance, extends)
96 return
97 for index, subschema in enumerate(extends):
98 yield from validator.descend(instance, subschema, schema_path=index)
101def items_draft3_draft4(validator, items, instance, schema):
102 if not validator.is_type(instance, "array"):
103 return
105 if validator.is_type(items, "object"):
106 for index, item in enumerate(instance):
107 yield from validator.descend(item, items, path=index)
108 else:
109 for (index, item), subschema in zip(enumerate(instance), items):
110 yield from validator.descend(
111 item, subschema, path=index, schema_path=index,
112 )
115def items_draft6_draft7_draft201909(validator, items, instance, schema):
116 if not validator.is_type(instance, "array"):
117 return
119 if validator.is_type(items, "array"):
120 for (index, item), subschema in zip(enumerate(instance), items):
121 yield from validator.descend(
122 item, subschema, path=index, schema_path=index,
123 )
124 else:
125 for index, item in enumerate(instance):
126 yield from validator.descend(item, items, path=index)
129def minimum_draft3_draft4(validator, minimum, instance, schema):
130 if not validator.is_type(instance, "number"):
131 return
133 if schema.get("exclusiveMinimum", False):
134 failed = instance <= minimum
135 cmp = "less than or equal to"
136 else:
137 failed = instance < minimum
138 cmp = "less than"
140 if failed:
141 message = f"{instance!r} is {cmp} the minimum of {minimum!r}"
142 yield ValidationError(message)
145def maximum_draft3_draft4(validator, maximum, instance, schema):
146 if not validator.is_type(instance, "number"):
147 return
149 if schema.get("exclusiveMaximum", False):
150 failed = instance >= maximum
151 cmp = "greater than or equal to"
152 else:
153 failed = instance > maximum
154 cmp = "greater than"
156 if failed:
157 message = f"{instance!r} is {cmp} the maximum of {maximum!r}"
158 yield ValidationError(message)
161def properties_draft3(validator, properties, instance, schema):
162 if not validator.is_type(instance, "object"):
163 return
165 for property, subschema in properties.items():
166 if property in instance:
167 yield from validator.descend(
168 instance[property],
169 subschema,
170 path=property,
171 schema_path=property,
172 )
173 elif subschema.get("required", False):
174 error = ValidationError(f"{property!r} is a required property")
175 error._set(
176 validator="required",
177 validator_value=subschema["required"],
178 instance=instance,
179 schema=schema,
180 )
181 error.path.appendleft(property)
182 error.schema_path.extend([property, "required"])
183 yield error
186def type_draft3(validator, types, instance, schema):
187 types = _utils.ensure_list(types)
189 all_errors = []
190 for index, type in enumerate(types):
191 if validator.is_type(type, "object"):
192 errors = list(validator.descend(instance, type, schema_path=index))
193 if not errors:
194 return
195 all_errors.extend(errors)
196 else:
197 if validator.is_type(instance, type):
198 return
199 else:
200 reprs = []
201 for type in types:
202 try:
203 reprs.append(repr(type["name"]))
204 except Exception:
205 reprs.append(repr(type))
206 yield ValidationError(
207 f"{instance!r} is not of type {', '.join(reprs)}",
208 context=all_errors,
209 )
212def contains_draft6_draft7(validator, contains, instance, schema):
213 if not validator.is_type(instance, "array"):
214 return
216 if not any(
217 validator.evolve(schema=contains).is_valid(element)
218 for element in instance
219 ):
220 yield ValidationError(
221 f"None of {instance!r} are valid under the given schema",
222 )
225def recursiveRef(validator, recursiveRef, instance, schema):
226 lookup_url, target = validator.resolver.resolution_scope, validator.schema
228 for each in reversed(validator.resolver._scopes_stack[1:]):
229 lookup_url, next_target = validator.resolver.resolve(each)
230 if next_target.get("$recursiveAnchor"):
231 target = next_target
232 else:
233 break
235 fragment = recursiveRef.lstrip("#")
236 subschema = validator.resolver.resolve_fragment(target, fragment)
237 # FIXME: This is gutted (and not calling .descend) because it can trigger
238 # recursion errors, so there's a bug here. Re-enable the tests to
239 # see it.
240 subschema
241 return []
244def find_evaluated_item_indexes_by_schema(validator, instance, schema):
245 """
246 Get all indexes of items that get evaluated under the current schema
248 Covers all keywords related to unevaluatedItems: items, prefixItems, if,
249 then, else, contains, unevaluatedItems, allOf, oneOf, anyOf
250 """
251 if validator.is_type(schema, "boolean"):
252 return []
253 evaluated_indexes = []
255 if "additionalItems" in schema:
256 return list(range(0, len(instance)))
258 if "$ref" in schema:
259 scope, resolved = validator.resolver.resolve(schema["$ref"])
260 validator.resolver.push_scope(scope)
262 try:
263 evaluated_indexes += find_evaluated_item_indexes_by_schema(
264 validator, instance, resolved,
265 )
266 finally:
267 validator.resolver.pop_scope()
269 if "items" in schema:
270 if validator.is_type(schema["items"], "object"):
271 return list(range(0, len(instance)))
272 evaluated_indexes += list(range(0, len(schema["items"])))
274 if "if" in schema:
275 if validator.evolve(schema=schema["if"]).is_valid(instance):
276 evaluated_indexes += find_evaluated_item_indexes_by_schema(
277 validator, instance, schema["if"],
278 )
279 if "then" in schema:
280 evaluated_indexes += find_evaluated_item_indexes_by_schema(
281 validator, instance, schema["then"],
282 )
283 else:
284 if "else" in schema:
285 evaluated_indexes += find_evaluated_item_indexes_by_schema(
286 validator, instance, schema["else"],
287 )
289 for keyword in ["contains", "unevaluatedItems"]:
290 if keyword in schema:
291 for k, v in enumerate(instance):
292 if validator.evolve(schema=schema[keyword]).is_valid(v):
293 evaluated_indexes.append(k)
295 for keyword in ["allOf", "oneOf", "anyOf"]:
296 if keyword in schema:
297 for subschema in schema[keyword]:
298 errs = list(validator.descend(instance, subschema))
299 if not errs:
300 evaluated_indexes += find_evaluated_item_indexes_by_schema(
301 validator, instance, subschema,
302 )
304 return evaluated_indexes
307def unevaluatedItems_draft2019(validator, unevaluatedItems, instance, schema):
308 if not validator.is_type(instance, "array"):
309 return
310 evaluated_item_indexes = find_evaluated_item_indexes_by_schema(
311 validator, instance, schema,
312 )
313 unevaluated_items = [
314 item for index, item in enumerate(instance)
315 if index not in evaluated_item_indexes
316 ]
317 if unevaluated_items:
318 error = "Unevaluated items are not allowed (%s %s unexpected)"
319 yield ValidationError(error % _utils.extras_msg(unevaluated_items))