diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2576d07fe7..b66dfe9bb2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: - 'release/*' pull_request: env: - CORE_REPO_SHA: d3694fc520f8542b232fd1065133286f4591dcec + CORE_REPO_SHA: 94d9c1eb77723123a779ddd18d2b12d4bec445fb jobs: build: diff --git a/CHANGELOG.md b/CHANGELOG.md index 35ea6ff194..769cfc1639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python-contrib/compare/v0.18b0...HEAD) +- Make getters and setters optional + ([#372](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/372)) - Updated instrumentations to use `opentelemetry.trace.use_span` instead of `Tracer.use_span()` ([#364](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/364)) - `opentelemetry-propagator-ot-trace` Do not throw an exception when headers are not present diff --git a/docs/nitpick-exceptions.ini b/docs/nitpick-exceptions.ini index e4ac50dfab..416e86928a 100644 --- a/docs/nitpick-exceptions.ini +++ b/docs/nitpick-exceptions.ini @@ -1,16 +1,22 @@ [default] class_references= ; TODO: Understand why sphinx is not able to find this local class + opentelemetry.propagators.textmap.CarrierT + opentelemetry.propagators.textmap.Setter + opentelemetry.propagators.textmap.Getter opentelemetry.propagators.textmap.TextMapPropagator ; - AwsXRayFormat - opentelemetry.propagators.textmap.DictGetter + opentelemetry.propagators.textmap.DefaultGetter ; API opentelemetry.propagators.textmap.Getter ; - DatadogFormat ; - AWSXRayFormat opentelemetry.sdk.trace.id_generator.IdGenerator ; - AwsXRayIdGenerator - TextMapPropagatorT + TextMapPropagator + CarrierT + Setter + Getter ; - AwsXRayFormat.extract anys= diff --git a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py index bddf0cabba..e9b71ef7d9 100644 --- a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py +++ b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py @@ -18,10 +18,12 @@ from opentelemetry.context import Context from opentelemetry.exporter.datadog import constants from opentelemetry.propagators.textmap import ( + CarrierT, Getter, Setter, TextMapPropagator, - TextMapPropagatorT, + default_getter, + default_setter, ) from opentelemetry.trace import get_current_span, set_span_in_context @@ -36,9 +38,9 @@ class DatadogFormat(TextMapPropagator): def extract( self, - getter: Getter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: typing.Optional[Context] = None, + getter: Getter = default_getter, ) -> Context: trace_id = extract_first_element( getter.get(carrier, self.TRACE_ID_KEY) @@ -81,28 +83,28 @@ def extract( def inject( self, - set_in_carrier: Setter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: typing.Optional[Context] = None, + setter: Setter = default_setter, ) -> None: span = get_current_span(context) span_context = span.get_span_context() if span_context == trace.INVALID_SPAN_CONTEXT: return sampled = (trace.TraceFlags.SAMPLED & span.context.trace_flags) != 0 - set_in_carrier( + setter.set( carrier, self.TRACE_ID_KEY, format_trace_id(span.context.trace_id), ) - set_in_carrier( + setter.set( carrier, self.PARENT_ID_KEY, format_span_id(span.context.span_id) ) - set_in_carrier( + setter.set( carrier, self.SAMPLING_PRIORITY_KEY, str(constants.AUTO_KEEP if sampled else constants.AUTO_REJECT), ) if constants.DD_ORIGIN in span.context.trace_state: - set_in_carrier( + setter.set( carrier, self.ORIGIN_KEY, span.context.trace_state[constants.DD_ORIGIN], @@ -134,8 +136,8 @@ def format_span_id(span_id: int) -> str: def extract_first_element( - items: typing.Iterable[TextMapPropagatorT], -) -> typing.Optional[TextMapPropagatorT]: + items: typing.Iterable[CarrierT], +) -> typing.Optional[CarrierT]: if items is None: return None return next(iter(items), None) diff --git a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_format.py b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_format.py index fe3493a062..c724849028 100644 --- a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_format.py +++ b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_format.py @@ -17,15 +17,12 @@ from opentelemetry import trace as trace_api from opentelemetry.exporter.datadog import constants, propagator -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.sdk import trace from opentelemetry.sdk.trace.id_generator import RandomIdGenerator from opentelemetry.trace import get_current_span, set_span_in_context FORMAT = propagator.DatadogFormat() -carrier_getter = DictGetter() - class TestDatadogFormat(unittest.TestCase): @classmethod @@ -45,7 +42,6 @@ def test_malformed_headers(self): malformed_parent_id_key = FORMAT.PARENT_ID_KEY + "-x" context = get_current_span( FORMAT.extract( - carrier_getter, { malformed_trace_id_key: self.serialized_trace_id, malformed_parent_id_key: self.serialized_parent_id, @@ -63,7 +59,7 @@ def test_missing_trace_id(self): FORMAT.PARENT_ID_KEY: self.serialized_parent_id, } - ctx = FORMAT.extract(carrier_getter, carrier) + ctx = FORMAT.extract(carrier) span_context = get_current_span(ctx).get_span_context() self.assertEqual(span_context.trace_id, trace_api.INVALID_TRACE_ID) @@ -73,7 +69,7 @@ def test_missing_parent_id(self): FORMAT.TRACE_ID_KEY: self.serialized_trace_id, } - ctx = FORMAT.extract(carrier_getter, carrier) + ctx = FORMAT.extract(carrier) span_context = get_current_span(ctx).get_span_context() self.assertEqual(span_context.span_id, trace_api.INVALID_SPAN_ID) @@ -81,7 +77,6 @@ def test_context_propagation(self): """Test the propagation of Datadog headers.""" parent_span_context = get_current_span( FORMAT.extract( - carrier_getter, { FORMAT.TRACE_ID_KEY: self.serialized_trace_id, FORMAT.PARENT_ID_KEY: self.serialized_parent_id, @@ -118,7 +113,7 @@ def test_context_propagation(self): child_carrier = {} child_context = set_span_in_context(child) - FORMAT.inject(dict.__setitem__, child_carrier, context=child_context) + FORMAT.inject(child_carrier, context=child_context) self.assertEqual( child_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id @@ -138,7 +133,6 @@ def test_sampling_priority_auto_reject(self): """Test sampling priority rejected.""" parent_span_context = get_current_span( FORMAT.extract( - carrier_getter, { FORMAT.TRACE_ID_KEY: self.serialized_trace_id, FORMAT.PARENT_ID_KEY: self.serialized_parent_id, @@ -165,7 +159,7 @@ def test_sampling_priority_auto_reject(self): child_carrier = {} child_context = set_span_in_context(child) - FORMAT.inject(dict.__setitem__, child_carrier, context=child_context) + FORMAT.inject(child_carrier, context=child_context) self.assertEqual( child_carrier[FORMAT.SAMPLING_PRIORITY_KEY], @@ -178,7 +172,7 @@ def test_fields(self, mock_get_current_span): tracer = trace.TracerProvider().get_tracer("sdk_tracer_provider") - mock_set_in_carrier = Mock() + mock_setter = Mock() mock_get_current_span.configure_mock( **{ @@ -195,11 +189,11 @@ def test_fields(self, mock_get_current_span): with tracer.start_as_current_span("parent"): with tracer.start_as_current_span("child"): - FORMAT.inject(mock_set_in_carrier, {}) + FORMAT.inject({}, setter=mock_setter) inject_fields = set() - for call in mock_set_in_carrier.mock_calls: + for call in mock_setter.mock_calls: inject_fields.add(call[1][1]) self.assertEqual(FORMAT.fields, inject_fields) diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index 24dd360533..7d1ad04355 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -181,7 +181,7 @@ async def on_request_start( trace.set_span_in_context(trace_config_ctx.span) ) - inject(type(params.headers).__setitem__, params.headers) + inject(params.headers) async def on_request_end( unused_session: aiohttp.ClientSession, diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 7122ae63ba..3fe15b5069 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -29,11 +29,11 @@ from opentelemetry.instrumentation.asgi.version import __version__ # noqa from opentelemetry.instrumentation.utils import http_status_to_status_code from opentelemetry.propagate import extract -from opentelemetry.propagators.textmap import DictGetter +from opentelemetry.propagators.textmap import Getter from opentelemetry.trace.status import Status, StatusCode -class CarrierGetter(DictGetter): +class ASGIGetter(Getter): def get( self, carrier: dict, key: str ) -> typing.Optional[typing.List[str]]: @@ -62,8 +62,11 @@ def get( return None return decoded + def keys(self, carrier: dict) -> typing.List[str]: + return list(carrier.keys()) -carrier_getter = CarrierGetter() + +asgi_getter = ASGIGetter() def collect_request_attributes(scope): @@ -88,10 +91,10 @@ def collect_request_attributes(scope): if http_method: result["http.method"] = http_method - http_host_value_list = carrier_getter.get(scope, "host") + http_host_value_list = asgi_getter.get(scope, "host") if http_host_value_list: result["http.server_name"] = ",".join(http_host_value_list) - http_user_agent = carrier_getter.get(scope, "user-agent") + http_user_agent = asgi_getter.get(scope, "user-agent") if http_user_agent: result["http.user_agent"] = http_user_agent[0] @@ -186,7 +189,7 @@ async def __call__(self, scope, receive, send): if self.excluded_urls and self.excluded_urls.url_disabled(url): return await self.app(scope, receive, send) - token = context.attach(extract(carrier_getter, scope)) + token = context.attach(extract(scope, getter=asgi_getter)) span_name, additional_attributes = self.span_details_callback(scope) try: diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py index c7a5f1ef53..454162d715 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_getter.py @@ -14,18 +14,18 @@ from unittest import TestCase -from opentelemetry.instrumentation.asgi import CarrierGetter +from opentelemetry.instrumentation.asgi import ASGIGetter -class TestCarrierGetter(TestCase): +class TestASGIGetter(TestCase): def test_get_none(self): - getter = CarrierGetter() + getter = ASGIGetter() carrier = {} val = getter.get(carrier, "test") self.assertIsNone(val) def test_get_(self): - getter = CarrierGetter() + getter = ASGIGetter() carrier = {"headers": [(b"test-key", b"val")]} expected_val = ["val"] self.assertEqual( @@ -45,6 +45,6 @@ def test_get_(self): ) def test_keys(self): - getter = CarrierGetter() + getter = ASGIGetter() keys = getter.keys({}) self.assertEqual(keys, []) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py index 5adab4e3c8..e418064c91 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py @@ -66,7 +66,7 @@ def _patched_endpoint_prepare_request(wrapped, instance, args, kwargs): request = args[0] headers = request.headers - inject(type(headers).__setitem__, headers) + inject(headers) return wrapped(*args, **kwargs) diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index 24a2914541..cd12677a56 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -61,7 +61,7 @@ def add(x, y): from opentelemetry.instrumentation.celery.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.propagate import extract, inject -from opentelemetry.propagators.textmap import DictGetter +from opentelemetry.propagators.textmap import Getter from opentelemetry.trace.status import Status, StatusCode logger = logging.getLogger(__name__) @@ -78,7 +78,7 @@ def add(x, y): _MESSAGE_ID_ATTRIBUTE_NAME = "messaging.message_id" -class CarrierGetter(DictGetter): +class CeleryGetter(Getter): def get(self, carrier, key): value = getattr(carrier, key, None) if value is None: @@ -91,7 +91,7 @@ def keys(self, carrier): return [] -carrier_getter = CarrierGetter() +celery_getter = CeleryGetter() class CeleryInstrumentor(BaseInstrumentor): @@ -128,7 +128,7 @@ def _trace_prerun(self, *args, **kwargs): return request = task.request - tracectx = extract(carrier_getter, request) or None + tracectx = extract(request, getter=celery_getter) or None logger.debug("prerun signal start task_id=%s", task_id) @@ -193,7 +193,7 @@ def _trace_before_publish(self, *args, **kwargs): headers = kwargs.get("headers") if headers: - inject(type(headers).__setitem__, headers) + inject(headers) @staticmethod def _trace_after_publish(*args, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-celery/tests/test_getter.py b/instrumentation/opentelemetry-instrumentation-celery/tests/test_getter.py index a534309750..5943055f00 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/tests/test_getter.py +++ b/instrumentation/opentelemetry-instrumentation-celery/tests/test_getter.py @@ -14,31 +14,31 @@ from unittest import TestCase, mock -from opentelemetry.instrumentation.celery import CarrierGetter +from opentelemetry.instrumentation.celery import CeleryGetter -class TestCarrierGetter(TestCase): +class TestCeleryGetter(TestCase): def test_get_none(self): - getter = CarrierGetter() + getter = CeleryGetter() carrier = {} val = getter.get(carrier, "test") self.assertIsNone(val) def test_get_str(self): mock_obj = mock.Mock() - getter = CarrierGetter() + getter = CeleryGetter() mock_obj.test = "val" val = getter.get(mock_obj, "test") self.assertEqual(val, ("val",)) def test_get_iter(self): mock_obj = mock.Mock() - getter = CarrierGetter() + getter = CeleryGetter() mock_obj.test = ["val"] val = getter.get(mock_obj, "test") self.assertEqual(val, ["val"]) def test_keys(self): - getter = CarrierGetter() + getter = CeleryGetter() keys = getter.keys({}) self.assertEqual(keys, []) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py index b32b77e04a..d07777ff04 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py @@ -20,8 +20,8 @@ from opentelemetry.instrumentation.utils import extract_attributes_from_object from opentelemetry.instrumentation.wsgi import ( add_response_attributes, - carrier_getter, collect_request_attributes, + wsgi_getter, ) from opentelemetry.propagate import extract from opentelemetry.trace import SpanKind, get_tracer, use_span @@ -97,7 +97,7 @@ def process_request(self, request): request_meta = request.META - token = attach(extract(carrier_getter, request_meta)) + token = attach(extract(request_meta, getter=wsgi_getter)) tracer = get_tracer(__name__, __version__) diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 211df573cc..41db811287 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -110,7 +110,7 @@ def __call__(self, env, start_response): start_time = _time_ns() - token = context.attach(extract(otel_wsgi.carrier_getter, env)) + token = context.attach(extract(env, getter=otel_wsgi.wsgi_getter)) span = self._tracer.start_span( otel_wsgi.get_default_span_name(env), kind=trace.SpanKind.SERVER, diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index cf332a301b..f657a1f3bd 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -117,7 +117,7 @@ def _before_request(): flask_request_environ = flask.request.environ span_name = name_callback() token = context.attach( - extract(otel_wsgi.carrier_getter, flask_request_environ) + extract(flask_request_environ, getter=otel_wsgi.wsgi_getter) ) tracer = trace.get_tracer(__name__, __version__) diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py index 902ed91490..5321964a19 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py @@ -29,7 +29,6 @@ from opentelemetry import trace from opentelemetry.context import attach, detach from opentelemetry.propagate import extract -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.trace.status import Status, StatusCode logger = logging.getLogger(__name__) @@ -175,14 +174,13 @@ class OpenTelemetryServerInterceptor(grpc.ServerInterceptor): def __init__(self, tracer): self._tracer = tracer - self._carrier_getter = DictGetter() @contextmanager def _set_remote_context(self, servicer_context): metadata = servicer_context.invocation_metadata() if metadata: md_dict = {md.key: md.value for md in metadata} - ctx = extract(self._carrier_getter, md_dict) + ctx = extract(md_dict) token = attach(ctx) try: yield diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 0f9369d2b1..45f65793ad 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -78,7 +78,9 @@ def _before_traversal(event): start_time = request_environ.get(_ENVIRON_STARTTIME_KEY) - token = context.attach(extract(otel_wsgi.carrier_getter, request_environ)) + token = context.attach( + extract(request_environ, getter=otel_wsgi.wsgi_getter) + ) tracer = trace.get_tracer(__name__, __version__) if request.matched_route: diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 9a3fdfcd4b..a7415a08c8 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -134,7 +134,7 @@ def _instrumented_requests_call( span.set_attribute("http.url", url) headers = get_or_create_headers() - inject(type(headers).__setitem__, headers) + inject(headers) token = context.attach( context.set_value(_SUPPRESS_REQUESTS_INSTRUMENTATION_KEY, True) diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py index 1038fb62fe..05e850e42d 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -53,7 +53,6 @@ def get(self): unwrap, ) from opentelemetry.propagate import extract -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.trace.status import Status from opentelemetry.util._time import _time_ns from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs @@ -68,7 +67,6 @@ def get(self): _excluded_urls = get_excluded_urls("TORNADO") _traced_request_attrs = get_traced_request_attrs("TORNADO") -carrier_getter = DictGetter() class TornadoInstrumentor(BaseInstrumentor): @@ -197,7 +195,7 @@ def _get_operation_name(handler, request): def _start_span(tracer, handler, start_time) -> _TraceContext: - token = context.attach(extract(carrier_getter, handler.request.headers,)) + token = context.attach(extract(handler.request.headers)) span = tracer.start_span( _get_operation_name(handler, handler.request), diff --git a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py index 1e6a282e34..e3be598644 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py @@ -65,7 +65,7 @@ def fetch_async(tracer, func, _, args, kwargs): span.set_attribute(key, value) with trace.use_span(span): - inject(type(request.headers).__setitem__, request.headers) + inject(request.headers) future = func(*args, **kwargs) future.add_done_callback( functools.partial(_finish_tracing_callback, span=span) diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index 1c305748b5..8323053667 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -151,7 +151,7 @@ def _instrumented_open_call( span.set_attribute("http.url", url) headers = get_or_create_headers() - inject(type(headers).__setitem__, headers) + inject(headers) token = context.attach( context.set_value(_SUPPRESS_URLLIB_INSTRUMENTATION_KEY, True) diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index e8335c3fca..c3be93c5bd 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -62,7 +62,7 @@ def hello(): from opentelemetry.instrumentation.utils import http_status_to_status_code from opentelemetry.instrumentation.wsgi.version import __version__ from opentelemetry.propagate import extract -from opentelemetry.propagators.textmap import DictGetter +from opentelemetry.propagators.textmap import Getter from opentelemetry.trace.status import Status, StatusCode _HTTP_VERSION_PREFIX = "HTTP/" @@ -70,14 +70,14 @@ def hello(): _CARRIER_KEY_PREFIX_LEN = len(_CARRIER_KEY_PREFIX) -class CarrierGetter(DictGetter): +class WSGIGetter(Getter): def get( self, carrier: dict, key: str ) -> typing.Optional[typing.List[str]]: """Getter implementation to retrieve a HTTP header value from the PEP3333-conforming WSGI environ - Args: + Args: carrier: WSGI environ object key: header name in environ object Returns: @@ -98,7 +98,7 @@ def keys(self, carrier): ] -carrier_getter = CarrierGetter() +wsgi_getter = WSGIGetter() def setifnotnone(dic, key, value): @@ -214,7 +214,7 @@ def __call__(self, environ, start_response): start_response: The WSGI start_response callable. """ - token = context.attach(extract(carrier_getter, environ)) + token = context.attach(extract(environ, getter=wsgi_getter)) span_name = self.name_callback(environ) span = self.tracer.start_span( diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py index 1e6d5ef79b..7f2daa7e4d 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_getter.py @@ -14,26 +14,26 @@ from unittest import TestCase -from opentelemetry.instrumentation.wsgi import CarrierGetter +from opentelemetry.instrumentation.wsgi import WSGIGetter -class TestCarrierGetter(TestCase): +class TestGetter(TestCase): def test_get_none(self): - getter = CarrierGetter() + getter = WSGIGetter() carrier = {} val = getter.get(carrier, "test") self.assertIsNone(val) def test_get(self): - getter = CarrierGetter() + getter = WSGIGetter() carrier = {"HTTP_TEST_KEY": "val"} val = getter.get(carrier, "test-key") self.assertEqual(val, ["val"]) def test_keys(self): - getter = CarrierGetter() + getter = WSGIGetter() keys = getter.keys( { "HTTP_TEST_KEY": "val", @@ -45,7 +45,7 @@ def test_keys(self): self.assertEqual(keys, ["test-key", "other-key"]) def test_keys_empty(self): - getter = CarrierGetter() + getter = WSGIGetter() keys = getter.keys({}) self.assertEqual(keys, []) diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py index 603096cb6e..4013237749 100644 --- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py +++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py @@ -18,10 +18,12 @@ from opentelemetry.baggage import get_all, set_baggage from opentelemetry.context import Context from opentelemetry.propagators.textmap import ( + CarrierT, Getter, Setter, TextMapPropagator, - TextMapPropagatorT, + default_getter, + default_setter, ) from opentelemetry.trace import ( INVALID_SPAN_ID, @@ -49,9 +51,9 @@ class OTTracePropagator(TextMapPropagator): def extract( self, - getter: Getter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: Optional[Context] = None, + getter: Getter = default_getter, ) -> Context: traceid = _extract_first_element( @@ -107,9 +109,9 @@ def extract( def inject( self, - set_in_carrier: Setter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: Optional[Context] = None, + setter: Setter = default_setter, ) -> None: span_context = get_current_span(context).get_span_context() @@ -117,10 +119,10 @@ def inject( if span_context.trace_id == INVALID_TRACE_ID: return - set_in_carrier( + setter.set( carrier, OT_TRACE_ID_HEADER, hex(span_context.trace_id)[2:][-16:] ) - set_in_carrier( + setter.set( carrier, OT_SPAN_ID_HEADER, hex(span_context.span_id)[2:][-16:], ) @@ -129,7 +131,7 @@ def inject( else: traceflags = "false" - set_in_carrier(carrier, OT_SAMPLED_HEADER, traceflags) + setter.set(carrier, OT_SAMPLED_HEADER, traceflags) baggage = get_all(context) @@ -144,7 +146,7 @@ def inject( ): continue - set_in_carrier( + setter.set( carrier, "".join([OT_BAGGAGE_PREFIX, header_name]), header_value, @@ -165,8 +167,8 @@ def fields(self): def _extract_first_element( - items: Iterable[TextMapPropagatorT], default: Any = None, -) -> Optional[TextMapPropagatorT]: + items: Iterable[CarrierT], default: Any = None, +) -> Optional[CarrierT]: if items is None: return default return next(iter(items), None) diff --git a/propagator/opentelemetry-propagator-ot-trace/tests/test_ot_trace_propagator.py b/propagator/opentelemetry-propagator-ot-trace/tests/test_ot_trace_propagator.py index e8b19e44a0..5afa91d5da 100644 --- a/propagator/opentelemetry-propagator-ot-trace/tests/test_ot_trace_propagator.py +++ b/propagator/opentelemetry-propagator-ot-trace/tests/test_ot_trace_propagator.py @@ -22,7 +22,6 @@ OT_TRACE_ID_HEADER, OTTracePropagator, ) -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.sdk.trace import _Span from opentelemetry.trace import ( INVALID_SPAN_CONTEXT, @@ -34,8 +33,6 @@ ) from opentelemetry.trace.propagation import get_current_span -carrier_getter = DictGetter() - class TestOTTracePropagator(TestCase): @@ -46,7 +43,6 @@ def carrier_inject(self, trace_id, span_id, is_remote, trace_flags): carrier = {} self.ot_trace_propagator.inject( - dict.__setitem__, carrier, set_span_in_context( _Span( @@ -155,7 +151,6 @@ def test_inject_set_baggage(self): carrier = {} self.ot_trace_propagator.inject( - dict.__setitem__, carrier, set_baggage( "key", @@ -184,7 +179,6 @@ def test_inject_invalid_baggage_keys(self): carrier = {} self.ot_trace_propagator.inject( - dict.__setitem__, carrier, set_baggage( "(", @@ -213,7 +207,6 @@ def test_inject_invalid_baggage_values(self): carrier = {} self.ot_trace_propagator.inject( - dict.__setitem__, carrier, set_baggage( "key", @@ -241,7 +234,6 @@ def test_extract_trace_id_span_id_sampled_true(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "80f198ee56343ba864fe8b2a57d3eff7", OT_SPAN_ID_HEADER: "e457b5a2e4d86bd1", @@ -262,7 +254,6 @@ def test_extract_trace_id_span_id_sampled_false(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "80f198ee56343ba864fe8b2a57d3eff7", OT_SPAN_ID_HEADER: "e457b5a2e4d86bd1", @@ -283,7 +274,6 @@ def test_extract_malformed_trace_id(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "abc123!", OT_SPAN_ID_HEADER: "e457b5a2e4d86bd1", @@ -299,7 +289,6 @@ def test_extract_malformed_span_id(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "64fe8b2a57d3eff7", OT_SPAN_ID_HEADER: "abc123!", @@ -315,7 +304,6 @@ def test_extract_invalid_trace_id(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: INVALID_TRACE_ID, OT_SPAN_ID_HEADER: "e457b5a2e4d86bd1", @@ -331,7 +319,6 @@ def test_extract_invalid_span_id(self): span_context = get_current_span( self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "64fe8b2a57d3eff7", OT_SPAN_ID_HEADER: INVALID_SPAN_ID, @@ -346,7 +333,6 @@ def test_extract_baggage(self): """Test baggage extraction""" context = self.ot_trace_propagator.extract( - carrier_getter, { OT_TRACE_ID_HEADER: "64fe8b2a57d3eff7", OT_SPAN_ID_HEADER: "e457b5a2e4d86bd1", @@ -371,7 +357,7 @@ def test_extract_empty(self): "Test extraction when no headers are present" span_context = get_current_span( - self.ot_trace_propagator.extract(carrier_getter, {}) + self.ot_trace_propagator.extract({}) ).get_span_context() self.assertEqual(span_context, INVALID_SPAN_CONTEXT) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/propagation/aws_xray_format.py b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/propagation/aws_xray_format.py index 4bd8a08907..2ede9e9ae2 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/propagation/aws_xray_format.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/propagation/aws_xray_format.py @@ -54,10 +54,12 @@ import opentelemetry.trace as trace from opentelemetry.context import Context from opentelemetry.propagators.textmap import ( + CarrierT, Getter, Setter, TextMapPropagator, - TextMapPropagatorT, + default_getter, + default_setter, ) TRACE_HEADER_KEY = "X-Amzn-Trace-Id" @@ -100,9 +102,9 @@ class AwsXRayFormat(TextMapPropagator): def extract( self, - getter: Getter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: typing.Optional[Context] = None, + getter: Getter = default_getter, ) -> Context: trace_header_list = getter.get(carrier, TRACE_HEADER_KEY) @@ -267,9 +269,9 @@ def _parse_sampled_flag(sampled_flag_str): def inject( self, - set_in_carrier: Setter[TextMapPropagatorT], - carrier: TextMapPropagatorT, + carrier: CarrierT, context: typing.Optional[Context] = None, + setter: Setter = default_setter, ) -> None: span = trace.get_current_span(context=context) @@ -307,16 +309,12 @@ def inject( ] ) - set_in_carrier( + setter.set( carrier, TRACE_HEADER_KEY, trace_header, ) @property def fields(self): - """Returns a set with the fields set in `inject`. - - See - `opentelemetry.propagators.textmap.TextMapPropagator.fields` - """ + """Returns a set with the fields set in `inject`.""" return {TRACE_HEADER_KEY} diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/propagation/test_benchmark_aws_xray_format.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/propagation/test_benchmark_aws_xray_format.py index df2e205cae..cd1f48aac5 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/propagation/test_benchmark_aws_xray_format.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/performance/benchmarks/trace/propagation/test_benchmark_aws_xray_format.py @@ -14,7 +14,6 @@ from requests.structures import CaseInsensitiveDict -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.sdk.extension.aws.trace.propagation.aws_xray_format import ( TRACE_HEADER_KEY, AwsXRayFormat, @@ -26,7 +25,6 @@ def test_extract_single_header(benchmark): benchmark( XRAY_PROPAGATOR.extract, - DictGetter(), { TRACE_HEADER_KEY: "bdb5b63237ed38aea578af665aa5aa60-00000000000000000c32d953d73ad225" }, @@ -34,4 +32,6 @@ def test_extract_single_header(benchmark): def test_inject_empty_context(benchmark): - benchmark(XRAY_PROPAGATOR.inject, CaseInsensitiveDict.__setitem__, {}) + benchmark( + XRAY_PROPAGATOR.inject, {}, setter=CaseInsensitiveDict.__setitem__ + ) diff --git a/sdk-extension/opentelemetry-sdk-extension-aws/tests/trace/propagation/test_aws_xray_format.py b/sdk-extension/opentelemetry-sdk-extension-aws/tests/trace/propagation/test_aws_xray_format.py index 7248ed8c2c..cd066cc154 100644 --- a/sdk-extension/opentelemetry-sdk-extension-aws/tests/trace/propagation/test_aws_xray_format.py +++ b/sdk-extension/opentelemetry-sdk-extension-aws/tests/trace/propagation/test_aws_xray_format.py @@ -18,7 +18,6 @@ from requests.structures import CaseInsensitiveDict import opentelemetry.trace as trace_api -from opentelemetry.propagators.textmap import DictGetter from opentelemetry.sdk.extension.aws.trace.propagation.aws_xray_format import ( TRACE_HEADER_KEY, AwsXRayFormat, @@ -85,8 +84,6 @@ def build_test_span_context( class AwsXRayPropagatorTest(unittest.TestCase): - carrier_setter = CaseInsensitiveDict.__setitem__ - carrier_getter = DictGetter() XRAY_PROPAGATOR = AwsXRayFormat() # Inject Tests @@ -95,9 +92,7 @@ def test_inject_into_non_sampled_context(self): carrier = CaseInsensitiveDict() AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject( - AwsXRayPropagatorTest.carrier_setter, - carrier, - build_test_current_context(), + carrier, build_test_current_context(), ) injected_items = set(carrier.items()) @@ -115,7 +110,6 @@ def test_inject_into_sampled_context(self): carrier = CaseInsensitiveDict() AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject( - AwsXRayPropagatorTest.carrier_setter, carrier, build_test_current_context( trace_flags=TraceFlags(TraceFlags.SAMPLED) @@ -137,7 +131,6 @@ def test_inject_into_context_with_non_default_state(self): carrier = CaseInsensitiveDict() AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject( - AwsXRayPropagatorTest.carrier_setter, carrier, build_test_current_context( trace_state=TraceState([("foo", "bar")]) @@ -160,9 +153,7 @@ def test_inject_reported_fields_matches_carrier_fields(self): carrier = CaseInsensitiveDict() AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject( - AwsXRayPropagatorTest.carrier_setter, - carrier, - build_test_current_context(), + carrier, build_test_current_context(), ) injected_keys = set(carrier.keys()) @@ -175,7 +166,7 @@ def test_inject_reported_fields_matches_carrier_fields(self): def test_extract_empty_carrier_from_invalid_context(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict() + CaseInsensitiveDict() ) self.assertEqual( @@ -185,7 +176,6 @@ def test_extract_empty_carrier_from_invalid_context(self): def test_extract_not_sampled_context(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=0" @@ -200,7 +190,6 @@ def test_extract_not_sampled_context(self): def test_extract_sampled_context(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=1" @@ -217,7 +206,6 @@ def test_extract_sampled_context(self): def test_extract_different_order(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Sampled=0;Parent=53995c3f42cd8ad8;Root=1-8a3c60f7-d188f8fa79d48a391a778fa6" @@ -232,7 +220,6 @@ def test_extract_different_order(self): def test_extract_with_additional_fields(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=0;Foo=Bar" @@ -247,7 +234,6 @@ def test_extract_with_additional_fields(self): def test_extract_with_extra_whitespace(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: " Root = 1-8a3c60f7-d188f8fa79d48a391a778fa6 ; Parent = 53995c3f42cd8ad8 ; Sampled = 0 " @@ -262,7 +248,6 @@ def test_extract_with_extra_whitespace(self): def test_extract_invalid_xray_trace_header(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict({TRACE_HEADER_KEY: ""}), ) @@ -273,7 +258,6 @@ def test_extract_invalid_xray_trace_header(self): def test_extract_invalid_trace_id(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-12345678-abcdefghijklmnopqrstuvwx;Parent=53995c3f42cd8ad8;Sampled=0" @@ -288,7 +272,6 @@ def test_extract_invalid_trace_id(self): def test_extract_invalid_trace_id_size(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa600;Parent=53995c3f42cd8ad8;Sampled=0=" @@ -303,7 +286,6 @@ def test_extract_invalid_trace_id_size(self): def test_extract_invalid_span_id(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=abcdefghijklmnop;Sampled=0" @@ -318,7 +300,6 @@ def test_extract_invalid_span_id(self): def test_extract_invalid_span_id_size(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad800;Sampled=0" @@ -333,7 +314,6 @@ def test_extract_invalid_span_id_size(self): def test_extract_invalid_empty_sampled_flag(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=" @@ -348,7 +328,6 @@ def test_extract_invalid_empty_sampled_flag(self): def test_extract_invalid_sampled_flag_size(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=011" @@ -363,7 +342,6 @@ def test_extract_invalid_sampled_flag_size(self): def test_extract_invalid_non_numeric_sampled_flag(self): context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract( - AwsXRayPropagatorTest.carrier_getter, CaseInsensitiveDict( { TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=a" @@ -395,13 +373,13 @@ def test_fields(self, mock_trace): } ) - mock_set_in_carrier = Mock() + mock_setter = Mock() - AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject(mock_set_in_carrier, {}) + AwsXRayPropagatorTest.XRAY_PROPAGATOR.inject({}, setter=mock_setter) inject_fields = set() - for call in mock_set_in_carrier.mock_calls: + for call in mock_setter.mock_calls: inject_fields.add(call[1][1]) self.assertEqual(