Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use importlib-metadata regardless of Python version #3217

Merged
merged 4 commits into from
Mar 16, 2023
Merged
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
4 changes: 3 additions & 1 deletion opentelemetry-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ classifiers = [
dependencies = [
"Deprecated >= 1.2.6",
"setuptools >= 16.0",
"importlib-metadata >= 5.0.0; python_version=='3.7'"
# FIXME This should be able to be removed after 3.12 is released if there is a reliable API
# in importlib.metadata.
"importlib-metadata ~= 6.0.0",
]
dynamic = [
"version",
Expand Down
35 changes: 13 additions & 22 deletions opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from sys import version_info
# FIXME: Use importlib.metadata when support for 3.11 is dropped if the rest of
# the supported versions at that time have the same API.
from importlib_metadata import ( # type: ignore
ocelotl marked this conversation as resolved.
Show resolved Hide resolved
EntryPoint,
EntryPoints,
entry_points,
version,
)

# FIXME remove this when support for 3.7 is dropped.
if version_info.minor == 7:
# pylint: disable=import-error
from importlib_metadata import entry_points, version # type: ignore
# The importlib-metadata library has introduced breaking changes before to its
# API, this module is kept just to act as a layer between the
# importlib-metadata library and our project if in any case it is necessary to
# do so.

# FIXME remove this file when support for 3.9 is dropped.
elif version_info.minor in (8, 9):
# pylint: disable=import-error
from importlib.metadata import (
entry_points as importlib_metadata_entry_points,
)
from importlib.metadata import version

def entry_points(group: str, name: str): # type: ignore
for entry_point in importlib_metadata_entry_points()[group]:
if entry_point.name == name:
yield entry_point

else:
from importlib.metadata import entry_points, version

__all__ = ["entry_points", "version"]
__all__ = ["entry_points", "version", "EntryPoint", "EntryPoints"]
78 changes: 76 additions & 2 deletions opentelemetry-api/tests/util/test__importlib_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
from unittest import TestCase

from opentelemetry.metrics import MeterProvider
from opentelemetry.util._importlib_metadata import entry_points
from opentelemetry.util._importlib_metadata import EntryPoint, EntryPoints
from opentelemetry.util._importlib_metadata import (
entry_points as importlib_metadata_entry_points,
)


class TestEntryPoints(TestCase):
Expand All @@ -24,11 +27,82 @@ def test_entry_points(self):
self.assertIsInstance(
next(
iter(
entry_points(
importlib_metadata_entry_points(
group="opentelemetry_meter_provider",
name="default_meter_provider",
)
)
).load()(),
MeterProvider,
)

def test_uniform_behavior(self):
"""
Test that entry_points behaves the same regardless of the Python
version.
"""

entry_points = importlib_metadata_entry_points()

self.assertIsInstance(entry_points, EntryPoints)

entry_points = entry_points.select(group="opentelemetry_propagator")
self.assertIsInstance(entry_points, EntryPoints)

entry_points = entry_points.select(name="baggage")
self.assertIsInstance(entry_points, EntryPoints)

entry_point = next(iter(entry_points))
self.assertIsInstance(entry_point, EntryPoint)

self.assertEqual(entry_point.name, "baggage")
self.assertEqual(entry_point.group, "opentelemetry_propagator")
self.assertEqual(
entry_point.value,
"opentelemetry.baggage.propagation:W3CBaggagePropagator",
)

entry_points = importlib_metadata_entry_points(
group="opentelemetry_propagator"
)
self.assertIsInstance(entry_points, EntryPoints)

entry_points = entry_points.select(name="baggage")
self.assertIsInstance(entry_points, EntryPoints)

entry_point = next(iter(entry_points))
self.assertIsInstance(entry_point, EntryPoint)

self.assertEqual(entry_point.name, "baggage")
self.assertEqual(entry_point.group, "opentelemetry_propagator")
self.assertEqual(
entry_point.value,
"opentelemetry.baggage.propagation:W3CBaggagePropagator",
)

entry_points = importlib_metadata_entry_points(name="baggage")
self.assertIsInstance(entry_points, EntryPoints)

entry_point = next(iter(entry_points))
self.assertIsInstance(entry_point, EntryPoint)

self.assertEqual(entry_point.name, "baggage")
self.assertEqual(entry_point.group, "opentelemetry_propagator")
self.assertEqual(
entry_point.value,
"opentelemetry.baggage.propagation:W3CBaggagePropagator",
)

entry_points = importlib_metadata_entry_points(group="abc")
self.assertIsInstance(entry_points, EntryPoints)
self.assertEqual(len(entry_points), 0)

entry_points = importlib_metadata_entry_points(
group="opentelemetry_propagator", name="abc"
)
self.assertIsInstance(entry_points, EntryPoints)
self.assertEqual(len(entry_points), 0)

entry_points = importlib_metadata_entry_points(group="abc", name="abc")
self.assertIsInstance(entry_points, EntryPoints)
self.assertEqual(len(entry_points), 0)