Skip to content

Commit bfc6fc4

Browse files
committed
Use deepcopy to avoid modifying responses
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.
1 parent 1935f25 commit bfc6fc4

File tree

1 file changed

+5
-10
lines changed

1 file changed

+5
-10
lines changed

src/labthings/apispec/plugins.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import re
22

33
from apispec import BasePlugin
4+
from copy import deepcopy
45

56
from apispec.ext.marshmallow import (
67
MarshmallowPlugin as _MarshmallowPlugin,
@@ -101,11 +102,11 @@ def spec_for_interaction(cls, interaction):
101102
"parameters": [],
102103
}
103104
# Allow custom responses from the class, overridden by the method
104-
d[method]["responses"].update(getattr(interaction, "responses", {}))
105-
d[method]["responses"].update(getattr(prop, "responses", {}))
105+
d[method]["responses"].update(deepcopy(getattr(interaction, "responses", {})))
106+
d[method]["responses"].update(deepcopy(getattr(prop, "responses", {})))
106107
# Allow custom parameters from the class & method
107-
d[method]["parameters"].extend(getattr(interaction, "parameters", {}))
108-
d[method]["parameters"].extend(getattr(prop, "parameters", {}))
108+
d[method]["parameters"].extend(deepcopy(getattr(interaction, "parameters", {})))
109+
d[method]["parameters"].extend(deepcopy(getattr(prop, "parameters", {})))
109110
return d
110111

111112
@classmethod
@@ -148,10 +149,6 @@ def spec_for_property(cls, prop):
148149
},
149150
)
150151

151-
# Enable custom responses from all methods
152-
for method in d.keys():
153-
d[method]["responses"].update(prop.responses)
154-
155152
return d
156153

157154
def spec_for_action(self, action):
@@ -245,8 +242,6 @@ def spec_for_action(self, action):
245242
},
246243
},
247244
)
248-
# Enable custom responses from POST
249-
d["post"]["responses"].update(action.responses)
250245
return d
251246

252247
@classmethod

0 commit comments

Comments
 (0)