From c12ea57a48ccfd38f8ff1b2b18ad19033ecb6bfa Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 2 May 2023 12:11:42 +0200 Subject: [PATCH 1/2] fix #12: use a marker object for non-serializable objects instead of str this creates a difference in logged data warning messages needed a change instead of toplevel values, only the sub-object is affected --- CHANGELOG.rst | 1 + src/pytest_reportlog/plugin.py | 21 +++++---------------- tests/test_reportlog.py | 12 +++++++----- 3 files changed, 13 insertions(+), 21 deletions(-) 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..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 72d3813..f700ded 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,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: @@ -144,5 +146,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"}} From 5eb3d02c7923ad62043ce8b67a5feab7bbb99725 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 12:32:44 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pytest_reportlog/plugin.py | 2 +- tests/test_reportlog.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pytest_reportlog/plugin.py b/src/pytest_reportlog/plugin.py index 0eeac7f..b15a3d9 100644 --- a/src/pytest_reportlog/plugin.py +++ b/src/pytest_reportlog/plugin.py @@ -110,4 +110,4 @@ def pytest_terminal_summary(self, terminalreporter): 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)} + return {"$no-json": str(obj)} diff --git a/tests/test_reportlog.py b/tests/test_reportlog.py index f700ded..3198827 100644 --- a/tests/test_reportlog.py +++ b/tests/test_reportlog.py @@ -136,7 +136,6 @@ def test_warning(): def test_unserializable_to_marked(): """Unittest for the cleanup_unserializable function""" - good = {"x": 1, "y": ["a", "b"]} new = json.loads(json.dumps(good, default=unserializable_to_marked_str)) assert new == good