@@ -160,46 +160,7 @@ def _to_json(self):
160
160
161
161
Experimental method.
162
162
"""
163
-
164
- def disassembled_report (rep ):
165
- reprtraceback = rep .longrepr .reprtraceback .__dict__ .copy ()
166
- reprcrash = rep .longrepr .reprcrash .__dict__ .copy ()
167
-
168
- new_entries = []
169
- for entry in reprtraceback ["reprentries" ]:
170
- entry_data = {
171
- "type" : type (entry ).__name__ ,
172
- "data" : entry .__dict__ .copy (),
173
- }
174
- for key , value in entry_data ["data" ].items ():
175
- if hasattr (value , "__dict__" ):
176
- entry_data ["data" ][key ] = value .__dict__ .copy ()
177
- new_entries .append (entry_data )
178
-
179
- reprtraceback ["reprentries" ] = new_entries
180
-
181
- return {
182
- "reprcrash" : reprcrash ,
183
- "reprtraceback" : reprtraceback ,
184
- "sections" : rep .longrepr .sections ,
185
- }
186
-
187
- d = self .__dict__ .copy ()
188
- if hasattr (self .longrepr , "toterminal" ):
189
- if hasattr (self .longrepr , "reprtraceback" ) and hasattr (
190
- self .longrepr , "reprcrash"
191
- ):
192
- d ["longrepr" ] = disassembled_report (self )
193
- else :
194
- d ["longrepr" ] = str (self .longrepr )
195
- else :
196
- d ["longrepr" ] = self .longrepr
197
- for name in d :
198
- if isinstance (d [name ], (py .path .local , Path )):
199
- d [name ] = str (d [name ])
200
- elif name == "result" :
201
- d [name ] = None # for now
202
- return d
163
+ return _test_report_to_json (self )
203
164
204
165
@classmethod
205
166
def _from_json (cls , reportdict ):
@@ -211,55 +172,8 @@ def _from_json(cls, reportdict):
211
172
212
173
Experimental method.
213
174
"""
214
- if reportdict ["longrepr" ]:
215
- if (
216
- "reprcrash" in reportdict ["longrepr" ]
217
- and "reprtraceback" in reportdict ["longrepr" ]
218
- ):
219
-
220
- reprtraceback = reportdict ["longrepr" ]["reprtraceback" ]
221
- reprcrash = reportdict ["longrepr" ]["reprcrash" ]
222
-
223
- unserialized_entries = []
224
- reprentry = None
225
- for entry_data in reprtraceback ["reprentries" ]:
226
- data = entry_data ["data" ]
227
- entry_type = entry_data ["type" ]
228
- if entry_type == "ReprEntry" :
229
- reprfuncargs = None
230
- reprfileloc = None
231
- reprlocals = None
232
- if data ["reprfuncargs" ]:
233
- reprfuncargs = ReprFuncArgs (** data ["reprfuncargs" ])
234
- if data ["reprfileloc" ]:
235
- reprfileloc = ReprFileLocation (** data ["reprfileloc" ])
236
- if data ["reprlocals" ]:
237
- reprlocals = ReprLocals (data ["reprlocals" ]["lines" ])
238
-
239
- reprentry = ReprEntry (
240
- lines = data ["lines" ],
241
- reprfuncargs = reprfuncargs ,
242
- reprlocals = reprlocals ,
243
- filelocrepr = reprfileloc ,
244
- style = data ["style" ],
245
- )
246
- elif entry_type == "ReprEntryNative" :
247
- reprentry = ReprEntryNative (data ["lines" ])
248
- else :
249
- _report_unserialization_failure (entry_type , cls , reportdict )
250
- unserialized_entries .append (reprentry )
251
- reprtraceback ["reprentries" ] = unserialized_entries
252
-
253
- exception_info = ReprExceptionInfo (
254
- reprtraceback = ReprTraceback (** reprtraceback ),
255
- reprcrash = ReprFileLocation (** reprcrash ),
256
- )
257
-
258
- for section in reportdict ["longrepr" ]["sections" ]:
259
- exception_info .addsection (* section )
260
- reportdict ["longrepr" ] = exception_info
261
-
262
- return cls (** reportdict )
175
+ kwargs = _test_report_kwargs_from_json (reportdict )
176
+ return cls (** kwargs )
263
177
264
178
265
179
def _report_unserialization_failure (type_name , report_class , reportdict ):
@@ -424,3 +338,116 @@ def pytest_report_from_serializable(data):
424
338
assert False , "Unknown report_type unserialize data: {}" .format (
425
339
data ["_report_type" ]
426
340
)
341
+
342
+
343
+ def _test_report_to_json (test_report ):
344
+ """
345
+ This was originally the serialize_report() function from xdist (ca03269).
346
+
347
+ Returns the contents of this report as a dict of builtin entries, suitable for
348
+ serialization.
349
+ """
350
+
351
+ def serialize_repr_entry (entry ):
352
+ entry_data = {"type" : type (entry ).__name__ , "data" : entry .__dict__ .copy ()}
353
+ for key , value in entry_data ["data" ].items ():
354
+ if hasattr (value , "__dict__" ):
355
+ entry_data ["data" ][key ] = value .__dict__ .copy ()
356
+ return entry_data
357
+
358
+ def serialize_repr_traceback (reprtraceback ):
359
+ result = reprtraceback .__dict__ .copy ()
360
+ result ["reprentries" ] = [
361
+ serialize_repr_entry (x ) for x in reprtraceback .reprentries
362
+ ]
363
+ return result
364
+
365
+ def serialize_repr_crash (reprcrash ):
366
+ return reprcrash .__dict__ .copy ()
367
+
368
+ def serialize_longrepr (rep ):
369
+ return {
370
+ "reprcrash" : serialize_repr_crash (rep .longrepr .reprcrash ),
371
+ "reprtraceback" : serialize_repr_traceback (rep .longrepr .reprtraceback ),
372
+ "sections" : rep .longrepr .sections ,
373
+ }
374
+
375
+ d = test_report .__dict__ .copy ()
376
+ if hasattr (test_report .longrepr , "toterminal" ):
377
+ if hasattr (test_report .longrepr , "reprtraceback" ) and hasattr (
378
+ test_report .longrepr , "reprcrash"
379
+ ):
380
+ d ["longrepr" ] = serialize_longrepr (test_report )
381
+ else :
382
+ d ["longrepr" ] = str (test_report .longrepr )
383
+ else :
384
+ d ["longrepr" ] = test_report .longrepr
385
+ for name in d :
386
+ if isinstance (d [name ], (py .path .local , Path )):
387
+ d [name ] = str (d [name ])
388
+ elif name == "result" :
389
+ d [name ] = None # for now
390
+ return d
391
+
392
+
393
+ def _test_report_kwargs_from_json (reportdict ):
394
+ """
395
+ This was originally the serialize_report() function from xdist (ca03269).
396
+
397
+ Factory method that returns either a TestReport or CollectReport, depending on the calling
398
+ class. It's the callers responsibility to know which class to pass here.
399
+ """
400
+
401
+ def deserialize_repr_entry (entry_data ):
402
+ data = entry_data ["data" ]
403
+ entry_type = entry_data ["type" ]
404
+ if entry_type == "ReprEntry" :
405
+ reprfuncargs = None
406
+ reprfileloc = None
407
+ reprlocals = None
408
+ if data ["reprfuncargs" ]:
409
+ reprfuncargs = ReprFuncArgs (** data ["reprfuncargs" ])
410
+ if data ["reprfileloc" ]:
411
+ reprfileloc = ReprFileLocation (** data ["reprfileloc" ])
412
+ if data ["reprlocals" ]:
413
+ reprlocals = ReprLocals (data ["reprlocals" ]["lines" ])
414
+
415
+ reprentry = ReprEntry (
416
+ lines = data ["lines" ],
417
+ reprfuncargs = reprfuncargs ,
418
+ reprlocals = reprlocals ,
419
+ filelocrepr = reprfileloc ,
420
+ style = data ["style" ],
421
+ )
422
+ elif entry_type == "ReprEntryNative" :
423
+ reprentry = ReprEntryNative (data ["lines" ])
424
+ else :
425
+ _report_unserialization_failure (entry_type , TestReport , reportdict )
426
+ return reprentry
427
+
428
+ def deserialize_repr_traceback (repr_traceback_dict ):
429
+ repr_traceback_dict ["reprentries" ] = [
430
+ deserialize_repr_entry (x ) for x in repr_traceback_dict ["reprentries" ]
431
+ ]
432
+ return ReprTraceback (** repr_traceback_dict )
433
+
434
+ def deserialize_repr_crash (repr_crash_dict ):
435
+ return ReprFileLocation (** repr_crash_dict )
436
+
437
+ if (
438
+ reportdict ["longrepr" ]
439
+ and "reprcrash" in reportdict ["longrepr" ]
440
+ and "reprtraceback" in reportdict ["longrepr" ]
441
+ ):
442
+ exception_info = ReprExceptionInfo (
443
+ reprtraceback = deserialize_repr_traceback (
444
+ reportdict ["longrepr" ]["reprtraceback" ]
445
+ ),
446
+ reprcrash = deserialize_repr_crash (reportdict ["longrepr" ]["reprcrash" ]),
447
+ )
448
+
449
+ for section in reportdict ["longrepr" ]["sections" ]:
450
+ exception_info .addsection (* section )
451
+ reportdict ["longrepr" ] = exception_info
452
+
453
+ return reportdict
0 commit comments