|
3 | 3 | # SPDX-License-Identifier: Apache-2.0 |
4 | 4 |
|
5 | 5 | import warnings |
| 6 | +from copy import deepcopy |
6 | 7 |
|
7 | 8 | import pytest |
8 | 9 |
|
@@ -101,6 +102,30 @@ def test_from_dict(self): |
101 | 102 | assert answer.context_offset == ExtractedAnswer.Span(14, 16) |
102 | 103 | assert answer.meta == {"meta_key": "meta_value"} |
103 | 104 |
|
| 105 | + def test_from_dict_does_not_mutate_input(self): |
| 106 | + data = { |
| 107 | + "type": "haystack.dataclasses.answer.ExtractedAnswer", |
| 108 | + "init_parameters": { |
| 109 | + "data": "42", |
| 110 | + "query": "What is the answer?", |
| 111 | + "document": { |
| 112 | + "id": "8f800a524b139484fc719ecc35f971a080de87618319bc4836b784d69baca57f", |
| 113 | + "content": "I thought a lot about this. The answer is 42.", |
| 114 | + }, |
| 115 | + "context": "The answer is 42.", |
| 116 | + "score": 1.0, |
| 117 | + "document_offset": {"start": 42, "end": 44}, |
| 118 | + "context_offset": {"start": 14, "end": 16}, |
| 119 | + "meta": {"meta_key": "meta_value"}, |
| 120 | + }, |
| 121 | + } |
| 122 | + snapshot = deepcopy(data) |
| 123 | + first = ExtractedAnswer.from_dict(data) |
| 124 | + # from_dict must not mutate its input dictionary |
| 125 | + assert data == snapshot |
| 126 | + # deserializing the same dictionary again must still work and be equal |
| 127 | + assert ExtractedAnswer.from_dict(data) == first |
| 128 | + |
104 | 129 | def test_no_warning_on_init(self): |
105 | 130 | with warnings.catch_warnings(): |
106 | 131 | warnings.simplefilter("error", Warning) |
@@ -264,6 +289,29 @@ def test_from_dict_with_chat_message_in_meta(self): |
264 | 289 | assert answer.meta["meta_key"] == "meta_value" |
265 | 290 | assert answer.meta["all_messages"] == [ChatMessage.from_user("What is the answer?")] |
266 | 291 |
|
| 292 | + def test_from_dict_does_not_mutate_input(self): |
| 293 | + data = { |
| 294 | + "type": "haystack.dataclasses.answer.GeneratedAnswer", |
| 295 | + "init_parameters": { |
| 296 | + "data": "42", |
| 297 | + "query": "What is the answer?", |
| 298 | + "documents": [ |
| 299 | + {"id": "1", "content": "The answer is 42."}, |
| 300 | + {"id": "2", "content": "I believe the answer is 42."}, |
| 301 | + ], |
| 302 | + "meta": { |
| 303 | + "meta_key": "meta_value", |
| 304 | + "all_messages": [ChatMessage.from_user("What is the answer?").to_dict()], |
| 305 | + }, |
| 306 | + }, |
| 307 | + } |
| 308 | + snapshot = deepcopy(data) |
| 309 | + first = GeneratedAnswer.from_dict(data) |
| 310 | + # from_dict must not mutate its input dictionary |
| 311 | + assert data == snapshot |
| 312 | + # deserializing the same dictionary again must still work and be equal |
| 313 | + assert GeneratedAnswer.from_dict(data) == first |
| 314 | + |
267 | 315 | def test_from_dict_with_empty_all_messages(self): |
268 | 316 | # An empty `all_messages` list must not crash deserialization: `is not None` |
269 | 317 | # let `[]` through and then indexed `all_messages[0]`, raising IndexError. |
|
0 commit comments