From 7993de894ed9f826bc50c8545dceb600b1814b9b Mon Sep 17 00:00:00 2001 From: Gavin Hurlbut Date: Sat, 18 Apr 2020 23:49:40 -0700 Subject: [PATCH] Small change to Schema model to allow generated specs to be picklable - 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. --- openapi_core/schema/schemas/models.py | 6 +++++- openapi_core/unmarshalling/schemas/factories.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openapi_core/schema/schemas/models.py b/openapi_core/schema/schemas/models.py index a4109c4..534e1f9 100644 --- a/openapi_core/schema/schemas/models.py +++ b/openapi_core/schema/schemas/models.py @@ -67,8 +67,12 @@ class Schema(object): self._source = _source + # Overriding object.__dict__ is a VERY bad idea as it totally breaks any + # possibility of pickling this object. Pickling marshalls via object.__dict__ + # via default __getstate__ and __setstate__ methods. This is now renamed to + # keep the functionality for the validators, but keep pickling operational. @property - def __dict__(self): + def __newdict__(self): return self._source or self.to_dict() def to_dict(self): diff --git a/openapi_core/unmarshalling/schemas/factories.py b/openapi_core/unmarshalling/schemas/factories.py index 0952d00..272f831 100644 --- a/openapi_core/unmarshalling/schemas/factories.py +++ b/openapi_core/unmarshalling/schemas/factories.py @@ -86,7 +86,7 @@ class SchemaUnmarshallersFactory(object): } if self.context is not None: kwargs[self.CONTEXT_VALIDATION[self.context]] = True - return OAS30Validator(schema.__dict__, **kwargs) + return OAS30Validator(schema.__newdict__, **kwargs) def _get_format_checker(self): fc = deepcopy(oas30_format_checker)