From 5739cf9f31ef86832fe9bace722200c5d5b1748d Mon Sep 17 00:00:00 2001 From: Christopher Krah Date: Sun, 4 Oct 2026 01:03:47 +0000 Subject: [PATCH] Reject repeated histogram bucket bounds _prepare_buckets accepted any non-decreasing list, so buckets=[0.1, 0.5, 0.5, 1.0] exposed two series with le="0.5" and a NaN bound passed too. Require strictly increasing bounds, as client_golang does. Signed-off-by: Christopher Krah --- prometheus_client/metrics.py | 4 ++-- tests/test_core.py | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/prometheus_client/metrics.py b/prometheus_client/metrics.py index e3fe5323..a48e8199 100644 --- a/prometheus_client/metrics.py +++ b/prometheus_client/metrics.py @@ -639,10 +639,10 @@ def __init__(self, def _prepare_buckets(self, source_buckets: Sequence[Union[float, str]]) -> None: buckets = [float(b) for b in source_buckets] - if buckets != sorted(buckets): + if any(not lower < upper for lower, upper in zip(buckets, buckets[1:])): # This is probably an error on the part of the user, # so raise rather than sorting for them. - raise ValueError('Buckets not in sorted order') + raise ValueError('Buckets not in strictly increasing order') if buckets and buckets[-1] != INF: buckets.append(INF) if len(buckets) < 2: diff --git a/tests/test_core.py b/tests/test_core.py index 3aa19c24..3a97c3ea 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -458,6 +458,10 @@ def test_setting_buckets(self): self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[]) self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[float("inf")]) self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[3, 1]) + self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[1, 1, 2]) + self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[1, '1.0']) + self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[1, float("inf"), float("inf")]) + self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, buckets=[1, float("nan")]) def test_labels(self): self.assertRaises(ValueError, Histogram, 'h', 'help', registry=None, labelnames=['le'])