From 6b45703e9d17b6f5b6d2122501ea7ae1fcd3e688 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Fri, 14 Nov 2025 20:14:13 -0800 Subject: [PATCH] gh-140938: Raise ValueError for infinite inputs to stdev/pstdev (GH-141531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raise ValueError for infinite inputs to stdev/pstdev --- Co-authored-by: Raymond Hettinger Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> (cherry picked from commit f0a8bc737ab2f04d4196eee154cb1e17e26ad585) --- Lib/statistics.py | 18 ++++++++++++++---- Lib/test/test_statistics.py | 16 ++++++++++++++++ ...5-11-13-14-51-30.gh-issue-140938.kXsHHv.rst | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-11-13-14-51-30.gh-issue-140938.kXsHHv.rst diff --git a/Lib/statistics.py b/Lib/statistics.py index ad4a94219cf38c..c71e83aa7887d3 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -1206,9 +1206,14 @@ def stdev(data, xbar=None): if n < 2: raise StatisticsError('stdev requires at least two data points') mss = ss / (n - 1) + try: + mss_numerator = mss.numerator + mss_denominator = mss.denominator + except AttributeError: + raise ValueError('inf or nan encountered in data') if issubclass(T, Decimal): - return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) - return _float_sqrt_of_frac(mss.numerator, mss.denominator) + return _decimal_sqrt_of_frac(mss_numerator, mss_denominator) + return _float_sqrt_of_frac(mss_numerator, mss_denominator) def pstdev(data, mu=None): @@ -1224,9 +1229,14 @@ def pstdev(data, mu=None): if n < 1: raise StatisticsError('pstdev requires at least one data point') mss = ss / n + try: + mss_numerator = mss.numerator + mss_denominator = mss.denominator + except AttributeError: + raise ValueError('inf or nan encountered in data') if issubclass(T, Decimal): - return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) - return _float_sqrt_of_frac(mss.numerator, mss.denominator) + return _decimal_sqrt_of_frac(mss_numerator, mss_denominator) + return _float_sqrt_of_frac(mss_numerator, mss_denominator) def _mean_stdev(data): diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 40599c776a6a80..f51512bf419270 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -2122,6 +2122,14 @@ def test_center_not_at_mean(self): self.assertEqual(self.func(data), 2.5) self.assertEqual(self.func(data, mu=0.5), 6.5) + def test_gh_140938(self): + # Inputs with inf/nan should raise a ValueError + with self.assertRaises(ValueError): + self.func([1.0, math.inf]) + with self.assertRaises(ValueError): + self.func([1.0, math.nan]) + + class TestSqrtHelpers(unittest.TestCase): def test_integer_sqrt_of_frac_rto(self): @@ -2240,6 +2248,14 @@ def test_center_not_at_mean(self): data = (1.0, 2.0) self.assertEqual(self.func(data, xbar=2.0), 1.0) + def test_gh_140938(self): + # Inputs with inf/nan should raise a ValueError + with self.assertRaises(ValueError): + self.func([1.0, math.inf]) + with self.assertRaises(ValueError): + self.func([1.0, math.nan]) + + class TestGeometricMean(unittest.TestCase): def test_basics(self): diff --git a/Misc/NEWS.d/next/Library/2025-11-13-14-51-30.gh-issue-140938.kXsHHv.rst b/Misc/NEWS.d/next/Library/2025-11-13-14-51-30.gh-issue-140938.kXsHHv.rst new file mode 100644 index 00000000000000..bd3044002a2d54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-11-13-14-51-30.gh-issue-140938.kXsHHv.rst @@ -0,0 +1,2 @@ +The :func:`statistics.stdev` and :func:`statistics.pstdev` functions now raise a +:exc:`ValueError` when the input contains an infinity or a NaN.