From 2983d5caa4493576444030b3c8af7f02826637ce Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 14 Sep 2026 09:33:01 -0700 Subject: [PATCH 1/8] Fix overwritting of the service.instance.id which has been populated from the user provided values from the resource detectors --- .../opentelemetry/sdk/resources/__init__.py | 9 +++- .../tests/resources/test_resources.py | 50 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 36be319f71c..77e123c31af 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -633,6 +633,12 @@ def get_aggregated_resources( detected_resource: Resource = _EMPTY_RESOURCE try: detected_resource = future.result(timeout=timeout) + + if ( + isinstance(detector, ServiceInstanceIdResourceDetector) + and SERVICE_INSTANCE_ID in detectors_merged_resource.attributes + ): + continue except concurrent.futures.TimeoutError as ex: if detector.raise_on_error: raise ex @@ -646,8 +652,7 @@ def get_aggregated_resources( if detector.raise_on_error: raise ex logger.warning("Exception %s in detector %s, ignoring", ex, detector) - finally: - detectors_merged_resource = detectors_merged_resource.merge(detected_resource) + detectors_merged_resource = detectors_merged_resource.merge(detected_resource) finally: executor.shutdown(wait=False, cancel_futures=True) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index eec1cdcc936..3e4d2878328 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1044,6 +1044,56 @@ def tearDown(self) -> None: def test_is_process_dependent(self): self.assertTrue(ServiceInstanceIdResourceDetector().is_process_dependent()) + def test_aggregation_preserves_instance_id_from_previous_detector(self): + resource_detector = Mock(spec=ResourceDetector) + resource_detector.detect.return_value = Resource({SERVICE_INSTANCE_ID: "service-instance-id"}) + subsequent_detector = Mock(spec=ResourceDetector) + subsequent_detector.detect.return_value = Resource({"key": "value"}) + + resource = get_aggregated_resources( + [ + resource_detector, + ServiceInstanceIdResourceDetector(), + subsequent_detector, + ], + initial_resource=Resource.get_empty(), + ) + + self.assertEqual( + resource.attributes, + {SERVICE_INSTANCE_ID: "service-instance-id", "key": "value"}, + ) + + def test_aggregation_preserves_instance_id_from_initial_resource(self): + resource = get_aggregated_resources( + [ServiceInstanceIdResourceDetector()], + initial_resource=Resource({SERVICE_INSTANCE_ID: "user-provided-instance-id"}), + ) + + self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "user-provided-instance-id") + + @patch.dict( + environ, + {OTEL_RESOURCE_ATTRIBUTES: "service.instance.id=environment-instance-id"}, + clear=True, + ) + def test_aggregation_preserves_instance_id_from_environment(self): + resource = get_aggregated_resources( + [OTELResourceDetector(), ServiceInstanceIdResourceDetector()], + initial_resource=Resource.get_empty(), + ) + + self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "environment-instance-id") + + def test_aggregation_generates_instance_id_when_missing(self): + resource = get_aggregated_resources( + [ServiceInstanceIdResourceDetector()], + initial_resource=Resource({"key": "value"}), + ) + + self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) + self.assertEqual(resource.attributes["key"], "value") + def test_detect_value_is_valid_uuid4(self): _resources_module._service_instance_id = None _resources_module._service_instance_id_pid = None From e22cb8bd6fcd6fbd7848b98b6536af24b34def35 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 14 Sep 2026 15:26:44 -0700 Subject: [PATCH 2/8] Add CHANGELOG --- .changelog/5660.fixed | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changelog/5660.fixed diff --git a/.changelog/5660.fixed b/.changelog/5660.fixed new file mode 100644 index 00000000000..335362d6c13 --- /dev/null +++ b/.changelog/5660.fixed @@ -0,0 +1 @@ +`opentelemetry-sdk`: fix overriding of the service.instance.id which has been populated from the user provided values through the resource detectors From 38fe113cd360cb4260bf541ba34e32addc150f50 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 17 Sep 2026 08:48:36 -0700 Subject: [PATCH 3/8] Address feedback, move the ServiceInstanceIdResourceDetector to the top of the list --- .../opentelemetry/sdk/resources/__init__.py | 21 +++--- .../tests/resources/test_resources.py | 66 ++++++++----------- 2 files changed, 35 insertions(+), 52 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 77e123c31af..81b98ed053b 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -545,16 +545,16 @@ def _build_resource_detectors() -> list["ResourceDetector"]: Fast path: if no extra detectors are configured, returns only the two built-in detectors without scanning entry_points. - "service_instance" (ServiceInstanceIdResourceDetector) and "otel" - (OTELResourceDetector) are always appended as defaults. "otel" is last so - that OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME take highest merge - priority, but an explicit position in OTEL_EXPERIMENTAL_RESOURCE_DETECTORS + "service_instance" (ServiceInstanceIdResourceDetector) is pre-pended. "otel" + (OTELResourceDetector) is last so that OTEL_RESOURCE_ATTRIBUTES and + OTEL_SERVICE_NAME take highest merge priority, but an explicit position in OTEL_EXPERIMENTAL_RESOURCE_DETECTORS is respected for either name. """ detector_names: list[str] = list( dict.fromkeys( - [name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip()] - + ["service_instance", "otel"] + ["service_instance"] + + [name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip()] + + ["otel"] ) ) @@ -633,12 +633,6 @@ def get_aggregated_resources( detected_resource: Resource = _EMPTY_RESOURCE try: detected_resource = future.result(timeout=timeout) - - if ( - isinstance(detector, ServiceInstanceIdResourceDetector) - and SERVICE_INSTANCE_ID in detectors_merged_resource.attributes - ): - continue except concurrent.futures.TimeoutError as ex: if detector.raise_on_error: raise ex @@ -652,7 +646,8 @@ def get_aggregated_resources( if detector.raise_on_error: raise ex logger.warning("Exception %s in detector %s, ignoring", ex, detector) - detectors_merged_resource = detectors_merged_resource.merge(detected_resource) + finally: + detectors_merged_resource = detectors_merged_resource.merge(detected_resource) finally: executor.shutdown(wait=False, cancel_futures=True) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index 3e4d2878328..63bcb80ae59 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1044,55 +1044,43 @@ def tearDown(self) -> None: def test_is_process_dependent(self): self.assertTrue(ServiceInstanceIdResourceDetector().is_process_dependent()) - def test_aggregation_preserves_instance_id_from_previous_detector(self): - resource_detector = Mock(spec=ResourceDetector) - resource_detector.detect.return_value = Resource({SERVICE_INSTANCE_ID: "service-instance-id"}) - subsequent_detector = Mock(spec=ResourceDetector) - subsequent_detector.detect.return_value = Resource({"key": "value"}) - - resource = get_aggregated_resources( - [ - resource_detector, - ServiceInstanceIdResourceDetector(), - subsequent_detector, - ], - initial_resource=Resource.get_empty(), - ) - - self.assertEqual( - resource.attributes, - {SERVICE_INSTANCE_ID: "service-instance-id", "key": "value"}, - ) - - def test_aggregation_preserves_instance_id_from_initial_resource(self): - resource = get_aggregated_resources( - [ServiceInstanceIdResourceDetector()], - initial_resource=Resource({SERVICE_INSTANCE_ID: "user-provided-instance-id"}), - ) + @patch.dict(environ, {}, clear=True) + def test_service_instance_detector_sets_id_without_custom_detector(self): + resource = Resource.create() - self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "user-provided-instance-id") + self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) @patch.dict( environ, - {OTEL_RESOURCE_ATTRIBUTES: "service.instance.id=environment-instance-id"}, + {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock"}, clear=True, ) - def test_aggregation_preserves_instance_id_from_environment(self): - resource = get_aggregated_resources( - [OTELResourceDetector(), ServiceInstanceIdResourceDetector()], - initial_resource=Resource.get_empty(), + def test_configured_detector_overrides_service_instance_id(self): + custom_detector = Mock(spec=ResourceDetector) + custom_detector.detect.return_value = Resource( + { + SERVICE_INSTANCE_ID: "configured-instance-id", + "custom.detector": "value", + } + ) + entry_point = Mock( + **{"load.return_value": Mock(return_value=custom_detector)} ) - self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "environment-instance-id") + def side_effect(*args, **kwargs): + if kwargs.get("name") == "mock": + return [entry_point] + return real_entry_points(*args, **kwargs) - def test_aggregation_generates_instance_id_when_missing(self): - resource = get_aggregated_resources( - [ServiceInstanceIdResourceDetector()], - initial_resource=Resource({"key": "value"}), - ) + with patch( + "opentelemetry.util._importlib_metadata.entry_points", + side_effect=side_effect, + ): + resource = Resource.create() - self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) - self.assertEqual(resource.attributes["key"], "value") + custom_detector.detect.assert_called_once() + self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "configured-instance-id") + self.assertEqual(resource.attributes["custom.detector"], "value") def test_detect_value_is_valid_uuid4(self): _resources_module._service_instance_id = None From 7a3dab8d65b7f42c2950febc97f9bd9e015ecfe6 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 17 Sep 2026 09:31:58 -0700 Subject: [PATCH 4/8] Fix lint and spellcheck --- .../src/opentelemetry/sdk/resources/__init__.py | 8 ++++++-- opentelemetry-sdk/tests/resources/test_resources.py | 4 +--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 81b98ed053b..1d9a8e62b8e 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -545,7 +545,7 @@ def _build_resource_detectors() -> list["ResourceDetector"]: Fast path: if no extra detectors are configured, returns only the two built-in detectors without scanning entry_points. - "service_instance" (ServiceInstanceIdResourceDetector) is pre-pended. "otel" + "service_instance" (ServiceInstanceIdResourceDetector) is prepended. "otel" (OTELResourceDetector) is last so that OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME take highest merge priority, but an explicit position in OTEL_EXPERIMENTAL_RESOURCE_DETECTORS is respected for either name. @@ -553,7 +553,11 @@ def _build_resource_detectors() -> list["ResourceDetector"]: detector_names: list[str] = list( dict.fromkeys( ["service_instance"] - + [name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip()] + + [ + name.strip() + for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") + if name.strip() + ] + ["otel"] ) ) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index 63bcb80ae59..2666351a504 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1063,9 +1063,7 @@ def test_configured_detector_overrides_service_instance_id(self): "custom.detector": "value", } ) - entry_point = Mock( - **{"load.return_value": Mock(return_value=custom_detector)} - ) + entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) def side_effect(*args, **kwargs): if kwargs.get("name") == "mock": From d1c2dc2891dc424d5a55421ca5e24f11029896a5 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 21 Sep 2026 08:59:29 -0700 Subject: [PATCH 5/8] Address feedback --- .../opentelemetry/sdk/resources/__init__.py | 25 +++++------- .../tests/resources/test_resources.py | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py index 1d9a8e62b8e..7d0b1f429e9 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py @@ -545,22 +545,17 @@ def _build_resource_detectors() -> list["ResourceDetector"]: Fast path: if no extra detectors are configured, returns only the two built-in detectors without scanning entry_points. - "service_instance" (ServiceInstanceIdResourceDetector) is prepended. "otel" - (OTELResourceDetector) is last so that OTEL_RESOURCE_ATTRIBUTES and - OTEL_SERVICE_NAME take highest merge priority, but an explicit position in OTEL_EXPERIMENTAL_RESOURCE_DETECTORS - is respected for either name. + "service_instance" (ServiceInstanceIdResourceDetector) is prepended unless + it is explicitly configured. "otel" (OTELResourceDetector) is last so + that OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME take highest merge + priority, but an explicit position in + OTEL_EXPERIMENTAL_RESOURCE_DETECTORS is respected for either name. """ - detector_names: list[str] = list( - dict.fromkeys( - ["service_instance"] - + [ - name.strip() - for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") - if name.strip() - ] - + ["otel"] - ) - ) + configured_detector_names = [ + name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip() + ] + default_detector_names = [] if "service_instance" in configured_detector_names else ["service_instance"] + detector_names: list[str] = list(dict.fromkeys(default_detector_names + configured_detector_names + ["otel"])) # Fast path: only the two built-in detectors — no entry_points scan needed. if detector_names == ["service_instance", "otel"]: diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index 2666351a504..e411680aaa4 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1050,6 +1050,22 @@ def test_service_instance_detector_sets_id_without_custom_detector(self): self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) + @patch.dict(environ, {}, clear=True) + def test_resource_attributes_override_service_instance_id(self): + resource = Resource.create({SERVICE_INSTANCE_ID: "resource-instance-id"}) + + self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "resource-instance-id") + + @patch.dict( + environ, + {OTEL_RESOURCE_ATTRIBUTES: "service.instance.id=environment-instance-id"}, + clear=True, + ) + def test_environment_resource_attributes_override_service_instance_id(self): + resource = Resource.create() + + self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "environment-instance-id") + @patch.dict( environ, {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock"}, @@ -1080,6 +1096,30 @@ def side_effect(*args, **kwargs): self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "configured-instance-id") self.assertEqual(resource.attributes["custom.detector"], "value") + @patch.dict( + environ, + {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock,service_instance"}, + clear=True, + ) + def test_explicit_service_instance_detector_position_is_respected(self): + custom_detector = Mock(spec=ResourceDetector) + custom_detector.detect.return_value = Resource({SERVICE_INSTANCE_ID: "configured-instance-id"}) + entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) + + def side_effect(*args, **kwargs): + if kwargs.get("name") == "mock": + return [entry_point] + return real_entry_points(*args, **kwargs) + + with patch( + "opentelemetry.util._importlib_metadata.entry_points", + side_effect=side_effect, + ): + resource = Resource.create() + + custom_detector.detect.assert_called_once() + self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) + def test_detect_value_is_valid_uuid4(self): _resources_module._service_instance_id = None _resources_module._service_instance_id_pid = None From 97c2eb1e51c62946fd8baa7e6b91e2b1fe5d07df Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 21 Sep 2026 12:40:44 -0700 Subject: [PATCH 6/8] Condese tests --- .../tests/resources/test_resources.py | 104 ++++++++---------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index e411680aaa4..fd581d24beb 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1044,12 +1044,6 @@ def tearDown(self) -> None: def test_is_process_dependent(self): self.assertTrue(ServiceInstanceIdResourceDetector().is_process_dependent()) - @patch.dict(environ, {}, clear=True) - def test_service_instance_detector_sets_id_without_custom_detector(self): - resource = Resource.create() - - self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) - @patch.dict(environ, {}, clear=True) def test_resource_attributes_override_service_instance_id(self): resource = Resource.create({SERVICE_INSTANCE_ID: "resource-instance-id"}) @@ -1066,59 +1060,57 @@ def test_environment_resource_attributes_override_service_instance_id(self): self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "environment-instance-id") - @patch.dict( - environ, - {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock"}, - clear=True, - ) - def test_configured_detector_overrides_service_instance_id(self): - custom_detector = Mock(spec=ResourceDetector) - custom_detector.detect.return_value = Resource( - { - SERVICE_INSTANCE_ID: "configured-instance-id", - "custom.detector": "value", - } + def test_service_instance_detector_ordering(self): + test_cases = ( + ("", False, True), + ("mock", True, False), + ("mock,service_instance", True, True), ) - entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) - - def side_effect(*args, **kwargs): - if kwargs.get("name") == "mock": - return [entry_point] - return real_entry_points(*args, **kwargs) - - with patch( - "opentelemetry.util._importlib_metadata.entry_points", - side_effect=side_effect, - ): - resource = Resource.create() - - custom_detector.detect.assert_called_once() - self.assertEqual(resource.attributes[SERVICE_INSTANCE_ID], "configured-instance-id") - self.assertEqual(resource.attributes["custom.detector"], "value") - @patch.dict( - environ, - {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "mock,service_instance"}, - clear=True, - ) - def test_explicit_service_instance_detector_position_is_respected(self): - custom_detector = Mock(spec=ResourceDetector) - custom_detector.detect.return_value = Resource({SERVICE_INSTANCE_ID: "configured-instance-id"}) - entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) - - def side_effect(*args, **kwargs): - if kwargs.get("name") == "mock": - return [entry_point] - return real_entry_points(*args, **kwargs) - - with patch( - "opentelemetry.util._importlib_metadata.entry_points", - side_effect=side_effect, - ): - resource = Resource.create() + for detector_names, includes_custom_detector, expects_generated_id in test_cases: + with self.subTest(detector_names=detector_names): + custom_detector = Mock(spec=ResourceDetector) + custom_detector.detect.return_value = Resource( + { + SERVICE_INSTANCE_ID: "configured-instance-id", + "custom.detector": "value", + } + ) + entry_point = Mock( + **{"load.return_value": Mock(return_value=custom_detector)} + ) - custom_detector.detect.assert_called_once() - self.assertEqual(uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, 4) + def side_effect(*args, **kwargs): + if kwargs.get("name") == "mock": + return [entry_point] + return real_entry_points(*args, **kwargs) + + with patch.dict( + environ, + {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: detector_names}, + clear=True, + ): + if includes_custom_detector: + with patch( + "opentelemetry.util._importlib_metadata.entry_points", + side_effect=side_effect, + ): + resource = Resource.create() + custom_detector.detect.assert_called_once() + self.assertEqual(resource.attributes["custom.detector"], "value") + else: + resource = Resource.create() + + if expects_generated_id: + self.assertEqual( + uuid.UUID(resource.attributes[SERVICE_INSTANCE_ID]).version, + 4, + ) + else: + self.assertEqual( + resource.attributes[SERVICE_INSTANCE_ID], + "configured-instance-id", + ) def test_detect_value_is_valid_uuid4(self): _resources_module._service_instance_id = None From 4e082b2900c20411cafc3374382b5b54e7d50490 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 21 Sep 2026 13:01:59 -0700 Subject: [PATCH 7/8] Fix lint --- opentelemetry-sdk/tests/resources/test_resources.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index fd581d24beb..1d224dae05a 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -1076,9 +1076,7 @@ def test_service_instance_detector_ordering(self): "custom.detector": "value", } ) - entry_point = Mock( - **{"load.return_value": Mock(return_value=custom_detector)} - ) + entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) def side_effect(*args, **kwargs): if kwargs.get("name") == "mock": From f012f47c622970508c0c43b31afee02bab13d67f Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 21 Sep 2026 13:26:53 -0700 Subject: [PATCH 8/8] Fix lint --- opentelemetry-sdk/tests/resources/test_resources.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/opentelemetry-sdk/tests/resources/test_resources.py b/opentelemetry-sdk/tests/resources/test_resources.py index 1d224dae05a..dfc621d0821 100644 --- a/opentelemetry-sdk/tests/resources/test_resources.py +++ b/opentelemetry-sdk/tests/resources/test_resources.py @@ -10,6 +10,7 @@ import unittest import uuid from concurrent.futures import TimeoutError +from functools import partial from logging import ERROR, WARNING from os import environ from unittest.mock import Mock, patch @@ -1067,6 +1068,11 @@ def test_service_instance_detector_ordering(self): ("mock,service_instance", True, True), ) + def entry_points_side_effect(entry_point, *args, **kwargs): + if kwargs.get("name") == "mock": + return [entry_point] + return real_entry_points(*args, **kwargs) + for detector_names, includes_custom_detector, expects_generated_id in test_cases: with self.subTest(detector_names=detector_names): custom_detector = Mock(spec=ResourceDetector) @@ -1078,11 +1084,6 @@ def test_service_instance_detector_ordering(self): ) entry_point = Mock(**{"load.return_value": Mock(return_value=custom_detector)}) - def side_effect(*args, **kwargs): - if kwargs.get("name") == "mock": - return [entry_point] - return real_entry_points(*args, **kwargs) - with patch.dict( environ, {OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: detector_names}, @@ -1091,7 +1092,7 @@ def side_effect(*args, **kwargs): if includes_custom_detector: with patch( "opentelemetry.util._importlib_metadata.entry_points", - side_effect=side_effect, + side_effect=partial(entry_points_side_effect, entry_point), ): resource = Resource.create() custom_detector.detect.assert_called_once()