From 70ac083c5ebdecf7bfeb7cf11af0bbbcd4fa081d Mon Sep 17 00:00:00 2001 From: ckarnell <7363269+ckarnell@users.noreply.github.com> Date: Tue, 18 Aug 2026 13:27:28 -0400 Subject: [PATCH] Honour force='yes' in stringify_param ChildRelationship.stringify_param accepted force and never read it, so path(force='yes') returned None for an unrepresentable dict key, the case its own docstring promises to render as '(unrepresentable)'. Adds test_unrepresentable_dict_key_path. --- deepdiff/model.py | 3 +++ tests/test_diff_tree.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/deepdiff/model.py b/deepdiff/model.py index d44eccdb..18c61ef8 100644 --- a/deepdiff/model.py +++ b/deepdiff/model.py @@ -947,6 +947,9 @@ def stringify_param(self, force: Optional[str] = None) -> Optional[str]: else: result = candidate if resurrected == param else None + if result is None and force == 'yes': + result = '(unrepresentable)' + if result: result = ':' if self.param_repr_format is None else self.param_repr_format.format(result) diff --git a/tests/test_diff_tree.py b/tests/test_diff_tree.py index 8369a435..a89dae32 100644 --- a/tests/test_diff_tree.py +++ b/tests/test_diff_tree.py @@ -121,6 +121,27 @@ def test_non_subscriptable_iterable_path(self): assert change.path(force='yes') == 'root(unrepresentable)' assert change.path(force='fake') == 'root[2]' + def test_unrepresentable_dict_key_path(self): + class Id: + def __repr__(self): + return '' + + def __hash__(self): + return 1 + + def __eq__(self, other): + return isinstance(other, Id) + + key = Id() + t1 = {key: 10} + t2 = {key: 20} + ddiff = DeepDiff(t1, t2, view='tree') + (change, ) = ddiff['values_changed'] + + # repr does not round-trip, so there is no parsable path + assert change.path() is None + assert change.path(force='yes') == 'root[(unrepresentable)]' + def test_report_type_in_iterable(self): a = {"temp": ["a"]} b = {"temp": ["b"]}