diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ebd4ca6..bae6575 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,7 @@ Next (tbd) * `#16 `_: switch recommended file extension to `jsonl `__. * `#17 `_: add compression support for ``.bz2``/``.gz``/``.xz`` log file extensions. +* `#12 `_: handle unserializable objects with a pinpointed marker 0.3.0 (2023-04-26) diff --git a/src/pytest_reportlog/plugin.py b/src/pytest_reportlog/plugin.py index ab9b9ec..b15a3d9 100644 --- a/src/pytest_reportlog/plugin.py +++ b/src/pytest_reportlog/plugin.py @@ -63,11 +63,7 @@ def close(self): self._file = None def _write_json_data(self, data): - try: - json_data = json.dumps(data) - except TypeError: - data = cleanup_unserializable(data) - json_data = json.dumps(data) + json_data = json.dumps(data, default=unserializable_to_marked_str) self._file.write(json_data + "\n") self._file.flush() @@ -92,7 +88,7 @@ def pytest_warning_recorded(self, warning_message, when, nodeid, location): ), "filename": warning_message.filename, "lineno": warning_message.lineno, - "message": warning_message.message, + "message": str(warning_message.message), } extra_data = { "$report_type": "WarningMessage", @@ -112,13 +108,6 @@ def pytest_terminal_summary(self, terminalreporter): terminalreporter.write_sep("-", f"generated report log file: {self._log_path}") -def cleanup_unserializable(d: Dict[str, Any]) -> Dict[str, Any]: - """Return new dict with entries that are not json serializable by their str().""" - result = {} - for k, v in d.items(): - try: - json.dumps({k: v}) - except TypeError: - v = str(v) - result[k] = v - return result +def unserializable_to_marked_str(obj: object) -> Dict[str, str]: + """for a object that json can not serialize. return {"$no-json": str(obj)}""" + return {"$no-json": str(obj)} diff --git a/tests/test_reportlog.py b/tests/test_reportlog.py index 72d3813..3198827 100644 --- a/tests/test_reportlog.py +++ b/tests/test_reportlog.py @@ -6,7 +6,7 @@ from pathlib import Path from _pytest.reports import BaseReport -from pytest_reportlog.plugin import cleanup_unserializable, _open_filtered_writer +from pytest_reportlog.plugin import _open_filtered_writer, unserializable_to_marked_str from typing_extensions import Protocol, Literal @@ -133,10 +133,11 @@ def test_warning(): } -def test_cleanup_unserializable(): +def test_unserializable_to_marked(): """Unittest for the cleanup_unserializable function""" + good = {"x": 1, "y": ["a", "b"]} - new = cleanup_unserializable(good) + new = json.loads(json.dumps(good, default=unserializable_to_marked_str)) assert new == good class C: @@ -144,5 +145,5 @@ def __str__(self): return "C instance" bad = {"x": 1, "y": ["a", "b"], "c": C()} - new = cleanup_unserializable(bad) - assert new == {"x": 1, "c": "C instance", "y": ["a", "b"]} + new_bad = json.loads(json.dumps(bad, default=unserializable_to_marked_str)) + assert new_bad == {**bad, "c": {"$no-json": "C instance"}}