|
36 | 36 | import contextlib
|
37 | 37 | import itertools
|
38 | 38 | import types
|
| 39 | +from copy import deepcopy |
39 | 40 | from functools import partial
|
40 | 41 |
|
41 | 42 | with contextlib.suppress(ImportError):
|
@@ -197,17 +198,21 @@ def collect(self, model):
|
197 | 198 | for var, reporter in self.model_reporters.items():
|
198 | 199 | # Check if lambda or partial function
|
199 | 200 | if isinstance(reporter, types.LambdaType | partial):
|
200 |
| - self.model_vars[var].append(reporter(model)) |
| 201 | + # Use deepcopy to store a copy of the data, |
| 202 | + # preventing references from being updated across steps. |
| 203 | + self.model_vars[var].append(deepcopy(reporter(model))) |
201 | 204 | # Check if model attribute
|
202 | 205 | elif isinstance(reporter, str):
|
203 |
| - self.model_vars[var].append(getattr(model, reporter, None)) |
| 206 | + self.model_vars[var].append( |
| 207 | + deepcopy(getattr(model, reporter, None)) |
| 208 | + ) |
204 | 209 | # Check if function with arguments
|
205 | 210 | elif isinstance(reporter, list):
|
206 |
| - self.model_vars[var].append(reporter[0](*reporter[1])) |
207 |
| - # TODO: Check if method of a class, as of now it is assumed |
208 |
| - # implicitly if the other checks fail. |
| 211 | + self.model_vars[var].append(deepcopy(reporter[0](*reporter[1]))) |
| 212 | + # Assume it's a callable otherwise (e.g., method) |
| 213 | + # TODO: Check if method of a class explicitly |
209 | 214 | else:
|
210 |
| - self.model_vars[var].append(reporter()) |
| 215 | + self.model_vars[var].append(deepcopy(reporter())) |
211 | 216 |
|
212 | 217 | if self.agent_reporters:
|
213 | 218 | agent_records = self._record_agents(model)
|
|
0 commit comments