mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
Remove pkg resources (#2871)
This commit is contained in:

committed by
GitHub

parent
d7d7e96ce5
commit
e4ece57a81
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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]
|
||||
|
@ -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"):
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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"',
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
1
tox.ini
1
tox.ini
@ -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
Reference in New Issue
Block a user