Skip to content

Add get_dist_dependency_conflicts back to opentelemetry-instrumentation #3418

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `opentelemetry-instrumentation` Catch `ModuleNotFoundError` when the library is not installed
and log as debug instead of exception
([#3423](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3423))
- Add `get_dist_dependency_conflicts` back to opentelemetry-instrumentation
([#3418](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3418))

## Version 1.32.0/0.53b0 (2025-04-10)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@

from __future__ import annotations

import warnings
from logging import getLogger
from typing import Collection

from packaging.requirements import InvalidRequirement, Requirement

from opentelemetry.util._importlib_metadata import (
Distribution,
PackageNotFoundError,
version,
)
Expand Down Expand Up @@ -49,6 +51,30 @@ def __str__(self):
return str(self.conflict)


def get_dist_dependency_conflicts(
dist: Distribution,
) -> DependencyConflict | None:
warnings.warn(
"get_dist_dependency_conflicts is deprecated since 0.53b0 and will be removed in a future release.",
DeprecationWarning,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't add deprecation warning until we are sure of our path forward.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed in slack: let's remove this.

stacklevel=2,
)
instrumentation_deps = []
extra = "extra"
instruments = "instruments"
instruments_marker = {extra: instruments}
if dist.requires:
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 | Requirement],
) -> DependencyConflict | None:
Expand Down
40 changes: 40 additions & 0 deletions opentelemetry-instrumentation/tests/test_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
from opentelemetry.instrumentation.dependencies import (
DependencyConflict,
get_dependency_conflicts,
get_dist_dependency_conflicts,
)
from opentelemetry.test.test_base import TestBase
from opentelemetry.util._importlib_metadata import Distribution


class TestDependencyConflicts(TestBase):
Expand Down Expand Up @@ -62,3 +64,41 @@ def test_get_dependency_conflicts_mismatched_version(self):
str(conflict),
f'DependencyConflict: requested: "pytest == 5000" but found: "pytest {pytest.__version__}"',
)

def test_get_dist_dependency_conflicts(self):
class MockDistribution(Distribution):
def locate_file(self, path):
pass

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; extra == "instruments"" but found: "None"',
)

def test_get_dist_dependency_conflicts_requires_none(self):
class MockDistribution(Distribution):
def locate_file(self, path):
pass

def read_text(self, filename):
pass

@property
def requires(self):
return None

dist = MockDistribution()
conflict = get_dist_dependency_conflicts(dist)
self.assertTrue(conflict is None)