diff --git a/prometheus_client/registry.py b/prometheus_client/registry.py index d4cfc273..63f8ab03 100644 --- a/prometheus_client/registry.py +++ b/prometheus_client/registry.py @@ -61,6 +61,8 @@ def unregister(self, collector: Collector) -> None: for name in self._collector_to_names[collector]: del self._names_to_collectors[name] del self._collector_to_names[collector] + if collector in self._collectors_without_names: + self._collectors_without_names.remove(collector) def _get_names(self, collector): """Get names of timeseries the collector produces and clashes with.""" diff --git a/tests/test_core.py b/tests/test_core.py index f339b6df..b4d36d07 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -960,6 +960,21 @@ def test_unregister_works(self): registry.unregister(s) Gauge('s_count', 'help', registry=registry) + def test_unregister_removes_no_names_collector(self): + registry = CollectorRegistry(support_collectors_without_names=True) + + class NamelessCollector: + def collect(self): + return [GaugeMetricFamily('foo', 'help', value=42)] + + collector = NamelessCollector() + registry.register(collector) + registry.unregister(collector) + # A nameless collector must be removed from the collectors-without-names + # list too, otherwise a restricted registry keeps collecting it after it + # was unregistered. + self.assertEqual([], list(registry.restricted_registry(['foo']).collect())) + def custom_collector(self, metric_family, registry): class CustomCollector: def collect(self):