@@ -57,20 +57,17 @@ def test_to_dict(self):
5757 meta = {"meta_key" : "meta_value" },
5858 )
5959 assert answer .to_dict () == {
60- "type" : "haystack.dataclasses.answer.ExtractedAnswer" ,
61- "init_parameters" : {
62- "data" : "42" ,
63- "query" : "What is the answer?" ,
64- "document" : document .to_dict (flatten = False ),
65- "context" : "The answer is 42." ,
66- "score" : 1.0 ,
67- "document_offset" : {"start" : 42 , "end" : 44 },
68- "context_offset" : {"start" : 14 , "end" : 16 },
69- "meta" : {"meta_key" : "meta_value" },
70- },
60+ "data" : "42" ,
61+ "query" : "What is the answer?" ,
62+ "document" : document .to_dict (flatten = False ),
63+ "context" : "The answer is 42." ,
64+ "score" : 1.0 ,
65+ "document_offset" : {"start" : 42 , "end" : 44 },
66+ "context_offset" : {"start" : 14 , "end" : 16 },
67+ "meta" : {"meta_key" : "meta_value" },
7168 }
7269
73- def test_from_dict (self ):
70+ def test_from_dict_legacy (self ):
7471 answer = ExtractedAnswer .from_dict (
7572 {
7673 "type" : "haystack.dataclasses.answer.ExtractedAnswer" ,
@@ -101,6 +98,34 @@ def test_from_dict(self):
10198 assert answer .context_offset == ExtractedAnswer .Span (14 , 16 )
10299 assert answer .meta == {"meta_key" : "meta_value" }
103100
101+ def test_from_dict (self ):
102+ answer = ExtractedAnswer .from_dict (
103+ {
104+ "data" : "42" ,
105+ "query" : "What is the answer?" ,
106+ "document" : {
107+ "id" : "8f800a524b139484fc719ecc35f971a080de87618319bc4836b784d69baca57f" ,
108+ "content" : "I thought a lot about this. The answer is 42." ,
109+ },
110+ "context" : "The answer is 42." ,
111+ "score" : 1.0 ,
112+ "document_offset" : {"start" : 42 , "end" : 44 },
113+ "context_offset" : {"start" : 14 , "end" : 16 },
114+ "meta" : {"meta_key" : "meta_value" },
115+ }
116+ )
117+ assert answer .data == "42"
118+ assert answer .query == "What is the answer?"
119+ assert answer .document == Document (
120+ id = "8f800a524b139484fc719ecc35f971a080de87618319bc4836b784d69baca57f" ,
121+ content = "I thought a lot about this. The answer is 42." ,
122+ )
123+ assert answer .context == "The answer is 42."
124+ assert answer .score == 1.0
125+ assert answer .document_offset == ExtractedAnswer .Span (42 , 44 )
126+ assert answer .context_offset == ExtractedAnswer .Span (14 , 16 )
127+ assert answer .meta == {"meta_key" : "meta_value" }
128+
104129 def test_no_warning_on_init (self ):
105130 with warnings .catch_warnings ():
106131 warnings .simplefilter ("error" , Warning )
@@ -158,10 +183,7 @@ def test_protocol(self):
158183
159184 def test_to_dict (self ):
160185 answer = GeneratedAnswer (data = "42" , query = "What is the answer?" , documents = [])
161- assert answer .to_dict () == {
162- "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
163- "init_parameters" : {"data" : "42" , "query" : "What is the answer?" , "documents" : [], "meta" : {}},
164- }
186+ assert answer .to_dict () == {"data" : "42" , "query" : "What is the answer?" , "documents" : [], "meta" : {}}
165187
166188 def test_to_dict_with_meta (self ):
167189 answer = GeneratedAnswer (
@@ -171,13 +193,10 @@ def test_to_dict_with_meta(self):
171193 meta = {"meta_key" : "meta_value" , "all_messages" : ["What is the answer?" ]},
172194 )
173195 assert answer .to_dict () == {
174- "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
175- "init_parameters" : {
176- "data" : "42" ,
177- "query" : "What is the answer?" ,
178- "documents" : [],
179- "meta" : {"meta_key" : "meta_value" , "all_messages" : ["What is the answer?" ]},
180- },
196+ "data" : "42" ,
197+ "query" : "What is the answer?" ,
198+ "documents" : [],
199+ "meta" : {"meta_key" : "meta_value" , "all_messages" : ["What is the answer?" ]},
181200 }
182201
183202 def test_to_dict_with_chat_message_in_meta (self ):
@@ -193,19 +212,16 @@ def test_to_dict_with_chat_message_in_meta(self):
193212 meta = {"meta_key" : "meta_value" , "all_messages" : [ChatMessage .from_user ("What is the answer?" )]},
194213 )
195214 assert answer .to_dict () == {
196- "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
197- "init_parameters" : {
198- "data" : "42" ,
199- "query" : "What is the answer?" ,
200- "documents" : [d .to_dict (flatten = False ) for d in documents ],
201- "meta" : {
202- "meta_key" : "meta_value" ,
203- "all_messages" : [ChatMessage .from_user ("What is the answer?" ).to_dict ()],
204- },
215+ "data" : "42" ,
216+ "query" : "What is the answer?" ,
217+ "documents" : [d .to_dict (flatten = False ) for d in documents ],
218+ "meta" : {
219+ "meta_key" : "meta_value" ,
220+ "all_messages" : [ChatMessage .from_user ("What is the answer?" ).to_dict ()],
205221 },
206222 }
207223
208- def test_from_dict (self ):
224+ def test_from_dict_legacy (self ):
209225 answer = GeneratedAnswer .from_dict (
210226 {
211227 "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
@@ -217,7 +233,7 @@ def test_from_dict(self):
217233 assert answer .documents == []
218234 assert answer .meta == {}
219235
220- def test_from_dict_with_meta (self ):
236+ def test_from_dict_with_meta_legacy (self ):
221237 answer = GeneratedAnswer .from_dict (
222238 {
223239 "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
@@ -235,7 +251,7 @@ def test_from_dict_with_meta(self):
235251 assert answer .meta ["meta_key" ] == "meta_value"
236252 assert answer .meta ["all_messages" ] == ["What is the answer?" ]
237253
238- def test_from_dict_with_chat_message_in_meta (self ):
254+ def test_from_dict_with_chat_message_in_meta_legacy (self ):
239255 answer = GeneratedAnswer .from_dict (
240256 {
241257 "type" : "haystack.dataclasses.answer.GeneratedAnswer" ,
@@ -264,7 +280,7 @@ def test_from_dict_with_chat_message_in_meta(self):
264280 assert answer .meta ["meta_key" ] == "meta_value"
265281 assert answer .meta ["all_messages" ] == [ChatMessage .from_user ("What is the answer?" )]
266282
267- def test_from_dict_with_empty_all_messages (self ):
283+ def test_from_dict_with_empty_all_messages_legacy (self ):
268284 # An empty `all_messages` list must not crash deserialization: `is not None`
269285 # let `[]` through and then indexed `all_messages[0]`, raising IndexError.
270286 answer = GeneratedAnswer .from_dict (
@@ -280,6 +296,73 @@ def test_from_dict_with_empty_all_messages(self):
280296 )
281297 assert answer .meta ["all_messages" ] == []
282298
299+ def test_from_dict (self ):
300+ answer = GeneratedAnswer .from_dict ({"data" : "42" , "query" : "What is the answer?" , "documents" : [], "meta" : {}})
301+ assert answer .data == "42"
302+ assert answer .query == "What is the answer?"
303+ assert answer .documents == []
304+ assert answer .meta == {}
305+
306+ def test_from_dict_with_meta (self ):
307+ answer = GeneratedAnswer .from_dict (
308+ {
309+ "data" : "42" ,
310+ "query" : "What is the answer?" ,
311+ "documents" : [],
312+ "meta" : {"meta_key" : "meta_value" , "all_messages" : ["What is the answer?" ]},
313+ }
314+ )
315+ assert answer .data == "42"
316+ assert answer .query == "What is the answer?"
317+ assert answer .documents == []
318+ assert answer .meta ["meta_key" ] == "meta_value"
319+ assert answer .meta ["all_messages" ] == ["What is the answer?" ]
320+
321+ def test_from_dict_with_chat_message_in_meta (self ):
322+ answer = GeneratedAnswer .from_dict (
323+ {
324+ "data" : "42" ,
325+ "query" : "What is the answer?" ,
326+ "documents" : [
327+ {"id" : "1" , "content" : "The answer is 42." },
328+ {"id" : "2" , "content" : "I believe the answer is 42." },
329+ {"id" : "3" , "content" : "42 is definitely the answer." },
330+ ],
331+ "meta" : {
332+ "meta_key" : "meta_value" ,
333+ "all_messages" : [ChatMessage .from_user ("What is the answer?" ).to_dict ()],
334+ },
335+ }
336+ )
337+ assert answer .data == "42"
338+ assert answer .query == "What is the answer?"
339+ assert answer .documents == [
340+ Document (id = "1" , content = "The answer is 42." ),
341+ Document (id = "2" , content = "I believe the answer is 42." ),
342+ Document (id = "3" , content = "42 is definitely the answer." ),
343+ ]
344+ assert answer .meta ["meta_key" ] == "meta_value"
345+ assert answer .meta ["all_messages" ] == [ChatMessage .from_user ("What is the answer?" )]
346+
347+ def test_from_dict_with_empty_all_messages (self ):
348+ answer = GeneratedAnswer .from_dict (
349+ {"data" : "42" , "query" : "What is the answer?" , "documents" : [], "meta" : {"all_messages" : []}}
350+ )
351+ assert answer .meta ["all_messages" ] == []
352+
353+ def test_from_dict_does_not_mutate_input (self ):
354+ # from_dict must not mutate the caller's input dict while converting
355+ # `all_messages` dicts into ChatMessage objects (regression test).
356+ meta = {"all_messages" : [ChatMessage .from_user ("What is the answer?" ).to_dict ()]}
357+ serialized = {"data" : "42" , "query" : "What is the answer?" , "documents" : [], "meta" : meta }
358+ answer = GeneratedAnswer .from_dict (serialized )
359+
360+ # the deserialized answer still holds ChatMessage objects
361+ assert answer .meta ["all_messages" ] == [ChatMessage .from_user ("What is the answer?" )]
362+ # but the caller's meta dict is left untouched: it still holds plain dicts
363+ assert isinstance (meta ["all_messages" ][0 ], dict )
364+ assert meta ["all_messages" ] == [ChatMessage .from_user ("What is the answer?" ).to_dict ()]
365+
283366 def test_to_dict_from_dict_round_trip_with_empty_all_messages (self ):
284367 answer = GeneratedAnswer (data = "42" , query = "What is the answer?" , documents = [], meta = {"all_messages" : []})
285368 assert GeneratedAnswer .from_dict (answer .to_dict ()) == answer
0 commit comments