Skip to content

Commit 9f47591

Browse files
committed
Pass through user warnings, update whatsnew
1 parent 816db57 commit 9f47591

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

doc/source/whatsnew/v1.4.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ Other Deprecations
337337
- Deprecated the ``squeeze`` argument to :meth:`read_csv`, :meth:`read_table`, and :meth:`read_excel`. Users should squeeze the DataFrame afterwards with ``.squeeze("columns")`` instead. (:issue:`43242`)
338338
- Deprecated the ``index`` argument to :class:`SparseArray` construction (:issue:`23089`)
339339
- Deprecated :meth:`.Rolling.validate`, :meth:`.Expanding.validate`, and :meth:`.ExponentialMovingWindow.validate` (:issue:`43665`)
340-
- Deprecated silent dropping of columns that raised a ``TypeError``, ``DataError``, or some cases of ``ValueError`` in :class:`Series.aggregate` and :class:`DataFrame.aggregate` when used with a list (:issue:`43740`)
340+
- Deprecated silent dropping of columns that raised a ``TypeError``, ``DataError``, and some cases of ``ValueError`` in :meth:`Series.aggregate`, :meth:`DataFrame.aggregate`, :meth:`Series.groupby.aggregate`, and :meth:`DataFrame.groupby.aggregate` when used with a list (:issue:`43740`)
341341

342342
.. ---------------------------------------------------------------------------
343343

pandas/core/apply.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from collections import defaultdict
55
from functools import partial
66
import inspect
7+
import re
78
from typing import (
89
TYPE_CHECKING,
910
Any,
@@ -338,6 +339,12 @@ def agg_list_like(self) -> DataFrame | Series:
338339
keys = []
339340
failed_names = []
340341

342+
depr_nuisance_columns_msg = (
343+
"{} did not aggregate successfully. If any error is "
344+
"raised this will raise in a future version of pandas. "
345+
"Drop these columns/ops to avoid this warning."
346+
)
347+
341348
# degenerate case
342349
if selected_obj.ndim == 1:
343350
for a in arg:
@@ -360,10 +367,24 @@ def agg_list_like(self) -> DataFrame | Series:
360367
for index, col in enumerate(selected_obj):
361368
colg = obj._gotitem(col, ndim=1, subset=selected_obj.iloc[:, index])
362369
try:
363-
with warnings.catch_warnings(record=True) as w:
370+
# Capture and suppress any warnings emitted by us in the call
371+
# to agg below, but pass through any warnings that were
372+
# generated otherwise.
373+
with warnings.catch_warnings(record=True) as record:
364374
new_res = colg.aggregate(arg)
365-
if len(w) > 0:
366-
failed_names.append(col)
375+
if len(record) > 0:
376+
match = re.compile(depr_nuisance_columns_msg.format(".*"))
377+
for warning in record:
378+
if re.match(match, str(warning.message)):
379+
failed_names.append(col)
380+
else:
381+
warnings.warn_explicit(
382+
message=warning.message,
383+
category=warning.category,
384+
filename=warning.filename,
385+
lineno=warning.lineno,
386+
)
387+
367388
except (TypeError, DataError):
368389
failed_names.append(col)
369390
except ValueError as err:
@@ -391,9 +412,7 @@ def agg_list_like(self) -> DataFrame | Series:
391412

392413
if len(failed_names) > 0:
393414
warnings.warn(
394-
f"{failed_names} did not aggregate successfully. If any error is "
395-
f"raised this will raise in a future version of pandas. "
396-
f"Drop these columns/ops to avoid this warning.",
415+
depr_nuisance_columns_msg.format(failed_names),
397416
FutureWarning,
398417
stacklevel=find_stack_level(),
399418
)

pandas/tests/apply/test_frame_apply.py

+17
Original file line numberDiff line numberDiff line change
@@ -1462,3 +1462,20 @@ def test_apply_getitem_axis_1():
14621462
result = df[["a", "a"]].apply(lambda x: x[0] + x[1], axis=1)
14631463
expected = Series([0, 2, 4])
14641464
tm.assert_series_equal(result, expected)
1465+
1466+
1467+
def test_nuisance_depr_passes_through_warnings():
1468+
# GH 43740
1469+
# DataFrame.agg with list-likes may emit warnings for both individual
1470+
# args and for entire columns, but we only want to emit once. We
1471+
# catch and suppress the warnings for individual args, but need to make
1472+
# sure if some other warnings were raised, they get passed through to
1473+
# the user.
1474+
1475+
def foo(x):
1476+
warnings.warn("Hello, World!")
1477+
return x.sum()
1478+
1479+
df = DataFrame({"a": [1, 2, 3]})
1480+
with tm.assert_produces_warning(UserWarning, match="Hello, World!"):
1481+
df.agg([foo])

0 commit comments

Comments
 (0)