Remember a call.
(*args: Any, **kwargs: Any)
| 321 | |
| 322 | # It also returns `Any` but it only happens during `subject.xxx` call. |
| 323 | def decorate(*args: Any, **kwargs: Any) -> Self: |
| 324 | """Remember a call.""" |
| 325 | call: Call = {"name": attr, "args": args, "kwargs": kwargs} |
| 326 | # Ensure that signature is valid |
| 327 | getattr(self.subject, attr)(*args, **kwargs) |
| 328 | |
| 329 | try: |
| 330 | key = self.serialize(call) |
| 331 | except TypeError as e: |
| 332 | # Serialization error will occur if unpredicted return value |
| 333 | # will be used as an argument to other call |
| 334 | msg = f"Failed to serialize call: '{call}'." |
| 335 | values = list(flatten(args)) + list(flatten(kwargs.values())) |
| 336 | prophecy = next((value for value in values if isinstance(value, Prophecy)), None) |
| 337 | if prophecy is None: |
| 338 | msg += "\nCouldn't find related Prophecy." |
| 339 | raise TypeError(msg) from e |
| 340 | |
| 341 | msg += "\nPossibly due to unpredicted return value for some call." |
| 342 | calls_strs: list[str] = [] |
| 343 | for call in reversed(prophecy.calls): |
| 344 | call_str = self.serialize(call) |
| 345 | if call_str in prophecy.return_values: |
| 346 | continue |
| 347 | calls_strs.append(f"- {call}") |
| 348 | if calls_strs: |
| 349 | msg += "\nSee the list of the recent calls without return values:\n" |
| 350 | msg += "\n".join(calls_strs) |
| 351 | raise TypeError(msg) from e |
| 352 | |
| 353 | self.calls.append(call) |
| 354 | if key in self.return_values: |
| 355 | return self.return_values[key] |
| 356 | return self |
| 357 | |
| 358 | return decorate |
| 359 |