Skip to content

Commit 20c7ecb

Browse files
committed
gh-149259: Fix median_grouped() exception chaining and error messages
Split the single try/except block into two, add `from exc` chaining so the original ValueError is visible in tracebacks, and improve the error messages to identify whether `interval` or the data value failed the float conversion.
1 parent f2c7c0d commit 20c7ecb

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

Lib/statistics.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,16 @@ def median_grouped(data, interval=1.0):
453453
# Coerce to floats, raising a TypeError if not possible
454454
try:
455455
interval = float(interval)
456+
except ValueError as exc:
457+
raise TypeError(
458+
f'interval must be a real number, got {interval!r}'
459+
) from exc
460+
try:
456461
x = float(x)
457-
except ValueError:
458-
raise TypeError(f'Value cannot be converted to a float')
462+
except ValueError as exc:
463+
raise TypeError(
464+
f'data sequence must contain real numbers, found {x!r}'
465+
) from exc
459466

460467
# Interpolate the median using the formula found at:
461468
# https://www.cuemath.com/data/median-of-grouped-data/

Lib/test/test_statistics.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,25 @@ def test_data_type_error(self):
17991799
interval = b""
18001800
self.assertRaises(TypeError, self.func, data, interval)
18011801

1802+
def test_exception_chaining_and_messages(self):
1803+
# TypeError raised for bad interval should chain the original ValueError
1804+
# and identify the problematic parameter.
1805+
data = [1, 2, 3]
1806+
with self.assertRaises(TypeError) as cm:
1807+
self.func(data, interval="bad")
1808+
exc = cm.exception
1809+
self.assertIsInstance(exc.__cause__, ValueError)
1810+
self.assertIn("interval", str(exc))
1811+
1812+
# TypeError raised for non-numeric data should chain the original ValueError
1813+
# and identify that the data is the problem.
1814+
data = ["a", "b", "c"]
1815+
with self.assertRaises(TypeError) as cm:
1816+
self.func(data)
1817+
exc = cm.exception
1818+
self.assertIsInstance(exc.__cause__, ValueError)
1819+
self.assertIn("data", str(exc))
1820+
18021821

18031822
class TestMode(NumericTestCase, AverageMixin, UnivariateTypeMixin):
18041823
# Test cases for the discrete version of mode.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :func:`statistics.median_grouped` to chain the original :exc:`ValueError`
2+
when coercing *interval* or the median data value to ``float`` fails, and
3+
improve the error message to identify which parameter caused the failure.

0 commit comments

Comments
 (0)