Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Brian Okken
Brianna Laugher
Bruno Oliveira
Cal Jacobson
croc100
Cal Leeming
Carl Friedrich Bolz
Carlos Jenkins
Expand Down
1 change: 1 addition & 0 deletions changelog/12860.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Assertion diffs for ``dict.items()`` and ``dict.keys()`` comparisons (``>=``, ``<=``, ``>``, ``<``, ``==``) now show which items are missing, the same way set comparisons do.
5 changes: 3 additions & 2 deletions src/_pytest/assertion/_guards.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import collections.abc
from collections.abc import Mapping
from collections.abc import Set as AbstractSet
import dataclasses
from typing import TypeGuard

Expand All @@ -18,8 +19,8 @@ def ismapping(x: object) -> TypeGuard[Mapping[object, object]]:
return isinstance(x, Mapping)


def isset(x: object) -> TypeGuard[set[object] | frozenset[object]]:
return isinstance(x, set | frozenset)
def isset(x: object) -> TypeGuard[AbstractSet[object]]:
return isinstance(x, AbstractSet)


def isnamedtuple(obj: object) -> bool:
Expand Down
32 changes: 32 additions & 0 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,38 @@ def test_hello():
]
)

@pytest.mark.parametrize("op", [">=", "<="])
def test_dict_items_view_subset(self, op, pytester: Pytester) -> None:
"""dict.items() supports set-like comparisons; assert diff should show the missing items."""
if op == ">=":
pytester.makepyfile(
"""
def test_hello():
x = {"a": 1, "b": 2}
y = {"a": 1, "b": 2, "c": 3}
assert x.items() >= y.items()
"""
)
else:
pytester.makepyfile(
"""
def test_hello():
x = {"a": 1, "b": 2, "c": 3}
y = {"a": 1, "b": 2}
assert x.items() <= y.items()
"""
)
result = pytester.runpytest()
side = "right" if op == ">=" else "left"
result.stdout.fnmatch_lines(
[
"*def test_hello():*",
f"*assert x.items() {op} y.items()*",
f"*E*Extra items in the {side} set:*",
"*E*('c', 3)*",
]
)


def test_assertrepr_loaded_per_dir(pytester: Pytester) -> None:
pytester.makepyfile(test_base=["def test_base(): assert 1 == 2"])
Expand Down
Loading