Skip to content

Commit a730486

Browse files
authored
ENH: Allow performance warnings to be disabled (#56921)
* ENH: Allow performance warnings to be disabled * ENH: Allow performance warnings to be disabled * Add tests * fixup
1 parent 54d2033 commit a730486

39 files changed

+301
-217
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Other enhancements
3333
- :meth:`Styler.set_tooltips` provides alternative method to storing tooltips by using title attribute of td elements. (:issue:`56981`)
3434
- Allow dictionaries to be passed to :meth:`pandas.Series.str.replace` via ``pat`` parameter (:issue:`51748`)
3535
- Support passing a :class:`Series` input to :func:`json_normalize` that retains the :class:`Series` :class:`Index` (:issue:`51452`)
36+
- Users can globally disable any ``PerformanceWarning`` by setting the option ``mode.performance_warnings`` to ``False`` (:issue:`56920`)
3637
-
3738

3839
.. ---------------------------------------------------------------------------

pandas/conftest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,6 +1983,16 @@ def indexer_ial(request):
19831983
return request.param
19841984

19851985

1986+
@pytest.fixture(params=[True, False])
1987+
def performance_warning(request) -> Iterator[bool | type[Warning]]:
1988+
"""
1989+
Fixture to check if performance warnings are enabled. Either produces
1990+
``PerformanceWarning`` if they are enabled, otherwise ``False``.
1991+
"""
1992+
with pd.option_context("mode.performance_warnings", request.param):
1993+
yield pd.errors.PerformanceWarning if request.param else False
1994+
1995+
19861996
@pytest.fixture
19871997
def using_infer_string() -> bool:
19881998
"""

pandas/core/arrays/arrow/_arrow_utils.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import numpy as np
66
import pyarrow
77

8+
from pandas._config.config import _get_option
9+
810
from pandas.errors import PerformanceWarning
911
from pandas.util._exceptions import find_stack_level
1012

@@ -14,10 +16,11 @@ def fallback_performancewarning(version: str | None = None) -> None:
1416
Raise a PerformanceWarning for falling back to ExtensionArray's
1517
non-pyarrow method
1618
"""
17-
msg = "Falling back on a non-pyarrow code path which may decrease performance."
18-
if version is not None:
19-
msg += f" Upgrade to pyarrow >={version} to possibly suppress this warning."
20-
warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level())
19+
if _get_option("performance_warnings"):
20+
msg = "Falling back on a non-pyarrow code path which may decrease performance."
21+
if version is not None:
22+
msg += f" Upgrade to pyarrow >={version} to possibly suppress this warning."
23+
warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level())
2124

2225

2326
def pyarrow_array_to_numpy_and_mask(

pandas/core/arrays/datetimelike.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import numpy as np
2222

23+
from pandas._config.config import _get_option
24+
2325
from pandas._libs import (
2426
algos,
2527
lib,
@@ -1332,12 +1334,13 @@ def _addsub_object_array(self, other: npt.NDArray[np.object_], op) -> np.ndarray
13321334
# If both 1D then broadcasting is unambiguous
13331335
return op(self, other[0])
13341336

1335-
warnings.warn(
1336-
"Adding/subtracting object-dtype array to "
1337-
f"{type(self).__name__} not vectorized.",
1338-
PerformanceWarning,
1339-
stacklevel=find_stack_level(),
1340-
)
1337+
if _get_option("performance_warnings"):
1338+
warnings.warn(
1339+
"Adding/subtracting object-dtype array to "
1340+
f"{type(self).__name__} not vectorized.",
1341+
PerformanceWarning,
1342+
stacklevel=find_stack_level(),
1343+
)
13411344

13421345
# Caller is responsible for broadcasting if necessary
13431346
assert self.shape == other.shape, (self.shape, other.shape)

pandas/core/arrays/datetimes.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import numpy as np
1717

18+
from pandas._config.config import _get_option
19+
1820
from pandas._libs import (
1921
lib,
2022
tslib,
@@ -818,11 +820,13 @@ def _add_offset(self, offset: BaseOffset) -> Self:
818820
# "dtype[Any] | type[Any] | _SupportsDType[dtype[Any]]"
819821
res_values = res_values.view(values.dtype) # type: ignore[arg-type]
820822
except NotImplementedError:
821-
warnings.warn(
822-
"Non-vectorized DateOffset being applied to Series or DatetimeIndex.",
823-
PerformanceWarning,
824-
stacklevel=find_stack_level(),
825-
)
823+
if _get_option("performance_warnings"):
824+
warnings.warn(
825+
"Non-vectorized DateOffset being applied to Series or "
826+
"DatetimeIndex.",
827+
PerformanceWarning,
828+
stacklevel=find_stack_level(),
829+
)
826830
res_values = self.astype("O") + offset
827831
# TODO(GH#55564): as_unit will be unnecessary
828832
result = type(self)._from_sequence(res_values).as_unit(self.unit)

pandas/core/arrays/sparse/array.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import numpy as np
2020

21+
from pandas._config.config import _get_option
22+
2123
from pandas._libs import lib
2224
import pandas._libs.sparse as splib
2325
from pandas._libs.sparse import (
@@ -1154,8 +1156,9 @@ def searchsorted(
11541156
side: Literal["left", "right"] = "left",
11551157
sorter: NumpySorter | None = None,
11561158
) -> npt.NDArray[np.intp] | np.intp:
1157-
msg = "searchsorted requires high memory usage."
1158-
warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level())
1159+
if _get_option("performance_warnings"):
1160+
msg = "searchsorted requires high memory usage."
1161+
warnings.warn(msg, PerformanceWarning, stacklevel=find_stack_level())
11591162
v = np.asarray(v)
11601163
return np.asarray(self, dtype=self.dtype.subtype).searchsorted(v, side, sorter)
11611164

pandas/core/arrays/string_arrow.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import numpy as np
1414

15+
from pandas._config.config import _get_option
16+
1517
from pandas._libs import (
1618
lib,
1719
missing as libmissing,
@@ -343,7 +345,8 @@ def _str_contains(
343345
self, pat, case: bool = True, flags: int = 0, na=np.nan, regex: bool = True
344346
):
345347
if flags:
346-
fallback_performancewarning()
348+
if _get_option("mode.performance_warnings"):
349+
fallback_performancewarning()
347350
return super()._str_contains(pat, case, flags, na, regex)
348351

349352
if regex:
@@ -403,7 +406,8 @@ def _str_replace(
403406
regex: bool = True,
404407
):
405408
if isinstance(pat, re.Pattern) or callable(repl) or not case or flags:
406-
fallback_performancewarning()
409+
if _get_option("mode.performance_warnings"):
410+
fallback_performancewarning()
407411
return super()._str_replace(pat, repl, n, case, flags, regex)
408412

409413
func = pc.replace_substring_regex if regex else pc.replace_substring

pandas/core/computation/align.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import numpy as np
1717

18+
from pandas._config.config import _get_option
19+
1820
from pandas.errors import PerformanceWarning
1921
from pandas.util._exceptions import find_stack_level
2022

@@ -124,7 +126,11 @@ def _align_core(terms):
124126
reindexer_size = len(reindexer)
125127

126128
ordm = np.log10(max(1, abs(reindexer_size - term_axis_size)))
127-
if ordm >= 1 and reindexer_size >= 10000:
129+
if (
130+
_get_option("performance_warnings")
131+
and ordm >= 1
132+
and reindexer_size >= 10000
133+
):
128134
w = (
129135
f"Alignment difference on axis {axis} is larger "
130136
f"than an order of magnitude on term {terms[i].name!r}, "

pandas/core/config_init.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,19 @@ def is_terminal() -> bool:
444444
validator=is_one_of_factory([None, "warn", "raise"]),
445445
)
446446

447+
performance_warnings = """
448+
: boolean
449+
Whether to show or hide PerformanceWarnings.
450+
"""
451+
452+
with cf.config_prefix("mode"):
453+
cf.register_option(
454+
"performance_warnings",
455+
True,
456+
performance_warnings,
457+
validator=is_bool,
458+
)
459+
447460

448461
string_storage_doc = """
449462
: string

pandas/core/dtypes/dtypes.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import numpy as np
2222
import pytz
2323

24+
from pandas._config.config import _get_option
25+
2426
from pandas._libs import (
2527
lib,
2628
missing as libmissing,
@@ -2028,7 +2030,9 @@ def _get_common_dtype(self, dtypes: list[DtypeObj]) -> DtypeObj | None:
20282030

20292031
# np.nan isn't a singleton, so we may end up with multiple
20302032
# NaNs here, so we ignore the all NA case too.
2031-
if not (len(set(fill_values)) == 1 or isna(fill_values).all()):
2033+
if _get_option("performance_warnings") and (
2034+
not (len(set(fill_values)) == 1 or isna(fill_values).all())
2035+
):
20322036
warnings.warn(
20332037
"Concatenating sparse arrays with multiple fill "
20342038
f"values: '{fill_values}'. Picking the first and "

0 commit comments

Comments
 (0)