Repository: pandas-dev/pandas

Issue:
REGR: DataFrame.from_records for subclasses no longer calls subclass constructor
Example

```
In [16]: from pandas.tests.frame.test_subclass import MySubclassWithMetadata

In [17]: df = MySubclassWithMetadata.from_records([{'a': 1, 'b': 2}])

In [18]: type(df)
Out[18]: pandas.tests.frame.test_subclass.MySubclassWithMetadata

In [19]: df.my_metadata
...
AttributeError: 'MySubclassWithMetadata' object has no attribute 'my_metadata'
```

With pandas 2.1.4, this works fine. 

The reason for this is because ``from_records`` was updated (https://github.com/pandas-dev/pandas/pull/52419) to use

https://github.com/pandas-dev/pandas/blob/5740667a55aabffc660936079268cee2f2800225/pandas/core/frame.py#L2532

instead of `cls(mgr)` for the final dataframe construction.

I think this should probably at least use `_constructor_from_mgr` instead of `_from_mgr` (and maybe even still call the class? because in this case there is not finalize that can be called to finalize the initialization)

Discussion:
mroeschke: > Are we back porting regression fixes or just into 3.0?

I think these should just go into 3.0 as 2.3 will just be new string functionality


phofl: Sounds good, I’ll move the whatsnew
phofl: Moved

Patch:
diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst
index 9e0e095eb4..96eed72823 100644
--- a/doc/source/whatsnew/v2.3.0.rst
+++ b/doc/source/whatsnew/v2.3.0.rst
@@ -175,7 +175,6 @@ Other
 ^^^^^
 - Fixed usage of ``inspect`` when the optional dependencies ``pyarrow`` or ``jinja2``
   are not installed (:issue:`60196`)
--
 
 .. ---------------------------------------------------------------------------
 .. _whatsnew_230.contributors:
diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst
index 1e33971aca..102628257d 100644
--- a/doc/source/whatsnew/v3.0.0.rst
+++ b/doc/source/whatsnew/v3.0.0.rst
@@ -812,6 +812,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 regression in :meth:`DataFrame.from_records` not initializing subclasses properly (:issue:`57008`)
 
 .. ***DO NOT USE THIS SECTION***
 
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index ffffaeba41..863465ca15 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -2317,7 +2317,10 @@ class DataFrame(NDFrame, OpsMixin):
             columns = columns.drop(exclude)
 
         mgr = arrays_to_mgr(arrays, columns, result_index)
-        return cls._from_mgr(mgr, axes=mgr.axes)
+        df = DataFrame._from_mgr(mgr, axes=mgr.axes)
+        if cls is not DataFrame:
+            return cls(df, copy=False)
+        return df
 
     def to_records(
         self, index: bool = True, column_dtypes=None, index_dtypes=None


Test patch:
diff --git a/pandas/tests/frame/test_subclass.py b/pandas/tests/frame/test_subclass.py
index 7d18ef28a7..cbd563a03b 100644
--- a/pandas/tests/frame/test_subclass.py
+++ b/pandas/tests/frame/test_subclass.py
@@ -769,6 +769,13 @@ def test_constructor_with_metadata():
     assert isinstance(subset, MySubclassWithMetadata)
 
 
+def test_constructor_with_metadata_from_records():
+    # GH#57008
+    df = MySubclassWithMetadata.from_records([{"a": 1, "b": 2}])
+    assert df.my_metadata is None
+    assert type(df) is MySubclassWithMetadata
+
+
 class SimpleDataFrameSubClass(DataFrame):
     """A subclass of DataFrame that does not define a constructor."""