Skip to content

Commit 477f51e

Browse files
authored
TST: tighten stacklevel checks (#41560)
1 parent a395185 commit 477f51e

28 files changed

+96
-63
lines changed

pandas/core/arrays/datetimelike.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,9 @@ def _validate_shift_value(self, fill_value):
599599
"will raise in a future version, pass "
600600
f"{self._scalar_type.__name__} instead.",
601601
FutureWarning,
602-
stacklevel=8,
602+
# There is no way to hard-code the level since this might be
603+
# reached directly or called from the Index or Block method
604+
stacklevel=find_stack_level(),
603605
)
604606
fill_value = new_fill
605607

pandas/core/arrays/datetimes.py

+1
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ def to_perioddelta(self, freq) -> TimedeltaArray:
11751175
"future version. "
11761176
"Use `dtindex - dtindex.to_period(freq).to_timestamp()` instead",
11771177
FutureWarning,
1178+
# stacklevel chosen to be correct for when called from DatetimeIndex
11781179
stacklevel=3,
11791180
)
11801181
from pandas.core.arrays.timedeltas import TimedeltaArray

pandas/core/frame.py

+1
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,7 @@ def to_dict(self, orient: str = "dict", into=dict):
17641764
"will be used in a future version. Use one of the above "
17651765
"to silence this warning.",
17661766
FutureWarning,
1767+
stacklevel=2,
17671768
)
17681769

17691770
if orient.startswith("d"):

pandas/core/generic.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -481,13 +481,19 @@ def _data(self):
481481
@property
482482
def _AXIS_NUMBERS(self) -> dict[str, int]:
483483
""".. deprecated:: 1.1.0"""
484-
warnings.warn("_AXIS_NUMBERS has been deprecated.", FutureWarning, stacklevel=3)
484+
level = self.ndim + 1
485+
warnings.warn(
486+
"_AXIS_NUMBERS has been deprecated.", FutureWarning, stacklevel=level
487+
)
485488
return {"index": 0}
486489

487490
@property
488491
def _AXIS_NAMES(self) -> dict[int, str]:
489492
""".. deprecated:: 1.1.0"""
490-
warnings.warn("_AXIS_NAMES has been deprecated.", FutureWarning, stacklevel=3)
493+
level = self.ndim + 1
494+
warnings.warn(
495+
"_AXIS_NAMES has been deprecated.", FutureWarning, stacklevel=level
496+
)
491497
return {0: "index"}
492498

493499
@final

pandas/core/indexes/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3691,7 +3691,7 @@ def is_int(v):
36913691
"and will raise TypeError in a future version. "
36923692
"Use .loc with labels or .iloc with positions instead.",
36933693
FutureWarning,
3694-
stacklevel=6,
3694+
stacklevel=5,
36953695
)
36963696
indexer = key
36973697
else:

pandas/core/indexes/datetimes.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
cache_readonly,
4141
doc,
4242
)
43+
from pandas.util._exceptions import find_stack_level
4344

4445
from pandas.core.dtypes.common import (
4546
DT64NS_DTYPE,
@@ -660,7 +661,7 @@ def _deprecate_mismatched_indexing(self, key) -> None:
660661
"raise KeyError in a future version. "
661662
"Use a timezone-aware object instead."
662663
)
663-
warnings.warn(msg, FutureWarning, stacklevel=5)
664+
warnings.warn(msg, FutureWarning, stacklevel=find_stack_level())
664665

665666
def get_loc(self, key, method=None, tolerance=None):
666667
"""

pandas/core/reshape/merge.py

+2
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,8 @@ def __init__(
673673
f"in a future version. ({left.columns.nlevels} levels on the left,"
674674
f"{right.columns.nlevels} on the right)"
675675
)
676+
# stacklevel chosen to be correct when this is reached via pd.merge
677+
# (and not DataFrame.join)
676678
warnings.warn(msg, FutureWarning, stacklevel=3)
677679

678680
self._validate_specification()

pandas/tests/arrays/test_datetimelike.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,8 @@ def test_shift_fill_int_deprecated(self):
561561
data = np.arange(10, dtype="i8") * 24 * 3600 * 10 ** 9
562562
arr = self.array_cls(data, freq="D")
563563

564-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
564+
msg = "Passing <class 'int'> to shift"
565+
with tm.assert_produces_warning(FutureWarning, match=msg):
565566
result = arr.shift(1, fill_value=1)
566567

567568
expected = arr.copy()
@@ -783,10 +784,13 @@ def test_to_perioddelta(self, datetime_index, freqstr):
783784
dti = datetime_index
784785
arr = DatetimeArray(dti)
785786

786-
with tm.assert_produces_warning(FutureWarning):
787+
msg = "to_perioddelta is deprecated and will be removed"
788+
with tm.assert_produces_warning(FutureWarning, match=msg):
787789
# Deprecation GH#34853
788790
expected = dti.to_perioddelta(freq=freqstr)
789-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
791+
with tm.assert_produces_warning(
792+
FutureWarning, match=msg, check_stacklevel=False
793+
):
790794
# stacklevel is chosen to be "correct" for DatetimeIndex, not
791795
# DatetimeArray
792796
result = arr.to_perioddelta(freq=freqstr)

pandas/tests/dtypes/cast/test_promote.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,13 @@ def test_maybe_promote_any_with_datetime64(
406406
exp_val_for_scalar = fill_value
407407

408408
warn = None
409+
msg = "Using a `date` object for fill_value"
409410
if type(fill_value) is datetime.date and dtype.kind == "M":
410411
# Casting date to dt64 is deprecated
411412
warn = FutureWarning
412413

413-
with tm.assert_produces_warning(warn, check_stacklevel=False):
414+
with tm.assert_produces_warning(warn, match=msg, check_stacklevel=False):
415+
# stacklevel is chosen to make sense when called from higher-level functions
414416
_check_promote(dtype, fill_value, expected_dtype, exp_val_for_scalar)
415417

416418

pandas/tests/dtypes/test_missing.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,10 @@ def test_array_equivalent(dtype_equal):
443443
)
444444
def test_array_equivalent_series(val):
445445
arr = np.array([1, 2])
446+
msg = "elementwise comparison failed"
446447
cm = (
447-
tm.assert_produces_warning(FutureWarning, check_stacklevel=False)
448+
# stacklevel is chosen to make sense when called from .equals
449+
tm.assert_produces_warning(FutureWarning, match=msg, check_stacklevel=False)
448450
if isinstance(val, str)
449451
else nullcontext()
450452
)

pandas/tests/frame/methods/test_join.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,11 @@ def test_merge_join_different_levels(self):
345345
# join, see discussion in GH#12219
346346
columns = ["a", "b", ("a", ""), ("c", "c1")]
347347
expected = DataFrame(columns=columns, data=[[1, 11, 0, 44], [0, 22, 1, 33]])
348-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
348+
msg = "merging between different levels is deprecated"
349+
with tm.assert_produces_warning(
350+
FutureWarning, match=msg, check_stacklevel=False
351+
):
352+
# stacklevel is chosen to be correct for pd.merge, not DataFrame.join
349353
result = df1.join(df2, on="a")
350354
tm.assert_frame_equal(result, expected)
351355

pandas/tests/frame/methods/test_reset_index.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ def test_reset_index_with_datetimeindex_cols(self, name):
341341
)
342342
df.index.name = name
343343

344-
with tm.assert_produces_warning(warn, check_stacklevel=False):
344+
with tm.assert_produces_warning(warn):
345345
result = df.reset_index()
346346

347347
item = name if name is not None else "index"

pandas/tests/frame/methods/test_to_dict.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ def test_to_dict_invalid_orient(self):
8181
def test_to_dict_short_orient_warns(self, orient):
8282
# GH#32515
8383
df = DataFrame({"A": [0, 1]})
84-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
84+
msg = "Using short name for 'orient' is deprecated"
85+
with tm.assert_produces_warning(FutureWarning, match=msg):
8586
df.to_dict(orient=orient)
8687

8788
@pytest.mark.parametrize("mapping", [dict, defaultdict(list), OrderedDict])

pandas/tests/generic/test_generic.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -474,14 +474,16 @@ def test_axis_names_deprecated(self, frame_or_series):
474474
# GH33637
475475
box = frame_or_series
476476
obj = box(dtype=object)
477-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
477+
msg = "_AXIS_NAMES has been deprecated"
478+
with tm.assert_produces_warning(FutureWarning, match=msg):
478479
obj._AXIS_NAMES
479480

480481
def test_axis_numbers_deprecated(self, frame_or_series):
481482
# GH33637
482483
box = frame_or_series
483484
obj = box(dtype=object)
484-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
485+
msg = "_AXIS_NUMBERS has been deprecated"
486+
with tm.assert_produces_warning(FutureWarning, match=msg):
485487
obj._AXIS_NUMBERS
486488

487489
def test_flags_identity(self, frame_or_series):

pandas/tests/indexes/common.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,11 @@ def test_engine_reference_cycle(self, simple_index):
719719
def test_getitem_2d_deprecated(self, simple_index):
720720
# GH#30588
721721
idx = simple_index
722-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
722+
msg = "Support for multi-dimensional indexing"
723+
check = not isinstance(idx, (RangeIndex, CategoricalIndex))
724+
with tm.assert_produces_warning(
725+
FutureWarning, match=msg, check_stacklevel=check
726+
):
723727
res = idx[:, None]
724728

725729
assert isinstance(res, np.ndarray), type(res)

pandas/tests/indexes/datetimes/test_indexing.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ def test_get_slice_bounds_datetime_within(
735735
key = box(year=2000, month=1, day=7)
736736

737737
warn = None if tz is None else FutureWarning
738-
with tm.assert_produces_warning(warn, check_stacklevel=False):
738+
with tm.assert_produces_warning(warn):
739739
# GH#36148 will require tzawareness-compat
740740
result = index.get_slice_bound(key, kind=kind, side=side)
741741
assert result == expected
@@ -753,7 +753,7 @@ def test_get_slice_bounds_datetime_outside(
753753
key = box(year=year, month=1, day=7)
754754

755755
warn = None if tz is None else FutureWarning
756-
with tm.assert_produces_warning(warn, check_stacklevel=False):
756+
with tm.assert_produces_warning(warn):
757757
# GH#36148 will require tzawareness-compat
758758
result = index.get_slice_bound(key, kind=kind, side=side)
759759
assert result == expected
@@ -767,7 +767,7 @@ def test_slice_datetime_locs(self, box, kind, tz_aware_fixture):
767767
key = box(2010, 1, 1)
768768

769769
warn = None if tz is None else FutureWarning
770-
with tm.assert_produces_warning(warn, check_stacklevel=False):
770+
with tm.assert_produces_warning(warn):
771771
# GH#36148 will require tzawareness-compat
772772
result = index.slice_locs(key, box(2010, 1, 2))
773773
expected = (0, 1)

pandas/tests/indexes/interval/test_astype.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def index(self, request):
205205
@pytest.mark.parametrize("subtype", ["int64", "uint64"])
206206
def test_subtype_integer(self, index, subtype):
207207
dtype = IntervalDtype(subtype, "right")
208-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
208+
with tm.assert_produces_warning(FutureWarning):
209209
result = index.astype(dtype)
210210
expected = IntervalIndex.from_arrays(
211211
index.left.astype(subtype),

pandas/tests/indexes/interval/test_base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def test_getitem_2d_deprecated(self, simple_index):
6464
# GH#30588 multi-dim indexing is deprecated, but raising is also acceptable
6565
idx = simple_index
6666
with pytest.raises(ValueError, match="multi-dimensional indexing not allowed"):
67-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
67+
with tm.assert_produces_warning(FutureWarning):
6868
idx[:, None]
6969

7070

pandas/tests/indexes/interval/test_constructors.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ def test_constructor_dtype(self, constructor, breaks, subtype):
7777
# astype(int64) deprecated
7878
warn = FutureWarning
7979

80-
with tm.assert_produces_warning(warn, check_stacklevel=False):
80+
with tm.assert_produces_warning(warn):
8181
expected_kwargs = self.get_kwargs_from_breaks(breaks.astype(subtype))
8282
expected = constructor(**expected_kwargs)
8383

8484
result_kwargs = self.get_kwargs_from_breaks(breaks)
8585
iv_dtype = IntervalDtype(subtype, "right")
8686
for dtype in (iv_dtype, str(iv_dtype)):
87-
with tm.assert_produces_warning(warn, check_stacklevel=False):
87+
with tm.assert_produces_warning(warn):
8888

8989
result = constructor(dtype=dtype, **result_kwargs)
9090
tm.assert_index_equal(result, expected)
@@ -112,7 +112,7 @@ def test_constructor_pass_closed(self, constructor, breaks):
112112
result_kwargs = self.get_kwargs_from_breaks(breaks)
113113

114114
for dtype in (iv_dtype, str(iv_dtype)):
115-
with tm.assert_produces_warning(warn, check_stacklevel=False):
115+
with tm.assert_produces_warning(warn):
116116

117117
result = constructor(dtype=dtype, closed="left", **result_kwargs)
118118
assert result.dtype.closed == "left"

pandas/tests/indexes/test_common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def test_astype_preserves_name(self, index, dtype):
343343
warn = FutureWarning
344344
try:
345345
# Some of these conversions cannot succeed so we use a try / except
346-
with tm.assert_produces_warning(warn, check_stacklevel=False):
346+
with tm.assert_produces_warning(warn):
347347
result = index.astype(dtype)
348348
except (ValueError, TypeError, NotImplementedError, SystemError):
349349
return

pandas/tests/indexing/test_loc.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ def test_loc_with_positional_slice_deprecation():
24002400
# GH#31840
24012401
ser = Series(range(4), index=["A", "B", "C", "D"])
24022402

2403-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
2403+
with tm.assert_produces_warning(FutureWarning):
24042404
ser.loc[:3] = 2
24052405

24062406
expected = Series([2, 2, 2, 3], index=["A", "B", "C", "D"])
@@ -2423,14 +2423,14 @@ def test_loc_slice_disallows_positional():
24232423
with pytest.raises(TypeError, match=msg):
24242424
obj.loc[1:3]
24252425

2426-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
2426+
with tm.assert_produces_warning(FutureWarning):
24272427
# GH#31840 deprecated incorrect behavior
24282428
obj.loc[1:3] = 1
24292429

24302430
with pytest.raises(TypeError, match=msg):
24312431
df.loc[1:3, 1]
24322432

2433-
with tm.assert_produces_warning(FutureWarning):
2433+
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
24342434
# GH#31840 deprecated incorrect behavior
24352435
df.loc[1:3, 1] = 2
24362436

pandas/tests/internals/test_internals.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ def test_astype(self, t):
545545
mgr = create_mgr("a,b: object; c: bool; d: datetime; e: f4; f: f2; g: f8")
546546

547547
t = np.dtype(t)
548-
with tm.assert_produces_warning(warn, check_stacklevel=False):
548+
with tm.assert_produces_warning(warn):
549549
tmgr = mgr.astype(t, errors="ignore")
550550
assert tmgr.iget(2).dtype.type == t
551551
assert tmgr.iget(4).dtype.type == t

pandas/tests/series/indexing/test_datetime.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,25 @@ def test_getitem_setitem_datetimeindex():
147147
assert result == expected
148148

149149
result = ts.copy()
150-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
150+
with tm.assert_produces_warning(FutureWarning):
151151
# GH#36148 will require tzawareness compat
152152
result[datetime(1990, 1, 1, 4)] = 0
153-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
153+
with tm.assert_produces_warning(FutureWarning):
154154
# GH#36148 will require tzawareness compat
155155
result[datetime(1990, 1, 1, 4)] = ts[4]
156156
tm.assert_series_equal(result, ts)
157157

158-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
158+
with tm.assert_produces_warning(FutureWarning):
159159
# GH#36148 will require tzawareness compat
160160
result = ts[datetime(1990, 1, 1, 4) : datetime(1990, 1, 1, 7)]
161161
expected = ts[4:8]
162162
tm.assert_series_equal(result, expected)
163163

164164
result = ts.copy()
165-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
165+
with tm.assert_produces_warning(FutureWarning):
166166
# GH#36148 will require tzawareness compat
167167
result[datetime(1990, 1, 1, 4) : datetime(1990, 1, 1, 7)] = 0
168-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
168+
with tm.assert_produces_warning(FutureWarning):
169169
# GH#36148 will require tzawareness compat
170170
result[datetime(1990, 1, 1, 4) : datetime(1990, 1, 1, 7)] = ts[4:8]
171171
tm.assert_series_equal(result, ts)

pandas/tests/series/methods/test_truncate.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def test_truncate_datetimeindex_tz(self):
1313
# GH 9243
1414
idx = date_range("4/1/2005", "4/30/2005", freq="D", tz="US/Pacific")
1515
s = Series(range(len(idx)), index=idx)
16-
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
16+
with tm.assert_produces_warning(FutureWarning):
1717
# GH#36148 in the future will require tzawareness compat
1818
s.truncate(datetime(2005, 4, 2), datetime(2005, 4, 4))
1919

pandas/tests/series/test_arithmetic.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,9 @@ def test_series_ops_name_retention(
783783
else:
784784
# GH#37374 logical ops behaving as set ops deprecated
785785
warn = FutureWarning if is_rlogical and box is Index else None
786-
with tm.assert_produces_warning(warn, check_stacklevel=False):
786+
msg = "operating as a set operation is deprecated"
787+
with tm.assert_produces_warning(warn, match=msg, check_stacklevel=False):
788+
# stacklevel is correct for Index op, not reversed op
787789
result = op(left, right)
788790

789791
if box is Index and is_rlogical:

0 commit comments

Comments
 (0)