1
changelog/196.bugfix
Normal file
1
changelog/196.bugfix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Fix serialization of native tracebacks (``--tb=native``).
|
||||||
@@ -113,8 +113,9 @@ class TestReportSerialization:
|
|||||||
assert added_section in a.longrepr.sections
|
assert added_section in a.longrepr.sections
|
||||||
|
|
||||||
def test_reprentries_serialization_170(self, testdir):
|
def test_reprentries_serialization_170(self, testdir):
|
||||||
|
from _pytest._code.code import ReprEntry
|
||||||
reprec = testdir.inline_runsource("""
|
reprec = testdir.inline_runsource("""
|
||||||
def test_fail():
|
def test_repr_entry():
|
||||||
x = 0
|
x = 0
|
||||||
assert x
|
assert x
|
||||||
""", '--showlocals', '-n1')
|
""", '--showlocals', '-n1')
|
||||||
@@ -128,6 +129,7 @@ class TestReportSerialization:
|
|||||||
a_entries = a.longrepr.reprtraceback.reprentries
|
a_entries = a.longrepr.reprtraceback.reprentries
|
||||||
assert rep_entries == a_entries
|
assert rep_entries == a_entries
|
||||||
for i in range(len(a_entries)):
|
for i in range(len(a_entries)):
|
||||||
|
assert isinstance(rep_entries[i], ReprEntry)
|
||||||
assert rep_entries[i].lines == a_entries[i].lines
|
assert rep_entries[i].lines == a_entries[i].lines
|
||||||
assert rep_entries[i].localssep == a_entries[i].localssep
|
assert rep_entries[i].localssep == a_entries[i].localssep
|
||||||
assert rep_entries[i].reprfileloc == a_entries[i].reprfileloc
|
assert rep_entries[i].reprfileloc == a_entries[i].reprfileloc
|
||||||
@@ -135,6 +137,26 @@ class TestReportSerialization:
|
|||||||
assert rep_entries[i].reprlocals == a_entries[i].reprlocals
|
assert rep_entries[i].reprlocals == a_entries[i].reprlocals
|
||||||
assert rep_entries[i].style == a_entries[i].style
|
assert rep_entries[i].style == a_entries[i].style
|
||||||
|
|
||||||
|
def test_reprentries_serialization_196(self, testdir):
|
||||||
|
from _pytest._code.code import ReprEntryNative
|
||||||
|
reprec = testdir.inline_runsource("""
|
||||||
|
def test_repr_entry_native():
|
||||||
|
x = 0
|
||||||
|
assert x
|
||||||
|
""", '--tb=native', '-n1')
|
||||||
|
reports = reprec.getreports("pytest_runtest_logreport")
|
||||||
|
assert len(reports) == 3
|
||||||
|
rep = reports[1]
|
||||||
|
d = serialize_report(rep)
|
||||||
|
a = unserialize_report("testreport", d)
|
||||||
|
|
||||||
|
rep_entries = rep.longrepr.reprtraceback.reprentries
|
||||||
|
a_entries = a.longrepr.reprtraceback.reprentries
|
||||||
|
assert rep_entries == a_entries
|
||||||
|
for i in range(len(a_entries)):
|
||||||
|
assert isinstance(rep_entries[i], ReprEntryNative)
|
||||||
|
assert rep_entries[i].lines == a_entries[i].lines
|
||||||
|
|
||||||
def test_itemreport_outcomes(self, testdir):
|
def test_itemreport_outcomes(self, testdir):
|
||||||
reprec = testdir.inline_runsource("""
|
reprec = testdir.inline_runsource("""
|
||||||
import py
|
import py
|
||||||
|
|||||||
@@ -104,11 +104,14 @@ def serialize_report(rep):
|
|||||||
|
|
||||||
new_entries = []
|
new_entries = []
|
||||||
for entry in reprtraceback['reprentries']:
|
for entry in reprtraceback['reprentries']:
|
||||||
new_entry = entry.__dict__
|
entry_data = {
|
||||||
for key, value in new_entry.items():
|
'type': type(entry).__name__,
|
||||||
|
'data': entry.__dict__,
|
||||||
|
}
|
||||||
|
for key, value in entry_data['data'].items():
|
||||||
if hasattr(value, '__dict__'):
|
if hasattr(value, '__dict__'):
|
||||||
new_entry[key] = value.__dict__
|
entry_data['data'][key] = value.__dict__
|
||||||
new_entries.append(new_entry)
|
new_entries.append(entry_data)
|
||||||
|
|
||||||
reprtraceback['reprentries'] = new_entries
|
reprtraceback['reprentries'] = new_entries
|
||||||
|
|
||||||
|
|||||||
@@ -332,6 +332,7 @@ def unserialize_report(name, reportdict):
|
|||||||
def assembled_report(reportdict):
|
def assembled_report(reportdict):
|
||||||
from _pytest._code.code import (
|
from _pytest._code.code import (
|
||||||
ReprEntry,
|
ReprEntry,
|
||||||
|
ReprEntryNative,
|
||||||
ReprExceptionInfo,
|
ReprExceptionInfo,
|
||||||
ReprFileLocation,
|
ReprFileLocation,
|
||||||
ReprFuncArgs,
|
ReprFuncArgs,
|
||||||
@@ -345,22 +346,36 @@ def unserialize_report(name, reportdict):
|
|||||||
reprcrash = reportdict['longrepr']['reprcrash']
|
reprcrash = reportdict['longrepr']['reprcrash']
|
||||||
|
|
||||||
unserialized_entries = []
|
unserialized_entries = []
|
||||||
for entry in reprtraceback['reprentries']:
|
reprentry = None
|
||||||
reprfuncargs, reprfileloc, reprlocals = None, None, None
|
for entry_data in reprtraceback['reprentries']:
|
||||||
if entry['reprfuncargs']:
|
data = entry_data['data']
|
||||||
reprfuncargs = ReprFuncArgs(**entry['reprfuncargs'])
|
entry_type = entry_data['type']
|
||||||
if entry['reprfileloc']:
|
if entry_type == 'ReprEntry':
|
||||||
reprfileloc = ReprFileLocation(**entry['reprfileloc'])
|
reprfuncargs = None
|
||||||
if entry['reprlocals']:
|
reprfileloc = None
|
||||||
reprlocals = ReprLocals(entry['reprlocals']['lines'])
|
reprlocals = None
|
||||||
|
if data['reprfuncargs']:
|
||||||
|
reprfuncargs = ReprFuncArgs(
|
||||||
|
**data['reprfuncargs'])
|
||||||
|
if data['reprfileloc']:
|
||||||
|
reprfileloc = ReprFileLocation(
|
||||||
|
**data['reprfileloc'])
|
||||||
|
if data['reprlocals']:
|
||||||
|
reprlocals = ReprLocals(
|
||||||
|
data['reprlocals']['lines'])
|
||||||
|
|
||||||
reprentry = ReprEntry(
|
reprentry = ReprEntry(
|
||||||
lines=entry['lines'],
|
lines=data['lines'],
|
||||||
reprfuncargs=reprfuncargs,
|
reprfuncargs=reprfuncargs,
|
||||||
reprlocals=reprlocals,
|
reprlocals=reprlocals,
|
||||||
filelocrepr=reprfileloc,
|
filelocrepr=reprfileloc,
|
||||||
style=entry['style']
|
style=data['style']
|
||||||
)
|
)
|
||||||
|
elif entry_type == 'ReprEntryNative':
|
||||||
|
reprentry = ReprEntryNative(data['lines'])
|
||||||
|
else:
|
||||||
|
report_unserialization_failure(
|
||||||
|
entry_type, name, reportdict)
|
||||||
unserialized_entries.append(reprentry)
|
unserialized_entries.append(reprentry)
|
||||||
reprtraceback['reprentries'] = unserialized_entries
|
reprtraceback['reprentries'] = unserialized_entries
|
||||||
|
|
||||||
@@ -378,3 +393,17 @@ def unserialize_report(name, reportdict):
|
|||||||
return runner.TestReport(**assembled_report(reportdict))
|
return runner.TestReport(**assembled_report(reportdict))
|
||||||
elif name == "collectreport":
|
elif name == "collectreport":
|
||||||
return runner.CollectReport(**assembled_report(reportdict))
|
return runner.CollectReport(**assembled_report(reportdict))
|
||||||
|
|
||||||
|
|
||||||
|
def report_unserialization_failure(type_name, report_name, reportdict):
|
||||||
|
from pprint import pprint
|
||||||
|
url = 'https://github.com/pytest-dev/pytest-xdist/issues'
|
||||||
|
stream = py.io.TextIO()
|
||||||
|
pprint('-' * 100, stream=stream)
|
||||||
|
pprint('INTERNALERROR: Unknown entry type returned: %s' % type_name,
|
||||||
|
stream=stream)
|
||||||
|
pprint('report_name: %s' % report_name, stream=stream)
|
||||||
|
pprint(reportdict, stream=stream)
|
||||||
|
pprint('Please report this bug at %s' % url, stream=stream)
|
||||||
|
pprint('-' * 100, stream=stream)
|
||||||
|
assert 0, stream.getvalue()
|
||||||
|
|||||||
Reference in New Issue
Block a user