Skip to content

Commit 4dca66f

Browse files
committed
stash
1 parent c4347e0 commit 4dca66f

File tree

3 files changed

+118
-3
lines changed

3 files changed

+118
-3
lines changed

instrumentation/opentelemetry-instrumentation-fastapi/pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ dependencies = [
3636
instruments = [
3737
"fastapi ~= 0.92",
3838
]
39+
instruments_either = [
40+
"fastapi ~= 0.92",
41+
"fastapi-slim ~= 0.92",
42+
]
3943

4044
[project.entry-points.opentelemetry_instrumentor]
4145
fastapi = "opentelemetry.instrumentation.fastapi:FastAPIInstrumentor"

instrumentation/opentelemetry-instrumentation-kafka-python/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dependencies = [
3131
]
3232

3333
[project.optional-dependencies]
34-
instruments = [
34+
instruments_either = [
3535
"kafka-python >= 2.0, < 3.0",
3636
"kafka-python-ng >= 2.0, < 3.0"
3737
]

opentelemetry-instrumentation/src/opentelemetry/instrumentation/dependencies.py

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,49 @@
2020
from packaging.requirements import InvalidRequirement, Requirement
2121

2222
from opentelemetry.util._importlib_metadata import (
23+
Distribution,
2324
PackageNotFoundError,
2425
version,
2526
)
2627

2728
logger = getLogger(__name__)
2829

30+
#TODO: consider replacing _either with _any or _or
2931

3032
class DependencyConflict:
3133
required: str | None = None
3234
found: str | None = None
35+
# The following fields are used when an instrumentation requires any of a set of dependencies rather than all.
36+
required_either: Collection[str] = []
37+
found_either: Collection[str] = []
3338

34-
def __init__(self, required: str | None, found: str | None = None):
39+
# TODO: No longer requires required field
40+
def __init__(self, required: str | None = None, found: str | None = None, required_either: Collection[str] = [], found_either: Collection[str] = []):
3541
self.required = required
3642
self.found = found
43+
# The following fields are used when an instrumentation requires any of a set of dependencies rather than all.
44+
self.required_either = required_either
45+
self.found_either = found_either
3746

3847
def __str__(self):
48+
if not self.required and (self.required_either or self.found_either):
49+
# TODO: make sure this formats correctly
50+
return f'DependencyConflict: requested any of the following: "{self.required_either}" but found: "{self.found_either}"'
3951
return f'DependencyConflict: requested: "{self.required}" but found: "{self.found}"'
4052

53+
# TODO: Figure out if this should be a subclass of DependencyConflict.
54+
# If now, change functions to return either and then ensure that all the dependents can handle the new value
55+
# class DependencyConflictEither(DependencyConflict):
56+
# required: Collection[str] = []
57+
# found: Collection[str] = []
58+
59+
# def __init__(self, required: Collection[str], found: Collection[str] = []):
60+
# self.required = required
61+
# self.found = found
62+
63+
# def __str__(self):
64+
# return f'DependencyConflictEither: requested: "{self.required}" but found: "{self.found}"'
65+
4166

4267
class DependencyConflictError(Exception):
4368
conflict: DependencyConflict
@@ -49,10 +74,49 @@ def __str__(self):
4974
return str(self.conflict)
5075

5176

77+
def get_dist_dependency_conflicts(
78+
dist: Distribution,
79+
) -> DependencyConflict | None:
80+
instrumentation_deps = []
81+
instrumentation_either_deps = []
82+
extra = "extra"
83+
instruments = "instruments"
84+
instruments_marker = {extra: instruments}
85+
instruments_either = "instruments_either"
86+
instruments_either_marker = {extra: instruments_either}
87+
print(f"dist: {dist}")
88+
print(f"dist.requires: {dist.requires}")
89+
if dist.requires:
90+
for dep in dist.requires:
91+
print(f"dep: {dep}")
92+
if extra not in dep:
93+
print(f"Skipping dep: {dep}")
94+
continue
95+
if instruments not in dep and instruments_either not in dep:
96+
print(f"Skipping dep: {dep}")
97+
continue
98+
99+
req = Requirement(dep)
100+
print(f"req: {req}")
101+
if req.marker.evaluate(instruments_marker): # type: ignore
102+
print("Evaluated. Append")
103+
instrumentation_deps.append(req) # type: ignore
104+
if req.marker.evaluate(instruments_either_marker): # type: ignore
105+
print("Evaluated. either. Append")
106+
# Need someway to separate
107+
instrumentation_either_deps.append(req) # type: ignore
108+
dc = get_dependency_conflicts(instrumentation_deps, instrumentation_either_deps) # type: ignore
109+
print(f"dep conf: {dc}")
110+
return dc
111+
# return get_dependency_conflicts(instrumentation_deps, instrumentation_either_deps) # type: ignore
112+
113+
52114
def get_dependency_conflicts(
53-
deps: Collection[str | Requirement],
115+
deps: Collection[str | Requirement], # Depedencies all of which are required
116+
deps_either: Collection[str | Requirement] = [], # Dependencies any of which are required
54117
) -> DependencyConflict | None:
55118
for dep in deps:
119+
# TODO: what is this?
56120
if isinstance(dep, Requirement):
57121
req = dep
58122
else:
@@ -69,8 +133,55 @@ def get_dependency_conflicts(
69133
try:
70134
dist_version = version(req.name)
71135
except PackageNotFoundError:
136+
# TODO: Technically this field should allow Requirements type. Tackle this in a separate PR.
72137
return DependencyConflict(dep)
73138

74139
if not req.specifier.contains(dist_version):
140+
# TODO: Technically this field should allow Requirements type
75141
return DependencyConflict(dep, f"{req.name} {dist_version}")
142+
143+
# TODO: add eval of deps_either
144+
if deps_either:
145+
# TODO: change to using DependencyConflict
146+
# is_dependency_conflict = True
147+
required_either: Collection[str] = []
148+
found_either: Collection[str] = []
149+
for dep in deps_either:
150+
# TODO: what is this?
151+
if isinstance(dep, Requirement):
152+
req = dep
153+
else:
154+
try:
155+
req = Requirement(dep)
156+
except InvalidRequirement as exc:
157+
logger.warning(
158+
'error parsing dependency, reporting as a conflict: "%s" - %s',
159+
dep,
160+
exc,
161+
)
162+
return DependencyConflict(dep)
163+
164+
try:
165+
dist_version = version(req.name)
166+
except PackageNotFoundError:
167+
print(f"PackageNotFoundError: {req.name}")
168+
continue
169+
# TODO: anything here?
170+
# return DependencyConflict(dep)
171+
required_either.append(dep)
172+
173+
if req.specifier.contains(dist_version):
174+
# is_dependency_conflict = False
175+
# Since only one of the instrumentation_either dependencies is required, there is no depdendency conflict.
176+
break
177+
else:
178+
required_either.append(dep)
179+
found_either.append(f"{req.name} {dist_version}")
180+
181+
# return DependencyConflict(dep, f"{req.name} {dist_version}")
182+
return DependencyConflict(
183+
required_either=required_either,
184+
found_either=found_either,
185+
)
186+
76187
return None

0 commit comments

Comments
 (0)