Remove pkg resources (#2871)

This commit is contained in:
Riccardo Magliocchetti
2024-10-19 15:49:08 +02:00
committed by GitHub
parent d7d7e96ce5
commit e4ece57a81
101 changed files with 247 additions and 262 deletions

View File

@ -25,12 +25,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `opentelemetry-instrumentation-aiokafka` Wrap `AIOKafkaConsumer.getone()` instead of `AIOKafkaConsumer.__anext__`
([#2874](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2874))
### Breaking changes
- Deprecation of pkg_resource in favor of importlib.metadata
([#2871](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2871))
## Version 1.27.0/0.48b0 (2024-08-28)
### Added
- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng
inside kafka-python's instrumentation
- `opentelemetry-instrumentation-kafka-python` Instrument temporary fork, kafka-python-ng inside kafka-python's instrumentation
([#2537](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2537))
- `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi` Add ability to disable internal HTTP send and receive spans
([#2802](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2802))

View File

@ -6,7 +6,6 @@ cramjam==2.1.0; platform_python_implementation == "PyPy"
cramjam==2.8.1; platform_python_implementation != "PyPy"
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
flaky==3.7.0
importlib-metadata==6.11.0
iniconfig==2.0.0
markdown-it-py==3.0.0
mdurl==0.1.2

View File

@ -3,7 +3,6 @@ aiormq==6.2.3
asgiref==3.8.1
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
multidict==6.0.5
packaging==24.0

View File

@ -3,7 +3,6 @@ aiormq==6.6.4
asgiref==3.8.1
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
multidict==6.0.5
packaging==24.0

View File

@ -3,7 +3,6 @@ aiormq==6.7.1
asgiref==3.8.1
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
multidict==6.0.5
packaging==24.0

View File

@ -3,7 +3,6 @@ aiormq==6.8.0
asgiref==3.8.1
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
multidict==6.0.5
packaging==24.0

View File

@ -11,7 +11,6 @@ Flask==3.0.2
frozenlist==1.4.1
http_server_mock==1.7
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.4

View File

@ -24,7 +24,6 @@ import aiohttp
import aiohttp.test_utils
import yarl
from http_server_mock import HttpServerMock
from pkg_resources import iter_entry_points
from opentelemetry import trace as trace_api
from opentelemetry.instrumentation import aiohttp_client
@ -47,6 +46,7 @@ from opentelemetry.semconv.attributes.url_attributes import URL_FULL
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.test.test_base import TestBase
from opentelemetry.trace import Span, StatusCode
from opentelemetry.util._importlib_metadata import entry_points
def run_with_test_server(
@ -886,9 +886,9 @@ class TestAioHttpClientInstrumentor(TestBase):
class TestLoadingAioHttpInstrumentor(unittest.TestCase):
def test_loading_instrumentor(self):
entry_points = iter_entry_points(
"opentelemetry_instrumentor", "aiohttp-client"
(entry_point,) = entry_points(
group="opentelemetry_instrumentor", name="aiohttp-client"
)
instrumentor = next(entry_points).load()()
instrumentor = entry_point.load()()
self.assertIsInstance(instrumentor, AioHttpClientInstrumentor)

View File

@ -5,7 +5,6 @@ async-timeout==4.0.3
Deprecated==1.2.14
frozenlist==1.4.1
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
multidict==6.0.5
packaging==24.0

View File

@ -2,7 +2,6 @@ aiopg==1.4.0
asgiref==3.8.1
async-timeout==4.0.3
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
async-timeout==4.0.3
asyncpg==0.29.0
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -9,7 +9,6 @@ cryptography==43.0.1
Deprecated==1.2.14
docker==7.0.0
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
Jinja2==3.1.4
jmespath==1.0.1

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
boto3==1.34.44
botocore==1.34.44
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
jmespath==1.0.1
packaging==24.0

View File

@ -9,7 +9,6 @@ cryptography==43.0.1
Deprecated==1.2.14
docker==7.0.0
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
Jinja2==3.1.4
jmespath==1.0.1

View File

@ -4,7 +4,6 @@ pyasyncore==1.0.4 # for python 3.13 (should removed when cassandra-driver repla
click==8.1.7
Deprecated==1.2.14
geomet==0.2.1.post1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -8,7 +8,6 @@ click-didyoumean==0.3.0
click-plugins==1.1.1
click-repl==0.3.0
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
kombu==5.3.5
packaging==24.0

View File

@ -7,7 +7,6 @@ click-didyoumean==0.3.0
click-plugins==1.1.1
click-repl==0.3.0
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
kombu==5.3.5
packaging==24.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
confluent-kafka==2.4.0
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
Django==2.2.28
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
Django==3.2.25
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
backports.zoneinfo==0.2.1
Deprecated==1.2.14
Django==4.2.15
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
Django==4.2.15
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
Deprecated==1.2.14
elasticsearch==6.8.2
elasticsearch-dsl==6.4.0
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
Deprecated==1.2.14
elasticsearch==7.17.9
elasticsearch-dsl==7.4.1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -3,7 +3,6 @@ Deprecated==1.2.14
elasticsearch==8.13.1
elasticsearch-dsl==8.13.1
elastic-transport==8.13.0
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
falcon==1.4.1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
falcon==2.0.0
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
falcon==3.1.1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -10,7 +10,6 @@ h11==0.14.0
httpcore==1.0.4
httpx==0.27.0
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -22,7 +22,6 @@ import fastapi
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
from pkg_resources import DistributionNotFound, iter_entry_points
import opentelemetry.instrumentation.fastapi as otel_fastapi
from opentelemetry import trace
@ -55,6 +54,10 @@ from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.test.globals_test import reset_trace_globals
from opentelemetry.test.test_base import TestBase
from opentelemetry.util._importlib_metadata import (
PackageNotFoundError,
entry_points,
)
from opentelemetry.util.http import (
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
@ -1028,16 +1031,24 @@ class TestFastAPIManualInstrumentationHooks(TestBaseManualFastAPI):
)
def get_distribution_with_fastapi(*args, **kwargs):
dist = args[0]
if dist == "fastapi~=0.58":
# Value does not matter. Only whether an exception is thrown
return None
raise DistributionNotFound()
def mock_version_with_fastapi(*args, **kwargs):
req_name = args[0]
if req_name == "fastapi":
# TODO: Value now matters
return "0.58"
raise PackageNotFoundError()
def get_distribution_without_fastapi(*args, **kwargs):
raise DistributionNotFound()
def mock_version_with_old_fastapi(*args, **kwargs):
req_name = args[0]
if req_name == "fastapi":
# TODO: Value now matters
return "0.57"
raise PackageNotFoundError()
def mock_version_without_fastapi(*args, **kwargs):
raise PackageNotFoundError()
class TestAutoInstrumentation(TestBaseAutoFastAPI):
@ -1048,43 +1059,37 @@ class TestAutoInstrumentation(TestBaseAutoFastAPI):
"""
def test_entry_point_exists(self):
eps = iter_entry_points("opentelemetry_instrumentor")
ep = next(eps)
self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi")
self.assertEqual(
ep.module_name, "opentelemetry.instrumentation.fastapi"
)
self.assertEqual(ep.attrs, ("FastAPIInstrumentor",))
(ep,) = entry_points(group="opentelemetry_instrumentor")
self.assertEqual(ep.name, "fastapi")
self.assertIsNone(next(eps, None))
@patch("opentelemetry.instrumentation.dependencies.get_distribution")
def test_instruments_with_fastapi_installed(self, mock_get_distribution):
mock_get_distribution.side_effect = get_distribution_with_fastapi
@patch("opentelemetry.instrumentation.dependencies.version")
def test_instruments_with_fastapi_installed(self, mock_version):
mock_version.side_effect = mock_version_with_fastapi
mock_distro = Mock()
_load_instrumentors(mock_distro)
mock_get_distribution.assert_called_once_with("fastapi~=0.58")
mock_version.assert_called_once_with("fastapi")
self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 1)
args = mock_distro.load_instrumentor.call_args.args
ep = args[0]
self.assertEqual(ep.dist.key, "opentelemetry-instrumentation-fastapi")
self.assertEqual(
ep.module_name, "opentelemetry.instrumentation.fastapi"
)
self.assertEqual(ep.attrs, ("FastAPIInstrumentor",))
(ep,) = mock_distro.load_instrumentor.call_args.args
self.assertEqual(ep.name, "fastapi")
@patch("opentelemetry.instrumentation.dependencies.get_distribution")
def test_instruments_without_fastapi_installed(
self, mock_get_distribution
):
mock_get_distribution.side_effect = get_distribution_without_fastapi
@patch("opentelemetry.instrumentation.dependencies.version")
def test_instruments_with_old_fastapi_installed(
self, mock_version
): # pylint: disable=no-self-use
mock_version.side_effect = mock_version_with_old_fastapi
mock_distro = Mock()
_load_instrumentors(mock_distro)
mock_get_distribution.assert_called_once_with("fastapi~=0.58")
with self.assertRaises(DistributionNotFound):
mock_get_distribution("fastapi~=0.58")
self.assertEqual(len(mock_distro.load_instrumentor.call_args_list), 0)
mock_version.assert_called_once_with("fastapi")
mock_distro.load_instrumentor.assert_not_called()
@patch("opentelemetry.instrumentation.dependencies.version")
def test_instruments_without_fastapi_installed(
self, mock_version
): # pylint: disable=no-self-use
mock_version.side_effect = mock_version_without_fastapi
mock_distro = Mock()
_load_instrumentors(mock_distro)
mock_version.assert_called_once_with("fastapi")
mock_distro.load_instrumentor.assert_not_called()
def _create_app(self):

View File

@ -31,7 +31,6 @@ dependencies = [
"opentelemetry-semantic-conventions == 0.49b0.dev",
"opentelemetry-util-http == 0.49b0.dev",
"packaging >= 21.0",
"importlib-metadata >= 4.0",
]
[project.optional-dependencies]

View File

@ -245,7 +245,6 @@ from timeit import default_timer
from typing import Collection
import flask
import importlib_metadata as metadata
from packaging import version as package_version
import opentelemetry.instrumentation.wsgi as otel_wsgi
@ -272,6 +271,7 @@ from opentelemetry.semconv.metrics.http_metrics import (
HTTP_SERVER_REQUEST_DURATION,
)
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.util._importlib_metadata import version
from opentelemetry.util.http import (
get_excluded_urls,
parse_excluded_urls,
@ -288,7 +288,7 @@ _ENVIRON_TOKEN = "opentelemetry-flask.token"
_excluded_urls_from_env = get_excluded_urls("FLASK")
flask_version = metadata.version("flask")
flask_version = version("flask")
if package_version.parse(flask_version) >= package_version.parse("2.2.0"):

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
click==8.1.7
Deprecated==1.2.14
Flask==2.1.3
importlib-metadata==6.11.0
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.4

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
click==8.1.7
Deprecated==1.2.14
Flask==2.2.0
importlib-metadata==6.11.0
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.4

View File

@ -3,7 +3,6 @@ blinker==1.7.0
click==8.1.7
Deprecated==1.2.14
Flask==3.0.2
importlib-metadata==6.11.0
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.4

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
grpcio==1.62.0
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
grpcio==1.63.0
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -7,7 +7,6 @@ h11==0.12.0
httpcore==0.13.7
httpx==0.18.2
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -7,7 +7,6 @@ h11==0.14.0
httpcore==1.0.4
httpx==0.27.0
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
Jinja2==3.1.4
MarkupSafe==2.0.1

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
kafka-python-ng==2.2.2
packaging==24.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
kafka-python==2.0.2
packaging==24.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
mysql-connector-python==8.3.0
packaging==24.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
mysql-connector-python==9.0.0
packaging==24.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
mysqlclient==2.2.4
packaging==24.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pika==0.13.1

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pika==1.3.2

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
backports.zoneinfo==0.2.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
dnspython==2.6.1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
hupper==1.12.1
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
PasteDeploy==3.1.0

View File

@ -2,7 +2,6 @@ asgiref==3.8.1
async-timeout==4.0.3
Deprecated==1.2.14
fakeredis==2.23.3
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -4,7 +4,6 @@ charset-normalizer==3.3.2
Deprecated==1.2.14
httpretty==1.1.4
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
cffi==1.17.0
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -2,7 +2,6 @@ aiosqlite==0.20.0
asgiref==3.8.1
Deprecated==1.2.14
greenlet==3.0.3
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -8,7 +8,6 @@ h11==0.14.0
httpcore==1.0.4
httpx==0.27.0
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,23 +0,0 @@
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pkg_resources
# IMPORTANT: Only the TEst module needs this because it is always the first
# package that uses the `{rootdir}/*/tests/` path and gets installed by
# `eachdist.py` and according to `eachdist.ini`.
# Naming the tests module as a namespace package ensures that
# relative imports will resolve properly for subsequent test packages,
# as it enables searching for a composite of multiple test modules.
pkg_resources.declare_namespace(__name__)

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -7,7 +7,6 @@ Deprecated==1.2.14
Flask==3.0.2
http_server_mock==1.7
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.4

View File

@ -2,7 +2,6 @@ aiosqlite==0.17.0
annotated-types==0.7.0
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
iso8601==1.1.0
packaging==24.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
httpretty==1.1.4
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
httpretty==1.1.4
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,7 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
httpretty==1.1.4
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,23 +0,0 @@
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pkg_resources
# IMPORTANT: Only the wsgi module needs this because it is always the first
# package that uses the `{rootdir}/*/tests/` path and gets installed by
# `eachdist.py` and according to `eachdist.ini`.
# Naming the tests module as a namespace package ensures that
# relative imports will resolve properly for subsequent test packages,
# as it enables searching for a composite of multiple test modules.
pkg_resources.declare_namespace(__name__)

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -16,21 +16,23 @@
import os
from unittest import TestCase, mock
from pkg_resources import DistributionNotFound, require
from opentelemetry.distro import OpenTelemetryDistro
from opentelemetry.environment_variables import (
OTEL_METRICS_EXPORTER,
OTEL_TRACES_EXPORTER,
)
from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_PROTOCOL
from opentelemetry.util._importlib_metadata import (
PackageNotFoundError,
version,
)
class TestDistribution(TestCase):
def test_package_available(self):
try:
require(["opentelemetry-distro"])
except DistributionNotFound:
version("opentelemetry-distro")
except PackageNotFoundError:
self.fail("opentelemetry-distro not installed")
@mock.patch.dict("os.environ", {}, clear=True)

View File

@ -27,8 +27,8 @@ classifiers = [
dependencies = [
"opentelemetry-api ~= 1.4",
"opentelemetry-semantic-conventions >= 0.48b0",
"setuptools >= 16.0",
"wrapt >= 1.0.0, < 2.0.0",
"packaging >= 18.0",
]
[project.scripts]

View File

@ -19,9 +19,8 @@ from os.path import abspath, dirname, pathsep
from re import sub
from shutil import which
from pkg_resources import iter_entry_points
from opentelemetry.instrumentation.version import __version__
from opentelemetry.util._importlib_metadata import entry_points
_logger = getLogger(__name__)
@ -48,8 +47,8 @@ def run() -> None:
argument_otel_environment_variable = {}
for entry_point in iter_entry_points(
"opentelemetry_environment_variables"
for entry_point in entry_points(
group="opentelemetry_environment_variables"
):
environment_variable_module = entry_point.load()

View File

@ -12,11 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
from logging import getLogger
from os import environ
from pkg_resources import iter_entry_points
from opentelemetry.instrumentation.dependencies import (
get_dist_dependency_conflicts,
)
@ -27,13 +26,39 @@ from opentelemetry.instrumentation.environment_variables import (
OTEL_PYTHON_DISTRO,
)
from opentelemetry.instrumentation.version import __version__
from opentelemetry.util._importlib_metadata import (
EntryPoint,
distributions,
entry_points,
)
_logger = getLogger(__name__)
class _EntryPointDistFinder:
@cached_property
def _mapping(self):
return {
self._key_for(ep): dist
for dist in distributions()
for ep in dist.entry_points
}
def dist_for(self, entry_point: EntryPoint):
dist = getattr(entry_point, "dist", None)
if dist:
return dist
return self._mapping.get(self._key_for(entry_point))
@staticmethod
def _key_for(entry_point: EntryPoint):
return f"{entry_point.group}:{entry_point.name}:{entry_point.value}"
def _load_distro() -> BaseDistro:
distro_name = environ.get(OTEL_PYTHON_DISTRO, None)
for entry_point in iter_entry_points("opentelemetry_distro"):
for entry_point in entry_points(group="opentelemetry_distro"):
try:
# If no distro is specified, use first to come up.
if distro_name is None or distro_name == entry_point.name:
@ -58,15 +83,16 @@ def _load_distro() -> BaseDistro:
def _load_instrumentors(distro):
package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])
entry_point_finder = _EntryPointDistFinder()
if isinstance(package_to_exclude, str):
package_to_exclude = package_to_exclude.split(",")
# to handle users entering "requests , flask" or "requests, flask" with spaces
package_to_exclude = [x.strip() for x in package_to_exclude]
for entry_point in iter_entry_points("opentelemetry_pre_instrument"):
for entry_point in entry_points(group="opentelemetry_pre_instrument"):
entry_point.load()()
for entry_point in iter_entry_points("opentelemetry_instrumentor"):
for entry_point in entry_points(group="opentelemetry_instrumentor"):
if entry_point.name in package_to_exclude:
_logger.debug(
"Instrumentation skipped for library %s", entry_point.name
@ -74,7 +100,8 @@ def _load_instrumentors(distro):
continue
try:
conflict = get_dist_dependency_conflicts(entry_point.dist)
entry_point_dist = entry_point_finder.dist_for(entry_point)
conflict = get_dist_dependency_conflicts(entry_point_dist)
if conflict:
_logger.debug(
"Skipping instrumentation %s: %s",
@ -90,14 +117,14 @@ def _load_instrumentors(distro):
_logger.exception("Instrumenting of %s failed", entry_point.name)
raise exc
for entry_point in iter_entry_points("opentelemetry_post_instrument"):
for entry_point in entry_points(group="opentelemetry_post_instrument"):
entry_point.load()()
def _load_configurators():
configurator_name = environ.get(OTEL_PYTHON_CONFIGURATOR, None)
configured = None
for entry_point in iter_entry_points("opentelemetry_configurator"):
for entry_point in entry_points(group="opentelemetry_configurator"):
if configured is not None:
_logger.warning(
"Configuration of %s not loaded, %s already loaded",

View File

@ -23,13 +23,17 @@ from subprocess import (
check_call,
)
import pkg_resources
from packaging.requirements import Requirement
from opentelemetry.instrumentation.bootstrap_gen import (
default_instrumentations,
libraries,
)
from opentelemetry.instrumentation.version import __version__
from opentelemetry.util._importlib_metadata import (
PackageNotFoundError,
version,
)
logger = logging.getLogger(__name__)
@ -91,18 +95,19 @@ def _pip_check():
def _is_installed(req):
if req in sys.modules:
return True
req = Requirement(req)
try:
pkg_resources.get_distribution(req)
except pkg_resources.DistributionNotFound:
dist_version = version(req.name)
except PackageNotFoundError:
return False
except pkg_resources.VersionConflict as exc:
if not req.specifier.filter(dist_version):
logger.warning(
"instrumentation for package %s is available but version %s is installed. Skipping.",
exc.req,
exc.dist.as_requirement(), # pylint: disable=no-member
"instrumentation for package %s is available"
" but version %s is installed. Skipping.",
req,
dist_version,
)
return False
return True

View File

@ -1,12 +1,26 @@
from logging import getLogger
from typing import Collection, Optional
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from pkg_resources import (
from logging import getLogger
from typing import Collection, Optional, Union
from packaging.requirements import InvalidRequirement, Requirement
from opentelemetry.util._importlib_metadata import (
Distribution,
DistributionNotFound,
RequirementParseError,
VersionConflict,
get_distribution,
PackageNotFoundError,
version,
)
logger = getLogger(__name__)
@ -27,36 +41,43 @@ class DependencyConflict:
def get_dist_dependency_conflicts(
dist: Distribution,
) -> Optional[DependencyConflict]:
main_deps = dist.requires()
instrumentation_deps = []
for dep in dist.requires(("instruments",)):
if dep not in main_deps:
# we set marker to none so string representation of the dependency looks like
# requests ~= 1.0
# instead of
# requests ~= 1.0; extra = "instruments"
# which does not work with `get_distribution()`
dep.marker = None
instrumentation_deps.append(str(dep))
extra = "extra"
instruments = "instruments"
instruments_marker = {extra: instruments}
for dep in dist.requires:
if extra not in dep or instruments not in dep:
continue
req = Requirement(dep)
if req.marker.evaluate(instruments_marker):
instrumentation_deps.append(req)
return get_dependency_conflicts(instrumentation_deps)
def get_dependency_conflicts(
deps: Collection[str],
deps: Collection[Union[str, Requirement]],
) -> Optional[DependencyConflict]:
for dep in deps:
if isinstance(dep, Requirement):
req = dep
else:
try:
req = Requirement(dep)
except InvalidRequirement as exc:
logger.warning(
'error parsing dependency, reporting as a conflict: "%s" - %s',
dep,
exc,
)
return DependencyConflict(dep)
try:
get_distribution(dep)
except VersionConflict as exc:
return DependencyConflict(dep, exc.dist)
except DistributionNotFound:
return DependencyConflict(dep)
except RequirementParseError as exc:
logger.warning(
'error parsing dependency, reporting as a conflict: "%s" - %s',
dep,
exc,
)
dist_version = version(req.name)
except PackageNotFoundError:
return DependencyConflict(dep)
if not req.specifier.contains(dist_version):
return DependencyConflict(dep, f"{req.name} {dist_version}")
return None

View File

@ -20,9 +20,8 @@ OpenTelemetry Base Distribution (Distro)
from abc import ABC, abstractmethod
from logging import getLogger
from pkg_resources import EntryPoint
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
from opentelemetry.util._importlib_metadata import EntryPoint
_LOG = getLogger(__name__)

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -23,6 +23,7 @@ from opentelemetry.instrumentation.environment_variables import (
OTEL_PYTHON_DISTRO,
)
from opentelemetry.instrumentation.version import __version__
from opentelemetry.util._importlib_metadata import EntryPoint, entry_points
class TestLoad(TestCase):
@ -30,7 +31,7 @@ class TestLoad(TestCase):
"os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"}
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_configurators(
self, iter_mock
@ -61,7 +62,7 @@ class TestLoad(TestCase):
"os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"}
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_configurators_no_ep(
self, iter_mock
@ -74,7 +75,7 @@ class TestLoad(TestCase):
"os.environ", {OTEL_PYTHON_CONFIGURATOR: "custom_configurator2"}
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_configurators_error(self, iter_mock):
# Add multiple entry points but only specify the 2nd in the environment variable.
@ -101,7 +102,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.isinstance"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_distro(self, iter_mock, isinstance_mock):
# Add multiple entry points but only specify the 2nd in the environment variable.
@ -134,7 +135,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.DefaultDistro"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_distro_not_distro(
self, iter_mock, default_distro_mock, isinstance_mock
@ -166,7 +167,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.DefaultDistro"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_distro_no_ep(self, iter_mock, default_distro_mock):
iter_mock.return_value = ()
@ -181,7 +182,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.isinstance"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_distro_error(self, iter_mock, isinstance_mock):
ep_mock1 = Mock()
@ -211,7 +212,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_instrumentors(self, iter_mock, dep_mock):
# Mock opentelemetry_pre_instrument entry points
@ -285,7 +286,7 @@ class TestLoad(TestCase):
"opentelemetry.instrumentation.auto_instrumentation._load.get_dist_dependency_conflicts"
)
@patch(
"opentelemetry.instrumentation.auto_instrumentation._load.iter_entry_points"
"opentelemetry.instrumentation.auto_instrumentation._load.entry_points"
)
def test_load_instrumentors_dep_conflict(
self, iter_mock, dep_mock
@ -314,3 +315,37 @@ class TestLoad(TestCase):
]
)
distro_mock.load_instrumentor.assert_called_once()
def test_load_instrumentors_no_entry_point_mocks(self):
distro_mock = Mock()
_load._load_instrumentors(distro_mock)
# this has no specific assert because it is run for every instrumentation
self.assertTrue(distro_mock)
def test_entry_point_dist_finder(self):
entry_point_finder = _load._EntryPointDistFinder()
self.assertTrue(entry_point_finder._mapping)
entry_point = list(
entry_points(group="opentelemetry_environment_variables")
)[0]
self.assertTrue(entry_point)
self.assertTrue(entry_point.dist)
# this will not hit cache
entry_point_dist = entry_point_finder.dist_for(entry_point)
self.assertTrue(entry_point_dist)
# dist are not comparable so we are sure we are not hitting the cache
self.assertEqual(entry_point.dist, entry_point_dist)
# this will hit cache
entry_point_without_dist = EntryPoint(
name=entry_point.name,
group=entry_point.group,
value=entry_point.value,
)
self.assertIsNone(entry_point_without_dist.dist)
new_entry_point_dist = entry_point_finder.dist_for(
entry_point_without_dist
)
# dist are not comparable, being truthy is enough
self.assertTrue(new_entry_point_dist)

View File

@ -14,8 +14,8 @@
# pylint: disable=protected-access
import pkg_resources
import pytest
from packaging.requirements import Requirement
from opentelemetry.instrumentation.dependencies import (
DependencyConflict,
@ -23,15 +23,30 @@ from opentelemetry.instrumentation.dependencies import (
get_dist_dependency_conflicts,
)
from opentelemetry.test.test_base import TestBase
from opentelemetry.util._importlib_metadata import Distribution
class TestDependencyConflicts(TestBase):
def test_get_dependency_conflicts_empty(self):
self.assertIsNone(get_dependency_conflicts([]))
def test_get_dependency_conflicts_no_conflict_requirement(self):
req = Requirement("pytest")
self.assertIsNone(get_dependency_conflicts([req]))
def test_get_dependency_conflicts_no_conflict(self):
self.assertIsNone(get_dependency_conflicts(["pytest"]))
def test_get_dependency_conflicts_not_installed_requirement(self):
req = Requirement("this-package-does-not-exist")
conflict = get_dependency_conflicts([req])
self.assertTrue(conflict is not None)
self.assertTrue(isinstance(conflict, DependencyConflict))
self.assertEqual(
str(conflict),
'DependencyConflict: requested: "this-package-does-not-exist" but found: "None"',
)
def test_get_dependency_conflicts_not_installed(self):
conflict = get_dependency_conflicts(["this-package-does-not-exist"])
self.assertTrue(conflict is not None)
@ -51,24 +66,23 @@ class TestDependencyConflicts(TestBase):
)
def test_get_dist_dependency_conflicts(self):
def mock_requires(extras=()):
if "instruments" in extras:
return [
pkg_resources.Requirement(
'test-pkg ~= 1.0; extra == "instruments"'
)
]
return []
class MockDistribution(Distribution):
def locate_file(self, path):
pass
dist = pkg_resources.Distribution(
project_name="test-instrumentation", version="1.0"
)
dist.requires = mock_requires
def read_text(self, filename):
pass
@property
def requires(self):
return ['test-pkg ~= 1.0; extra == "instruments"']
dist = MockDistribution()
conflict = get_dist_dependency_conflicts(dist)
self.assertTrue(conflict is not None)
self.assertTrue(isinstance(conflict, DependencyConflict))
self.assertEqual(
str(conflict),
'DependencyConflict: requested: "test-pkg~=1.0" but found: "None"',
'DependencyConflict: requested: "test-pkg~=1.0; extra == "instruments"" but found: "None"',
)

View File

@ -15,10 +15,9 @@
from unittest import TestCase
from pkg_resources import EntryPoint
from opentelemetry.instrumentation.distro import BaseDistro
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
from opentelemetry.util._importlib_metadata import EntryPoint
class MockInstrumetor(BaseInstrumentor):
@ -33,11 +32,13 @@ class MockInstrumetor(BaseInstrumentor):
class MockEntryPoint(EntryPoint):
def __init__(self, obj): # pylint: disable=super-init-not-called
self._obj = obj
def __init__(
self, name, value, group
): # pylint: disable=super-init-not-called
pass
def load(self, *args, **kwargs): # pylint: disable=signature-differs
return self._obj
return MockInstrumetor
class MockDistro(BaseDistro):
@ -51,7 +52,11 @@ class TestDistro(TestCase):
distro = MockDistro()
instrumentor = MockInstrumetor()
entry_point = MockEntryPoint(MockInstrumetor)
entry_point = MockEntryPoint(
"MockInstrumetor",
value="opentelemetry",
group="opentelemetry_distro",
)
self.assertFalse(instrumentor._is_instrumented_by_opentelemetry)
distro.load_instrumentor(entry_point)

View File

@ -3,7 +3,6 @@ certifi==2024.7.4
charset-normalizer==3.3.2
Deprecated==1.2.14
idna==3.7
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1,6 +1,5 @@
asgiref==3.8.1
Deprecated==1.2.14
importlib-metadata==6.11.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.5.0

View File

@ -1234,7 +1234,6 @@ deps =
greenlet==3.0.3
grpcio==1.62.1
idna==2.10
importlib-metadata==6.11.0
iniconfig==2.0.0
jsonschema==3.2.0
kombu==5.3.5

Some files were not shown because too many files have changed in this diff Show More