From 09d4a63bf75ca189d3db3fc628fe0a69a34db81d Mon Sep 17 00:00:00 2001 From: iabhi4 Date: Sat, 17 May 2025 15:24:35 -0700 Subject: [PATCH 1/3] BUG: Fix DataFrame constructor misclassification of array-like with 'name' attribute Previously, any object with a .name attribute (like some vtkArray-like objects) was assumed to be a Series or Index, causing the constructor to misinterpret the input. This fix ensures we only apply the named-Index/Series logic when the input is actually an instance of ABCSeries or ABCIndex *and* has a non-None name. Closes #61443. --- pandas/core/frame.py | 6 +++++- pandas/tests/frame/test_constructors.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 6158e19737185..b9bd574144bc4 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -116,6 +116,10 @@ isna, notna, ) +from pandas.core.dtypes.generic import ( + ABCSeries, + ABCIndex +) from pandas.core import ( algorithms, @@ -795,7 +799,7 @@ def __init__( dtype, copy, ) - elif getattr(data, "name", None) is not None: + elif isinstance(data, (ABCSeries, ABCIndex)) and data.name is not None: # i.e. Series/Index with non-None name mgr = dict_to_mgr( # error: Item "ndarray" of "Union[ndarray, Series, Index]" has no diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 037a2ae294bb2..034b6c0ff6d93 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2780,6 +2780,17 @@ def test_construction_nan_value_timedelta64_dtype(self): ) tm.assert_frame_equal(result, expected) + def test_dataframe_from_array_like_with_name_attribute(self): + class DummyArray(np.ndarray): + def __new__(cls, input_array): + obj = np.asarray(input_array).view(cls) + obj.name = "foo" + return obj + + dummy = DummyArray(np.eye(3)) + df = DataFrame(dummy) + expected = DataFrame(np.eye(3)) + tm.assert_frame_equal(df, expected) class TestDataFrameConstructorIndexInference: def test_frame_from_dict_of_series_overlapping_monthly_period_indexes(self): From 9687457576142bee476e3c3d5a49a7397e6d8e40 Mon Sep 17 00:00:00 2001 From: iabhi4 Date: Sat, 17 May 2025 17:07:05 -0700 Subject: [PATCH 2/3] Apply pre-commit fixes: isort and remove unused type ignore --- pandas/core/frame.py | 10 +++++----- pandas/tests/frame/test_constructors.py | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b9bd574144bc4..d5c506d712563 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -112,14 +112,14 @@ BaseMaskedDtype, ExtensionDtype, ) +from pandas.core.dtypes.generic import ( + ABCIndex, + ABCSeries, +) from pandas.core.dtypes.missing import ( isna, notna, ) -from pandas.core.dtypes.generic import ( - ABCSeries, - ABCIndex -) from pandas.core import ( algorithms, @@ -804,7 +804,7 @@ def __init__( mgr = dict_to_mgr( # error: Item "ndarray" of "Union[ndarray, Series, Index]" has no # attribute "name" - {data.name: data}, # type: ignore[union-attr] + {data.name: data}, index, columns, dtype=dtype, diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 034b6c0ff6d93..5b17474bdf181 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2792,6 +2792,7 @@ def __new__(cls, input_array): expected = DataFrame(np.eye(3)) tm.assert_frame_equal(df, expected) + class TestDataFrameConstructorIndexInference: def test_frame_from_dict_of_series_overlapping_monthly_period_indexes(self): rng1 = pd.period_range("1/1/1999", "1/1/2012", freq="M") From 889f81a4439926b1b0f7592b0705fc90f5dce397 Mon Sep 17 00:00:00 2001 From: iabhi4 Date: Sun, 18 May 2025 12:43:19 -0700 Subject: [PATCH 3/3] TST/CLN: Add issue reference in test and update whatsnew for GH#61443 --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/tests/frame/test_constructors.py | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 6642f5855f4fe..79b304e7979e0 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -904,6 +904,7 @@ Other - Bug in ``Series.list`` methods not preserving the original name. (:issue:`60522`) - Bug in printing a :class:`DataFrame` with a :class:`DataFrame` stored in :attr:`DataFrame.attrs` raised a ``ValueError`` (:issue:`60455`) - 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`) .. ***DO NOT USE THIS SECTION*** diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 5b17474bdf181..2426c89dbcff5 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2781,6 +2781,7 @@ def test_construction_nan_value_timedelta64_dtype(self): tm.assert_frame_equal(result, expected) def test_dataframe_from_array_like_with_name_attribute(self): + # GH#61443 class DummyArray(np.ndarray): def __new__(cls, input_array): obj = np.asarray(input_array).view(cls)