Skip to content

Commit d578962

Browse files
committed
Refinements
1 parent 98ae53c commit d578962

File tree

7 files changed

+44
-26
lines changed

7 files changed

+44
-26
lines changed

pandas/_config/config.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373

7474
class DeprecatedOption(NamedTuple):
7575
key: str
76+
category: type[Warning]
7677
msg: str | None
7778
rkey: str | None
7879
removal_ver: str | None
@@ -589,6 +590,7 @@ def register_option(
589590

590591
def deprecate_option(
591592
key: str,
593+
category: type[Warning],
592594
msg: str | None = None,
593595
rkey: str | None = None,
594596
removal_ver: str | None = None,
@@ -608,6 +610,8 @@ def deprecate_option(
608610
key : str
609611
Name of the option to be deprecated.
610612
must be a fully-qualified option name (e.g "x.y.z.rkey").
613+
category : Warning
614+
Warning class for the deprecation.
611615
msg : str, optional
612616
Warning message to output when the key is referenced.
613617
if no message is given a default message will be emitted.
@@ -631,7 +635,7 @@ def deprecate_option(
631635
if key in _deprecated_options:
632636
raise OptionError(f"Option '{key}' has already been defined as deprecated.")
633637

634-
_deprecated_options[key] = DeprecatedOption(key, msg, rkey, removal_ver)
638+
_deprecated_options[key] = DeprecatedOption(key, category, msg, rkey, removal_ver)
635639

636640

637641
#
@@ -716,7 +720,7 @@ def _warn_if_deprecated(key: str) -> bool:
716720
if d.msg:
717721
warnings.warn(
718722
d.msg,
719-
FutureWarning, # pdlint: ignore[warning_class]
723+
d.category,
720724
stacklevel=find_stack_level(),
721725
)
722726
else:
@@ -730,7 +734,7 @@ def _warn_if_deprecated(key: str) -> bool:
730734

731735
warnings.warn(
732736
msg,
733-
FutureWarning, # pdlint: ignore[warning_class]
737+
d.category,
734738
stacklevel=find_stack_level(),
735739
)
736740
return True

pandas/core/groupby/groupby.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class providing the base-class of operations.
6161
from pandas.errors import (
6262
AbstractMethodError,
6363
DataError,
64+
Pandas4Warning,
6465
)
6566
from pandas.util._decorators import (
6667
Appender,
@@ -557,7 +558,7 @@ def groups(self) -> dict[Hashable, Index]:
557558
"and will be removed. In a future version `groups` by one element "
558559
"list will return tuple. Use ``df.groupby(by='a').groups`` "
559560
"instead of ``df.groupby(by=['a']).groups`` to avoid this warning",
560-
FutureWarning, # pdlint: ignore[warning_class]
561+
Pandas4Warning,
561562
stacklevel=find_stack_level(),
562563
)
563564
return self._grouper.groups

pandas/core/resample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,7 @@ def _get_resampler(self, obj: NDFrame) -> Resampler:
22932293
)
22942294
elif isinstance(ax, PeriodIndex):
22952295
if isinstance(ax, PeriodIndex):
2296+
# TODO: Enforce in 3.0 (#53481)
22962297
# GH#53481
22972298
warnings.warn(
22982299
"Resampling with a PeriodIndex is deprecated. "

pandas/core/strings/object_array.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ def _str_contains(
159159
upper_pat = pat.upper()
160160
f = lambda x: upper_pat in x.upper()
161161
if na is not lib.no_default and not isna(na) and not isinstance(na, bool):
162+
# TODO: Enforce in 3.0 (#59615)
162163
# GH#59561
163164
warnings.warn(
164165
"Allowing a non-bool 'na' in obj.str.contains is deprecated "
@@ -171,6 +172,7 @@ def _str_contains(
171172
def _str_startswith(self, pat, na=lib.no_default):
172173
f = lambda x: x.startswith(pat)
173174
if na is not lib.no_default and not isna(na) and not isinstance(na, bool):
175+
# TODO: Enforce in 3.0 (#59615)
174176
# GH#59561
175177
warnings.warn(
176178
"Allowing a non-bool 'na' in obj.str.startswith is deprecated "
@@ -183,6 +185,7 @@ def _str_startswith(self, pat, na=lib.no_default):
183185
def _str_endswith(self, pat, na=lib.no_default):
184186
f = lambda x: x.endswith(pat)
185187
if na is not lib.no_default and not isna(na) and not isinstance(na, bool):
188+
# TODO: Enforce in 3.0 (#59615)
186189
# GH#59561
187190
warnings.warn(
188191
"Allowing a non-bool 'na' in obj.str.endswith is deprecated "

pandas/tests/config/test_config.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ def test_register_option(self):
7575
def test_describe_option(self):
7676
cf.register_option("a", 1, "doc")
7777
cf.register_option("b", 1, "doc2")
78-
cf.deprecate_option("b")
78+
cf.deprecate_option("b", FutureWarning)
7979

8080
cf.register_option("c.d.e1", 1, "doc3")
8181
cf.register_option("c.d.e2", 1, "doc4")
8282
cf.register_option("f", 1)
8383
cf.register_option("g.h", 1)
8484
cf.register_option("k", 2)
85-
cf.deprecate_option("g.h", rkey="k")
85+
cf.deprecate_option("g.h", FutureWarning, rkey="k")
8686
cf.register_option("l", "foo")
8787

8888
# non-existent keys raise KeyError
@@ -111,7 +111,8 @@ def test_describe_option(self):
111111
cf.set_option("l", "bar")
112112
assert "bar" in cf.describe_option("l", _print_desc=False)
113113

114-
def test_case_insensitive(self):
114+
@pytest.mark.parametrize("category", [DeprecationWarning, FutureWarning])
115+
def test_case_insensitive(self, category):
115116
cf.register_option("KanBAN", 1, "doc")
116117

117118
assert "doc" in cf.describe_option("kanbaN", _print_desc=False)
@@ -124,9 +125,9 @@ def test_case_insensitive(self):
124125
with pytest.raises(OptionError, match=msg):
125126
cf.get_option("no_such_option")
126127

127-
cf.deprecate_option("KanBan")
128+
cf.deprecate_option("KanBan", category)
128129
msg = "'kanban' is deprecated, please refrain from using it."
129-
with pytest.raises(FutureWarning, match=msg):
130+
with pytest.raises(category, match=msg):
130131
cf.get_option("kAnBaN")
131132

132133
def test_get_option(self):
@@ -285,7 +286,7 @@ def test_reset_option_all(self):
285286

286287
def test_deprecate_option(self):
287288
# we can deprecate non-existent options
288-
cf.deprecate_option("foo")
289+
cf.deprecate_option("foo", FutureWarning)
289290

290291
with tm.assert_produces_warning(FutureWarning, match="deprecated"):
291292
with pytest.raises(KeyError, match="No such keys.s.: 'foo'"):
@@ -295,15 +296,15 @@ def test_deprecate_option(self):
295296
cf.register_option("b.c", "hullo", "doc2")
296297
cf.register_option("foo", "hullo", "doc2")
297298

298-
cf.deprecate_option("a", removal_ver="nifty_ver")
299+
cf.deprecate_option("a", FutureWarning, removal_ver="nifty_ver")
299300
with tm.assert_produces_warning(FutureWarning, match="eprecated.*nifty_ver"):
300301
cf.get_option("a")
301302

302303
msg = "Option 'a' has already been defined as deprecated"
303304
with pytest.raises(OptionError, match=msg):
304-
cf.deprecate_option("a")
305+
cf.deprecate_option("a", FutureWarning)
305306

306-
cf.deprecate_option("b.c", "zounds!")
307+
cf.deprecate_option("b.c", FutureWarning, "zounds!")
307308
with tm.assert_produces_warning(FutureWarning, match="zounds!"):
308309
cf.get_option("b.c")
309310

@@ -313,7 +314,7 @@ def test_deprecate_option(self):
313314
assert cf.get_option("d.a") == "foo"
314315
assert cf.get_option("d.dep") == "bar"
315316

316-
cf.deprecate_option("d.dep", rkey="d.a") # reroute d.dep to d.a
317+
cf.deprecate_option("d.dep", FutureWarning, rkey="d.a") # reroute d.dep to d.a
317318
with tm.assert_produces_warning(FutureWarning, match="eprecated"):
318319
assert cf.get_option("d.dep") == "foo"
319320

pandas/tests/groupby/test_grouping.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
import numpy as np
1111
import pytest
1212

13-
from pandas.errors import SpecificationError
13+
from pandas.errors import (
14+
Pandas4Warning,
15+
SpecificationError,
16+
)
1417

1518
import pandas as pd
1619
from pandas import (
@@ -545,21 +548,21 @@ def test_multiindex_columns_empty_level(self):
545548
grouped = df.groupby("to filter").groups
546549
assert grouped["A"] == [0]
547550

548-
with tm.assert_produces_warning(FutureWarning, match=msg):
551+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
549552
grouped = df.groupby([("to filter", "")]).groups
550553
assert grouped["A"] == [0]
551554

552555
df = DataFrame([[1, "A"], [2, "B"]], columns=midx)
553556

554557
expected = df.groupby("to filter").groups
555-
with tm.assert_produces_warning(FutureWarning, match=msg):
558+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
556559
result = df.groupby([("to filter", "")]).groups
557560
assert result == expected
558561

559562
df = DataFrame([[1, "A"], [2, "A"]], columns=midx)
560563

561564
expected = df.groupby("to filter").groups
562-
with tm.assert_produces_warning(FutureWarning, match=msg):
565+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
563566
result = df.groupby([("to filter", "")]).groups
564567
tm.assert_dict_equal(result, expected)
565568

@@ -571,7 +574,7 @@ def test_groupby_multiindex_tuple(self):
571574
)
572575

573576
msg = "`groups` by one element list returns scalar is deprecated"
574-
with tm.assert_produces_warning(FutureWarning, match=msg):
577+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
575578
expected = df.groupby([("b", 1)]).groups
576579
result = df.groupby(("b", 1)).groups
577580
tm.assert_dict_equal(expected, result)
@@ -583,14 +586,14 @@ def test_groupby_multiindex_tuple(self):
583586
),
584587
)
585588

586-
with tm.assert_produces_warning(FutureWarning, match=msg):
589+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
587590
expected = df2.groupby([("b", "d")]).groups
588591
result = df.groupby(("b", 1)).groups
589592
tm.assert_dict_equal(expected, result)
590593

591594
df3 = DataFrame(df.values, columns=[("a", "d"), ("b", "d"), ("b", "e"), "c"])
592595

593-
with tm.assert_produces_warning(FutureWarning, match=msg):
596+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
594597
expected = df3.groupby([("b", "d")]).groups
595598
result = df.groupby(("b", 1)).groups
596599
tm.assert_dict_equal(expected, result)
@@ -623,7 +626,7 @@ def test_groupby_multiindex_partial_indexing_equivalence(self):
623626
tm.assert_frame_equal(expected_max, result_max)
624627

625628
msg = "`groups` by one element list returns scalar is deprecated"
626-
with tm.assert_produces_warning(FutureWarning, match=msg):
629+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
627630
expected_groups = df.groupby([("a", 1)])[[("b", 1), ("b", 2)]].groups
628631
result_groups = df.groupby([("a", 1)])["b"].groups
629632
tm.assert_dict_equal(expected_groups, result_groups)
@@ -737,7 +740,7 @@ def test_list_grouper_with_nat(self):
737740
# Grouper in a list grouping
738741
gb = df.groupby([grouper])
739742
expected = {Timestamp("2011-01-01"): Index(list(range(364)))}
740-
with tm.assert_produces_warning(FutureWarning, match=msg):
743+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
741744
result = gb.groups
742745
tm.assert_dict_equal(result, expected)
743746

@@ -1019,7 +1022,7 @@ def test_groups(self, df):
10191022
grouped = df.groupby(["A"])
10201023
msg = "`groups` by one element list returns scalar is deprecated"
10211024

1022-
with tm.assert_produces_warning(FutureWarning, match=msg):
1025+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
10231026
groups = grouped.groups
10241027
assert groups is grouped.groups # caching works
10251028

scripts/validate_unwanted_patterns.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,15 @@ def doesnt_use_pandas_warnings(file_obj: IO[str]) -> Iterable[tuple[int, str]]:
371371
if not isinstance(node, ast.Call):
372372
continue
373373

374-
if isinstance(node.func, ast.Attribute):
375-
if node.func.attr != "warn":
374+
if (
375+
isinstance(node.func, ast.Attribute)
376+
and isinstance(node.func.value, ast.Name)
377+
):
378+
# Check for `warnings.warn`.
379+
if node.func.value.id != "warnings" or node.func.attr != "warn":
376380
continue
377381
elif isinstance(node.func, ast.Name):
382+
# Check for just `warn` when using `from warnings import warn`.
378383
if node.func.id != "warn":
379384
continue
380385
if any(

0 commit comments

Comments
 (0)