From c89bdf73ffd4e6b4e3c0da5821ffaed5a41cb86f Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 4 Sep 2022 21:53:57 +0100 Subject: [PATCH 1/2] show first diff in assert_frame_equal --- doc/source/whatsnew/v1.6.0.rst | 1 + pandas/_libs/testing.pyx | 5 ++++- pandas/_testing/asserters.py | 7 ++++++- pandas/tests/util/test_assert_frame_equal.py | 3 ++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v1.6.0.rst b/doc/source/whatsnew/v1.6.0.rst index 848e87f0bc029..a5dddc99cc144 100644 --- a/doc/source/whatsnew/v1.6.0.rst +++ b/doc/source/whatsnew/v1.6.0.rst @@ -29,6 +29,7 @@ enhancement2 Other enhancements ^^^^^^^^^^^^^^^^^^ - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`) +- :func:`assert_frame_equal` now shows the first element where the DataFrames differ, analogously to ``pytest``'s output (:issue:`47910`) - .. --------------------------------------------------------------------------- diff --git a/pandas/_libs/testing.pyx b/pandas/_libs/testing.pyx index cfe9f40f12452..3b024db946407 100644 --- a/pandas/_libs/testing.pyx +++ b/pandas/_libs/testing.pyx @@ -91,6 +91,7 @@ cpdef assert_almost_equal(a, b, Py_ssize_t i, na, nb double fa, fb bint is_unequal = False, a_is_ndarray, b_is_ndarray + str first_diff = '' if lobj is None: lobj = a @@ -159,12 +160,14 @@ cpdef assert_almost_equal(a, b, except AssertionError: is_unequal = True diff += 1 + if not first_diff: + first_diff = f"At index {i} diff: {a[i]} != {b[i]}" if is_unequal: from pandas._testing import raise_assert_detail msg = (f"{obj} values are different " f"({np.round(diff * 100.0 / na, 5)} %)") - raise_assert_detail(obj, msg, lobj, robj, index_values=index_values) + raise_assert_detail(obj, msg, lobj, robj, first_diff=first_diff, index_values=index_values) return True diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index 945639ef4b00a..3858670850074 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -639,7 +639,9 @@ def assert_timedelta_array_equal( assert_attr_equal("freq", left, right, obj=obj) -def raise_assert_detail(obj, message, left, right, diff=None, index_values=None): +def raise_assert_detail( + obj, message, left, right, diff=None, first_diff=None, index_values=None +): __tracebackhide__ = True msg = f"""{obj} are different @@ -674,6 +676,9 @@ def raise_assert_detail(obj, message, left, right, diff=None, index_values=None) if diff is not None: msg += f"\n[diff]: {diff}" + if first_diff is not None: + msg += f"\n{first_diff}" + raise AssertionError(msg) diff --git a/pandas/tests/util/test_assert_frame_equal.py b/pandas/tests/util/test_assert_frame_equal.py index 6ff1a1c17b179..1f5e7c13222b2 100644 --- a/pandas/tests/util/test_assert_frame_equal.py +++ b/pandas/tests/util/test_assert_frame_equal.py @@ -151,7 +151,8 @@ def test_frame_equal_index_mismatch(check_like, obj_fixture): {obj_fixture}\\.index values are different \\(33\\.33333 %\\) \\[left\\]: Index\\(\\['a', 'b', 'c'\\], dtype='object'\\) -\\[right\\]: Index\\(\\['a', 'b', 'd'\\], dtype='object'\\)""" +\\[right\\]: Index\\(\\['a', 'b', 'd'\\], dtype='object'\\) +At index 2 diff: c != d""" df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "c"]) df2 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "d"]) From af9974b7bb00c74bc2949e22cb6e649b90cd7425 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 11 Sep 2022 16:10:58 +0100 Subject: [PATCH 2/2] reword diff -> first_diff --- pandas/_libs/testing.pyx | 2 +- pandas/tests/util/test_assert_frame_equal.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/testing.pyx b/pandas/_libs/testing.pyx index 3b024db946407..e710a6fb6b24e 100644 --- a/pandas/_libs/testing.pyx +++ b/pandas/_libs/testing.pyx @@ -161,7 +161,7 @@ cpdef assert_almost_equal(a, b, is_unequal = True diff += 1 if not first_diff: - first_diff = f"At index {i} diff: {a[i]} != {b[i]}" + first_diff = f"At positional index {i}, first diff: {a[i]} != {b[i]}" if is_unequal: from pandas._testing import raise_assert_detail diff --git a/pandas/tests/util/test_assert_frame_equal.py b/pandas/tests/util/test_assert_frame_equal.py index 1f5e7c13222b2..8139ffed78f7f 100644 --- a/pandas/tests/util/test_assert_frame_equal.py +++ b/pandas/tests/util/test_assert_frame_equal.py @@ -152,7 +152,7 @@ def test_frame_equal_index_mismatch(check_like, obj_fixture): {obj_fixture}\\.index values are different \\(33\\.33333 %\\) \\[left\\]: Index\\(\\['a', 'b', 'c'\\], dtype='object'\\) \\[right\\]: Index\\(\\['a', 'b', 'd'\\], dtype='object'\\) -At index 2 diff: c != d""" +At positional index 2, first diff: c != d""" df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "c"]) df2 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "d"])