From 803070c6bfc828c55f6664ec543087aa9384b5b3 Mon Sep 17 00:00:00 2001 From: 0x3vAD <0x3vad@gmail.com> Date: Tue, 12 Aug 2025 12:05:39 +0400 Subject: [PATCH 1/2] BUG: Fix assert_frame_equal with check_dtype=False for pd.NA with different dtypes --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/_testing/asserters.py | 14 ++++++++++---- pandas/tests/util/test_assert_frame_equal.py | 8 ++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 53f4f2a80aa8a..03fb923ba87f1 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -994,6 +994,7 @@ Other - Bug in printing a :class:`Series` with a :class:`DataFrame` stored in :attr:`Series.attrs` raised a ``ValueError`` (:issue:`60568`) - Fixed bug where the :class:`DataFrame` constructor misclassified array-like objects with a ``.name`` attribute as :class:`Series` or :class:`Index` (:issue:`61443`) - Fixed regression in :meth:`DataFrame.from_records` not initializing subclasses properly (:issue:`57008`) +- Bug in :func:`assert_frame_equal` with ``check_dtype=False`` failing to compare DataFrames containing ``pd.NA`` that differ only in dtype (``object`` vs ``Int32``). (:issue:`61473`) .. ***DO NOT USE THIS SECTION*** diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index daa5187cdb636..90628ac4e1318 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -1031,10 +1031,16 @@ def assert_series_equal( else: # convert both to NumPy if not, check_dtype would raise earlier lv, rv = left_values, right_values - if isinstance(left_values, ExtensionArray): - lv = left_values.to_numpy() - if isinstance(right_values, ExtensionArray): - rv = right_values.to_numpy() + if check_dtype: + if isinstance(left_values, ExtensionArray): + lv = left_values.to_numpy() + if isinstance(right_values, ExtensionArray): + rv = right_values.to_numpy() + else: + if isinstance(left_values, ExtensionArray): + lv = left_values.to_numpy(dtype="object") + if isinstance(right_values, ExtensionArray): + rv = right_values.to_numpy(dtype="object") assert_numpy_array_equal( lv, rv, diff --git a/pandas/tests/util/test_assert_frame_equal.py b/pandas/tests/util/test_assert_frame_equal.py index ea954756d63c8..83a7ebf51dae6 100644 --- a/pandas/tests/util/test_assert_frame_equal.py +++ b/pandas/tests/util/test_assert_frame_equal.py @@ -395,3 +395,11 @@ def test_assert_frame_equal_set_mismatch(): msg = r'DataFrame.iloc\[:, 0\] \(column name="set_column"\) values are different' with pytest.raises(AssertionError, match=msg): tm.assert_frame_equal(df1, df2) + + +def test_assert_frame_equal_pdNa_ignore_dtype(): + # GH#61473 + df1 = DataFrame({"x": pd.Series([pd.NA], dtype="Int32")}) + df2 = DataFrame({"x": pd.Series([pd.NA], dtype="object")}) + + tm.assert_frame_equal(df1, df2, check_dtype=False) From 13e48c03c05fec48e5687e017519128eef463e64 Mon Sep 17 00:00:00 2001 From: 0x3vAD <0x3vad@gmail.com> Date: Tue, 12 Aug 2025 12:43:01 +0400 Subject: [PATCH 2/2] sort whatsnew records alphabetically --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 03fb923ba87f1..b80ec8a6aa677 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -955,6 +955,7 @@ Other ^^^^^ - Bug in :class:`DataFrame` when passing a ``dict`` with a NA scalar and ``columns`` that would always return ``np.nan`` (:issue:`57205`) - Bug in :class:`Series` ignoring errors when trying to convert :class:`Series` input data to the given ``dtype`` (:issue:`60728`) +- Bug in :func:`assert_frame_equal` with ``check_dtype=False`` failing to compare DataFrames containing ``pd.NA`` that differ only in dtype (``object`` vs ``Int32``). (:issue:`61473`) - Bug in :func:`eval` on :class:`ExtensionArray` on including division ``/`` failed with a ``TypeError``. (:issue:`58748`) - Bug in :func:`eval` where method calls on binary operations like ``(x + y).dropna()`` would raise ``AttributeError: 'BinOp' object has no attribute 'value'`` (:issue:`61175`) - Bug in :func:`eval` where the names of the :class:`Series` were not preserved when using ``engine="numexpr"``. (:issue:`10239`) @@ -994,7 +995,6 @@ Other - Bug in printing a :class:`Series` with a :class:`DataFrame` stored in :attr:`Series.attrs` raised a ``ValueError`` (:issue:`60568`) - Fixed bug where the :class:`DataFrame` constructor misclassified array-like objects with a ``.name`` attribute as :class:`Series` or :class:`Index` (:issue:`61443`) - Fixed regression in :meth:`DataFrame.from_records` not initializing subclasses properly (:issue:`57008`) -- Bug in :func:`assert_frame_equal` with ``check_dtype=False`` failing to compare DataFrames containing ``pd.NA`` that differ only in dtype (``object`` vs ``Int32``). (:issue:`61473`) .. ***DO NOT USE THIS SECTION***