|
1 | 1 | import datetime |
2 | 2 | import decimal |
3 | 3 | import uuid |
| 4 | +from copy import deepcopy |
4 | 5 | from inspect import isclass |
5 | 6 |
|
6 | 7 | from marshmallow import Schema, fields, missing, validate |
|
68 | 69 | } |
69 | 70 |
|
70 | 71 |
|
| 72 | +def convert_type_list_to_oneof(schema): |
| 73 | + """Avoid setting `type` to a list, using `oneOf` |
| 74 | +
|
| 75 | + JSONSchema allows datatypes to be specified as lists, which |
| 76 | + means the type may be any of the specified values. This is |
| 77 | + not permitted by W3C Thing Description. This function will |
| 78 | + use the oneOf mechanism in JSONSchema to convert schemas |
| 79 | + that use a list of types into a series of schemas each with |
| 80 | + one type. Those schemas are then nested together using |
| 81 | + OneOf. |
| 82 | + """ |
| 83 | + if "type" not in schema or type(schema["type"]) != list: |
| 84 | + return schema |
| 85 | + subschemas = [] |
| 86 | + for t in schema["type"]: |
| 87 | + subschemas.append(deepcopy(schema)) |
| 88 | + subschemas[-1]["type"] = t |
| 89 | + return {"oneOf": subschemas} |
| 90 | + |
| 91 | + |
71 | 92 | class JSONSchema(Schema): |
72 | 93 | """Converts to JSONSchema as defined by http://json-schema.org/.""" |
73 | 94 |
|
@@ -202,6 +223,8 @@ def _get_schema_for_field(self, obj, field): |
202 | 223 | ) |
203 | 224 | if base_class is not None and base_class in FIELD_VALIDATORS: |
204 | 225 | schema = FIELD_VALIDATORS[base_class](schema, field, validator, obj) |
| 226 | + if "type" in schema and type(schema["type"]) == list: |
| 227 | + schema = convert_type_list_to_oneof(schema) |
205 | 228 | return schema |
206 | 229 |
|
207 | 230 | def _from_nested_schema(self, _, field): |
|
0 commit comments