Skip to content

Commit

Permalink
Use deepcopy to avoid modifying responses
Browse files Browse the repository at this point in the history
Responses and parameters can be stored as
dictionary/list properties on View subclasses, or on
HTTP operation methods.
The LabThings apispec plugin includes these dictionaries in
the spec, and the Marshmallow plugin then modifies the
spec to reference schemas.

In unit testing, we build the API description multiple times
per run of Python, which means that the second time it's
built, the dictionaries have been modified and contain
only {"$ref": "#/components/schema/name"} instead of a Schema object.

This commit uses deepcopy so that the descriptions on the
classes/methods are not modified, and unit testing works again.
  • Loading branch information
rwb27 committed Jul 21, 2021
1 parent 1935f25 commit bfc6fc4
Showing 1 changed file with 5 additions and 10 deletions.
15 changes: 5 additions & 10 deletions src/labthings/apispec/plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re

from apispec import BasePlugin
from copy import deepcopy

from apispec.ext.marshmallow import (
MarshmallowPlugin as _MarshmallowPlugin,
Expand Down Expand Up @@ -101,11 +102,11 @@ def spec_for_interaction(cls, interaction):
"parameters": [],
}
# Allow custom responses from the class, overridden by the method
d[method]["responses"].update(getattr(interaction, "responses", {}))
d[method]["responses"].update(getattr(prop, "responses", {}))
d[method]["responses"].update(deepcopy(getattr(interaction, "responses", {})))
d[method]["responses"].update(deepcopy(getattr(prop, "responses", {})))
# Allow custom parameters from the class & method
d[method]["parameters"].extend(getattr(interaction, "parameters", {}))
d[method]["parameters"].extend(getattr(prop, "parameters", {}))
d[method]["parameters"].extend(deepcopy(getattr(interaction, "parameters", {})))
d[method]["parameters"].extend(deepcopy(getattr(prop, "parameters", {})))
return d

@classmethod
Expand Down Expand Up @@ -148,10 +149,6 @@ def spec_for_property(cls, prop):
},
)

# Enable custom responses from all methods
for method in d.keys():
d[method]["responses"].update(prop.responses)

return d

def spec_for_action(self, action):
Expand Down Expand Up @@ -245,8 +242,6 @@ def spec_for_action(self, action):
},
},
)
# Enable custom responses from POST
d["post"]["responses"].update(action.responses)
return d

@classmethod
Expand Down

0 comments on commit bfc6fc4

Please sign in to comment.