Skip to content

Commit d501318

Browse files
committed
fix: resolve UnboundLocalError for first_valid in oneOf validator
The first_valid variable was only assigned inside the for-else loop when a valid schema was found. If no valid schema was found initially but more_valid schemas were discovered later, the code would attempt to access an undefined variable. Initialize first_valid to None and check before using it.
1 parent efe702f commit d501318

1 file changed

Lines changed: 25 additions & 18 deletions

File tree

jsonschema/_keywords.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ def patternProperties(validator, patternProperties, instance, schema):
2121
for k, v in instance.items():
2222
if re.search(pattern, k):
2323
yield from validator.descend(
24-
v, subschema, path=k, schema_path=pattern,
24+
v,
25+
subschema,
26+
path=k,
27+
schema_path=pattern,
2528
)
2629

2730

@@ -204,18 +207,13 @@ def maxItems(validator, mI, instance, schema):
204207

205208

206209
def uniqueItems(validator, uI, instance, schema):
207-
if (
208-
uI
209-
and validator.is_type(instance, "array")
210-
and not uniq(instance)
211-
):
210+
if uI and validator.is_type(instance, "array") and not uniq(instance):
212211
yield ValidationError(f"{instance!r} has non-unique elements")
213212

214213

215214
def pattern(validator, patrn, instance, schema):
216-
if (
217-
validator.is_type(instance, "string")
218-
and not re.search(patrn, instance)
215+
if validator.is_type(instance, "string") and not re.search(
216+
patrn, instance
219217
):
220218
yield ValidationError(f"{instance!r} does not match {patrn!r}")
221219

@@ -262,7 +260,9 @@ def dependentSchemas(validator, dependentSchemas, instance, schema):
262260
if property not in instance:
263261
continue
264262
yield from validator.descend(
265-
instance, dependency, schema_path=property,
263+
instance,
264+
dependency,
265+
schema_path=property,
266266
)
267267

268268

@@ -312,7 +312,8 @@ def required(validator, required, instance, schema):
312312
def minProperties(validator, mP, instance, schema):
313313
if validator.is_type(instance, "object") and len(instance) < mP:
314314
message = (
315-
"should be non-empty" if mP == 1
315+
"should be non-empty"
316+
if mP == 1
316317
else "does not have enough properties"
317318
)
318319
yield ValidationError(f"{instance!r} {message}")
@@ -323,8 +324,7 @@ def maxProperties(validator, mP, instance, schema):
323324
return
324325
if validator.is_type(instance, "object") and len(instance) > mP:
325326
message = (
326-
"is expected to be empty" if mP == 0
327-
else "has too many properties"
327+
"is expected to be empty" if mP == 0 else "has too many properties"
328328
)
329329
yield ValidationError(f"{instance!r} {message}")
330330

@@ -351,6 +351,7 @@ def anyOf(validator, anyOf, instance, schema):
351351
def oneOf(validator, oneOf, instance, schema):
352352
subschemas = enumerate(oneOf)
353353
all_errors = []
354+
first_valid = None
354355
for index, subschema in subschemas:
355356
errs = list(validator.descend(instance, subschema, schema_path=index))
356357
if not errs:
@@ -364,10 +365,11 @@ def oneOf(validator, oneOf, instance, schema):
364365
)
365366

366367
more_valid = [
367-
each for _, each in subschemas
368+
each
369+
for _, each in subschemas
368370
if validator.evolve(schema=each).is_valid(instance)
369371
]
370-
if more_valid:
372+
if more_valid and first_valid is not None:
371373
more_valid.append(first_valid)
372374
reprs = ", ".join(repr(schema) for schema in more_valid)
373375
yield ValidationError(f"{instance!r} is valid under each of {reprs}")
@@ -393,10 +395,13 @@ def unevaluatedItems(validator, unevaluatedItems, instance, schema):
393395
if not validator.is_type(instance, "array"):
394396
return
395397
evaluated_item_indexes = find_evaluated_item_indexes_by_schema(
396-
validator, instance, schema,
398+
validator,
399+
instance,
400+
schema,
397401
)
398402
unevaluated_items = [
399-
item for index, item in enumerate(instance)
403+
item
404+
for index, item in enumerate(instance)
400405
if index not in evaluated_item_indexes
401406
]
402407
if unevaluated_items:
@@ -408,7 +413,9 @@ def unevaluatedProperties(validator, unevaluatedProperties, instance, schema):
408413
if not validator.is_type(instance, "object"):
409414
return
410415
evaluated_keys = find_evaluated_property_keys_by_schema(
411-
validator, instance, schema,
416+
validator,
417+
instance,
418+
schema,
412419
)
413420
unevaluated_keys = []
414421
for property in instance:

0 commit comments

Comments
 (0)