diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c5bddf5..d9b2253 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,7 +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..0eeac7f 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 ef3585c..e321c31 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 @@ -132,10 +132,12 @@ 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: @@ -143,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"}}