(value: Any, schema: Mapping[str, Any], *, path: str, issues: list[ValidationIssue])
| 45 | |
| 46 | |
| 47 | def _validate(value: Any, schema: Mapping[str, Any], *, path: str, issues: list[ValidationIssue]) -> None: |
| 48 | if "oneOf" in schema: |
| 49 | options = schema.get("oneOf") or [] |
| 50 | if any(_is_valid(value, opt) for opt in options): |
| 51 | return |
| 52 | issues.append(ValidationIssue(path, "does not match any allowed schema (oneOf)")) |
| 53 | return |
| 54 | |
| 55 | if "anyOf" in schema: |
| 56 | options = schema.get("anyOf") or [] |
| 57 | if any(_is_valid(value, opt) for opt in options): |
| 58 | return |
| 59 | issues.append(ValidationIssue(path, "does not match any allowed schema (anyOf)")) |
| 60 | return |
| 61 | |
| 62 | expected_type = schema.get("type") |
| 63 | if expected_type: |
| 64 | if expected_type == "object": |
| 65 | if not isinstance(value, dict): |
| 66 | issues.append(ValidationIssue(path, f"expected object, got {_type_name(value)}")) |
| 67 | return |
| 68 | _validate_object(value, schema, path=path, issues=issues) |
| 69 | return |
| 70 | if expected_type == "array": |
| 71 | if not isinstance(value, list): |
| 72 | issues.append(ValidationIssue(path, f"expected array, got {_type_name(value)}")) |
| 73 | return |
| 74 | item_schema = schema.get("items") |
| 75 | if isinstance(item_schema, dict): |
| 76 | for idx, item in enumerate(value): |
| 77 | _validate(item, item_schema, path=f"{path}[{idx}]", issues=issues) |
| 78 | return |
| 79 | if expected_type == "string": |
| 80 | if not isinstance(value, str): |
| 81 | issues.append(ValidationIssue(path, f"expected string, got {_type_name(value)}")) |
| 82 | return |
| 83 | elif expected_type == "boolean": |
| 84 | if not isinstance(value, bool): |
| 85 | issues.append(ValidationIssue(path, f"expected boolean, got {_type_name(value)}")) |
| 86 | return |
| 87 | elif expected_type == "number": |
| 88 | if not isinstance(value, (int, float)) or isinstance(value, bool): |
| 89 | issues.append(ValidationIssue(path, f"expected number, got {_type_name(value)}")) |
| 90 | return |
| 91 | elif expected_type == "integer": |
| 92 | if not isinstance(value, int) or isinstance(value, bool): |
| 93 | issues.append(ValidationIssue(path, f"expected integer, got {_type_name(value)}")) |
| 94 | return |
| 95 | |
| 96 | if "enum" in schema: |
| 97 | allowed = schema.get("enum") or [] |
| 98 | if value not in allowed: |
| 99 | issues.append(ValidationIssue(path, f"expected one of {allowed!r}, got {value!r}")) |
| 100 | return |
| 101 | |
| 102 | |
| 103 | def _validate_object(value: dict[str, Any], schema: Mapping[str, Any], *, path: str, issues: list[ValidationIssue]) -> None: |
no test coverage detected