Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/5250.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-api`: fix SelectableGroups deprecation warning
12 changes: 10 additions & 2 deletions opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- https://github.com/open-telemetry/opentelemetry-python/pull/5203
"""

import itertools
from functools import cache
from importlib.metadata import (
Distribution,
Expand All @@ -28,8 +29,15 @@
def _as_entry_points(eps: Any) -> EntryPoints:
if isinstance(eps, EntryPoints):
return eps
# Handle Python 3.10 SelectableGroups (dict-like)
return EntryPoints(ep for group_eps in eps.values() for ep in group_eps)
# Python 3.10 entry_points() returns a dict-like SelectableGroups object.
# Use dict.values() instead of eps.values() to avoid the DeprecationWarning
# that SelectableGroups raises when calling .values().
if isinstance(eps, dict):
return EntryPoints(itertools.chain.from_iterable(dict.values(eps)))
# Fallback for all other types
return EntryPoints(
ep for group in eps.groups for ep in eps.select(group=group)
)


@cache
Expand Down
26 changes: 26 additions & 0 deletions opentelemetry-api/tests/util/test__importlib_metadata.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

import unittest
import warnings
from unittest import TestCase

try:
# pylint: disable-next=no-name-in-module
from importlib.metadata import SelectableGroups as _SelectableGroups
except ImportError:
_SelectableGroups = None

from opentelemetry.metrics import MeterProvider
from opentelemetry.util._importlib_metadata import (
EntryPoint,
Expand Down Expand Up @@ -117,3 +125,21 @@ def test_as_entry_points_selectable_groups_compat(self):
self.assertIsInstance(normalized, EntryPoints)
self.assertEqual(len(normalized), 2)
self.assertEqual(list(normalized), [ep1, ep2])

@unittest.skipIf(
_SelectableGroups is None,
"SelectableGroups not available on this Python version",
)
def test_as_entry_points_selectable_groups_no_deprecation_warning(self):
ep1 = EntryPoint(name="foo", value="bar:baz", group="gp")
ep2 = EntryPoint(name="foo2", value="bar2:baz2", group="gp")

sg = _SelectableGroups({"gp": [ep1, ep2]}) # type: ignore

with warnings.catch_warnings():
warnings.simplefilter("error")
normalized = _as_entry_points(sg)

self.assertIsInstance(normalized, EntryPoints)
self.assertEqual(len(normalized), 2)
self.assertEqual(list(normalized), [ep1, ep2])
Loading