From 262f2751d905942264b1ec9db9b5a03110961be6 Mon Sep 17 00:00:00 2001 From: Nick Stenning Date: Thu, 23 Apr 2026 13:26:20 +0200 Subject: [PATCH] Use a covariant type for detectors argument This updates the type annotation for `get_aggregated_resources`'s `detectors` argument to use `collections.abc.Sequence`, which is covariant in its type parameter and thus has the expected behaviour for an input type. `typing.List` is invariant in its type parameter, which means that a simple list of `ResourceDetector` subclasses is not a `list[ResourceDetector]`. Some typecheckers are more lenient than others, but [ty] enforces this and thus the following code does not typecheck despite being semantically correct. from opentelemetry.sdk.resources import ( OsResourceDetector, ProcessResourceDetector, Resource, get_aggregated_resources, ) from opentelemetry.sdk.trace import TracerProvider resource = Resource.create() resource_detectors = [ ProcessResourceDetector(), OsResourceDetector(), ] tracer_provider = TracerProvider( resource=get_aggregated_resources( detectors=resource_detectors, initial_resource=resource, ), ) The full output of ty is as follows: $ uv run ty check error[invalid-argument-type]: Argument to function `get_aggregated_resources` is incorrect --> test.py:18:9 | 18 | detectors=resource_detectors, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Expected `list[ResourceDetector]`, found `list[ProcessResourceDetector | OsResourceDetector]` | info: Function defined here --> .venv/lib/python3.13/site-packages/opentelemetry/sdk/resources/__init__.py:507:5 | 507 | def get_aggregated_resources( | ^^^^^^^^^^^^^^^^^^^^^^^^ 508 | detectors: typing.List["ResourceDetector"], | ------------------------------------------ Parameter declared here | info: `list` is invariant in its type parameter info: Consider using the covariant supertype `collections.abc.Sequence` info: For more information, see https://docs.astral.sh/ty/reference/typing-faq/#invariant-generics Found 1 diagnostic [ty]: https://docs.astral.sh/ty/reference/typing-faq/#invariant-generics --- CHANGELOG.md | 2 ++ opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e56e7357c..15130d85ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#5120](https://github.com/open-telemetry/opentelemetry-python/pull/5120)) - Add WeaverLiveCheck test util ([#5088](https://github.com/open-telemetry/opentelemetry-python/pull/5088)) +- Fix incorrect type annotation on `detectors` parameter of `get_aggregated_resources` + ([#5135](https://github.com/open-telemetry/opentelemetry-python/pull/5135)) ## Version 1.41.0/0.62b0 (2026-04-09) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index beb21098e1..9e3c194770 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -67,6 +67,7 @@ import socket import sys import typing +from collections.abc import Sequence from json import dumps from os import environ from types import ModuleType @@ -517,7 +518,7 @@ def detect(self) -> "Resource": def get_aggregated_resources( - detectors: typing.List["ResourceDetector"], + detectors: Sequence["ResourceDetector"], initial_resource: typing.Optional[Resource] = None, timeout: int = 5, ) -> "Resource":