- overriding __dict__ is death for pickling. I renamed it to __newdict__
and tweaked the one user of it, and now this part of the structure is
working fine for pickling
- there are also upstream changes in jsonschema that need to be in for the
overall success
- this allows me to create the API spec from a swagger file once (which takes
2-20s for the files I'm working with), and cache the result as a pickle file
for loading on the next startup (assuming the swagger file hasn't been
updated). The load from pickle files takes 2-5ms. This is an improvement
of load time by 3 orders of magnitude.
The `integer_types` is always a tuple. When checking
if an instance is a number it fails because it's doing a comparison against a tuple
instead of real type.
➜ python -c "from six import integer_types;import sys;print(integer_types);print(sys.version)"
(<type 'int'>, <type 'long'>)
2.7.16 (default, Apr 6 2019, 01:42:57)
[GCC 8.3.0]
➜ python3 -c "from six import integer_types;import sys;print(integer_types);print(sys.version)"
(<class 'int'>,)
3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.3.0]
And spec defines a number as both int and float https://swagger.io/docs/specification/data-models/data-types/#numbers so both validators need to support both types.
`password` is a valid OpenAPIv3 string format, that is used as a UI hint
for frontend clients to mask the input field.
It was already present in the `SchemaFormat` enum, but it was not
handled in `_unmarshal_string` that uses `STRING_FORMAT_CALLABLE_GETTER`
to decide how to unmarshal a string, which would result in an error like
this one:
```
Traceback (most recent call last):
[... snip ...]
File ".venv/lib/python3.7/site-packages/openapi_core/validation/request/validators.py", line 37, in validate
body, body_errors = self._get_body(request, operation)
File ".venv/lib/python3.7/site-packages/openapi_core/validation/request/validators.py", line 82, in _get_body
body = media_type.unmarshal(raw_body, self.custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/media_types/models.py", line 45, in unmarshal
unmarshalled = self.schema.unmarshal(deserialized, custom_formatters=custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 189, in unmarshal
casted = self.cast(value, custom_formatters=custom_formatters, strict=strict)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 179, in cast
return cast_callable(value)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 295, in _unmarshal_object
value, custom_formatters=custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 335, in _unmarshal_properties
prop_value, custom_formatters=custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 189, in unmarshal
casted = self.cast(value, custom_formatters=custom_formatters, strict=strict)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 179, in cast
return cast_callable(value)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 295, in _unmarshal_object
value, custom_formatters=custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 335, in _unmarshal_properties
prop_value, custom_formatters=custom_formatters)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 189, in unmarshal
casted = self.cast(value, custom_formatters=custom_formatters, strict=strict)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 179, in cast
return cast_callable(value)
File ".venv/lib/python3.7/site-packages/openapi_core/schema/schemas/models.py", line 215, in _unmarshal_string
formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
KeyError: <SchemaFormat.PASSWORD: 'password'>
```
This is important because it does the correct validation over items that
are restricted in "oneOf", so that it's possible to use schemas that are
superset of one another as items of "oneOf".
Before this change, if a UUID instance got received as value in the
Schema, it was breaking the unmarshal because UUID instances can't be
used as values to instantiate other UUIDs.
Main motivation behind this change is to be able to catch exceptions
as per raise_for_errors() helpers, but to inspect state of exceptions
instead of just getting a rendered string. This allows rendering
exceptions into JSON, for example.