From 167ea89d747058df6bf9bd9adf4a6ca077e5b45f Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Sat, 4 Feb 2023 18:14:31 +0000 Subject: [PATCH 1/2] API: rename pandas/core/generic.py -> pandas/core.ndframe.py --- .pre-commit-config.yaml | 8 ++++---- pandas/_typing.py | 2 +- pandas/core/arraylike.py | 2 +- pandas/core/computation/align.py | 2 +- pandas/core/computation/eval.py | 2 +- pandas/core/dtypes/generic.py | 2 +- pandas/core/frame.py | 2 +- pandas/core/groupby/generic.py | 2 +- pandas/core/groupby/groupby.py | 2 +- pandas/core/groupby/grouper.py | 2 +- pandas/core/groupby/ops.py | 2 +- pandas/core/{generic.py => ndframe.py} | 0 pandas/core/resample.py | 8 ++++---- pandas/core/reshape/concat.py | 2 +- pandas/core/sample.py | 2 +- pandas/core/series.py | 2 +- pandas/core/window/ewm.py | 2 +- pandas/core/window/expanding.py | 2 +- pandas/core/window/rolling.py | 2 +- pandas/io/formats/style.py | 2 +- pandas/io/json/_json.py | 2 +- pandas/tests/{generic => ndframe}/__init__.py | 0 .../tests/{generic => ndframe}/test_duplicate_labels.py | 0 pandas/tests/{generic => ndframe}/test_finalize.py | 0 pandas/tests/{generic => ndframe}/test_frame.py | 0 .../test_generic.py => ndframe/test_frame_and_series.py} | 0 .../{generic => ndframe}/test_label_or_level_utils.py | 0 pandas/tests/{generic => ndframe}/test_series.py | 0 pandas/tests/{generic => ndframe}/test_to_xarray.py | 0 scripts/{no_bool_in_generic.py => no_bool_in_ndframe.py} | 8 ++++---- ...t_no_bool_in_generic.py => test_no_bool_in_ndframe.py} | 6 +++--- 31 files changed, 33 insertions(+), 33 deletions(-) rename pandas/core/{generic.py => ndframe.py} (100%) rename pandas/tests/{generic => ndframe}/__init__.py (100%) rename pandas/tests/{generic => ndframe}/test_duplicate_labels.py (100%) rename pandas/tests/{generic => ndframe}/test_finalize.py (100%) rename pandas/tests/{generic => ndframe}/test_frame.py (100%) rename pandas/tests/{generic/test_generic.py => ndframe/test_frame_and_series.py} (100%) rename pandas/tests/{generic => ndframe}/test_label_or_level_utils.py (100%) rename pandas/tests/{generic => ndframe}/test_series.py (100%) rename pandas/tests/{generic => ndframe}/test_to_xarray.py (100%) rename scripts/{no_bool_in_generic.py => no_bool_in_ndframe.py} (91%) rename scripts/tests/{test_no_bool_in_generic.py => test_no_bool_in_ndframe.py} (68%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 39c1f2b3a6c85..4ae5675ad0f09 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -369,11 +369,11 @@ repos: files: ^pandas/ exclude: ^pandas/tests/ types: [python] - - id: no-bool-in-core-generic - name: Use bool_t instead of bool in pandas/core/generic.py - entry: python scripts/no_bool_in_generic.py + - id: no-bool-in-core-ndframe + name: Use bool_t instead of bool in pandas/core/ndframe.py + entry: python scripts/no_bool_in_ndframe.py language: python - files: ^pandas/core/generic\.py$ + files: ^pandas/core/ndframe\.py$ - id: no-return-exception name: Use raise instead of return for exceptions language: pygrep diff --git a/pandas/_typing.py b/pandas/_typing.py index 8d3044a978291..bb518e6232c3b 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -50,7 +50,6 @@ ) from pandas.core.arrays.base import ExtensionArray from pandas.core.frame import DataFrame - from pandas.core.generic import NDFrame from pandas.core.groupby.generic import ( DataFrameGroupBy, GroupBy, @@ -63,6 +62,7 @@ SingleArrayManager, SingleBlockManager, ) + from pandas.core.ndframe import NDFrame from pandas.core.resample import Resampler from pandas.core.series import Series from pandas.core.window.rolling import BaseWindow diff --git a/pandas/core/arraylike.py b/pandas/core/arraylike.py index 1d10d797866f4..0e483da8d0b1e 100644 --- a/pandas/core/arraylike.py +++ b/pandas/core/arraylike.py @@ -262,8 +262,8 @@ def array_ufunc(self, ufunc: np.ufunc, method: str, *inputs: Any, **kwargs: Any) DataFrame, Series, ) - from pandas.core.generic import NDFrame from pandas.core.internals import BlockManager + from pandas.core.ndframe import NDFrame cls = type(self) diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index 2e7a0f842ee6d..c164c60cf453f 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -31,8 +31,8 @@ if TYPE_CHECKING: from pandas._typing import F - from pandas.core.generic import NDFrame from pandas.core.indexes.api import Index + from pandas.core.ndframe import NDFrame def _align_core_single_unary_op( diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index f0127ae05182a..f58ef92c312f4 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -16,7 +16,7 @@ ) from pandas.core.computation.parsing import tokenize_string from pandas.core.computation.scope import ensure_scope -from pandas.core.generic import NDFrame +from pandas.core.ndframe import NDFrame from pandas.io.formats.printing import pprint_thing diff --git a/pandas/core/dtypes/generic.py b/pandas/core/dtypes/generic.py index 5904ba4895aef..6e5e42a5d1d4b 100644 --- a/pandas/core/dtypes/generic.py +++ b/pandas/core/dtypes/generic.py @@ -28,7 +28,7 @@ PeriodArray, TimedeltaArray, ) - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame # define abstract base classes to enable isinstance type checking on our diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 4f13ead4005e7..b102f65bf0492 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -179,7 +179,6 @@ sanitize_array, sanitize_masked_array, ) -from pandas.core.generic import NDFrame from pandas.core.indexers import check_key_length from pandas.core.indexes.api import ( DatetimeIndex, @@ -213,6 +212,7 @@ to_arrays, treat_as_nested, ) +from pandas.core.ndframe import NDFrame from pandas.core.reshape.melt import melt from pandas.core.series import Series from pandas.core.shared_docs import _shared_docs diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index d6482b61a536d..46fd2e3ee49d4 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -97,7 +97,7 @@ from pandas.plotting import boxplot_frame_groupby if TYPE_CHECKING: - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame # TODO(typing) the return value on this callable should be any *scalar*. AggScalar = Union[str, Callable[..., Any]] diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index fd9a06a06cfa7..a87beaab16f35 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -106,7 +106,6 @@ class providing the base-class of operations. ) import pandas.core.common as com from pandas.core.frame import DataFrame -from pandas.core.generic import NDFrame from pandas.core.groupby import ( base, numba_, @@ -125,6 +124,7 @@ class providing the base-class of operations. default_index, ) from pandas.core.internals.blocks import ensure_block_shape +from pandas.core.ndframe import NDFrame from pandas.core.series import Series from pandas.core.sorting import get_group_index_sorter from pandas.core.util.numba_ import ( diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py index d77ad59a4bb82..8ef3c1ce1ff7e 100644 --- a/pandas/core/groupby/grouper.py +++ b/pandas/core/groupby/grouper.py @@ -50,7 +50,7 @@ from pandas.io.formats.printing import pprint_thing if TYPE_CHECKING: - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame class Grouper: diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index bff61ec135d74..f72d09277f3c9 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -96,7 +96,7 @@ ) if TYPE_CHECKING: - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame class WrappedCythonOp: diff --git a/pandas/core/generic.py b/pandas/core/ndframe.py similarity index 100% rename from pandas/core/generic.py rename to pandas/core/ndframe.py diff --git a/pandas/core/resample.py b/pandas/core/resample.py index ebb803ee8f3b4..d75148b12cfa5 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -57,10 +57,6 @@ from pandas.core.apply import ResamplerWindowApply from pandas.core.base import PandasObject import pandas.core.common as com -from pandas.core.generic import ( - NDFrame, - _shared_docs, -) from pandas.core.groupby.generic import SeriesGroupBy from pandas.core.groupby.groupby import ( BaseGroupBy, @@ -82,6 +78,10 @@ TimedeltaIndex, timedelta_range, ) +from pandas.core.ndframe import ( + NDFrame, + _shared_docs, +) from pandas.tseries.frequencies import ( is_subperiod, diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index f8220649bf890..566e08be1b1b7 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -60,7 +60,7 @@ DataFrame, Series, ) - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame # --------------------------------------------------------------------- # Concatenate DataFrame objects diff --git a/pandas/core/sample.py b/pandas/core/sample.py index a9b236b58a9ba..12c7fd1337e50 100644 --- a/pandas/core/sample.py +++ b/pandas/core/sample.py @@ -16,7 +16,7 @@ ) if TYPE_CHECKING: - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame def preprocess_weights(obj: NDFrame, weights, axis: AxisInt) -> np.ndarray: diff --git a/pandas/core/series.py b/pandas/core/series.py index abe31d0dbd52a..35409cfb7ed1b 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -132,7 +132,6 @@ extract_array, sanitize_array, ) -from pandas.core.generic import NDFrame from pandas.core.indexers import ( disallow_ndim_indexing, unpack_1tuple, @@ -156,6 +155,7 @@ SingleArrayManager, SingleBlockManager, ) +from pandas.core.ndframe import NDFrame from pandas.core.shared_docs import _shared_docs from pandas.core.sorting import ( ensure_key_mapped, diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py index c0a7b2b7cc361..ae012c04a6e68 100644 --- a/pandas/core/window/ewm.py +++ b/pandas/core/window/ewm.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from pandas import DataFrame, Series - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame from pandas.util._decorators import doc diff --git a/pandas/core/window/expanding.py b/pandas/core/window/expanding.py index 6147f0f43c558..b2c12c47522c3 100644 --- a/pandas/core/window/expanding.py +++ b/pandas/core/window/expanding.py @@ -15,7 +15,7 @@ if TYPE_CHECKING: from pandas import DataFrame, Series - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame from pandas.util._decorators import doc diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index ef0524e48f9e2..84328fe9c1c80 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -103,8 +103,8 @@ DataFrame, Series, ) - from pandas.core.generic import NDFrame from pandas.core.groupby.ops import BaseGrouper + from pandas.core.ndframe import NDFrame class BaseWindow(SelectionMixin): diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 442f2ab72a1e2..13e736509f4db 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -48,7 +48,7 @@ DataFrame, Series, ) -from pandas.core.generic import NDFrame +from pandas.core.ndframe import NDFrame from pandas.core.shared_docs import _shared_docs from pandas.io.formats.format import save_to_buffer diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 66991eab54671..c79e4b52a5f60 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -78,7 +78,7 @@ from pandas.io.parsers.readers import validate_integer if TYPE_CHECKING: - from pandas.core.generic import NDFrame + from pandas.core.ndframe import NDFrame FrameSeriesStrT = TypeVar("FrameSeriesStrT", bound=Literal["frame", "series"]) diff --git a/pandas/tests/generic/__init__.py b/pandas/tests/ndframe/__init__.py similarity index 100% rename from pandas/tests/generic/__init__.py rename to pandas/tests/ndframe/__init__.py diff --git a/pandas/tests/generic/test_duplicate_labels.py b/pandas/tests/ndframe/test_duplicate_labels.py similarity index 100% rename from pandas/tests/generic/test_duplicate_labels.py rename to pandas/tests/ndframe/test_duplicate_labels.py diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/ndframe/test_finalize.py similarity index 100% rename from pandas/tests/generic/test_finalize.py rename to pandas/tests/ndframe/test_finalize.py diff --git a/pandas/tests/generic/test_frame.py b/pandas/tests/ndframe/test_frame.py similarity index 100% rename from pandas/tests/generic/test_frame.py rename to pandas/tests/ndframe/test_frame.py diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/ndframe/test_frame_and_series.py similarity index 100% rename from pandas/tests/generic/test_generic.py rename to pandas/tests/ndframe/test_frame_and_series.py diff --git a/pandas/tests/generic/test_label_or_level_utils.py b/pandas/tests/ndframe/test_label_or_level_utils.py similarity index 100% rename from pandas/tests/generic/test_label_or_level_utils.py rename to pandas/tests/ndframe/test_label_or_level_utils.py diff --git a/pandas/tests/generic/test_series.py b/pandas/tests/ndframe/test_series.py similarity index 100% rename from pandas/tests/generic/test_series.py rename to pandas/tests/ndframe/test_series.py diff --git a/pandas/tests/generic/test_to_xarray.py b/pandas/tests/ndframe/test_to_xarray.py similarity index 100% rename from pandas/tests/generic/test_to_xarray.py rename to pandas/tests/ndframe/test_to_xarray.py diff --git a/scripts/no_bool_in_generic.py b/scripts/no_bool_in_ndframe.py similarity index 91% rename from scripts/no_bool_in_generic.py rename to scripts/no_bool_in_ndframe.py index 92e2c0983b25b..1e5243c83848d 100644 --- a/scripts/no_bool_in_generic.py +++ b/scripts/no_bool_in_ndframe.py @@ -1,11 +1,11 @@ """ -Check that pandas/core/generic.py doesn't use bool as a type annotation. +Check that pandas/core/ndframe.py doesn't use bool as a type annotation. There is already the method `bool`, so the alias `bool_t` should be used instead. This is meant to be run as a pre-commit hook - to run it manually, you can do: - pre-commit run no-bool-in-core-generic --all-files + pre-commit run no-bool-in-core-ndframe --all-files The function `visit` is adapted from a function by the same name in pyupgrade: https://github.com/asottile/pyupgrade/blob/5495a248f2165941c5d3b82ac3226ba7ad1fa59d/pyupgrade/_data.py#L70-L113 @@ -57,7 +57,7 @@ def replace_bool_with_bool_t(to_replace, content: str) -> str: return "\n".join(new_lines) -def check_for_bool_in_generic(content: str) -> tuple[bool, str]: +def check_for_bool_in_ndframe(content: str) -> tuple[bool, str]: tree = ast.parse(content) to_replace = visit(tree) @@ -77,7 +77,7 @@ def main(argv: Sequence[str] | None = None) -> None: for path in args.paths: with open(path, encoding="utf-8") as fd: content = fd.read() - mutated, new_content = check_for_bool_in_generic(content) + mutated, new_content = check_for_bool_in_ndframe(content) if mutated: with open(path, "w", encoding="utf-8") as fd: fd.write(new_content) diff --git a/scripts/tests/test_no_bool_in_generic.py b/scripts/tests/test_no_bool_in_ndframe.py similarity index 68% rename from scripts/tests/test_no_bool_in_generic.py rename to scripts/tests/test_no_bool_in_ndframe.py index 0bc91c5d1cf1e..ebbb75e066b97 100644 --- a/scripts/tests/test_no_bool_in_generic.py +++ b/scripts/tests/test_no_bool_in_ndframe.py @@ -1,4 +1,4 @@ -from scripts.no_bool_in_generic import check_for_bool_in_generic +from scripts.no_bool_in_ndframe import check_for_bool_in_ndframe BAD_FILE = "def foo(a: bool) -> bool:\n return bool(0)" GOOD_FILE = "def foo(a: bool_t) -> bool_t:\n return bool(0)" @@ -6,7 +6,7 @@ def test_bad_file_with_replace(): content = BAD_FILE - mutated, result = check_for_bool_in_generic(content) + mutated, result = check_for_bool_in_ndframe(content) expected = GOOD_FILE assert result == expected assert mutated @@ -14,7 +14,7 @@ def test_bad_file_with_replace(): def test_good_file_with_replace(): content = GOOD_FILE - mutated, result = check_for_bool_in_generic(content) + mutated, result = check_for_bool_in_ndframe(content) expected = content assert result == expected assert not mutated From bcf92170ba901ac8e4036f7b0a35a9955bac9305 Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Sat, 4 Feb 2023 21:46:21 +0000 Subject: [PATCH 2/2] add back pandas/core/generic.py + add deprecation test --- pandas/core/generic.py | 13 +++++++++++++ pandas/tests/ndframe/test_frame_and_series.py | 11 +++++++++++ 2 files changed, 24 insertions(+) create mode 100644 pandas/core/generic.py diff --git a/pandas/core/generic.py b/pandas/core/generic.py new file mode 100644 index 0000000000000..bd3bc458ab064 --- /dev/null +++ b/pandas/core/generic.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +import warnings + +from pandas.core.ndframe import * # noqa F401 + +warnings.warn( + "pandas.core.generic is deprecated " + "and will be removed from pandas in a future version. " + "Use pandas.core.ndframe instead.", + FutureWarning, + stacklevel=2, +) diff --git a/pandas/tests/ndframe/test_frame_and_series.py b/pandas/tests/ndframe/test_frame_and_series.py index 429dd9181ad50..40974502cb47c 100644 --- a/pandas/tests/ndframe/test_frame_and_series.py +++ b/pandas/tests/ndframe/test_frame_and_series.py @@ -447,3 +447,14 @@ def test_flags_identity(self, frame_or_series): assert obj.flags is obj.flags obj2 = obj.copy() assert obj2.flags is not obj.flags + + +def test_core_generic_deprecated(): + # GH51152 + msg = ( + "pandas.core.generic is deprecated " + "and will be removed from pandas in a future version. " + "Use pandas.core.ndframe instead." + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + from pandas.core import generic # noqa F401