Skip to content

Commit 30134c8

Browse files
committed
Remove NDFrame.__constructor_expanddim
1 parent eeef0ef commit 30134c8

File tree

7 files changed

+15
-36
lines changed

7 files changed

+15
-36
lines changed

doc/source/development/extending.rst

+4-14
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,11 @@ Each data structure has several *constructor properties* for returning a new
329329
data structure as the result of an operation. By overriding these properties,
330330
you can retain subclasses through ``pandas`` data manipulations.
331331

332-
There are 3 constructor properties to be defined:
332+
There are 3 possible constructor properties to be defined on a subclass:
333333

334-
* ``_constructor``: Used when a manipulation result has the same dimensions as the original.
335-
* ``_constructor_sliced``: Used when a manipulation result has one lower dimension(s) as the original, such as ``DataFrame`` single columns slicing.
336-
* ``_constructor_expanddim``: Used when a manipulation result has one higher dimension as the original, such as ``Series.to_frame()``.
337-
338-
Following table shows how ``pandas`` data structures define constructor properties by default.
339-
340-
=========================== ======================= =============
341-
Property Attributes ``Series`` ``DataFrame``
342-
=========================== ======================= =============
343-
``_constructor`` ``Series`` ``DataFrame``
344-
``_constructor_sliced`` ``NotImplementedError`` ``Series``
345-
``_constructor_expanddim`` ``DataFrame`` ``NotImplementedError``
346-
=========================== ======================= =============
334+
* ``DataFrame/Series._constructor``: Used when a manipulation result has the same (sub-)class as the original.
335+
* ``DataFrame._constructor_sliced``: Used when a ``DataFrame`` (sub-)class manipulation result should be a ``Series`` (sub-)class.
336+
* ``Series._constructor_expanddim``: Used when a ``Series`` (sub-)class manipulation result should be a ``DataFrame`` (sub-)class, e.g. ``Series.to_frame()``.
347337

348338
Below example shows how to define ``SubclassedSeries`` and ``SubclassedDataFrame`` overriding constructor properties.
349339

doc/source/whatsnew/v1.2.1.rst

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ I/O
4242
Other
4343
~~~~~
4444
- Fixed build failure on MacOS 11 in Python 3.9.1 (:issue:`38766`)
45-
- ``inspect.getmembers(Series)`` no longer raises an ``AbstractMethodError`` (:issue:`38782`).
4645
-
4746

4847
.. ---------------------------------------------------------------------------

doc/source/whatsnew/v1.3.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ See :ref:`install.dependencies` and :ref:`install.optional_dependencies` for mor
142142
Other API changes
143143
^^^^^^^^^^^^^^^^^
144144
- Partially initialized :class:`CategoricalDtype` (i.e. those with ``categories=None`` objects will no longer compare as equal to fully initialized dtype objects.
145-
-
145+
- Accessing ``_constructor_expanddim`` on a :class:`DataFrame` and ``_constructor_sliced`` on a :class:`Series` now raise an ``AttributeError``. Previously a ``NotImplementedError`` was raised (:issue:`38782`)
146146
-
147147

148148
.. ---------------------------------------------------------------------------

pandas/core/frame.py

+1-9
Original file line numberDiff line numberDiff line change
@@ -493,20 +493,12 @@ class DataFrame(NDFrame, OpsMixin):
493493
_HANDLED_TYPES = (Series, Index, ExtensionArray, np.ndarray)
494494
_accessors: Set[str] = {"sparse"}
495495
_hidden_attrs: FrozenSet[str] = NDFrame._hidden_attrs | frozenset([])
496-
_constructor_sliced: Type[Series] = Series
497496

498497
@property
499498
def _constructor(self) -> Type[DataFrame]:
500499
return DataFrame
501500

502-
@property
503-
def _constructor_expanddim(self):
504-
# GH#31549 raising NotImplementedError on a property causes trouble
505-
# for `inspect`
506-
def constructor(*args, **kwargs):
507-
raise NotImplementedError("Not supported for DataFrames!")
508-
509-
return constructor
501+
_constructor_sliced: Type[Series] = Series
510502

511503
# ----------------------------------------------------------------------
512504
# Constructors

pandas/core/generic.py

-8
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,6 @@ def _constructor(self: FrameOrSeries) -> Type[FrameOrSeries]:
370370
"""
371371
raise AbstractMethodError(self)
372372

373-
@property
374-
def _constructor_expanddim(self):
375-
"""
376-
Used when a manipulation result has one higher dimension as the
377-
original, such as Series.to_frame()
378-
"""
379-
raise NotImplementedError
380-
381373
# ----------------------------------------------------------------------
382374
# Internals
383375

pandas/core/series.py

+4
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ def _constructor(self) -> Type["Series"]:
402402

403403
@property
404404
def _constructor_expanddim(self) -> Type["DataFrame"]:
405+
"""
406+
Used when a manipulation result has one higher dimension as the
407+
original, such as Series.to_frame()
408+
"""
405409
from pandas.core.frame import DataFrame
406410

407411
return DataFrame

pandas/tests/frame/test_api.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,13 @@ def test_set_flags(self, allows_duplicate_labels, frame_or_series):
330330
assert obj.iloc[key] == 0
331331

332332
def test_constructor_expanddim_lookup(self):
333-
# GH#33628 accessing _constructor_expanddim should not
334-
# raise NotImplementedError
333+
# GH#33628 accessing _constructor_expanddim should not raise NotImplementedError
334+
# GH38782 pandas has no container higher than DatafFame (two-dim), so
335+
# DataFrame._constructor_expand_dim, doesn't make sense, so is removed.
335336
df = DataFrame()
336337

337-
with pytest.raises(NotImplementedError, match="Not supported for DataFrames!"):
338+
msg = "'DataFrame' object has no attribute '_constructor_expanddim'"
339+
with pytest.raises(AttributeError, match=msg):
338340
df._constructor_expanddim(np.arange(27).reshape(3, 3, 3))
339341

340342
@skip_if_no("jinja2")

0 commit comments

Comments
 (0)