File tree Expand file tree Collapse file tree 3 files changed +20
-5
lines changed
Expand file tree Collapse file tree 3 files changed +20
-5
lines changed Original file line number Diff line number Diff line change 1- Fixed subtests running with `pytest-xdist <https://github.com/pytest-dev/pytest >`__ when their contexts contain non-standard objects.
1+ Fixed subtests running with `pytest-xdist <https://github.com/pytest-dev/pytest >`__ when their contexts contain objects that are not JSON-serializable .
22
33Fixes `pytest-dev/pytest-xdist#1273 <https://github.com/pytest-dev/pytest-xdist/issues/1273 >`__.
Original file line number Diff line number Diff line change 1111from contextlib import ExitStack
1212from contextlib import nullcontext
1313import dataclasses
14+ import json
1415import time
1516from types import TracebackType
1617from typing import Any
@@ -63,8 +64,19 @@ class SubtestContext:
6364
6465 def _to_json (self ) -> dict [str , Any ]:
6566 result = dataclasses .asdict (self )
66- # Brute-force the returned kwargs dict to be JSON serializable (pytest-dev/pytest-xdist#1273).
67- result ["kwargs" ] = {k : saferepr (v ) for (k , v ) in result ["kwargs" ].items ()}
67+
68+ # Best-effort to convert the kwargs values to JSON (pytest-dev/pytest-xdist#1273).
69+ # If they can be converted, we return as it is, otherwise we return its saferepr because it seems
70+ # this is the best we can do at this point.
71+ def convert (x : Any ) -> Any :
72+ try :
73+ json .dumps (x )
74+ except TypeError :
75+ return saferepr (x )
76+ else :
77+ return x
78+
79+ result ["kwargs" ] = {k : convert (v ) for (k , v ) in result ["kwargs" ].items ()}
6880 return result
6981
7082 @classmethod
Original file line number Diff line number Diff line change 11from __future__ import annotations
22
33from enum import Enum
4+ import json
45import sys
56from typing import Literal
67
@@ -978,14 +979,16 @@ class MyEnum(Enum):
978979 )
979980 data = pytest_report_to_serializable (report )
980981 assert data is not None
982+ # Ensure the report is actually serializable to JSON.
983+ _ = json .dumps (data )
981984 new_report = pytest_report_from_serializable (data )
982985 assert new_report is not None
983986 assert new_report .context == SubtestContext (
984- msg = "custom message" , kwargs = dict (i = saferepr ( 10 ) , a = saferepr (MyEnum .A ))
987+ msg = "custom message" , kwargs = dict (i = 10 , a = saferepr (MyEnum .A ))
985988 )
986989
987990
988- def test_serialization_xdist (pytester : pytest .Pytester ) -> None :
991+ def test_serialization_xdist (pytester : pytest .Pytester ) -> None : # pragma: no cover
989992 """Regression test for pytest-dev/pytest-xdist#1273."""
990993 pytest .importorskip ("xdist" )
991994 pytester .makepyfile (
You can’t perform that action at this time.
0 commit comments