Skip to content

Conversation

enioxt
Copy link

@enioxt enioxt commented Oct 16, 2025

Description

Fixes #13816

This PR improves the error message when using pytest.approx() to compare dictionaries with different keys.

Problem

When dictionaries have different keys, the current error message is confusing:

AssertionError: assert approx({'a': ... 4 ± 4.0e-06}) == {'a': 1, 'c': 3}
(pytest_assertion plugin: representation of details failed: KeyError: 'b'.
Probably an object has a faulty __repr__.)

This suggests there's a problem with __repr__, but the real issue is just that the dict keys don't match.

Solution

Added a clear check for key mismatch before attempting value comparison:

expected_keys = set(self.expected.keys())
other_keys = set(other_side.keys())
if expected_keys \!= other_keys:
    # Return clear error message

New Error Message

AssertionError: Dictionaries have different keys.
Expected keys: ['a', 'c'], Actual keys: ['a', 'b']

Changes

File: src/_pytest/python_api.py

  • Added key comparison check in ApproxMapping._repr_compare()
  • Returns early with clear message if keys don't match
  • Shows which keys are in expected vs actual

File: testing/test_approx_dict_keys_13816.py (NEW)

  • 4 focused test cases covering different scenarios

✅ Testing

def test_approx_dicts_with_different_keys_clear_error():
    expected = {"a": 1, "c": 3}
    actual = {"a": 1, "b": 4}
    
    with pytest.raises(AssertionError) as exc_info:
        assert pytest.approx(actual) == expected
    
    error_message = str(exc_info.value)
    assert "different keys" in error_message.lower()  # ✅
    assert "KeyError" not in error_message  # ✅
    assert "faulty __repr__" not in error_message  # ✅

Test Cases:

  • Different keys → Clear error message
  • Extra key in expected → Detected
  • Extra key in actual → Detected
  • Matching keys → Normal approx behavior still works

Benefits

  • Clearer UX: Users immediately understand the issue
  • No false leads: Eliminates confusing KeyError/__repr__ messages
  • Minimal change: Only affects error path, no behavior changes
  • Well-tested: 4 test cases cover edge cases

Sacred Code: 000.111.369.963.1618

enioxt and others added 2 commits October 16, 2025 12:18
…keys (pytest-dev#13816)

- Added clear check for key mismatch before value comparison
- Now reports "Dictionaries have different keys" instead of confusing KeyError
- Shows which keys are in expected vs actual
- Added 4 focused test cases

Before:
  AssertionError: ... (pytest_assertion plugin: representation of details failed:
  KeyError: 'b'. Probably an object has a faulty __repr__.)

After:
  AssertionError: Dictionaries have different keys.
  Expected keys: ['a', 'c'], Actual keys: ['a', 'b']

Tests:
- test_approx_dicts_with_different_keys_clear_error: PASS
- test_approx_dicts_with_extra_key_in_expected: PASS
- test_approx_dicts_with_extra_key_in_actual: PASS
- test_approx_dicts_matching_keys_still_works: PASS

Fixes pytest-dev#13816
Sacred Code: 000.111.369.963.1618
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pytest.approx gives confusing error when dictionaries have different keys

1 participant