|
2 | 2 | # |
3 | 3 | # SPDX-License-Identifier: Apache-2.0 |
4 | 4 |
|
| 5 | +from copy import copy, deepcopy |
5 | 6 | from dataclasses import fields, is_dataclass |
6 | 7 | from inspect import getdoc |
7 | 8 | from typing import Any, Callable, Dict, Optional, Union, get_args, get_origin |
@@ -392,3 +393,29 @@ def _create_property_schema(self, python_type: Any, description: str, default: A |
392 | 393 | schema["default"] = default |
393 | 394 |
|
394 | 395 | return schema |
| 396 | + |
| 397 | + def __deepcopy__(self, memo: Dict[Any, Any]) -> "ComponentTool": |
| 398 | + # Jinja2 templates throw an Exception when we deepcopy them (see https://github.com/pallets/jinja/issues/758) |
| 399 | + # When we use a ComponentTool in a pipeline at runtime, we deepcopy the tool |
| 400 | + # We overwrite ComponentTool.__deepcopy__ to fix this in experimental until a more comprehensive fix is merged. |
| 401 | + # We track the issue here: https://github.com/deepset-ai/haystack/issues/9011 |
| 402 | + result = copy(self) |
| 403 | + |
| 404 | + # Add the object to the memo dictionary to handle circular references |
| 405 | + memo[id(self)] = result |
| 406 | + |
| 407 | + # Deep copy all attributes with exception handling |
| 408 | + for key, value in self.__dict__.items(): |
| 409 | + try: |
| 410 | + # Try to deep copy the attribute |
| 411 | + setattr(result, key, deepcopy(value, memo)) |
| 412 | + except TypeError: |
| 413 | + # Fall back to using the original attribute for components that use Jinja2-templates |
| 414 | + logger.debug( |
| 415 | + "deepcopy of ComponentTool {tool_name} failed. Using original attribute '{attribute}' instead.", |
| 416 | + tool_name=self.name, |
| 417 | + attribute=key, |
| 418 | + ) |
| 419 | + setattr(result, key, getattr(self, key)) |
| 420 | + |
| 421 | + return result |
0 commit comments