From 4184448731c15f9eaffa5fb05035f1487f383708 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 14 Mar 2023 11:36:09 -0600 Subject: [PATCH 1/4] Use importlib-metadata regardless of Python version Fixes #3167 --- opentelemetry-api/pyproject.toml | 2 +- .../src/opentelemetry/propagate/__init__.py | 2 +- .../opentelemetry/util/_importlib_metadata.py | 33 +++----- .../tests/util/test__importlib_metadata.py | 78 ++++++++++++++++++- 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/opentelemetry-api/pyproject.toml b/opentelemetry-api/pyproject.toml index e9490ab1d20..2afa6e1a260 100644 --- a/opentelemetry-api/pyproject.toml +++ b/opentelemetry-api/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ dependencies = [ "Deprecated >= 1.2.6", "setuptools >= 16.0", - "importlib-metadata >= 5.0.0; python_version=='3.7'" + "importlib-metadata >= 5.0.0", ] dynamic = [ "version", diff --git a/opentelemetry-api/src/opentelemetry/propagate/__init__.py b/opentelemetry-api/src/opentelemetry/propagate/__init__.py index 56f217f282d..07577ccf5dd 100644 --- a/opentelemetry-api/src/opentelemetry/propagate/__init__.py +++ b/opentelemetry-api/src/opentelemetry/propagate/__init__.py @@ -137,7 +137,7 @@ def inject( propagators.append( # type: ignore next( # type: ignore iter( # type: ignore - entry_points( # type: ignore + entry_points( # type: ignore group="opentelemetry_propagator", name=propagator, ) diff --git a/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py b/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py index 889c4cf1ac2..ae591259e2b 100644 --- a/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py +++ b/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py @@ -12,27 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from sys import version_info +from importlib_metadata import ( # type: ignore + 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"] diff --git a/opentelemetry-api/tests/util/test__importlib_metadata.py b/opentelemetry-api/tests/util/test__importlib_metadata.py index 7ca58881b8e..92a4e7dd62a 100644 --- a/opentelemetry-api/tests/util/test__importlib_metadata.py +++ b/opentelemetry-api/tests/util/test__importlib_metadata.py @@ -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): @@ -24,7 +27,7 @@ def test_entry_points(self): self.assertIsInstance( next( iter( - entry_points( + importlib_metadata_entry_points( group="opentelemetry_meter_provider", name="default_meter_provider", ) @@ -32,3 +35,74 @@ def test_entry_points(self): ).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) From 0baf52a8f99f3f2a678edd273fb795318ca8221d Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 14 Mar 2023 21:05:29 -0600 Subject: [PATCH 2/4] Fix lint --- opentelemetry-api/src/opentelemetry/propagate/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/propagate/__init__.py b/opentelemetry-api/src/opentelemetry/propagate/__init__.py index 07577ccf5dd..56f217f282d 100644 --- a/opentelemetry-api/src/opentelemetry/propagate/__init__.py +++ b/opentelemetry-api/src/opentelemetry/propagate/__init__.py @@ -137,7 +137,7 @@ def inject( propagators.append( # type: ignore next( # type: ignore iter( # type: ignore - entry_points( # type: ignore + entry_points( # type: ignore group="opentelemetry_propagator", name=propagator, ) From 6cec963e4104469fad2394d25ddfdeb4d45f6e6f Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 16 Mar 2023 12:48:14 -0600 Subject: [PATCH 3/4] Add FIXME comment --- opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py b/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py index ae591259e2b..cbf09f3ef8c 100644 --- a/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py +++ b/opentelemetry-api/src/opentelemetry/util/_importlib_metadata.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# 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 EntryPoint, EntryPoints, From 03e4b461b526beec59d248c9111aea815140c43a Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 16 Mar 2023 12:56:56 -0600 Subject: [PATCH 4/4] Constraint importlib-metadata versions --- opentelemetry-api/pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/pyproject.toml b/opentelemetry-api/pyproject.toml index 2afa6e1a260..5b2ac54af1f 100644 --- a/opentelemetry-api/pyproject.toml +++ b/opentelemetry-api/pyproject.toml @@ -27,7 +27,9 @@ classifiers = [ dependencies = [ "Deprecated >= 1.2.6", "setuptools >= 16.0", - "importlib-metadata >= 5.0.0", + # 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",