From 2f8d0a36703e81e4dca52ca9fe4f58c910c1b304 Mon Sep 17 00:00:00 2001 From: Marco Edward Gorelli Date: Thu, 11 Aug 2022 18:53:53 +0200 Subject: [PATCH] PERF cache find_stack_level (#48023) cache stacklevel --- pandas/_libs/interval.pyx | 4 +- pandas/_testing/asserters.py | 11 ++--- pandas/core/accessor.py | 3 +- pandas/core/algorithms.py | 6 ++- pandas/core/apply.py | 4 +- pandas/core/arraylike.py | 7 ++- pandas/core/arrays/arrow/_arrow_utils.py | 7 ++- pandas/core/arrays/base.py | 2 +- pandas/core/arrays/categorical.py | 29 ++++++------ pandas/core/arrays/datetimelike.py | 9 ++-- pandas/core/arrays/datetimes.py | 9 ++-- pandas/core/arrays/interval.py | 5 ++- pandas/core/arrays/sparse/array.py | 11 +++-- pandas/core/arrays/sparse/dtype.py | 3 +- pandas/core/base.py | 3 +- pandas/core/common.py | 6 ++- pandas/core/computation/align.py | 5 ++- pandas/core/computation/eval.py | 3 +- pandas/core/config_init.py | 5 ++- pandas/core/construction.py | 7 +-- pandas/core/describe.py | 3 +- pandas/core/dtypes/astype.py | 6 +-- pandas/core/dtypes/cast.py | 15 ++++--- pandas/core/dtypes/common.py | 5 ++- pandas/core/dtypes/concat.py | 3 +- pandas/core/dtypes/dtypes.py | 3 +- pandas/core/dtypes/inference.py | 3 +- pandas/core/frame.py | 29 ++++++------ pandas/core/generic.py | 57 ++++++++++++++---------- pandas/core/groupby/generic.py | 5 ++- pandas/core/groupby/groupby.py | 16 ++++--- pandas/core/groupby/grouper.py | 5 ++- pandas/core/index.py | 3 +- pandas/core/indexers/utils.py | 5 ++- pandas/core/indexes/accessors.py | 3 +- pandas/core/indexes/base.py | 51 ++++++++++----------- pandas/core/indexes/category.py | 7 +-- pandas/core/indexes/datetimelike.py | 3 +- pandas/core/indexes/datetimes.py | 15 ++++--- pandas/core/indexes/interval.py | 3 +- pandas/core/indexes/multi.py | 23 +++++----- pandas/core/indexes/numeric.py | 3 +- pandas/core/indexes/period.py | 3 +- pandas/core/indexes/range.py | 9 ++-- pandas/core/indexing.py | 11 ++--- pandas/core/internals/__init__.py | 3 +- pandas/core/internals/blocks.py | 7 +-- pandas/core/internals/construction.py | 3 +- pandas/core/internals/managers.py | 7 +-- pandas/core/ops/__init__.py | 3 +- pandas/core/resample.py | 5 ++- pandas/core/reshape/concat.py | 3 +- pandas/core/reshape/melt.py | 3 +- pandas/core/reshape/merge.py | 9 ++-- pandas/core/series.py | 25 ++++++----- pandas/core/strings/accessor.py | 11 +++-- pandas/core/tools/datetimes.py | 3 +- pandas/core/window/common.py | 3 +- pandas/core/window/ewm.py | 5 ++- pandas/core/window/rolling.py | 10 ++--- pandas/io/common.py | 3 +- pandas/io/date_converters.py | 9 ++-- pandas/io/excel/_base.py | 9 ++-- pandas/io/formats/style.py | 15 ++++--- pandas/io/parsers/base_parser.py | 5 ++- pandas/io/parsers/c_parser_wrapper.py | 7 ++- pandas/io/parsers/python_parser.py | 3 +- pandas/io/parsers/readers.py | 13 ++++-- pandas/io/pytables.py | 13 ++++-- pandas/io/sql.py | 5 ++- pandas/plotting/_matplotlib/tools.py | 5 ++- pandas/tseries/frequencies.py | 3 +- pandas/util/_decorators.py | 2 +- pandas/util/_exceptions.py | 13 ++++-- pandas/util/_validators.py | 5 ++- pandas/util/testing.py | 3 +- 76 files changed, 384 insertions(+), 257 deletions(-) diff --git a/pandas/_libs/interval.pyx b/pandas/_libs/interval.pyx index ec1dbff6903e7..bcd85f915e4a2 100644 --- a/pandas/_libs/interval.pyx +++ b/pandas/_libs/interval.pyx @@ -1,3 +1,4 @@ +import inspect import numbers from operator import ( le, @@ -45,6 +46,7 @@ cnp.import_array() import warnings from pandas._libs import lib + from pandas._libs cimport util from pandas._libs.hashtable cimport Int64Vector from pandas._libs.tslibs.timedeltas cimport _Timedelta @@ -394,7 +396,7 @@ cdef class Interval(IntervalMixin): warnings.warn( "Attribute `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.inclusive diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index c7924dc451752..369e4b3454b65 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect from typing import ( Literal, cast, @@ -112,7 +113,7 @@ def assert_almost_equal( "is deprecated and will be removed in a future version. " "You can stop passing 'check_less_precise' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) rtol = atol = _get_tol_from_less_precise(check_less_precise) @@ -339,7 +340,7 @@ def _get_ilevel_values(index, level): "is deprecated and will be removed in a future version. " "You can stop passing 'check_less_precise' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) rtol = atol = _get_tol_from_less_precise(check_less_precise) @@ -815,7 +816,7 @@ def assert_extension_array_equal( "is deprecated and will be removed in a future version. " "You can stop passing 'check_less_precise' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) rtol = atol = _get_tol_from_less_precise(check_less_precise) @@ -970,7 +971,7 @@ def assert_series_equal( "is deprecated and will be removed in a future version. " "You can stop passing 'check_less_precise' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) rtol = atol = _get_tol_from_less_precise(check_less_precise) @@ -1263,7 +1264,7 @@ def assert_frame_equal( "is deprecated and will be removed in a future version. " "You can stop passing 'check_less_precise' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) rtol = atol = _get_tol_from_less_precise(check_less_precise) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 07fa5799fe371..b66a91826b689 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -6,6 +6,7 @@ """ from __future__ import annotations +import inspect import warnings from pandas.util._decorators import doc @@ -268,7 +269,7 @@ def decorator(accessor): f"{repr(name)} for type {repr(cls)} is overriding a preexisting " f"attribute with the same name.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) setattr(cls, name, CachedAccessor(name, accessor)) cls._accessors.add(name) diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 159c0bb2e72c0..a4736c2a141a5 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -836,7 +836,9 @@ def resolve_na_sentinel( "Specify `use_na_sentinel=True` to use the sentinel value -1, and " "`use_na_sentinel=False` to encode NaN values." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) result = na_sentinel return result @@ -1658,7 +1660,7 @@ def diff(arr, n: int, axis: int = 0): "dtype lost in 'diff()'. In the future this will raise a " "TypeError. Convert to a suitable dtype prior to calling 'diff'.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) arr = np.asarray(arr) dtype = arr.dtype diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 18a0f9b7aa2ce..7a7050ea8bad7 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -291,7 +291,7 @@ def transform_dict_like(self, func): f"raised, this will raise in a future version of pandas. " f"Drop these columns/ops to avoid this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return concat(results, axis=1) @@ -423,7 +423,7 @@ def agg_list_like(self) -> DataFrame | Series: warnings.warn( depr_nuisance_columns_msg.format(failed_names), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) try: diff --git a/pandas/core/arraylike.py b/pandas/core/arraylike.py index 280a599de84ed..4e8e4ea7e8d87 100644 --- a/pandas/core/arraylike.py +++ b/pandas/core/arraylike.py @@ -6,6 +6,7 @@ """ from __future__ import annotations +import inspect import operator from typing import Any import warnings @@ -220,7 +221,7 @@ def _maybe_fallback(ufunc: np.ufunc, method: str, *inputs: Any, **kwargs: Any): "or align manually (eg 'df1, df2 = df1.align(df2)') before passing to " "the ufunc to obtain the future behaviour and silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # keep the first dataframe of the inputs, other DataFrame/Series is @@ -348,7 +349,9 @@ def _reconstruct(result): "to an array with '.to_numpy()' first." ) warnings.warn( - msg.format(ufunc), FutureWarning, stacklevel=find_stack_level() + msg.format(ufunc), + FutureWarning, + stacklevel=find_stack_level(inspect.currentframe()), ) return result raise NotImplementedError diff --git a/pandas/core/arrays/arrow/_arrow_utils.py b/pandas/core/arrays/arrow/_arrow_utils.py index c9666de9f892d..81ba04a4e1426 100644 --- a/pandas/core/arrays/arrow/_arrow_utils.py +++ b/pandas/core/arrays/arrow/_arrow_utils.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import json import warnings @@ -22,7 +23,9 @@ def fallback_performancewarning(version: str | None = None) -> None: msg = "Falling back on a non-pyarrow code path which may decrease performance." if version is not None: msg += f" Upgrade to pyarrow >={version} to possibly suppress this warning." - warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, PerformanceWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) def pyarrow_array_to_numpy_and_mask( @@ -133,7 +136,7 @@ def closed(self) -> IntervalInclusiveType: warnings.warn( "Attribute `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._inclusive diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 6c9b7adadb7b0..f268c24ca766d 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -476,7 +476,7 @@ def __init_subclass__(cls, **kwargs) -> None: f"instead. Add this argument to `{name}.factorize` to be compatible " f"with future versions of pandas and silence this warning.", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) def to_numpy( diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 127814dc58f4c..b50ddd42997cb 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -2,6 +2,7 @@ from csv import QUOTE_NONNUMERIC from functools import partial +import inspect import operator from shutil import get_terminal_size from typing import ( @@ -394,7 +395,7 @@ def __init__( "Allowing scalars in the Categorical constructor is deprecated " "and will raise in a future version. Use `[value]` instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) values = [values] @@ -749,7 +750,7 @@ def categories(self, categories) -> None: "Setting categories in-place is deprecated and will raise in a " "future version. Use rename_categories instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self._set_categories(categories) @@ -873,7 +874,7 @@ def set_ordered( "a future version. setting ordered-ness on categories will always " "return a new Categorical object.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1125,7 +1126,7 @@ def rename_categories( "a future version. Removing unused categories will always " "return a new Categorical object.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1189,7 +1190,7 @@ def reorder_categories(self, new_categories, ordered=None, inplace=no_default): "a future version. Reordering categories will always " "return a new Categorical object.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1273,7 +1274,7 @@ def add_categories( "a future version. Removing unused categories will always " "return a new Categorical object.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1349,7 +1350,7 @@ def remove_categories(self, removals, inplace=no_default): "a future version. Removing unused categories will always " "return a new Categorical object.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1437,7 +1438,7 @@ def remove_unused_categories( "remove_unused_categories is deprecated and " "will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -2046,7 +2047,7 @@ def to_dense(self) -> np.ndarray: "Categorical.to_dense is deprecated and will be removed in " "a future version. Use np.asarray(cat) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return np.asarray(self) @@ -2063,7 +2064,7 @@ def _codes(self, value: np.ndarray): "Setting the codes on a Categorical is deprecated and will raise in " "a future version. Create a new Categorical object instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # GH#40606 NDArrayBacked.__init__(self, value, self.dtype) @@ -2088,7 +2089,7 @@ def take_nd( warn( "Categorical.take_nd is deprecated, use Categorical.take instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.take(indexer, allow_fill=allow_fill, fill_value=fill_value) @@ -2381,7 +2382,7 @@ def mode(self, dropna: bool = True) -> Categorical: "Categorical.mode is deprecated and will be removed in a future version. " "Use Series.mode instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._mode(dropna=dropna) @@ -2524,7 +2525,7 @@ def is_dtype_equal(self, other) -> bool: "Categorical.is_dtype_equal is deprecated and will be removed " "in a future version", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) try: return self._categories_match_up_to_permutation(other) @@ -2648,7 +2649,7 @@ def replace(self, to_replace, value, inplace: bool = False) -> Categorical | Non "Categorical.replace is deprecated and will be removed in a future " "version. Use Series.replace directly instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._replace(to_replace=to_replace, value=value, inplace=inplace) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 11c236836e791..2c070499308a7 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -4,6 +4,7 @@ datetime, timedelta, ) +import inspect import operator from typing import ( TYPE_CHECKING, @@ -469,7 +470,7 @@ def astype(self, dtype, copy: bool = True): "exactly the specified dtype instead of uint64, and will " "raise if that conversion overflows.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) elif (self.asi8 < 0).any(): # GH#45034 @@ -479,7 +480,7 @@ def astype(self, dtype, copy: bool = True): "raise if the conversion overflows, as it did in this " "case with negative int64 values.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) elif dtype != np.int64: # GH#45034 @@ -489,7 +490,7 @@ def astype(self, dtype, copy: bool = True): "exactly the specified dtype instead of int64, and will " "raise if that conversion overflows.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if copy: @@ -628,7 +629,7 @@ def _validate_shift_value(self, fill_value): FutureWarning, # There is no way to hard-code the level since this might be # reached directly or called from the Index or Block method - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) fill_value = new_fill diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index ffd093b86582c..58dee30288be9 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -6,6 +6,7 @@ timedelta, tzinfo, ) +import inspect from typing import ( TYPE_CHECKING, Literal, @@ -473,7 +474,7 @@ def _check_compatible_with(self, other, setitem: bool = False): "timezone. To retain the old behavior, explicitly cast to " "object dtype before the operation.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) raise ValueError(f"Timezones don't match. '{self.tz}' != '{other.tz}'") @@ -1139,7 +1140,7 @@ def to_perioddelta(self, freq) -> TimedeltaArray: "Use `dtindex - dtindex.to_period(freq).to_timestamp()` instead.", FutureWarning, # stacklevel chosen to be correct for when called from DatetimeIndex - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) from pandas.core.arrays.timedeltas import TimedeltaArray @@ -1341,7 +1342,7 @@ def weekofyear(self): "weekofyear and return an Index, you may call " "pd.Int64Index(idx.isocalendar().week)", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) week_series = self.isocalendar().week if week_series.hasnans: @@ -2238,7 +2239,7 @@ def maybe_convert_dtype(data, copy: bool, tz: tzinfo | None = None): "before passing the data to pandas. To get the future behavior, " "first cast to 'int64'.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) elif is_timedelta64_dtype(data.dtype) or is_bool_dtype(data.dtype): diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index e7198a95c07f1..bd765b4601b01 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import operator from operator import ( le, @@ -1380,7 +1381,7 @@ def closed(self) -> IntervalInclusiveType: warnings.warn( "Attribute `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.dtype.inclusive @@ -1432,7 +1433,7 @@ def set_closed( "set_closed is deprecated and will be removed in a future version. " "Use set_inclusive instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.set_inclusive(closed) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index f946f881311c1..e9302efdce2e7 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections import abc +import inspect import numbers import operator from typing import ( @@ -414,7 +415,7 @@ def __init__( "to construct an array with the desired repeats of the " "scalar value instead.\n\n", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if index is not None and not is_scalar(data): @@ -493,7 +494,7 @@ def __init__( "loses timezone information. Cast to object before " "sparse to retain timezone information.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) data = np.asarray(data, dtype="datetime64[ns]") if fill_value is NaT: @@ -1182,7 +1183,9 @@ def searchsorted( ) -> npt.NDArray[np.intp] | np.intp: msg = "searchsorted requires high memory usage." - warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, PerformanceWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) if not is_scalar(v): v = np.asarray(v) v = np.asarray(v) @@ -1322,7 +1325,7 @@ def astype(self, dtype: AstypeArg | None = None, copy: bool = True): "array with the requested dtype. To retain the old behavior, use " "`obj.astype(SparseDtype(dtype))`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) dtype = self.dtype.update_dtype(dtype) diff --git a/pandas/core/arrays/sparse/dtype.py b/pandas/core/arrays/sparse/dtype.py index eaed6257736ba..cbe283b50b4f7 100644 --- a/pandas/core/arrays/sparse/dtype.py +++ b/pandas/core/arrays/sparse/dtype.py @@ -1,6 +1,7 @@ """Sparse Dtype""" from __future__ import annotations +import inspect import re from typing import ( TYPE_CHECKING, @@ -409,7 +410,7 @@ def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None: f"values: '{fill_values}'. Picking the first and " "converting the rest.", PerformanceWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) np_dtypes = [x.subtype if isinstance(x, SparseDtype) else x for x in dtypes] diff --git a/pandas/core/base.py b/pandas/core/base.py index f7e6c4434da32..e1775628d09ee 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -4,6 +4,7 @@ from __future__ import annotations +import inspect import textwrap from typing import ( TYPE_CHECKING, @@ -1064,7 +1065,7 @@ def is_monotonic(self) -> bool: "is_monotonic is deprecated and will be removed in a future version. " "Use is_monotonic_increasing instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.is_monotonic_increasing diff --git a/pandas/core/common.py b/pandas/core/common.py index 980e7a79414ba..41ed68e73a4c0 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -169,7 +169,7 @@ def cast_scalar_indexer(val, warn_float: bool = False): "Indexing with a float is deprecated, and will raise an IndexError " "in pandas 2.0. You can manually convert to an integer key instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return int(val) return val @@ -697,4 +697,6 @@ def deprecate_numeric_only_default( "this warning." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index 2e7a0f842ee6d..958e605727f27 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -7,6 +7,7 @@ partial, wraps, ) +import inspect from typing import ( TYPE_CHECKING, Callable, @@ -131,7 +132,9 @@ def _align_core(terms): f"by more than {ordm:.4g}; performance may suffer." ) warnings.warn( - w, category=PerformanceWarning, stacklevel=find_stack_level() + w, + category=PerformanceWarning, + stacklevel=find_stack_level(inspect.currentframe()), ) f = partial(ti.reindex, reindexer, axis=axis, copy=False) diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index ea70d0130a119..fa0ef46b850d1 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect import tokenize from typing import TYPE_CHECKING import warnings @@ -311,7 +312,7 @@ def eval( "will be removed in a future version." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) exprs: list[str | BinOp] diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 8c1a3fece255e..6c32cc98df9ac 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -11,6 +11,7 @@ """ from __future__ import annotations +import inspect import os from typing import Callable import warnings @@ -370,7 +371,7 @@ def _deprecate_column_space(key): "in a future version. Use df.to_string(col_space=...) " "instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) cf.register_option("column_space", 12, validator=is_int, cb=_deprecate_column_space) @@ -397,7 +398,7 @@ def _deprecate_negative_int_max_colwidth(key): "will not be supported in future version. Instead, use None " "to not limit the column width.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) cf.register_option( diff --git a/pandas/core/construction.py b/pandas/core/construction.py index 4b63d492ec1dd..e1a69086609e9 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -6,6 +6,7 @@ """ from __future__ import annotations +import inspect from typing import ( TYPE_CHECKING, Any, @@ -568,7 +569,7 @@ def sanitize_array( "passed dtype. To retain the old behavior, call Series(arr) or " "DataFrame(arr) without passing a dtype.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) subarr = np.array(data, copy=copy) except ValueError: @@ -580,7 +581,7 @@ def sanitize_array( "if they cannot be cast losslessly (matching Series behavior). " "To retain the old behavior, use DataFrame(data).astype(dtype)", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # GH#40110 until the deprecation is enforced, we _dont_ # ignore the dtype for DataFrame, and _do_ cast even though @@ -852,7 +853,7 @@ def _try_cast( "passed to 'DataFrame', either all columns will be cast to that " "dtype, or a TypeError will be raised.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) subarr = np.array(arr, dtype=object, copy=copy) return subarr diff --git a/pandas/core/describe.py b/pandas/core/describe.py index c70dbe0b8b0b1..d265a307078b9 100644 --- a/pandas/core/describe.py +++ b/pandas/core/describe.py @@ -9,6 +9,7 @@ ABC, abstractmethod, ) +import inspect from typing import ( TYPE_CHECKING, Any, @@ -373,7 +374,7 @@ def select_describe_func( "version of pandas. Specify `datetime_is_numeric=True` to " "silence this warning and adopt the future behavior now.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return describe_timestamp_as_categorical_1d elif is_timedelta64_dtype(data.dtype): diff --git a/pandas/core/dtypes/astype.py b/pandas/core/dtypes/astype.py index 7fb58468746a8..6d04dd755dbfd 100644 --- a/pandas/core/dtypes/astype.py +++ b/pandas/core/dtypes/astype.py @@ -371,7 +371,7 @@ def astype_dt64_to_dt64tz( "timezone-aware dtype is deprecated and will raise in a " "future version. Use ser.dt.tz_localize instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # GH#33401 this doesn't match DatetimeArray.astype, which @@ -387,7 +387,7 @@ def astype_dt64_to_dt64tz( "timezone-aware dtype is deprecated and will raise in a " "future version. Use obj.tz_localize instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return values.tz_localize(dtype.tz) @@ -407,7 +407,7 @@ def astype_dt64_to_dt64tz( "future version. Use obj.tz_localize(None) or " "obj.tz_convert('UTC').tz_localize(None) instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) result = values.tz_convert("UTC").tz_localize(None) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 769656d1c4755..5340bc6b590c4 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -10,6 +10,7 @@ timedelta, ) import functools +import inspect from typing import ( TYPE_CHECKING, Any, @@ -624,7 +625,7 @@ def _maybe_promote(dtype: np.dtype, fill_value=np.nan): "dtype is deprecated. In a future version, this will be cast " "to object dtype. Pass `fill_value=Timestamp(date_obj)` instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return dtype, fv elif isinstance(fill_value, str): @@ -1277,7 +1278,7 @@ def try_timedelta(v: np.ndarray) -> np.ndarray: "and will be removed in a future version. To retain the old behavior " f"explicitly pass Series(data, dtype={value.dtype})", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return value @@ -1336,7 +1337,7 @@ def maybe_cast_to_datetime( "`pd.Series(values).dt.tz_localize(None)` " "instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # equiv: dta.view(dtype) # Note: NOT equivalent to dta.astype(dtype) @@ -1376,7 +1377,7 @@ def maybe_cast_to_datetime( ".tz_localize('UTC').tz_convert(dtype.tz) " "or pd.Series(data.view('int64'), dtype=dtype)", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) value = dta.tz_localize("UTC").tz_convert(dtype.tz) @@ -1745,7 +1746,7 @@ def _maybe_unbox_datetimelike_tz_deprecation(value: Scalar, dtype: DtypeObj): "`pd.Series(values).dt.tz_localize(None)` " "instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) new_value = value.tz_localize(None) return _maybe_unbox_datetimelike(new_value, dtype) @@ -1863,7 +1864,7 @@ def maybe_cast_to_integer_array( "In a future version this will raise OverflowError. To retain the " f"old behavior, use pd.Series(values).astype({dtype})", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return casted @@ -1874,7 +1875,7 @@ def maybe_cast_to_integer_array( f"dtype={dtype} is deprecated and will raise in a future version. " "Use values.view(dtype) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return casted diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index c10461b2fc7f8..be4d50af8a053 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect from typing import ( Any, Callable, @@ -307,7 +308,7 @@ def is_categorical(arr) -> bool: "is_categorical is deprecated and will be removed in a future version. " "Use is_categorical_dtype instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return isinstance(arr, ABCCategorical) or is_categorical_dtype(arr) @@ -1386,7 +1387,7 @@ def is_extension_type(arr) -> bool: "'is_extension_type' is deprecated and will be removed in a future " "version. Use 'is_extension_array_dtype' instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if is_categorical_dtype(arr): diff --git a/pandas/core/dtypes/concat.py b/pandas/core/dtypes/concat.py index 059df4009e2f6..80efe96ae7146 100644 --- a/pandas/core/dtypes/concat.py +++ b/pandas/core/dtypes/concat.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect from typing import ( TYPE_CHECKING, cast, @@ -152,7 +153,7 @@ def is_nonempty(x) -> bool: "(instead of coercing bools to numeric values). To retain the old " "behavior, explicitly cast bool-dtype arrays to numeric dtype.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return result diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index 99b2082d409a9..c2c600adbbe09 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect import re from typing import ( TYPE_CHECKING, @@ -1194,7 +1195,7 @@ def closed(self): warnings.warn( "Attribute `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._inclusive diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 893e4a9be58ef..78cf76e747d1d 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections import abc +import inspect from numbers import Number import re from typing import Pattern @@ -459,7 +460,7 @@ def is_inferred_bool_dtype(arr: ArrayLike) -> bool: "will not be included in reductions with bool_only=True. " "Explicitly cast to bool dtype instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return result diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 49e5bc24786dd..0a7a6494d04eb 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -14,6 +14,7 @@ from collections import abc import datetime import functools +import inspect from io import StringIO import itertools from textwrap import dedent @@ -673,7 +674,7 @@ def __init__( "removed in a future version. Pass " "{name: data[name] for name in data.dtype.names} instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # a masked array @@ -1324,7 +1325,7 @@ def iteritems(self) -> Iterable[tuple[Hashable, Series]]: "iteritems is deprecated and will be removed in a future version. " "Use .items instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) yield from self.items() @@ -1909,7 +1910,7 @@ def to_dict(self, orient: str = "dict", into=dict): warnings.warn( "DataFrame columns are not unique, some columns will be omitted.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # GH16122 into_c = com.standardize_mapping(into) @@ -1930,7 +1931,7 @@ def to_dict(self, orient: str = "dict", into=dict): "will be used in a future version. Use one of the above " "to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if orient.startswith("d"): @@ -2773,7 +2774,7 @@ def to_markdown( "'showindex' is deprecated. Only 'index' will be used " "in a future version. Use 'index' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) kwargs.setdefault("headers", "keys") @@ -3387,7 +3388,7 @@ def info( warnings.warn( "null_counts is deprecated. Use show_counts instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) show_counts = null_counts info = DataFrameInfo( @@ -3772,7 +3773,7 @@ def _getitem_bool_array(self, key): warnings.warn( "Boolean Series key will be reindexed to match DataFrame index.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) elif len(key) != len(self.index): raise ValueError( @@ -4862,7 +4863,9 @@ def lookup( "You can use DataFrame.melt and DataFrame.loc " "as a substitute." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) n = len(row_labels) if n != len(col_labels): @@ -8364,7 +8367,7 @@ def groupby( "will be removed in a future version." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: squeeze = False @@ -9735,7 +9738,7 @@ def append( "and will be removed from pandas in a future version. " "Use pandas.concat instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._append(other, ignore_index, verify_integrity, sort) @@ -10701,7 +10704,7 @@ def count( "deprecated and will be removed in a future version. Use groupby " "instead. df.count(level=1) should use df.groupby(level=1).count().", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) res = self._count_level(level, axis=axis, numeric_only=numeric_only) return res.__finalize__(self, method="count") @@ -10803,7 +10806,7 @@ def _reduce( "will include datetime64 and datetime64tz columns in a " "future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # Non-copy equivalent to # dt64_cols = self.dtypes.apply(is_datetime64_any_dtype) @@ -10904,7 +10907,7 @@ def _get_data() -> DataFrame: "version this will raise TypeError. Select only valid " "columns before calling the reduction.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if hasattr(result, "dtype"): diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 003fe2571401f..8096b57168d8c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -5,6 +5,7 @@ from datetime import timedelta import functools import gc +import inspect import json import operator import pickle @@ -493,7 +494,7 @@ def _AXIS_NUMBERS(self) -> dict[str, int]: warnings.warn( "_AXIS_NUMBERS has been deprecated.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return {"index": 0} @@ -3375,7 +3376,9 @@ def to_latex( "to use `DataFrame.style.to_latex` which also contains additional " "functionality." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) # Get defaults from the pandas config if self.ndim == 1: @@ -3804,7 +3807,7 @@ class max_speed "is_copy is deprecated and will be removed in a future version. " "'take' always returns a copy, so there is no need to specify this.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) nv.validate_take((), kwargs) @@ -3960,7 +3963,7 @@ class animal locomotion "Passing lists as key for xs is deprecated and will be removed in a " "future version. Pass key as a tuple instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if level is not None: @@ -4145,7 +4148,11 @@ def _check_setitem_copy(self, t="setting", force=False): if value == "raise": raise SettingWithCopyError(t) elif value == "warn": - warnings.warn(t, SettingWithCopyWarning, stacklevel=find_stack_level()) + warnings.warn( + t, + SettingWithCopyWarning, + stacklevel=find_stack_level(inspect.currentframe()), + ) def __delitem__(self, key) -> None: """ @@ -5883,7 +5890,7 @@ def __setattr__(self, name: str, value) -> None: "created via a new attribute name - see " "https://pandas.pydata.org/pandas-docs/" "stable/indexing.html#attribute-access", - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) object.__setattr__(self, name, value) @@ -8262,7 +8269,7 @@ def between_time( "`include_start` and `include_end` are deprecated in " "favour of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) left = True if include_start is lib.no_default else include_start right = True if include_end is lib.no_default else include_end @@ -8978,7 +8985,7 @@ def rank( "and will raise in a future version. Pass either 'True' or " "'False'. 'False' will be the default.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) warned = True elif numeric_only is lib.no_default: @@ -9034,7 +9041,7 @@ def ranker(data): "is deprecated; in a future version this will raise TypeError. " "Select only valid columns before calling rank.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if numeric_only: @@ -9045,7 +9052,7 @@ def ranker(data): f"{self.dtype} is deprecated and will raise a TypeError in a " "future version of pandas", category=FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) data = self._get_numeric_data() else: @@ -9816,7 +9823,7 @@ def where( "try_cast keyword is deprecated and will be removed in a " "future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._where(cond, other, inplace, axis, level) @@ -9894,7 +9901,7 @@ def mask( "try_cast keyword is deprecated and will be removed in a " "future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # see gh-21891 @@ -10089,7 +10096,9 @@ def slice_shift(self: NDFrameT, periods: int = 1, axis=0) -> NDFrameT: "and will be removed in a future version. " "You can use DataFrame/Series.shift instead." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) if periods == 0: return self @@ -10142,7 +10151,7 @@ def tshift(self: NDFrameT, periods: int = 1, freq=None, axis: Axis = 0) -> NDFra "Please use shift instead." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if freq is None: @@ -10975,7 +10984,7 @@ def _logical_func( "deprecated and will be removed in a future version. Use groupby " "instead. df.any(level=1) should use df.groupby(level=1).any()", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if bool_only is not None: raise NotImplementedError( @@ -11109,7 +11118,7 @@ def _stat_function_ddof( "deprecated and will be removed in a future version. Use groupby " "instead. df.var(level=1) should use df.groupby(level=1).var().", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._agg_by_level( name, axis=axis, level=level, skipna=skipna, ddof=ddof @@ -11183,7 +11192,7 @@ def _stat_function( f"scalar {name} over the entire DataFrame. To retain the old " f"behavior, use 'frame.{name}(axis=0)' or just 'frame.{name}()'", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if axis is lib.no_default: axis = None @@ -11196,7 +11205,7 @@ def _stat_function( "deprecated and will be removed in a future version. Use groupby " "instead. df.median(level=1) should use df.groupby(level=1).median().", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._agg_by_level( name, axis=axis, level=level, skipna=skipna, numeric_only=numeric_only @@ -11320,7 +11329,7 @@ def _min_count_stat_function( "deprecated and will be removed in a future version. Use groupby " "instead. df.sum(level=1) should use df.groupby(level=1).sum().", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._agg_by_level( name, @@ -11408,7 +11417,9 @@ def mad( "The 'mad' method is deprecated and will be removed in a future version. " "To compute the same result, you may do `(df - df.mean()).abs().mean()`." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) if not is_bool(skipna): warnings.warn( @@ -11416,7 +11427,7 @@ def mad( "version. Pass True instead. Only boolean values will be allowed " "in the future.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) skipna = True if axis is None: @@ -11427,7 +11438,7 @@ def mad( "deprecated and will be removed in a future version. Use groupby " "instead. df.mad(level=1) should use df.groupby(level=1).mad()", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._agg_by_level("mad", axis=axis, level=level, skipna=skipna) @@ -11874,7 +11885,7 @@ def expanding( warnings.warn( "The `center` argument on `expanding` will be removed in the future.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: center = False diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 0f9befa7cff78..8a261f09e7118 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -9,6 +9,7 @@ from collections import abc from functools import partial +import inspect from textwrap import dedent from typing import ( TYPE_CHECKING, @@ -1235,7 +1236,7 @@ def _transform_general(self, func, *args, **kwargs): "`.to_numpy()` to the result in the transform function to keep " "the current behavior and silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) concat_index = obj.columns if self.axis == 0 else obj.index @@ -1405,7 +1406,7 @@ def __getitem__(self, key) -> DataFrameGroupBy | SeriesGroupBy: "Indexing with multiple keys (implicitly converted to a tuple " "of keys) will be deprecated, use a list instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return super().__getitem__(key) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 8e0ed959fabc3..138474e21fb57 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -833,7 +833,7 @@ def __iter__(self) -> Iterator[tuple[Hashable, NDFrameT]]: "to avoid this warning." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.grouper.get_iterator(self._selected_obj, axis=self.axis) @@ -1357,7 +1357,7 @@ def _resolve_numeric_only( f"numeric_only={numeric_only} and dtype {self.obj.dtype}. This will " "raise a TypeError in a future version of pandas", category=FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) raise NotImplementedError( f"{type(self).__name__}.{how} does not implement numeric_only" @@ -1619,7 +1619,9 @@ def _python_apply_general( "To adopt the future behavior and silence this warning, use " "\n\n\t>>> .groupby(..., group_keys=True)" ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) # We want to behave as if `self.group_keys=False` when reconstructing # the object. However, we don't want to mutate the stateful GroupBy # object, so we just override it. @@ -2940,7 +2942,7 @@ def pad(self, limit=None): "pad is deprecated and will be removed in a future version. " "Use ffill instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.ffill(limit=limit) @@ -2976,7 +2978,7 @@ def backfill(self, limit=None): "backfill is deprecated and will be removed in a future version. " "Use bfill instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.bfill(limit=limit) @@ -4362,7 +4364,7 @@ def warn_dropping_nuisance_columns_deprecated(cls, how: str, numeric_only) -> No f"Before calling .{how}, select only columns which " "should be valid for the function.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) elif numeric_only is lib.no_default: warnings.warn( @@ -4372,5 +4374,5 @@ def warn_dropping_nuisance_columns_deprecated(cls, how: str, numeric_only) -> No f"Either specify numeric_only or select only columns which " "should be valid for the function.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py index b9f4166b475ca..04ebc00b8e964 100644 --- a/pandas/core/groupby/grouper.py +++ b/pandas/core/groupby/grouper.py @@ -4,6 +4,7 @@ """ from __future__ import annotations +import inspect from typing import ( TYPE_CHECKING, Any, @@ -981,7 +982,7 @@ def _check_deprecated_resample_kwargs(kwargs, origin): "\nbecomes:\n" '\n>>> df.resample(freq="3s", offset="2s")\n', FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if kwargs.get("loffset", None) is not None: warnings.warn( @@ -992,5 +993,5 @@ def _check_deprecated_resample_kwargs(kwargs, origin): '\n>>> df = df.resample(freq="3s").mean()' '\n>>> df.index = df.index.to_timestamp() + to_offset("8H")\n', FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) diff --git a/pandas/core/index.py b/pandas/core/index.py index 19e9c6b27e4e7..519a82d680426 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -1,6 +1,7 @@ # pyright: reportUnusedImport = false from __future__ import annotations +import inspect import warnings from pandas.util._exceptions import find_stack_level @@ -31,7 +32,7 @@ "pandas.core.index is deprecated and will be removed in a future version. " "The public classes are available in the top-level namespace.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) __all__: list[str] = [] diff --git a/pandas/core/indexers/utils.py b/pandas/core/indexers/utils.py index 0f3cdc4195c85..70e6ff8ab7783 100644 --- a/pandas/core/indexers/utils.py +++ b/pandas/core/indexers/utils.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect from typing import ( TYPE_CHECKING, Any, @@ -348,7 +349,7 @@ def deprecate_ndim_indexing(result, stacklevel: int = 3) -> None: "is deprecated and will be removed in a future " "version. Convert to a numpy array before indexing instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) @@ -372,7 +373,7 @@ def unpack_1tuple(tup): "slice is deprecated and will raise in a future " "version. Pass a tuple instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return tup[0] diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index 46959aa5cd3e2..dea38e2ed2907 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect from typing import TYPE_CHECKING import warnings @@ -291,7 +292,7 @@ def weekofyear(self): "Series.dt.weekofyear and Series.dt.week have been deprecated. " "Please use Series.dt.isocalendar().week instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) week_series = self.isocalendar().week week_series.name = self.name diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 14f9b71c5e03c..7e2a9184f04d9 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2,6 +2,7 @@ from datetime import datetime import functools +import inspect from itertools import zip_longest import operator from typing import ( @@ -437,7 +438,7 @@ def __new__( "'tupleize_cols' is deprecated and will raise TypeError in a " "future version. Use the specific Index subclass directly instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) from pandas.core.arrays import PandasArray @@ -615,7 +616,7 @@ def _dtype_to_subclass(cls, dtype: DtypeObj): "dense numpy ndarray. To retain the old behavior, use " "pd.Index(arr.to_numpy()) instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return cls._dtype_to_subclass(dtype.subtype) @@ -683,7 +684,7 @@ def asi8(self): warnings.warn( "Index.asi8 is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return None @@ -797,7 +798,7 @@ def _get_attributes_dict(self) -> dict[str_t, Any]: "The Index._get_attributes_dict method is deprecated, and will be " "removed in a future version", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return {k: getattr(self, k, None) for k in self._attributes} @@ -1000,7 +1001,7 @@ def ravel(self, order="C"): "Index.ravel returning ndarray is deprecated; in a future version " "this will return a view on self.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if needs_i8_conversion(self.dtype): # Item "ndarray[Any, Any]" of "Union[ExtensionArray, ndarray[Any, Any]]" @@ -1295,7 +1296,7 @@ def copy( "parameter names is deprecated and will be removed in a future " "version. Use the name parameter instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) name = self._validate_names(name=name, names=names, deep=deep)[0] @@ -1310,7 +1311,7 @@ def copy( "parameter dtype is deprecated and will be removed in a future " "version. Use the astype method instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) new_index = new_index.astype(dtype) return new_index @@ -1502,7 +1503,7 @@ def to_native_types(self, slicer=None, **kwargs) -> np.ndarray: "The 'to_native_types' method is deprecated and will be removed in " "a future version. Use 'astype(str)' instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) values = self if slicer is not None: @@ -1703,7 +1704,7 @@ def to_frame( "the future `None` will be used as the name of the resulting " "DataFrame column.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) name = lib.no_default @@ -2289,7 +2290,7 @@ def is_monotonic(self) -> bool: "is_monotonic is deprecated and will be removed in a future version. " "Use is_monotonic_increasing instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.is_monotonic_increasing @@ -2714,7 +2715,7 @@ def is_mixed(self) -> bool: "Index.is_mixed is deprecated and will be removed in a future version. " "Check index.inferred_type directly instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.inferred_type in ["mixed"] @@ -2759,7 +2760,7 @@ def is_all_dates(self) -> bool: "Index.is_all_dates is deprecated, will be removed in a future version. " "check index.inferred_type instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._is_all_dates @@ -3140,7 +3141,7 @@ def __and__(self, other): "in the future this will be a logical operation matching " "Series.__and__. Use index.intersection(other) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.intersection(other) @@ -3151,7 +3152,7 @@ def __or__(self, other): "in the future this will be a logical operation matching " "Series.__or__. Use index.union(other) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.union(other) @@ -3162,7 +3163,7 @@ def __xor__(self, other): "in the future this will be a logical operation matching " "Series.__xor__. Use index.symmetric_difference(other) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.symmetric_difference(other) @@ -3218,7 +3219,7 @@ def _deprecate_dti_setop(self, other: Index, setop: str_t): "object dtype. To retain the old behavior, " f"use `index.astype(object).{setop}(other)`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) @final @@ -3794,7 +3795,7 @@ def get_loc(self, key, method=None, tolerance=None): "and will raise in a future version. Use " "index.get_indexer([item], method=...) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if is_scalar(key) and isna(key) and not self.hasnans: @@ -4258,7 +4259,7 @@ def is_int(v): "lookups. To retain the old behavior, use `series.iloc[i:j]`. " "To get the future behavior, use `series.loc[i:j]`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if self.is_integer() or is_index_slice: # Note: these checks are redundant if we know is_index_slice @@ -4292,7 +4293,7 @@ def is_int(v): "and will raise TypeError in a future version. " "Use .loc with labels or .iloc with positions instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) indexer = key else: @@ -4443,7 +4444,7 @@ def reindex( "reindexing with a non-unique Index is deprecated and " "will raise in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) target = self._wrap_reindex_result(target, indexer, preserve_names) @@ -5257,7 +5258,7 @@ def is_type_compatible(self, kind: str_t) -> bool: "Index.is_type_compatible is deprecated and will be removed in a " "future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return kind == self.inferred_type @@ -5904,7 +5905,7 @@ def get_value(self, series: Series, key): "get_value is deprecated and will be removed in a future version. " "Use Series[key] instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self._check_indexing_error(key) @@ -5972,7 +5973,7 @@ def set_value(self, arr, key, value) -> None: "will be removed in a future version." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) loc = self._engine.get_loc(key) if not can_hold_element(arr, value): @@ -7238,7 +7239,7 @@ def _deprecated_arg(self, value, name: str_t, methodname: str_t) -> None: f"'{name}' argument in {methodname} is deprecated " "and will be removed in a future version. Do not pass it.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) @@ -7492,6 +7493,6 @@ def _maybe_try_sort(result, sort): warnings.warn( f"{err}, sort order is undefined for incomparable objects.", RuntimeWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return result diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index c1ae3cb1b16ea..e068c1434fd4e 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect from typing import ( Any, Hashable, @@ -224,7 +225,7 @@ def __new__( "deprecated and will raise in a future version. " "Use CategoricalIndex([], ...) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) data = [] @@ -419,7 +420,7 @@ def reindex( "reindexing with a non-unique Index is deprecated and will " "raise in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) new_target: Index @@ -495,7 +496,7 @@ def take_nd(self, *args, **kwargs) -> CategoricalIndex: "CategoricalIndex.take_nd is deprecated, use CategoricalIndex.take " "instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.take(*args, **kwargs) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 8014d010afc1b..84955d5137383 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -4,6 +4,7 @@ from __future__ import annotations from datetime import datetime +import inspect from typing import ( TYPE_CHECKING, Any, @@ -393,7 +394,7 @@ def is_type_compatible(self, kind: str) -> bool: f"{type(self).__name__}.is_type_compatible is deprecated and will be " "removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return kind in self._data._infer_matches diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 30c770f32c2dc..2625d8c683a0c 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -7,6 +7,7 @@ timedelta, tzinfo, ) +import inspect import operator from typing import ( TYPE_CHECKING, @@ -423,7 +424,7 @@ def union_many(self, others): "DatetimeIndex.union_many is deprecated and will be removed in " "a future version. Use obj.union instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) this = self @@ -547,7 +548,7 @@ def to_series(self, keep_tz=lib.no_default, index=None, name=None): "is deprecated and will be removed in a future version. " "You can stop passing 'keep_tz' to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: warnings.warn( @@ -557,7 +558,7 @@ def to_series(self, keep_tz=lib.no_default, index=None, name=None): "can do 'idx.tz_convert(None)' before calling " "'to_series'.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: keep_tz = True @@ -660,7 +661,9 @@ def _deprecate_mismatched_indexing(self, key, one_way: bool = False) -> None: "raise KeyError in a future version. " "Use a timezone-aware object instead." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) def get_loc(self, key, method=None, tolerance=None): """ @@ -809,7 +812,7 @@ def check_str_or_none(point): "with non-existing keys is deprecated and will raise a " "KeyError in a future Version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) indexer = mask.nonzero()[0][::step] if len(indexer) == len(self): @@ -1089,7 +1092,7 @@ def date_range( warnings.warn( "Argument `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if closed is None: inclusive = "both" diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 23f2e724e208c..5ed8f79bbbefe 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -1,6 +1,7 @@ """ define the IntervalIndex """ from __future__ import annotations +import inspect from operator import ( le, lt, @@ -242,7 +243,7 @@ def closed(self): warnings.warn( "Attribute `closed` is deprecated in favor of `inclusive`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.inclusive diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 5a9b1e6943608..b282455cf6051 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1,6 +1,7 @@ from __future__ import annotations from functools import wraps +import inspect from sys import getsizeof from typing import ( TYPE_CHECKING, @@ -923,7 +924,7 @@ def set_levels( warnings.warn( "inplace is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1084,7 +1085,7 @@ def set_codes(self, codes, level=None, inplace=None, verify_integrity: bool = Tr warnings.warn( "inplace is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: inplace = False @@ -1197,7 +1198,7 @@ def copy( "parameter levels is deprecated and will be removed in a future " "version. Use the set_levels method instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) keep_id = False if codes is not None: @@ -1205,7 +1206,7 @@ def copy( "parameter codes is deprecated and will be removed in a future " "version. Use the set_codes method instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) keep_id = False @@ -1237,7 +1238,7 @@ def copy( "parameter dtype is deprecated and will be removed in a future " "version. Use the astype method instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) new_index = new_index.astype(dtype) return new_index @@ -1800,7 +1801,7 @@ def to_frame( "the future `None` will be used as the name of the resulting " "DataFrame column.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) name = lib.no_default @@ -1869,7 +1870,7 @@ def is_lexsorted(self) -> bool: "MultiIndex.is_lexsorted is deprecated as a public function, " "users should use MultiIndex.is_monotonic_increasing instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._is_lexsorted() @@ -1913,7 +1914,7 @@ def lexsort_depth(self) -> int: "MultiIndex.is_lexsorted is deprecated as a public function, " "users should use MultiIndex.is_monotonic_increasing instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._lexsort_depth @@ -2279,7 +2280,7 @@ def drop(self, codes, level=None, errors="raise"): "dropping on a non-lexsorted multi-index " "without a level parameter may impact performance.", PerformanceWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) loc = loc.nonzero()[0] inds.extend(loc) @@ -2955,7 +2956,7 @@ def _maybe_to_slice(loc): warnings.warn( "indexing past lexsort depth may impact performance.", PerformanceWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) loc = np.arange(start, stop, dtype=np.intp) @@ -3394,7 +3395,7 @@ def _to_bool_indexer(indexer) -> npt.NDArray[np.bool_]: # TODO: how to handle IntervalIndex level? # (no test cases) FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) continue else: diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index a597bea0eb724..d114fe47fa0f1 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect from typing import ( Callable, Hashable, @@ -360,7 +361,7 @@ def asi8(self) -> npt.NDArray[np.int64]: warnings.warn( "Index.asi8 is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._values.view(self._default_dtype) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index c034d9416eae7..fedcba7aa9644 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -4,6 +4,7 @@ datetime, timedelta, ) +import inspect from typing import Hashable import warnings @@ -366,7 +367,7 @@ def astype(self, dtype, copy: bool = True, how=lib.no_default): "will be removed in a future version. " "Use index.to_timestamp(how=how) instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: how = "start" diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 376c98b6e176f..9f49c7456d9ce 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -1,6 +1,7 @@ from __future__ import annotations from datetime import timedelta +import inspect import operator from sys import getsizeof from typing import ( @@ -263,7 +264,7 @@ def _start(self) -> int: warnings.warn( self._deprecation_message.format("_start", "start"), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.start @@ -286,7 +287,7 @@ def _stop(self) -> int: warnings.warn( self._deprecation_message.format("_stop", "stop"), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.stop @@ -310,7 +311,7 @@ def _step(self) -> int: warnings.warn( self._deprecation_message.format("_step", "step"), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.step @@ -471,7 +472,7 @@ def copy( "parameter dtype is deprecated and will be removed in a future " "version. Use the astype method instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) new_index = new_index.astype(dtype) return new_index diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 4e242e33627a4..b143e1e50aa6c 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1,6 +1,7 @@ from __future__ import annotations from contextlib import suppress +import inspect from typing import ( TYPE_CHECKING, Hashable, @@ -1497,7 +1498,7 @@ def _has_valid_setitem_indexer(self, indexer) -> bool: "a future version.\n" "consider using .loc with a DataFrame indexer for automatic alignment.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if not isinstance(indexer, tuple): @@ -2026,7 +2027,7 @@ def _setitem_single_column(self, loc: int, value, plane_indexer): "`df[df.columns[i]] = newvals` or, if columns are non-unique, " "`df.isetitem(i, newvals)`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # TODO: how to get future behavior? # TODO: what if we got here indirectly via loc? @@ -2502,7 +2503,7 @@ def convert_to_index_sliceable(obj: DataFrame, key): "and will be removed in a future version. Use `frame.loc[string]` " "instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return res except (KeyError, ValueError, NotImplementedError): @@ -2656,7 +2657,7 @@ def check_deprecated_indexers(key) -> None: "Passing a set as an indexer is deprecated and will raise in " "a future version. Use a list instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if ( isinstance(key, dict) @@ -2667,5 +2668,5 @@ def check_deprecated_indexers(key) -> None: "Passing a dict as an indexer is deprecated and will raise in " "a future version. Use a list instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) diff --git a/pandas/core/internals/__init__.py b/pandas/core/internals/__init__.py index ea69b567611e4..8c62576c2f2ca 100644 --- a/pandas/core/internals/__init__.py +++ b/pandas/core/internals/__init__.py @@ -41,6 +41,7 @@ def __getattr__(name: str): + import inspect import warnings from pandas.util._exceptions import find_stack_level @@ -50,7 +51,7 @@ def __getattr__(name: str): "CategoricalBlock is deprecated and will be removed in a future version. " "Use ExtensionBlock instead.", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) from pandas.core.internals.blocks import CategoricalBlock diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 46c375b92dd83..3e27cf0b15511 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1,6 +1,7 @@ from __future__ import annotations from functools import wraps +import inspect import re from typing import ( TYPE_CHECKING, @@ -181,7 +182,7 @@ def is_categorical(self) -> bool: "future version. Use isinstance(block.values, Categorical) " "instead. See https://github.com/pandas-dev/pandas/issues/40226", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return isinstance(self.values, Categorical) @@ -252,7 +253,7 @@ def make_block_same_class( "already been cast to DatetimeArray and TimedeltaArray, " "respectively.", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) values = new_values @@ -1564,7 +1565,7 @@ def fillna( "(usually object) instead of raising, matching the " "behavior of other dtypes.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) raise else: diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index c1d0ab730fe7e..6aad8dbd940d4 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -5,6 +5,7 @@ from __future__ import annotations from collections import abc +import inspect from typing import ( TYPE_CHECKING, Any, @@ -844,7 +845,7 @@ def to_arrays( "To retain the old behavior, pass as a dictionary " "DataFrame({col: categorical, ..})", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if columns is None: columns = default_index(len(data)) diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index 435992f7d5cff..4e84b013b2a11 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import itertools from typing import ( Any, @@ -909,7 +910,7 @@ def __init__( "will assume that a DatetimeTZBlock with block.ndim==2 " "has block.values.ndim == 2.", DeprecationWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # error: Incompatible types in assignment (expression has type @@ -1248,7 +1249,7 @@ def insert(self, loc: int, item: Hashable, value: ArrayLike) -> None: "Consider joining all columns at once using pd.concat(axis=1) " "instead. To get a de-fragmented frame, use `newframe = frame.copy()`", PerformanceWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) def _insert_update_mgr_locs(self, loc) -> None: @@ -1707,7 +1708,7 @@ def __init__( "The `fastpath` keyword is deprecated and will be removed " "in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self.axes = [axis] diff --git a/pandas/core/ops/__init__.py b/pandas/core/ops/__init__.py index e9fefd9268870..dde4d07b7915c 100644 --- a/pandas/core/ops/__init__.py +++ b/pandas/core/ops/__init__.py @@ -5,6 +5,7 @@ """ from __future__ import annotations +import inspect import operator from typing import TYPE_CHECKING import warnings @@ -301,7 +302,7 @@ def to_series(right): "Do `left, right = left.align(right, axis=1, copy=False)` " "before e.g. `left == right`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) left, right = left.align( diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 54b6b32ff1a68..e3d81e01ac94c 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -2,6 +2,7 @@ import copy from datetime import timedelta +import inspect from textwrap import dedent from typing import ( TYPE_CHECKING, @@ -549,7 +550,7 @@ def pad(self, limit=None): "pad is deprecated and will be removed in a future version. " "Use ffill instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.ffill(limit=limit) @@ -722,7 +723,7 @@ def backfill(self, limit=None): "backfill is deprecated and will be removed in a future version. " "Use bfill instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.bfill(limit=limit) diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index 5328c7995ea6f..3d9e4f0c69c62 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections import abc +import inspect from typing import ( TYPE_CHECKING, Callable, @@ -552,7 +553,7 @@ def __init__( "Passing non boolean values for sort is deprecated and " "will error in a future version!", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self.sort = sort diff --git a/pandas/core/reshape/melt.py b/pandas/core/reshape/melt.py index 5de9c8e2f4108..73f6aff82f330 100644 --- a/pandas/core/reshape/melt.py +++ b/pandas/core/reshape/melt.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import re from typing import TYPE_CHECKING import warnings @@ -59,7 +60,7 @@ def melt( "In the future this will raise an error, please set the 'value_name' " "parameter of DataFrame.melt to a unique name.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if id_vars is not None: diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 4b8547bd6a232..cb392eee1d589 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -6,6 +6,7 @@ import copy import datetime from functools import partial +import inspect import string from typing import ( TYPE_CHECKING, @@ -678,7 +679,9 @@ def __init__( ) # stacklevel chosen to be correct when this is reached via pd.merge # (and not DataFrame.join) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) self._validate_specification() @@ -2369,7 +2372,7 @@ def _items_overlap_with_suffix( "unexpected results. Provide 'suffixes' as a tuple instead. In the " "future a 'TypeError' will be raised.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) to_rename = left.intersection(right) @@ -2419,7 +2422,7 @@ def renamer(x, suffix): f"Passing 'suffixes' which cause duplicate columns {set(dups)} in the " f"result is deprecated and will raise a MergeError in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return llabels, rlabels diff --git a/pandas/core/series.py b/pandas/core/series.py index 206fcbe05d006..6f3769b53ad26 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import inspect from textwrap import dedent from typing import ( IO, @@ -389,7 +390,7 @@ def __init__( "of 'float64' in a future version. Specify a dtype explicitly " "to silence this warning.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # uncomment the line below when removing the FutureWarning # dtype = np.dtype(object) @@ -916,7 +917,7 @@ def take(self, indices, axis=0, is_copy=None, **kwargs) -> Series: "is_copy is deprecated and will be removed in a future version. " "'take' always returns a copy, so there is no need to specify this.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) nv.validate_take((), kwargs) @@ -1047,7 +1048,9 @@ def _get_values_tuple(self, key: tuple): # see tests.series.timeseries.test_mpl_compat_hack # the asarray is needed to avoid returning a 2D DatetimeArray result = np.asarray(self._values[key]) - deprecate_ndim_indexing(result, stacklevel=find_stack_level()) + deprecate_ndim_indexing( + result, stacklevel=find_stack_level(inspect.currentframe()) + ) return result if not isinstance(self.index, MultiIndex): @@ -1111,7 +1114,7 @@ def __setitem__(self, key, value) -> None: "Series. Use `series.iloc[an_int] = val` to treat the " "key as positional.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # can't use _mgr.setitem_inplace yet bc could have *both* # KeyError and then ValueError, xref GH#45070 @@ -1797,7 +1800,7 @@ def iteritems(self) -> Iterable[tuple[Hashable, Any]]: "iteritems is deprecated and will be removed in a future version. " "Use .items instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.items() @@ -1880,7 +1883,7 @@ def to_frame(self, name: Hashable = lib.no_default) -> DataFrame: "the future `None` will be used as the name of the resulting " "DataFrame column.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) name = lib.no_default @@ -2018,7 +2021,7 @@ def groupby( "will be removed in a future version." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) else: squeeze = False @@ -2078,7 +2081,7 @@ def count(self, level=None): "deprecated and will be removed in a future version. Use groupby " "instead. ser.count(level=1) should use ser.groupby(level=1).count().", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if not isinstance(self.index, MultiIndex): raise ValueError("Series.count level is only valid with a MultiIndex") @@ -3076,7 +3079,7 @@ def append( "and will be removed from pandas in a future version. " "Use pandas.concat instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._append(to_append, ignore_index, verify_integrity) @@ -4733,7 +4736,7 @@ def _reduce( f"Calling Series.{name} with {kwd_name}={numeric_only} and " f"dtype {self.dtype} will raise a TypeError in the future", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) raise NotImplementedError( f"Series.{name} does not implement {kwd_name}." @@ -5611,7 +5614,7 @@ def between(self, left, right, inclusive="both") -> Series: "Boolean inputs to the `inclusive` argument are deprecated in " "favour of `both` or `neither`.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if inclusive: inclusive = "both" diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index d50daad9a22b1..b66660f315df1 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -2,6 +2,7 @@ import codecs from functools import wraps +import inspect import re from typing import ( TYPE_CHECKING, @@ -242,7 +243,7 @@ def __iter__(self): warnings.warn( "Columnar iteration over characters will be deprecated in future releases.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) i = 0 g = self.get(i) @@ -1244,7 +1245,7 @@ def contains(self, pat, case=True, flags=0, na=None, regex=True): "This pattern is interpreted as a regular expression, and has " "match groups. To actually get the groups, use str.extract.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) result = self._data.array._str_contains(pat, case, flags, na, regex) @@ -1456,7 +1457,11 @@ def replace( " In addition, single character regular expressions will " "*not* be treated as literal strings when regex=True." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, + FutureWarning, + stacklevel=find_stack_level(inspect.currentframe()), + ) # Check whether repl is valid (GH 13438, GH 15055) if not (isinstance(repl, str) or callable(repl)): diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index 7ec4bc1016a9d..388f751d9cc57 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -3,6 +3,7 @@ from collections import abc from datetime import datetime from functools import partial +import inspect from itertools import islice from typing import ( TYPE_CHECKING, @@ -1284,7 +1285,7 @@ def to_time(arg, format=None, infer_time_format=False, errors="raise"): "`to_time` has been moved, should be imported from pandas.core.tools.times. " "This alias will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) from pandas.core.tools.times import to_time diff --git a/pandas/core/window/common.py b/pandas/core/window/common.py index e31b5c60a37ee..29b7558f40353 100644 --- a/pandas/core/window/common.py +++ b/pandas/core/window/common.py @@ -2,6 +2,7 @@ from __future__ import annotations from collections import defaultdict +import inspect from typing import cast import warnings @@ -203,5 +204,5 @@ def maybe_warn_args_and_kwargs(cls, kernel: str, args, kwargs) -> None: "no impact on the result and is deprecated. This will " "raise a TypeError in a future version of pandas.", category=FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py index 020ca71050015..32559d0d88bcf 100644 --- a/pandas/core/window/ewm.py +++ b/pandas/core/window/ewm.py @@ -2,6 +2,7 @@ import datetime from functools import partial +import inspect from textwrap import dedent from typing import ( TYPE_CHECKING, @@ -391,7 +392,7 @@ def __init__( "into times instead." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # self.times cannot be str anymore self.times = cast("Series", self._selected_obj[self.times]) @@ -683,7 +684,7 @@ def vol(self, bias: bool = False, *args, **kwargs): "Use std instead." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.std(bias, *args, **kwargs) diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index c92c448304de2..3fc48b121419a 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -171,7 +171,7 @@ def win_type(self): "win_type will no longer return 'freq' in a future version. " "Check the type of self.window instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return "freq" return self._win_type @@ -181,7 +181,7 @@ def is_datetimelike(self) -> bool: warnings.warn( "is_datetimelike is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._win_freq_i8 is not None @@ -189,7 +189,7 @@ def validate(self) -> None: warnings.warn( "validate is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._validate() @@ -549,7 +549,7 @@ def hfunc(values: ArrayLike) -> ArrayLike: "Select only valid columns before calling the operation. " f"Dropped columns were {dropped}", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self._resolve_output(df, obj) @@ -1967,7 +1967,7 @@ def count(self, numeric_only: bool = False): "Specify min_periods=0 instead." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self.min_periods = 0 result = super().count() diff --git a/pandas/io/common.py b/pandas/io/common.py index d911499aa848e..7add6ec10222c 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -10,6 +10,7 @@ import dataclasses import functools import gzip +import inspect from io import ( BufferedIOBase, BytesIO, @@ -322,7 +323,7 @@ def _get_filepath_or_buffer( warnings.warn( "compression has no effect when passing a non-binary object as input.", RuntimeWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) compression_method = None diff --git a/pandas/io/date_converters.py b/pandas/io/date_converters.py index 85e92da8c2a54..5885a3b9d14d7 100644 --- a/pandas/io/date_converters.py +++ b/pandas/io/date_converters.py @@ -1,6 +1,7 @@ """This module is designed for community supported date conversion functions""" from __future__ import annotations +import inspect import warnings import numpy as np @@ -22,7 +23,7 @@ def parse_date_time(date_col, time_col) -> npt.NDArray[np.object_]: Use pd.to_datetime(date_col + " " + time_col).to_pydatetime() instead to get a Numpy array. """, # noqa: E501 FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) date_col = _maybe_cast(date_col) time_col = _maybe_cast(time_col) @@ -42,7 +43,7 @@ def parse_date_fields(year_col, month_col, day_col) -> npt.NDArray[np.object_]: np.array([s.to_pydatetime() for s in ser]) instead to get a Numpy array. """, # noqa: E501 FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) year_col = _maybe_cast(year_col) @@ -69,7 +70,7 @@ def parse_all_fields( np.array([s.to_pydatetime() for s in ser]) instead to get a Numpy array. """, # noqa: E501 FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) year_col = _maybe_cast(year_col) @@ -95,7 +96,7 @@ def generic_parser(parse_func, *cols) -> np.ndarray: Use pd.to_datetime instead. """, FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) N = _check_columns(cols) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index 44152f100d390..2fda6d239d85b 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -3,6 +3,7 @@ import abc import datetime from functools import partial +import inspect from io import BytesIO import os from textwrap import fill @@ -719,7 +720,7 @@ def parse( warnings.warn( "convert_float is deprecated and will be removed in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) validate_header_arg(header) @@ -1122,7 +1123,7 @@ def __new__( warnings.warn( "Use of **kwargs is deprecated, use engine_kwargs instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # only switch class if generic(ExcelWriter) @@ -1156,7 +1157,7 @@ def __new__( "deprecated and will also raise a warning, it can " "be globally set and the warning suppressed.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) # for mypy @@ -1326,7 +1327,7 @@ def _deprecate(self, attr: str): f"{attr} is not part of the public API, usage can give in unexpected " "results and will be removed in a future version", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) @property diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index df246ad30d806..0522e113d6525 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -6,6 +6,7 @@ from contextlib import contextmanager import copy from functools import partial +import inspect import operator from typing import ( Any, @@ -443,7 +444,7 @@ def render( warnings.warn( "this method is deprecated in favour of `Styler.to_html()`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if sparse_index is None: sparse_index = get_option("styler.sparse.index") @@ -2123,7 +2124,7 @@ def where( warnings.warn( "this method is deprecated in favour of `Styler.applymap()`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if other is None: @@ -2155,7 +2156,7 @@ def set_precision(self, precision: int) -> StylerRenderer: warnings.warn( "this method is deprecated in favour of `Styler.format(precision=..)`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self.precision = precision return self.format(precision=precision, na_rep=self.na_rep) @@ -2667,7 +2668,7 @@ def set_na_rep(self, na_rep: str) -> StylerRenderer: warnings.warn( "this method is deprecated in favour of `Styler.format(na_rep=..)`", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) self.na_rep = na_rep return self.format(na_rep=na_rep, precision=self.precision) @@ -2721,7 +2722,7 @@ def hide_index( warnings.warn( 'this method is deprecated in favour of `Styler.hide(axis="index")`', FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.hide(axis="index", level=level, subset=subset, names=names) @@ -2774,7 +2775,7 @@ def hide_columns( warnings.warn( 'this method is deprecated in favour of `Styler.hide(axis="columns")`', FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return self.hide(axis="columns", level=level, subset=subset, names=names) @@ -3381,7 +3382,7 @@ def f(data: DataFrame, props: str) -> np.ndarray: warnings.warn( "`null_color` is deprecated: use `color` instead", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if color is None and null_color == lib.no_default: diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index 0e40e47bf7cb1..89bf903fea8dd 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -5,6 +5,7 @@ import csv import datetime from enum import Enum +import inspect import itertools from typing import ( TYPE_CHECKING, @@ -559,7 +560,7 @@ def _convert_to_ndarrays( f"for column {c} - only the converter will be used." ), ParserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) try: @@ -857,7 +858,7 @@ def _check_data_length( "Length of header or names does not match length of data. This leads " "to a loss of data with index_col=False.", ParserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) @overload diff --git a/pandas/io/parsers/c_parser_wrapper.py b/pandas/io/parsers/c_parser_wrapper.py index aec999e40b0f5..99051ec661413 100644 --- a/pandas/io/parsers/c_parser_wrapper.py +++ b/pandas/io/parsers/c_parser_wrapper.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections import defaultdict +import inspect from io import TextIOWrapper from typing import ( TYPE_CHECKING, @@ -421,7 +422,11 @@ def _concatenate_chunks(chunks: list[dict[int, ArrayLike]]) -> dict: f"Specify dtype option on import or set low_memory=False." ] ) - warnings.warn(warning_message, DtypeWarning, stacklevel=find_stack_level()) + warnings.warn( + warning_message, + DtypeWarning, + stacklevel=find_stack_level(inspect.currentframe()), + ) return result diff --git a/pandas/io/parsers/python_parser.py b/pandas/io/parsers/python_parser.py index 7c03a81dbc0e6..ff8c21ab89f30 100644 --- a/pandas/io/parsers/python_parser.py +++ b/pandas/io/parsers/python_parser.py @@ -5,6 +5,7 @@ defaultdict, ) import csv +import inspect from io import StringIO import re import sys @@ -599,7 +600,7 @@ def _handle_usecols( "Defining usecols with out of bounds indices is deprecated " "and will raise a ParserError in a future version.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) col_indices = self.usecols diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index dc4556542d8e2..03a634cf07e26 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -5,6 +5,7 @@ from collections import abc import csv +import inspect import sys from textwrap import fill from typing import ( @@ -1609,7 +1610,7 @@ def _clean_options( "engine='python'." ), ParserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) index_col = options["index_col"] @@ -1628,7 +1629,11 @@ def _clean_options( f"The {arg} argument has been deprecated and will be " f"removed in a future version. {depr_default.msg}\n\n" ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, + FutureWarning, + stacklevel=find_stack_level(inspect.currentframe()), + ) else: result[arg] = parser_default @@ -2203,7 +2208,9 @@ def _merge_with_dialect_properties( if conflict_msgs: warnings.warn( - "\n\n".join(conflict_msgs), ParserWarning, stacklevel=find_stack_level() + "\n\n".join(conflict_msgs), + ParserWarning, + stacklevel=find_stack_level(inspect.currentframe()), ) kwds[param] = dialect_val return kwds diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index a4049eff8ae71..f7d5fb9270247 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -10,6 +10,7 @@ date, tzinfo, ) +import inspect import itertools import os import re @@ -686,7 +687,7 @@ def iteritems(self): "iteritems is deprecated and will be removed in a future version. " "Use .items instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) yield from self.items() @@ -2195,7 +2196,9 @@ def update_info(self, info) -> None: if key in ["freq", "index_name"]: ws = attribute_conflict_doc % (key, existing_value, value) warnings.warn( - ws, AttributeConflictWarning, stacklevel=find_stack_level() + ws, + AttributeConflictWarning, + stacklevel=find_stack_level(inspect.currentframe()), ) # reset @@ -3093,7 +3096,11 @@ def write_array( pass else: ws = performance_doc % (inferred_type, key, items) - warnings.warn(ws, PerformanceWarning, stacklevel=find_stack_level()) + warnings.warn( + ws, + PerformanceWarning, + stacklevel=find_stack_level(inspect.currentframe()), + ) vlarr = self._handle.create_vlarray(self.group, key, _tables().ObjectAtom()) vlarr.append(value) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 71fecba4340ac..2b835a1e7ebed 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -12,6 +12,7 @@ time, ) from functools import partial +import inspect import re from typing import ( TYPE_CHECKING, @@ -1193,7 +1194,7 @@ def _sqlalchemy_type(self, col): "the 'timedelta' type is not supported, and will be " "written as integer values (ns frequency) to the database.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return BigInteger elif col_type == "floating": @@ -1962,7 +1963,7 @@ def _sql_type_name(self, col): "the 'timedelta' type is not supported, and will be " "written as integer values (ns frequency) to the database.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) col_type = "integer" diff --git a/pandas/plotting/_matplotlib/tools.py b/pandas/plotting/_matplotlib/tools.py index a8b1e4c572c43..c5119205d1861 100644 --- a/pandas/plotting/_matplotlib/tools.py +++ b/pandas/plotting/_matplotlib/tools.py @@ -1,6 +1,7 @@ # being a bit too dynamic from __future__ import annotations +import inspect from math import ceil from typing import ( TYPE_CHECKING, @@ -239,7 +240,7 @@ def create_subplots( "When passing multiple axes, sharex and sharey " "are ignored. These settings must be specified when creating axes.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) if ax.size == naxes: fig = ax.flat[0].get_figure() @@ -262,7 +263,7 @@ def create_subplots( "To output multiple subplots, the figure containing " "the passed axes is being cleared.", UserWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) fig.clear() diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index b2fbc022b2708..35174d92b4125 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -1,5 +1,6 @@ from __future__ import annotations +import inspect import warnings import numpy as np @@ -116,7 +117,7 @@ def get_offset(name: str) -> BaseOffset: "get_offset is deprecated and will be removed in a future version, " "use to_offset instead.", FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return _get_offset(name) diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index f8359edaa8d44..86c945f1321f5 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -312,7 +312,7 @@ def wrapper(*args, **kwargs): warnings.warn( msg.format(arguments=arguments), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), ) return func(*args, **kwargs) diff --git a/pandas/util/_exceptions.py b/pandas/util/_exceptions.py index c718451fbf621..fcd191e25ced5 100644 --- a/pandas/util/_exceptions.py +++ b/pandas/util/_exceptions.py @@ -1,6 +1,7 @@ from __future__ import annotations import contextlib +import functools import inspect import os from typing import Iterator @@ -25,10 +26,16 @@ def rewrite_exception(old_name: str, new_name: str) -> Iterator[None]: raise -def find_stack_level() -> int: +@functools.lru_cache +def find_stack_level(frame) -> int: """ Find the first place in the stack that is not inside pandas (tests notwithstanding). + + ``frame`` should be passed as ``inspect.currentframe()`` by the + calling function. + + https://stackoverflow.com/questions/17407119/python-inspect-stack-is-slow """ import pandas as pd @@ -36,9 +43,7 @@ def find_stack_level() -> int: pkg_dir = os.path.dirname(pd.__file__) test_dir = os.path.join(pkg_dir, "tests") - # https://stackoverflow.com/questions/17407119/python-inspect-stack-is-slow - frame = inspect.currentframe() - n = 0 + n = 1 while frame: fname = inspect.getfile(frame) if fname.startswith(pkg_dir) and not fname.startswith(test_dir): diff --git a/pandas/util/_validators.py b/pandas/util/_validators.py index a4a9ebfbf4126..7e938e4648e97 100644 --- a/pandas/util/_validators.py +++ b/pandas/util/_validators.py @@ -4,6 +4,7 @@ """ from __future__ import annotations +import inspect from typing import ( Any, Iterable, @@ -355,7 +356,9 @@ def validate_axis_style_args( "positional arguments for 'index' or 'columns' will raise " "a 'TypeError'." ) - warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) + warnings.warn( + msg, FutureWarning, stacklevel=find_stack_level(inspect.currentframe()) + ) out[data._get_axis_name(0)] = args[0] out[data._get_axis_name(1)] = args[1] else: diff --git a/pandas/util/testing.py b/pandas/util/testing.py index db9bfc274cd78..5585ea0b58628 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -1,3 +1,4 @@ +import inspect import warnings from pandas.util._exceptions import find_stack_level @@ -10,5 +11,5 @@ "public API at pandas.testing instead." ), FutureWarning, - stacklevel=find_stack_level(), + stacklevel=find_stack_level(inspect.currentframe()), )