From da1288753fa9c5d32504d02577d425725a806bfb Mon Sep 17 00:00:00 2001 From: richard Date: Tue, 4 Nov 2025 17:42:37 -0500 Subject: [PATCH] DOC: Run all doctests --- .github/workflows/code-checks.yml | 2 ++ pandas/_libs/interval.pyx | 1 - pandas/_libs/missing.pyx | 1 - pandas/_libs/tslibs/nattype.pyx | 1 - pandas/_libs/tslibs/np_datetime.pyx | 4 +--- pandas/_libs/tslibs/offsets.pyx | 4 ++-- pandas/_libs/tslibs/period.pyx | 2 +- pandas/core/apply.py | 8 +++++--- pandas/core/arrays/arrow/array.py | 8 +++++--- pandas/core/arrays/base.py | 7 +++---- pandas/core/arrays/boolean.py | 3 +-- pandas/core/arrays/categorical.py | 4 ++-- pandas/core/arrays/datetimes.py | 4 ++-- pandas/core/arrays/floating.py | 3 +-- pandas/core/arrays/integer.py | 3 +-- pandas/core/arrays/interval.py | 4 ++-- pandas/core/arrays/numpy_.py | 3 ++- pandas/core/arrays/period.py | 4 ++-- pandas/core/arrays/sparse/array.py | 8 +++++--- pandas/core/arrays/string_.py | 3 +-- pandas/core/arrays/string_arrow.py | 4 ++-- pandas/core/arrays/timedeltas.py | 4 ++-- pandas/core/col.py | 3 +-- pandas/core/dtypes/base.py | 3 +-- pandas/core/flags.py | 5 +++-- pandas/core/groupby/grouper.py | 10 +++++++--- pandas/core/indexers/objects.py | 10 ++++------ pandas/core/indexes/frozen.py | 5 +++-- pandas/core/indexes/range.py | 2 -- pandas/core/interchange/dataframe_protocol.py | 5 +++-- pandas/core/resample.py | 16 ++++++---------- pandas/core/window/ewm.py | 11 ++++++----- pandas/core/window/expanding.py | 8 ++++---- pandas/core/window/rolling.py | 9 ++++----- pandas/io/json/_json.py | 3 +-- pandas/io/sas/sasreader.py | 3 +-- pandas/io/stata.py | 2 +- pandas/plotting/_core.py | 3 +-- pandas/util/_decorators.py | 14 ++++++++++---- pandas/util/version/__init__.py | 3 ++- 40 files changed, 100 insertions(+), 100 deletions(-) diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml index 82b1ef586e5dc..083c80b7c291b 100644 --- a/.github/workflows/code-checks.yml +++ b/.github/workflows/code-checks.yml @@ -57,6 +57,8 @@ jobs: run: sudo apt-get update && sudo apt-get install -y libegl1 libopengl0 - name: Run doctests + env: + PANDAS_SET_MODULE_DUNDER: 0 run: cd ci && ./code_checks.sh doctests if: ${{ steps.build.outcome == 'success' && always() }} diff --git a/pandas/_libs/interval.pyx b/pandas/_libs/interval.pyx index a1cd4c9d15447..ad32adf5d19f9 100644 --- a/pandas/_libs/interval.pyx +++ b/pandas/_libs/interval.pyx @@ -445,7 +445,6 @@ cdef class Interval(IntervalMixin): >>> interval.closed 'left' """ - __module__ = "pandas" def __init__(self, left, right, str closed="right"): # note: it is faster to just do these checks than to use a special diff --git a/pandas/_libs/missing.pyx b/pandas/_libs/missing.pyx index a67c533d03e0e..b24dd9d61589d 100644 --- a/pandas/_libs/missing.pyx +++ b/pandas/_libs/missing.pyx @@ -394,7 +394,6 @@ class NAType(C_NAType): True """ __module__ = "pandas.api.typing" - _instance = None def __new__(cls, *args, **kwargs): diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index a0265297fe873..fef104b9760af 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -371,7 +371,6 @@ class NaTType(_NaT): 0 2023-01-01 1 NaT """ - __module__ = "pandas.api.typing" def __new__(cls): diff --git a/pandas/_libs/tslibs/np_datetime.pyx b/pandas/_libs/tslibs/np_datetime.pyx index 0fc7a6945d2e0..102ae21d55a9b 100644 --- a/pandas/_libs/tslibs/np_datetime.pyx +++ b/pandas/_libs/tslibs/np_datetime.pyx @@ -193,7 +193,6 @@ class OutOfBoundsDatetime(ValueError): at position 0 """ __module__ = "pandas.errors" - pass class OutOfBoundsTimedelta(ValueError): @@ -213,9 +212,8 @@ class OutOfBoundsTimedelta(ValueError): OutOfBoundsTimedelta: Cannot cast 139999 days 00:00:00 to unit='ns' without overflow. """ - __module__ = "pandas.errors" # Timedelta analogue to OutOfBoundsDatetime - pass + __module__ = "pandas.errors" cdef get_implementation_bounds( diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index be86118a2b9e2..547a39d39a3b9 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -47,6 +47,7 @@ from pandas._libs.tslibs.ccalendar import ( int_to_weekday, weekday_to_int, ) +from pandas.util._decorators import set_module from pandas.util._exceptions import find_stack_level from pandas._libs.tslibs.ccalendar cimport ( @@ -1695,6 +1696,7 @@ class OffsetMeta(type): # TODO: figure out a way to use a metaclass with a cdef class +@set_module("pandas") class DateOffset(RelativeDeltaOffset, metaclass=OffsetMeta): """ Standard kind of date increment used for a date range. @@ -1822,8 +1824,6 @@ class DateOffset(RelativeDeltaOffset, metaclass=OffsetMeta): >>> ts + pd.DateOffset(hour=8) Timestamp('2017-01-01 08:10:11') """ - __module__ = "pandas" - def __setattr__(self, name, value): raise AttributeError("DateOffset objects are immutable.") diff --git a/pandas/_libs/tslibs/period.pyx b/pandas/_libs/tslibs/period.pyx index facf430060e73..fd905248c4558 100644 --- a/pandas/_libs/tslibs/period.pyx +++ b/pandas/_libs/tslibs/period.pyx @@ -1626,12 +1626,12 @@ DIFFERENT_FREQ = ("Input has different freq={other_freq} " "from {cls}(freq={own_freq})") +@set_module("pandas.errors") class IncompatibleFrequency(TypeError): """ Raised when trying to compare or operate between Periods with different frequencies. """ - __module__ = "pandas.errors" pass diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 1098ceb4c3929..c1889dc212697 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -29,7 +29,10 @@ ) from pandas.compat._optional import import_optional_dependency from pandas.errors import SpecificationError -from pandas.util._decorators import cache_readonly +from pandas.util._decorators import ( + cache_readonly, + set_module, +) from pandas.core.dtypes.cast import is_nested_object from pandas.core.dtypes.common import ( @@ -75,6 +78,7 @@ ResType: TypeAlias = dict[int, Any] +@set_module("pandas.api.executors") class BaseExecutionEngine(abc.ABC): """ Base class for execution engines for map and apply methods. @@ -88,8 +92,6 @@ class BaseExecutionEngine(abc.ABC): simply runs the code with the Python interpreter and pandas. """ - __module__ = "pandas.api.executors" - @staticmethod @abc.abstractmethod def map( diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 53c938faf9257..b5d01572deeac 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -36,7 +36,10 @@ PYARROW_MIN_VERSION, ) from pandas.errors import Pandas4Warning -from pandas.util._decorators import doc +from pandas.util._decorators import ( + doc, + set_module, +) from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.cast import ( @@ -241,6 +244,7 @@ def to_pyarrow_type( return None +@set_module("pandas.arrays") class ArrowExtensionArray( OpsMixin, ExtensionArraySupportsAnyAll, @@ -296,8 +300,6 @@ class ArrowExtensionArray( Length: 3, dtype: int64[pyarrow] """ # noqa: E501 (http link too long) - __module__ = "pandas.arrays" - _pa_array: pa.ChunkedArray _dtype: ArrowDtype diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index e091ecf18668d..a0fca279d5e3c 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -31,6 +31,7 @@ from pandas.errors import AbstractMethodError from pandas.util._decorators import ( cache_readonly, + set_module, ) from pandas.util._validators import ( validate_bool_kwarg, @@ -105,6 +106,7 @@ _extension_array_shared_docs: dict[str, str] = {} +@set_module("pandas.api.extensions") class ExtensionArray: """ Abstract base class for custom 1-D array types. @@ -256,8 +258,6 @@ class ExtensionArray: https://github.com/pandas-dev/pandas/blob/main/pandas/tests/extension/list/array.py """ - __module__ = "pandas.api.extensions" - # '_typ' is for pandas.core.dtypes.generic.ABCExtensionArray. # Don't override this. _typ = "extension" @@ -2788,6 +2788,7 @@ def _add_logical_ops(cls) -> None: setattr(cls, "__rxor__", cls._create_logical_method(roperator.rxor)) +@set_module("pandas.api.extensions") class ExtensionScalarOpsMixin(ExtensionOpsMixin): """ A mixin for defining ops on an ExtensionArray. @@ -2814,8 +2815,6 @@ class ExtensionScalarOpsMixin(ExtensionOpsMixin): with NumPy arrays. """ - __module__ = "pandas.api.extensions" - @classmethod def _create_method(cls, op, coerce_to_dtype: bool = True, result_dtype=None): """ diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 2d7bae7833f29..15e59060898f2 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -262,6 +262,7 @@ def coerce_to_array( return values, mask +@set_module("pandas.arrays") class BooleanArray(BaseMaskedArray): """ Array of boolean (True/False) data with missing values. @@ -321,8 +322,6 @@ class BooleanArray(BaseMaskedArray): Length: 3, dtype: boolean """ - __module__ = "pandas.arrays" - _TRUE_VALUES = {"True", "TRUE", "true", "1", "1.0"} _FALSE_VALUES = {"False", "FALSE", "false", "0", "0.0"} diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 41e5c6f65dbb9..7080b8d797bbe 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -26,6 +26,7 @@ from pandas._libs.arrays import NDArrayBacked from pandas.compat.numpy import function as nv from pandas.errors import Pandas4Warning +from pandas.util._decorators import set_module from pandas.util._exceptions import find_stack_level from pandas.util._validators import validate_bool_kwarg @@ -245,6 +246,7 @@ def contains(cat, key, container) -> bool: return any(loc_ in container for loc_ in loc) +@set_module("pandas") class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMixin): """ Represent a categorical variable in classic R / S-plus fashion. @@ -361,8 +363,6 @@ class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMi 'c' """ - __module__ = "pandas" - # For comparisons, so that numpy uses our implementation if the compare # ops, which raise __array_priority__ = 1000 diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 4cf5f4b13890e..942856847f57b 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -46,6 +46,7 @@ ) from pandas._libs.tslibs.dtypes import abbrev_to_npy_unit from pandas.errors import PerformanceWarning +from pandas.util._decorators import set_module from pandas.util._exceptions import find_stack_level from pandas.util._validators import validate_inclusive @@ -171,6 +172,7 @@ def f(self): return property(f) +@set_module("pandas.arrays") class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): """ Pandas ExtensionArray for tz-naive or tz-aware datetime data. @@ -223,8 +225,6 @@ class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): Length: 2, dtype: datetime64[s] """ - __module__ = "pandas.arrays" - _typ = "datetimearray" _internal_fill_value = np.datetime64("NaT", "ns") _recognized_scalars = (datetime, np.datetime64) diff --git a/pandas/core/arrays/floating.py b/pandas/core/arrays/floating.py index e547c3fe76089..602b0c225999e 100644 --- a/pandas/core/arrays/floating.py +++ b/pandas/core/arrays/floating.py @@ -63,6 +63,7 @@ def _safe_cast(cls, values: np.ndarray, dtype: np.dtype, copy: bool) -> np.ndarr return values.astype(dtype, copy=copy) +@set_module("pandas.arrays") class FloatingArray(NumericArray): """ Array of floating (optional missing) values. @@ -129,8 +130,6 @@ class FloatingArray(NumericArray): Length: 3, dtype: Float32 """ - __module__ = "pandas.arrays" - _dtype_cls = FloatingDtype diff --git a/pandas/core/arrays/integer.py b/pandas/core/arrays/integer.py index 7a8ca85a83db5..3cf950b6594a1 100644 --- a/pandas/core/arrays/integer.py +++ b/pandas/core/arrays/integer.py @@ -71,6 +71,7 @@ def _safe_cast(cls, values: np.ndarray, dtype: np.dtype, copy: bool) -> np.ndarr ) from err +@set_module("pandas.arrays") class IntegerArray(NumericArray): """ Array of integer (optional missing) values. @@ -142,8 +143,6 @@ class IntegerArray(NumericArray): Length: 3, dtype: UInt16 """ - __module__ = "pandas.arrays" - _dtype_cls = IntegerDtype diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 3e724b176b76d..e9dd687ca5184 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -39,6 +39,7 @@ ) from pandas.compat.numpy import function as nv from pandas.errors import IntCastingNaNError +from pandas.util._decorators import set_module from pandas.core.dtypes.cast import ( LossySetitemError, @@ -176,6 +177,7 @@ """ +@set_module("pandas.arrays") class IntervalArray(IntervalMixin, ExtensionArray): """ Pandas array for interval data that are closed on the same side. @@ -243,8 +245,6 @@ class IntervalArray(IntervalMixin, ExtensionArray): :meth:`IntervalArray.from_breaks`, and :meth:`IntervalArray.from_tuples`. """ - __module__ = "pandas.arrays" - can_hold_na = True _na_value = _fill_value = np.nan diff --git a/pandas/core/arrays/numpy_.py b/pandas/core/arrays/numpy_.py index eca47d3c9657f..dfe99e50f1f31 100644 --- a/pandas/core/arrays/numpy_.py +++ b/pandas/core/arrays/numpy_.py @@ -13,6 +13,7 @@ from pandas._libs import lib from pandas._libs.tslibs import is_supported_dtype from pandas.compat.numpy import function as nv +from pandas.util._decorators import set_module from pandas.core.dtypes.astype import astype_array from pandas.core.dtypes.cast import ( @@ -52,12 +53,12 @@ from pandas.arrays import StringArray +@set_module("pandas.arrays") class NumpyExtensionArray( OpsMixin, NDArrayBackedExtensionArray, ObjectStringArrayMixin, ): - __module__ = "pandas.arrays" """ A pandas ExtensionArray for NumPy data. diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 18e4ff31164ac..fe5163d8a77a2 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -54,6 +54,7 @@ from pandas.util._decorators import ( cache_readonly, doc, + set_module, ) from pandas.core.dtypes.common import ( @@ -120,6 +121,7 @@ def f(self): return property(f) +@set_module("pandas.arrays") # error: Definition of "_concat_same_type" in base class "NDArrayBacked" is # incompatible with definition in base class "ExtensionArray" class PeriodArray(dtl.DatelikeOps, libperiod.PeriodMixin): # type: ignore[misc] @@ -177,8 +179,6 @@ class PeriodArray(dtl.DatelikeOps, libperiod.PeriodMixin): # type: ignore[misc] Length: 2, dtype: period[D] """ - __module__ = "pandas.arrays" - # array priority higher than numpy scalars __array_priority__ = 1000 _typ = "periodarray" # ABCPeriodArray diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 83e16f5d4b8db..b1585ad28e671 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -31,7 +31,10 @@ from pandas._libs.tslibs import NaT from pandas.compat.numpy import function as nv from pandas.errors import PerformanceWarning -from pandas.util._decorators import doc +from pandas.util._decorators import ( + doc, + set_module, +) from pandas.util._exceptions import find_stack_level from pandas.util._validators import ( validate_bool_kwarg, @@ -289,6 +292,7 @@ def _wrap_result( ) +@set_module("pandas.arrays") class SparseArray(OpsMixin, PandasObject, ExtensionArray): """ An ExtensionArray for storing sparse data. @@ -370,8 +374,6 @@ class SparseArray(OpsMixin, PandasObject, ExtensionArray): Indices: array([2, 3], dtype=int32) """ - __module__ = "pandas.arrays" - _subtyp = "sparse_array" # register ABCSparseArray _hidden_attrs = PandasObject._hidden_attrs | frozenset([]) _sparse_index: SparseIndex diff --git a/pandas/core/arrays/string_.py b/pandas/core/arrays/string_.py index ec591d7711fa9..6cb75ba44a3fd 100644 --- a/pandas/core/arrays/string_.py +++ b/pandas/core/arrays/string_.py @@ -548,6 +548,7 @@ def view(self, dtype: Dtype | None = None) -> Self: return super().view() +@set_module("pandas.arrays") # error: Definition of "_concat_same_type" in base class "NDArrayBacked" is # incompatible with definition in base class "ExtensionArray" class StringArray(BaseStringArray, NumpyExtensionArray): # type: ignore[misc] @@ -633,8 +634,6 @@ class StringArray(BaseStringArray, NumpyExtensionArray): # type: ignore[misc] Length: 3, dtype: boolean """ - __module__ = "pandas.arrays" - # undo the NumpyExtensionArray hack _typ = "extension" diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index 7dd41cc0e9960..58385e84b8b4d 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -18,6 +18,7 @@ PYARROW_MIN_VERSION, pa_version_under16p0, ) +from pandas.util._decorators import set_module from pandas.util._validators import validate_na_arg from pandas.core.dtypes.common import ( @@ -80,6 +81,7 @@ def _is_string_view(typ): # fallback for the ones that pyarrow doesn't yet support +@set_module("pandas.arrays") class ArrowStringArray(ObjectStringArrayMixin, ArrowExtensionArray, BaseStringArray): """ Extension array for string data in a ``pyarrow.ChunkedArray``. @@ -124,8 +126,6 @@ class ArrowStringArray(ObjectStringArrayMixin, ArrowExtensionArray, BaseStringAr Length: 4, dtype: string """ - __module__ = "pandas.arrays" - # error: Incompatible types in assignment (expression has type "StringDtype", # base class "ArrowExtensionArray" defined the type as "ArrowDtype") _dtype: StringDtype # type: ignore[assignment] diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index c081d6190204e..5b69787c3b2bc 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -40,6 +40,7 @@ truediv_object_array, ) from pandas.compat.numpy import function as nv +from pandas.util._decorators import set_module from pandas.util._validators import validate_endpoints from pandas.core.dtypes.common import ( @@ -103,6 +104,7 @@ def f(self) -> np.ndarray: return property(f) +@set_module("pandas.arrays") class TimedeltaArray(dtl.TimelikeOps): """ Pandas ExtensionArray for timedelta data. @@ -147,8 +149,6 @@ class TimedeltaArray(dtl.TimelikeOps): Length: 2, dtype: timedelta64[ns] """ - __module__ = "pandas.arrays" - _typ = "timedeltaarray" _internal_fill_value = np.timedelta64("NaT", "ns") _recognized_scalars = (timedelta, np.timedelta64, Tick) diff --git a/pandas/core/col.py b/pandas/core/col.py index 416a34aaa6c4a..39c4a7fd016c2 100644 --- a/pandas/core/col.py +++ b/pandas/core/col.py @@ -71,6 +71,7 @@ def _pretty_print_args_kwargs(*args: Any, **kwargs: Any) -> str: return ", ".join(all_args) +@set_module("pandas.api.typing") class Expression: """ Class representing a deferred column. @@ -78,8 +79,6 @@ class Expression: This is not meant to be instantiated directly. Instead, use :meth:`pandas.col`. """ - __module__ = "pandas.api.typing" - def __init__(self, func: Callable[[DataFrame], Any], repr_str: str) -> None: self._func = func self._repr_str = repr_str diff --git a/pandas/core/dtypes/base.py b/pandas/core/dtypes/base.py index 59f360650ff8c..08a0c8a921c71 100644 --- a/pandas/core/dtypes/base.py +++ b/pandas/core/dtypes/base.py @@ -42,6 +42,7 @@ ExtensionDtypeT = TypeVar("ExtensionDtypeT", bound="ExtensionDtype") +@set_module("pandas.api.extensions") class ExtensionDtype: """ A custom data type, to be paired with an ExtensionArray. @@ -112,8 +113,6 @@ class property**. provided for registering virtual subclasses. """ - __module__ = "pandas.api.extensions" - _metadata: tuple[str, ...] = () def __str__(self) -> str: diff --git a/pandas/core/flags.py b/pandas/core/flags.py index a98380e9f7d16..f6088e3f40b1b 100644 --- a/pandas/core/flags.py +++ b/pandas/core/flags.py @@ -3,10 +3,13 @@ from typing import TYPE_CHECKING import weakref +from pandas.util._decorators import set_module + if TYPE_CHECKING: from pandas.core.generic import NDFrame +@set_module("pandas") class Flags: """ Flags that apply to pandas objects. @@ -55,8 +58,6 @@ class Flags: """ - __module__ = "pandas" - _keys: set[str] = {"allows_duplicate_labels"} def __init__(self, obj: NDFrame, *, allows_duplicate_labels: bool) -> None: diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py index a45ce1f385e4d..311726b9aa01e 100644 --- a/pandas/core/groupby/grouper.py +++ b/pandas/core/groupby/grouper.py @@ -17,7 +17,10 @@ ) from pandas._libs.tslibs import OutOfBoundsDatetime from pandas.errors import InvalidIndexError -from pandas.util._decorators import cache_readonly +from pandas.util._decorators import ( + cache_readonly, + set_module, +) from pandas.core.dtypes.common import ( ensure_int64, @@ -63,6 +66,9 @@ from pandas.core.generic import NDFrame +set_module("pandas") + + class Grouper: """ A Grouper allows the user to specify a groupby instruction for an object. @@ -253,8 +259,6 @@ class Grouper: Freq: 17min, dtype: int64 """ - __module__ = "pandas" - sort: bool dropna: bool _grouper: Index | None diff --git a/pandas/core/indexers/objects.py b/pandas/core/indexers/objects.py index 2c2413c74f2fa..42fc4971f1613 100644 --- a/pandas/core/indexers/objects.py +++ b/pandas/core/indexers/objects.py @@ -8,6 +8,7 @@ from pandas._libs.tslibs import BaseOffset from pandas._libs.window.indexers import calculate_variable_window_bounds +from pandas.util._decorators import set_module from pandas.core.dtypes.common import ensure_platform_int @@ -16,6 +17,7 @@ from pandas.tseries.offsets import Nano +@set_module("pandas.api.indexers") class BaseIndexer: """ Base class for window bounds calculations. @@ -58,8 +60,6 @@ class BaseIndexer: 4 4.0 """ - __module__ = "pandas.api.indexers" - def __init__( self, index_array: np.ndarray | None = None, window_size: int = 0, **kwargs ) -> None: @@ -212,6 +212,7 @@ def get_window_bounds( ) +@set_module("pandas.api.indexers") class VariableOffsetWindowIndexer(BaseIndexer): """ Calculate window boundaries based on a non-fixed offset such as a BusinessDay. @@ -273,8 +274,6 @@ class VariableOffsetWindowIndexer(BaseIndexer): 2020-01-10 9.0 """ - __module__ = "pandas.api.indexers" - def __init__( self, index_array: np.ndarray | None = None, @@ -437,6 +436,7 @@ def get_window_bounds( ) +@set_module("pandas.api.indexers") class FixedForwardWindowIndexer(BaseIndexer): """ Creates window boundaries for fixed-length windows that include the current row. @@ -482,8 +482,6 @@ class FixedForwardWindowIndexer(BaseIndexer): 4 4.0 """ - __module__ = "pandas.api.indexers" - def get_window_bounds( self, num_values: int = 0, diff --git a/pandas/core/indexes/frozen.py b/pandas/core/indexes/frozen.py index fe06e235e0fd9..59800c3b9dc5e 100644 --- a/pandas/core/indexes/frozen.py +++ b/pandas/core/indexes/frozen.py @@ -14,11 +14,14 @@ Self, ) +from pandas.util._decorators import set_module + from pandas.core.base import PandasObject from pandas.io.formats.printing import pprint_thing +@set_module("pandas.api.typing") class FrozenList(PandasObject, list): """ Container that doesn't allow setting item *but* @@ -26,8 +29,6 @@ class FrozenList(PandasObject, list): for lookups, appropriately, etc. """ - __module__ = "pandas.api.typing" - # Side note: This has to be of type list. Otherwise, # it messes up PyTables type checks. diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 7a025cdd5fb68..c5dcb53d3c81c 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -136,8 +136,6 @@ class RangeIndex(Index): [] """ - __module__ = "pandas" - _typ = "rangeindex" _dtype_validation_metadata = (is_signed_integer_dtype, "signed integer") _range: range diff --git a/pandas/core/interchange/dataframe_protocol.py b/pandas/core/interchange/dataframe_protocol.py index 15bd323d5fade..28aa13202a712 100644 --- a/pandas/core/interchange/dataframe_protocol.py +++ b/pandas/core/interchange/dataframe_protocol.py @@ -15,6 +15,8 @@ TypedDict, ) +from pandas.util._decorators import set_module + if TYPE_CHECKING: from collections.abc import ( Iterable, @@ -362,6 +364,7 @@ def get_buffers(self) -> ColumnBuffers: # pass +@set_module("pandas.api.interchange") class DataFrame(ABC): """ A data frame class, with only the methods required by the interchange @@ -377,8 +380,6 @@ class DataFrame(ABC): to the dataframe interchange protocol specification. """ - __module__ = "pandas.api.interchange" - version = 0 # version of the protocol @abstractmethod diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 2694b581a6707..1fdcbbec837a0 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -30,6 +30,7 @@ AbstractMethodError, Pandas4Warning, ) +from pandas.util._decorators import set_module from pandas.util._exceptions import find_stack_level from pandas.core.dtypes.dtypes import ( @@ -115,6 +116,7 @@ _shared_docs_kwargs: dict[str, str] = {} +@set_module("pandas.api.typing") class Resampler(BaseGroupBy, PandasObject): """ Class for resampling datetimelike data, a groupby-like operation. @@ -136,8 +138,6 @@ class Resampler(BaseGroupBy, PandasObject): After resampling, see aggregate, apply, and transform functions. """ - __module__ = "pandas.api.typing" - _grouper: BinGrouper _timegrouper: TimeGrouper binner: DatetimeIndex | TimedeltaIndex | PeriodIndex # depends on subclass @@ -2171,6 +2171,7 @@ def _wrap_result(self, result): return result +@set_module("pandas.api.typing") # error: Definition of "ax" in base class "_GroupByMixin" is incompatible # with definition in base class "DatetimeIndexResampler" class DatetimeIndexResamplerGroupby( # type: ignore[misc] @@ -2180,8 +2181,6 @@ class DatetimeIndexResamplerGroupby( # type: ignore[misc] Provides a resample of a groupby implementation """ - __module__ = "pandas.api.typing" - @property def _resampler_cls(self): return DatetimeIndexResampler @@ -2274,6 +2273,7 @@ def _upsample(self, method, limit: int | None = None, fill_value=None): return self._wrap_result(new_obj) +@set_module("pandas.api.typing") # error: Definition of "ax" in base class "_GroupByMixin" is incompatible with # definition in base class "PeriodIndexResampler" class PeriodIndexResamplerGroupby( # type: ignore[misc] @@ -2283,8 +2283,6 @@ class PeriodIndexResamplerGroupby( # type: ignore[misc] Provides a resample of a groupby implementation. """ - __module__ = "pandas.api.typing" - @property def _resampler_cls(self): return PeriodIndexResampler @@ -2312,6 +2310,7 @@ def _adjust_binner_for_upsample(self, binner): return binner +@set_module("pandas.api.typing") # error: Definition of "ax" in base class "_GroupByMixin" is incompatible with # definition in base class "DatetimeIndexResampler" class TimedeltaIndexResamplerGroupby( # type: ignore[misc] @@ -2321,8 +2320,6 @@ class TimedeltaIndexResamplerGroupby( # type: ignore[misc] Provides a resample of a groupby implementation. """ - __module__ = "pandas.api.typing" - @property def _resampler_cls(self): return TimedeltaIndexResampler @@ -2357,6 +2354,7 @@ def get_resampler_for_grouping( return resampler._get_resampler_for_grouping(groupby=groupby, key=tg.key) +@set_module("pandas.api.typing") class TimeGrouper(Grouper): """ Custom groupby class for time-interval grouping. @@ -2370,8 +2368,6 @@ class TimeGrouper(Grouper): If axis is PeriodIndex """ - __module__ = "pandas.api.typing" - _attributes = Grouper._attributes + ( "closed", "label", diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py index 1ea05e24d0db5..0a5cfad105f26 100644 --- a/pandas/core/window/ewm.py +++ b/pandas/core/window/ewm.py @@ -9,7 +9,10 @@ from pandas._libs.tslibs import Timedelta import pandas._libs.window.aggregations as window_aggregations -from pandas.util._decorators import doc +from pandas.util._decorators import ( + doc, + set_module, +) from pandas.core.dtypes.common import ( is_datetime64_dtype, @@ -129,6 +132,7 @@ def _calculate_deltas( return np.diff(_times) / _halflife +@set_module("pandas.api.typing") class ExponentialMovingWindow(BaseWindow): r""" Provide exponentially weighted (EW) calculations. @@ -316,8 +320,6 @@ class ExponentialMovingWindow(BaseWindow): 4 3.233686 """ - __module__ = "pandas.api.typing" - _attributes = [ "com", "span", @@ -904,13 +906,12 @@ def _cov(X, Y): ) +@set_module("pandas.api.typing") class ExponentialMovingWindowGroupby(BaseWindowGroupby, ExponentialMovingWindow): """ Provide an exponential moving window groupby implementation. """ - __module__ = "pandas.api.typing" - _attributes = ExponentialMovingWindow._attributes + BaseWindowGroupby._attributes def __init__(self, obj, *args, _grouper=None, **kwargs) -> None: diff --git a/pandas/core/window/expanding.py b/pandas/core/window/expanding.py index 2527a5dd508d8..ad49cc0d5ef63 100644 --- a/pandas/core/window/expanding.py +++ b/pandas/core/window/expanding.py @@ -10,6 +10,8 @@ overload, ) +from pandas.util._decorators import set_module + from pandas.core.indexers.objects import ( BaseIndexer, ExpandingIndexer, @@ -37,6 +39,7 @@ from pandas.core.generic import NDFrame +@set_module("pandas.api.typing") class Expanding(RollingAndExpandingMixin): """ Provide expanding window calculations. @@ -106,8 +109,6 @@ class Expanding(RollingAndExpandingMixin): 4 7.0 """ - __module__ = "pandas.api.typing" - _attributes: list[str] = ["min_periods", "method"] def __init__( @@ -1452,13 +1453,12 @@ def corr( ) +@set_module("pandas.api.typing") class ExpandingGroupby(BaseWindowGroupby, Expanding): """ Provide an expanding groupby implementation. """ - __module__ = "pandas.api.typing" - _attributes = Expanding._attributes + BaseWindowGroupby._attributes def _get_window_indexer(self) -> GroupbyIndexer: diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index e6f84941f6b1a..8d5b8ba508e9e 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -29,6 +29,7 @@ import pandas._libs.window.aggregations as window_aggregations from pandas.compat._optional import import_optional_dependency from pandas.errors import DataError +from pandas.util._decorators import set_module from pandas.core.dtypes.common import ( ensure_float64, @@ -855,6 +856,7 @@ def _gotitem(self, key, ndim, subset=None): return super()._gotitem(key, ndim, subset=subset) +@set_module("pandas.api.typing") class Window(BaseWindow): """ Provide rolling window calculations. @@ -1111,8 +1113,6 @@ class Window(BaseWindow): 2020-01-03 2020-01-02 6.0 """ - __module__ = "pandas.api.typing" - _attributes = [ "window", "min_periods", @@ -1969,8 +1969,8 @@ def corr_func(x, y): ) +@set_module("pandas.api.typing") class Rolling(RollingAndExpandingMixin): - __module__ = "pandas.api.typing" _attributes: list[str] = [ "window", "min_periods", @@ -3532,13 +3532,12 @@ def corr( Rolling.__doc__ = Window.__doc__ +@set_module("pandas.api.typing") class RollingGroupby(BaseWindowGroupby, Rolling): """ Provide a rolling groupby implementation. """ - __module__ = "pandas.api.typing" - _attributes = Rolling._attributes + BaseWindowGroupby._attributes def _get_window_indexer(self) -> GroupbyIndexer: diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index bfa61253c9c1f..d52513918b6e2 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -820,6 +820,7 @@ def read_json( return json_reader.read() +@set_module("pandas.api.typing") class JsonReader(abc.Iterator, Generic[FrameSeriesStrT]): """ JsonReader provides an interface for reading in a JSON file. @@ -829,8 +830,6 @@ class JsonReader(abc.Iterator, Generic[FrameSeriesStrT]): whole document. """ - __module__ = "pandas.api.typing" - def __init__( self, filepath_or_buffer, diff --git a/pandas/io/sas/sasreader.py b/pandas/io/sas/sasreader.py index 936cc4868daf2..ffb0b668c2dc3 100644 --- a/pandas/io/sas/sasreader.py +++ b/pandas/io/sas/sasreader.py @@ -37,13 +37,12 @@ from pandas import DataFrame +@set_module("pandas.api.typing") class SASReader(Iterator["DataFrame"], ABC): """ Abstract class for XportReader and SAS7BDATReader. """ - __module__ = "pandas.api.typing" - @abstractmethod def read(self, nrows: int | None = None) -> DataFrame: ... diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 1f953650365ef..0d5b0213de1ce 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -1018,8 +1018,8 @@ def __init__(self) -> None: } +@set_module("pandas.api.typing") class StataReader(StataParser, abc.Iterator): - __module__ = "pandas.api.typing" __doc__ = _stata_reader_doc _path_or_buf: IO[bytes] # Will be assigned by `_open_file`. diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index c9dd179fac6e0..a456098f68cfc 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -769,6 +769,7 @@ def boxplot_frame_groupby( ) +@set_module("pandas.plotting") class PlotAccessor(PandasObject): """ Make plots of Series or DataFrame. @@ -987,8 +988,6 @@ class PlotAccessor(PandasObject): >>> plot = df.groupby("col2").plot(kind="bar", title="DataFrameGroupBy Plot") """ - __module__ = "pandas.plotting" - _common_kinds = ("line", "bar", "barh", "kde", "density", "area", "hist", "box") _series_kinds = ("pie",) _dataframe_kinds = ("scatter", "hexbin") diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index dd2ed6c00e48c..eeb3fd07ddf0b 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -2,6 +2,7 @@ from functools import wraps import inspect +import os from textwrap import dedent from typing import ( TYPE_CHECKING, @@ -523,10 +524,15 @@ def example(): assert example.__module__ == "pandas" """ + if os.environ.get("PANDAS_SET_MODULE_DUNDER", "1") == "0": - def decorator(func: F) -> F: - if module is not None: - func.__module__ = module - return func + def decorator(func: F) -> F: + return func + else: + + def decorator(func: F) -> F: + if module is not None: + func.__module__ = module + return func return decorator diff --git a/pandas/util/version/__init__.py b/pandas/util/version/__init__.py index 412a606bb023e..0a88a165cb6d3 100644 --- a/pandas/util/version/__init__.py +++ b/pandas/util/version/__init__.py @@ -111,7 +111,6 @@ def parse(version: str) -> Version: # The docstring is from an older version of the packaging library to avoid # errors in the docstring validation. class InvalidVersion(ValueError): - __module__ = "pandas.errors" """ An invalid version was found, users should refer to PEP 440. @@ -130,6 +129,8 @@ class InvalidVersion(ValueError): InvalidVersion: Invalid version: '1.' """ + __module__ = "pandas.errors" + class _BaseVersion: _key: tuple[Any, ...]