3
3
4
4
import py
5
5
6
+ from _pytest ._code .code import ExceptionChainRepr
6
7
from _pytest ._code .code import ExceptionInfo
7
8
from _pytest ._code .code import ReprEntry
8
9
from _pytest ._code .code import ReprEntryNative
@@ -160,46 +161,7 @@ def _to_json(self):
160
161
161
162
Experimental method.
162
163
"""
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
164
+ return _report_to_json (self )
203
165
204
166
@classmethod
205
167
def _from_json (cls , reportdict ):
@@ -211,55 +173,8 @@ def _from_json(cls, reportdict):
211
173
212
174
Experimental method.
213
175
"""
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 )
176
+ kwargs = _report_kwargs_from_json (reportdict )
177
+ return cls (** kwargs )
263
178
264
179
265
180
def _report_unserialization_failure (type_name , report_class , reportdict ):
@@ -424,3 +339,142 @@ def pytest_report_from_serializable(data):
424
339
assert False , "Unknown report_type unserialize data: {}" .format (
425
340
data ["_report_type" ]
426
341
)
342
+
343
+
344
+ def _report_to_json (report ):
345
+ """
346
+ This was originally the serialize_report() function from xdist (ca03269).
347
+
348
+ Returns the contents of this report as a dict of builtin entries, suitable for
349
+ serialization.
350
+ """
351
+
352
+ def serialize_repr_entry (entry ):
353
+ entry_data = {"type" : type (entry ).__name__ , "data" : entry .__dict__ .copy ()}
354
+ for key , value in entry_data ["data" ].items ():
355
+ if hasattr (value , "__dict__" ):
356
+ entry_data ["data" ][key ] = value .__dict__ .copy ()
357
+ return entry_data
358
+
359
+ def serialize_repr_traceback (reprtraceback ):
360
+ result = reprtraceback .__dict__ .copy ()
361
+ result ["reprentries" ] = [
362
+ serialize_repr_entry (x ) for x in reprtraceback .reprentries
363
+ ]
364
+ return result
365
+
366
+ def serialize_repr_crash (reprcrash ):
367
+ return reprcrash .__dict__ .copy ()
368
+
369
+ def serialize_longrepr (rep ):
370
+ result = {
371
+ "reprcrash" : serialize_repr_crash (rep .longrepr .reprcrash ),
372
+ "reprtraceback" : serialize_repr_traceback (rep .longrepr .reprtraceback ),
373
+ "sections" : rep .longrepr .sections ,
374
+ }
375
+ if isinstance (rep .longrepr , ExceptionChainRepr ):
376
+ result ["chain" ] = []
377
+ for repr_traceback , repr_crash , description in rep .longrepr .chain :
378
+ result ["chain" ].append (
379
+ (
380
+ serialize_repr_traceback (repr_traceback ),
381
+ serialize_repr_crash (repr_crash ),
382
+ description ,
383
+ )
384
+ )
385
+ else :
386
+ result ["chain" ] = None
387
+ return result
388
+
389
+ d = report .__dict__ .copy ()
390
+ if hasattr (report .longrepr , "toterminal" ):
391
+ if hasattr (report .longrepr , "reprtraceback" ) and hasattr (
392
+ report .longrepr , "reprcrash"
393
+ ):
394
+ d ["longrepr" ] = serialize_longrepr (report )
395
+ else :
396
+ d ["longrepr" ] = str (report .longrepr )
397
+ else :
398
+ d ["longrepr" ] = report .longrepr
399
+ for name in d :
400
+ if isinstance (d [name ], (py .path .local , Path )):
401
+ d [name ] = str (d [name ])
402
+ elif name == "result" :
403
+ d [name ] = None # for now
404
+ return d
405
+
406
+
407
+ def _report_kwargs_from_json (reportdict ):
408
+ """
409
+ This was originally the serialize_report() function from xdist (ca03269).
410
+
411
+ Returns **kwargs that can be used to construct a TestReport or CollectReport instance.
412
+ """
413
+
414
+ def deserialize_repr_entry (entry_data ):
415
+ data = entry_data ["data" ]
416
+ entry_type = entry_data ["type" ]
417
+ if entry_type == "ReprEntry" :
418
+ reprfuncargs = None
419
+ reprfileloc = None
420
+ reprlocals = None
421
+ if data ["reprfuncargs" ]:
422
+ reprfuncargs = ReprFuncArgs (** data ["reprfuncargs" ])
423
+ if data ["reprfileloc" ]:
424
+ reprfileloc = ReprFileLocation (** data ["reprfileloc" ])
425
+ if data ["reprlocals" ]:
426
+ reprlocals = ReprLocals (data ["reprlocals" ]["lines" ])
427
+
428
+ reprentry = ReprEntry (
429
+ lines = data ["lines" ],
430
+ reprfuncargs = reprfuncargs ,
431
+ reprlocals = reprlocals ,
432
+ filelocrepr = reprfileloc ,
433
+ style = data ["style" ],
434
+ )
435
+ elif entry_type == "ReprEntryNative" :
436
+ reprentry = ReprEntryNative (data ["lines" ])
437
+ else :
438
+ _report_unserialization_failure (entry_type , TestReport , reportdict )
439
+ return reprentry
440
+
441
+ def deserialize_repr_traceback (repr_traceback_dict ):
442
+ repr_traceback_dict ["reprentries" ] = [
443
+ deserialize_repr_entry (x ) for x in repr_traceback_dict ["reprentries" ]
444
+ ]
445
+ return ReprTraceback (** repr_traceback_dict )
446
+
447
+ def deserialize_repr_crash (repr_crash_dict ):
448
+ return ReprFileLocation (** repr_crash_dict )
449
+
450
+ if (
451
+ reportdict ["longrepr" ]
452
+ and "reprcrash" in reportdict ["longrepr" ]
453
+ and "reprtraceback" in reportdict ["longrepr" ]
454
+ ):
455
+
456
+ reprtraceback = deserialize_repr_traceback (
457
+ reportdict ["longrepr" ]["reprtraceback" ]
458
+ )
459
+ reprcrash = deserialize_repr_crash (reportdict ["longrepr" ]["reprcrash" ])
460
+ if reportdict ["longrepr" ]["chain" ]:
461
+ chain = []
462
+ for repr_traceback_data , repr_crash_data , description in reportdict [
463
+ "longrepr"
464
+ ]["chain" ]:
465
+ chain .append (
466
+ (
467
+ deserialize_repr_traceback (repr_traceback_data ),
468
+ deserialize_repr_crash (repr_crash_data ),
469
+ description ,
470
+ )
471
+ )
472
+ exception_info = ExceptionChainRepr (chain )
473
+ else :
474
+ exception_info = ReprExceptionInfo (reprtraceback , reprcrash )
475
+
476
+ for section in reportdict ["longrepr" ]["sections" ]:
477
+ exception_info .addsection (* section )
478
+ reportdict ["longrepr" ] = exception_info
479
+
480
+ return reportdict
0 commit comments