diff --git a/.sg/rules/core-dispatch-list-args-bare-multi.yml b/.sg/rules/core-dispatch-list-args-bare-multi.yml new file mode 100644 index 00000000000..7471aa81a29 --- /dev/null +++ b/.sg/rules/core-dispatch-list-args-bare-multi.yml @@ -0,0 +1,19 @@ +id: core-dispatch-list-args-bare-multi +message: Pass a tuple, not a list, to `dispatch()` +severity: error +language: python +fix: dispatch($EVENT, ($FIRST, $$$REST)) +rule: + pattern: dispatch($EVENT, [$FIRST, $$$REST]) +ignores: + - "ddtrace/internal/core/__init__.py" + - "ddtrace/internal/core/event_hub.py" +note: | + `dispatch()` (imported from `ddtrace.internal.core`) is typed as + `args: tuple[Any, ...]`. Passing a list literal violates the type contract. + + Before: + dispatch("my.event", [arg1, arg2]) + + After: + dispatch("my.event", (arg1, arg2)) diff --git a/.sg/rules/core-dispatch-list-args-bare-single.yml b/.sg/rules/core-dispatch-list-args-bare-single.yml new file mode 100644 index 00000000000..7f0d005b1f5 --- /dev/null +++ b/.sg/rules/core-dispatch-list-args-bare-single.yml @@ -0,0 +1,20 @@ +id: core-dispatch-list-args-bare-single +message: Pass a tuple, not a list, to `dispatch()` — single-element tuples need a trailing comma +severity: error +language: python +fix: dispatch($EVENT, ($ARG,)) +rule: + pattern: dispatch($EVENT, [$ARG]) +ignores: + - "ddtrace/internal/core/__init__.py" + - "ddtrace/internal/core/event_hub.py" +note: | + `dispatch()` (imported from `ddtrace.internal.core`) is typed as + `args: tuple[Any, ...]`. Passing a list literal violates the type contract. + Single-element tuples require a trailing comma. + + Before: + dispatch("my.event", [arg]) + + After: + dispatch("my.event", (arg,)) diff --git a/.sg/rules/core-dispatch-list-args-multi.yml b/.sg/rules/core-dispatch-list-args-multi.yml new file mode 100644 index 00000000000..6544737bda9 --- /dev/null +++ b/.sg/rules/core-dispatch-list-args-multi.yml @@ -0,0 +1,19 @@ +id: core-dispatch-list-args-multi +message: Pass a tuple, not a list, to `core.dispatch()` +severity: error +language: python +fix: $OBJ.dispatch($EVENT, ($FIRST, $$$REST)) +rule: + pattern: $OBJ.dispatch($EVENT, [$FIRST, $$$REST]) +constraints: + OBJ: + regex: "^(core|event_hub)$" +note: | + `core.dispatch()` is typed as `args: tuple[Any, ...]`. Passing a list literal + violates the type contract. + + Before: + core.dispatch("my.event", [arg1, arg2]) + + After: + core.dispatch("my.event", (arg1, arg2)) diff --git a/.sg/rules/core-dispatch-list-args-single.yml b/.sg/rules/core-dispatch-list-args-single.yml new file mode 100644 index 00000000000..9b5c2dd9653 --- /dev/null +++ b/.sg/rules/core-dispatch-list-args-single.yml @@ -0,0 +1,19 @@ +id: core-dispatch-list-args-single +message: Pass a tuple, not a list, to `core.dispatch()` — single-element tuples need a trailing comma +severity: error +language: python +fix: $OBJ.dispatch($EVENT, ($ARG,)) +rule: + pattern: $OBJ.dispatch($EVENT, [$ARG]) +constraints: + OBJ: + regex: "^(core|event_hub)$" +note: | + `core.dispatch()` is typed as `args: tuple[Any, ...]`. Passing a list literal + violates the type contract. Single-element tuples require a trailing comma. + + Before: + core.dispatch("my.event", [arg]) + + After: + core.dispatch("my.event", (arg,)) diff --git a/.sg/tests/__snapshots__/core-dispatch-list-args-bare-multi-snapshot.yml b/.sg/tests/__snapshots__/core-dispatch-list-args-bare-multi-snapshot.yml new file mode 100644 index 00000000000..7f47b1a6c96 --- /dev/null +++ b/.sg/tests/__snapshots__/core-dispatch-list-args-bare-multi-snapshot.yml @@ -0,0 +1,31 @@ +id: core-dispatch-list-args-bare-multi +snapshots: + ? | + from ddtrace.internal.core import dispatch + dispatch( + "my.event", + [ctx, span, result], + ) + : fixed: | + from ddtrace.internal.core import dispatch + dispatch("my.event", (ctx, span, result)) + labels: + - source: |- + dispatch( + "my.event", + [ctx, span, result], + ) + style: primary + start: 43 + end: 95 + ? | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg1, arg2]) + : fixed: | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg1, arg2)) + labels: + - source: dispatch("my.event", [arg1, arg2]) + style: primary + start: 43 + end: 77 diff --git a/.sg/tests/__snapshots__/core-dispatch-list-args-bare-single-snapshot.yml b/.sg/tests/__snapshots__/core-dispatch-list-args-bare-single-snapshot.yml new file mode 100644 index 00000000000..4f30664b118 --- /dev/null +++ b/.sg/tests/__snapshots__/core-dispatch-list-args-bare-single-snapshot.yml @@ -0,0 +1,31 @@ +id: core-dispatch-list-args-bare-single +snapshots: + ? | + from ddtrace.internal.core import dispatch + dispatch( + "my.event", + [ctx], + ) + : fixed: | + from ddtrace.internal.core import dispatch + dispatch("my.event", (ctx,)) + labels: + - source: |- + dispatch( + "my.event", + [ctx], + ) + style: primary + start: 43 + end: 81 + ? | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg]) + : fixed: | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg,)) + labels: + - source: dispatch("my.event", [arg]) + style: primary + start: 43 + end: 70 diff --git a/.sg/tests/__snapshots__/core-dispatch-list-args-multi-snapshot.yml b/.sg/tests/__snapshots__/core-dispatch-list-args-multi-snapshot.yml new file mode 100644 index 00000000000..12524d3555c --- /dev/null +++ b/.sg/tests/__snapshots__/core-dispatch-list-args-multi-snapshot.yml @@ -0,0 +1,75 @@ +id: core-dispatch-list-args-multi +snapshots: + ? | + core.dispatch( + "my.event", + [ + arg1, + arg2, + arg3, + ], + ) + : fixed: | + core.dispatch("my.event", (arg1, arg2, + arg3,)) + labels: + - source: |- + core.dispatch( + "my.event", + [ + arg1, + arg2, + arg3, + ], + ) + style: primary + start: 0 + end: 87 + ? | + core.dispatch( + "my.event", + [ctx, span, result], + ) + : fixed: | + core.dispatch("my.event", (ctx, span, result)) + labels: + - source: |- + core.dispatch( + "my.event", + [ctx, span, result], + ) + style: primary + start: 0 + end: 57 + core.dispatch("my.event", [arg1, arg2, arg3]): + fixed: core.dispatch("my.event", (arg1, arg2, arg3)) + labels: + - source: core.dispatch("my.event", [arg1, arg2, arg3]) + style: primary + start: 0 + end: 45 + core.dispatch("my.event", [arg1, arg2]): + fixed: core.dispatch("my.event", (arg1, arg2)) + labels: + - source: core.dispatch("my.event", [arg1, arg2]) + style: primary + start: 0 + end: 39 + core.dispatch("my.event", [ctx, rowcount]): + fixed: core.dispatch("my.event", (ctx, rowcount)) + labels: + - source: core.dispatch("my.event", [ctx, rowcount]) + style: primary + start: 0 + end: 42 + ? | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg1, arg2]) + : fixed: | + from ddtrace.internal.core import dispatch + .dispatch("my.event", (arg1, arg2)) + labels: + - source: dispatch("my.event", [arg1, arg2]) + style: primary + start: 43 + end: 77 diff --git a/.sg/tests/__snapshots__/core-dispatch-list-args-single-snapshot.yml b/.sg/tests/__snapshots__/core-dispatch-list-args-single-snapshot.yml new file mode 100644 index 00000000000..04fa0e75130 --- /dev/null +++ b/.sg/tests/__snapshots__/core-dispatch-list-args-single-snapshot.yml @@ -0,0 +1,43 @@ +id: core-dispatch-list-args-single +snapshots: + ? | + core.dispatch( + "my.event", + [ctx], + ) + : fixed: | + core.dispatch("my.event", (ctx,)) + labels: + - source: |- + core.dispatch( + "my.event", + [ctx], + ) + style: primary + start: 0 + end: 43 + core.dispatch("my.event", [arg]): + fixed: core.dispatch("my.event", (arg,)) + labels: + - source: core.dispatch("my.event", [arg]) + style: primary + start: 0 + end: 32 + core.dispatch("my.event", [ctx]): + fixed: core.dispatch("my.event", (ctx,)) + labels: + - source: core.dispatch("my.event", [ctx]) + style: primary + start: 0 + end: 32 + ? | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg]) + : fixed: | + from ddtrace.internal.core import dispatch + .dispatch("my.event", (arg,)) + labels: + - source: dispatch("my.event", [arg]) + style: primary + start: 43 + end: 70 diff --git a/.sg/tests/core-dispatch-list-args-bare-multi-test.yml b/.sg/tests/core-dispatch-list-args-bare-multi-test.yml new file mode 100644 index 00000000000..2c9b00fcd65 --- /dev/null +++ b/.sg/tests/core-dispatch-list-args-bare-multi-test.yml @@ -0,0 +1,30 @@ +id: core-dispatch-list-args-bare-multi +valid: + # Tuple (correct) + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg1, arg2)) + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg1, arg2, arg3)) + # Single-element tuple — handled by the -single rule + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg,)) + # Variable (not a list literal) + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", args) + # Qualified form — handled by the non-bare rules + - core.dispatch("my.event", [arg1, arg2]) + +invalid: + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg1, arg2]) + - | + from ddtrace.internal.core import dispatch + dispatch( + "my.event", + [ctx, span, result], + ) diff --git a/.sg/tests/core-dispatch-list-args-bare-single-test.yml b/.sg/tests/core-dispatch-list-args-bare-single-test.yml new file mode 100644 index 00000000000..522df575170 --- /dev/null +++ b/.sg/tests/core-dispatch-list-args-bare-single-test.yml @@ -0,0 +1,27 @@ +id: core-dispatch-list-args-bare-single +valid: + # Tuple (correct) + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg,)) + # Multi-element tuple — handled by the -multi rule + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", (arg1, arg2)) + # Variable (not a list literal) + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", args) + # Qualified form — handled by the non-bare rules + - core.dispatch("my.event", [arg]) + +invalid: + - | + from ddtrace.internal.core import dispatch + dispatch("my.event", [arg]) + - | + from ddtrace.internal.core import dispatch + dispatch( + "my.event", + [ctx], + ) diff --git a/.sg/tests/core-dispatch-list-args-multi-test.yml b/.sg/tests/core-dispatch-list-args-multi-test.yml new file mode 100644 index 00000000000..c118518ab95 --- /dev/null +++ b/.sg/tests/core-dispatch-list-args-multi-test.yml @@ -0,0 +1,31 @@ +id: core-dispatch-list-args-multi +valid: + # Tuple (correct) + - core.dispatch("my.event", (arg1, arg2)) + - core.dispatch("my.event", (arg1, arg2, arg3)) + # Single-element tuple — handled by the -single rule + - core.dispatch("my.event", (arg,)) + # Variable (not a list literal) + - core.dispatch("my.event", args) + # Non-core dispatcher — must not be flagged even with a list literal + - some_dispatcher.dispatch("my.event", [arg1, arg2]) + - self.dispatcher.dispatch("my.event", [arg1, arg2]) + +invalid: + - core.dispatch("my.event", [arg1, arg2]) + - core.dispatch("my.event", [ctx, rowcount]) + - core.dispatch("my.event", [arg1, arg2, arg3]) + - | + core.dispatch( + "my.event", + [ctx, span, result], + ) + - | + core.dispatch( + "my.event", + [ + arg1, + arg2, + arg3, + ], + ) diff --git a/.sg/tests/core-dispatch-list-args-single-test.yml b/.sg/tests/core-dispatch-list-args-single-test.yml new file mode 100644 index 00000000000..850ef09574f --- /dev/null +++ b/.sg/tests/core-dispatch-list-args-single-test.yml @@ -0,0 +1,20 @@ +id: core-dispatch-list-args-single +valid: + # Tuple (correct) + - core.dispatch("my.event", (arg,)) + # Multi-element tuple — handled by the -multi rule + - core.dispatch("my.event", (arg1, arg2)) + # Variable (not a list literal — can't statically check the type) + - core.dispatch("my.event", args) + # Non-core dispatcher — must not be flagged even with a list literal + - some_dispatcher.dispatch("my.event", [arg]) + - self.dispatcher.dispatch("my.event", [arg]) + +invalid: + - core.dispatch("my.event", [arg]) + - core.dispatch("my.event", [ctx]) + - | + core.dispatch( + "my.event", + [ctx], + ) diff --git a/ddtrace/contrib/internal/botocore/patch.py b/ddtrace/contrib/internal/botocore/patch.py index 6562a480d7a..65695394845 100644 --- a/ddtrace/contrib/internal/botocore/patch.py +++ b/ddtrace/contrib/internal/botocore/patch.py @@ -244,7 +244,7 @@ def prep_context_injection(ctx, endpoint_name, operation, trace_operation, param core.dispatch( "botocore.prep_context_injection.post", - [ctx, cloud_service, schematization_function, injection_function, trace_operation], + (ctx, cloud_service, schematization_function, injection_function, trace_operation), ) @@ -274,7 +274,7 @@ def patched_api_call_fallback(original_func, instance, args, kwargs, function_va ) as ctx, ctx.span, ): - core.dispatch("botocore.patched_api_call.started", [ctx]) + core.dispatch("botocore.patched_api_call.started", (ctx,)) if args and config.botocore["distributed_tracing"]: prep_context_injection(ctx, endpoint_name, operation, trace_operation, params) @@ -283,14 +283,14 @@ def patched_api_call_fallback(original_func, instance, args, kwargs, function_va except botocore.exceptions.ClientError as e: core.dispatch( "botocore.patched_api_call.exception", - [ + ( ctx, e.response, botocore.exceptions.ClientError, config.botocore.operations[ctx.span.resource].is_error_code, - ], + ), ) raise else: - core.dispatch("botocore.patched_api_call.success", [ctx, result]) + core.dispatch("botocore.patched_api_call.success", (ctx, result)) return result diff --git a/ddtrace/contrib/internal/botocore/services/bedrock.py b/ddtrace/contrib/internal/botocore/services/bedrock.py index a35d146ac7b..aa66c8ad1c1 100644 --- a/ddtrace/contrib/internal/botocore/services/bedrock.py +++ b/ddtrace/contrib/internal/botocore/services/bedrock.py @@ -34,13 +34,10 @@ def traced_stream_read(traced_stream, original_read, amt=None): handler.chunks.append(json.loads(body)) if traced_stream.__wrapped__.tell() == int(traced_stream.__wrapped__._content_length): formatted_response = _extract_text_and_response_reason(execution_ctx, handler.chunks[0]) - core.dispatch( - "botocore.bedrock.process_response", - [execution_ctx, formatted_response], - ) + core.dispatch("botocore.bedrock.process_response", (execution_ctx, formatted_response)) return body except Exception: - core.dispatch("botocore.patched_bedrock_api_call.exception", [execution_ctx, sys.exc_info()]) + core.dispatch("botocore.patched_bedrock_api_call.exception", (execution_ctx, sys.exc_info())) raise @@ -53,13 +50,10 @@ def traced_stream_readlines(traced_stream, original_readlines): for line in lines: handler.chunks.append(json.loads(line)) formatted_response = _extract_text_and_response_reason(execution_ctx, handler.chunks[0]) - core.dispatch( - "botocore.bedrock.process_response", - [execution_ctx, formatted_response], - ) + core.dispatch("botocore.bedrock.process_response", (execution_ctx, formatted_response)) return lines except Exception: - core.dispatch("botocore.patched_bedrock_api_call.exception", [execution_ctx, sys.exc_info()]) + core.dispatch("botocore.patched_bedrock_api_call.exception", (execution_ctx, sys.exc_info())) raise @@ -69,7 +63,7 @@ def process_chunk(self, chunk, iterator=None): def handle_exception(self, exception): core.dispatch( - "botocore.patched_bedrock_api_call.exception", [self.options.get("execution_ctx", {}), sys.exc_info()] + "botocore.patched_bedrock_api_call.exception", (self.options.get("execution_ctx", {}), sys.exc_info()) ) def finalize_stream(self, exception=None): @@ -77,10 +71,7 @@ def finalize_stream(self, exception=None): return execution_ctx = self.options.get("execution_ctx", {}) formatted_response = _extract_streamed_response(execution_ctx, self.chunks) - core.dispatch( - "botocore.bedrock.process_response", - [execution_ctx, formatted_response], - ) + core.dispatch("botocore.bedrock.process_response", (execution_ctx, formatted_response)) class BotocoreConverseStreamHandler(StreamHandler): @@ -92,14 +83,14 @@ def process_chunk(self, chunk: dict[str, Any], iterator=None): def handle_exception(self, exception): stream_processor = self.options.get("stream_processor", None) execution_ctx = self.options.get("execution_ctx", {}) - core.dispatch("botocore.bedrock.process_response_converse", [execution_ctx, stream_processor]) + core.dispatch("botocore.bedrock.process_response_converse", (execution_ctx, stream_processor)) def finalize_stream(self, exception=None): if exception: return stream_processor = self.options.get("stream_processor", None) execution_ctx = self.options.get("execution_ctx", {}) - core.dispatch("botocore.bedrock.process_response_converse", [execution_ctx, stream_processor]) + core.dispatch("botocore.bedrock.process_response_converse", (execution_ctx, stream_processor)) def make_botocore_streaming_body_traced_stream(streaming_body, execution_ctx): @@ -391,7 +382,7 @@ def handle_bedrock_request(ctx: core.ExecutionContext) -> None: else _extract_request_params_for_invoke(ctx["params"], ctx["model_provider"]) ) - core.dispatch("botocore.patched_bedrock_api_call.started", [ctx, request_params]) + core.dispatch("botocore.patched_bedrock_api_call.started", (ctx, request_params)) if ctx["bedrock_integration"].llmobs_enabled: ctx.set_item("llmobs.request_params", request_params) @@ -441,7 +432,7 @@ def handle_bedrock_response( ) if ctx["resource"] == "Converse": - core.dispatch("botocore.bedrock.process_response_converse", [ctx, result]) + core.dispatch("botocore.bedrock.process_response_converse", (ctx, result)) return result if ctx["resource"] == "ConverseStream": if "stream" in result: @@ -483,5 +474,5 @@ def patched_bedrock_api_call(original_func, instance, args, kwargs, function_var result = handle_bedrock_response(ctx, result) return result except Exception: - core.dispatch("botocore.patched_bedrock_api_call.exception", [ctx, sys.exc_info()]) + core.dispatch("botocore.patched_bedrock_api_call.exception", (ctx, sys.exc_info())) raise diff --git a/ddtrace/contrib/internal/botocore/services/kinesis.py b/ddtrace/contrib/internal/botocore/services/kinesis.py index 532b2b63d98..a61d1d54c68 100644 --- a/ddtrace/contrib/internal/botocore/services/kinesis.py +++ b/ddtrace/contrib/internal/botocore/services/kinesis.py @@ -34,10 +34,7 @@ class TraceInjectionSizeExceed(Exception): def update_record(ctx, record: dict[str, Any], stream: str, inject_trace_context: bool = True) -> None: line_break, data_obj = get_kinesis_data_object(record["Data"]) if data_obj is not None: - core.dispatch( - "botocore.kinesis.update_record", - [ctx, stream, data_obj, record, inject_trace_context], - ) + core.dispatch("botocore.kinesis.update_record", (ctx, stream, data_obj, record, inject_trace_context)) try: data_json = json.dumps(data_obj) @@ -86,7 +83,7 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, try: start_ns = time_ns() is_getrecords_call = True - core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", [params]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", (params,)) result = original_func(*args, **kwargs) records = result["Records"] @@ -96,7 +93,7 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, time_estimate = record.get("ApproximateArrivalTimestamp", datetime.now()).timestamp() core.dispatch( f"botocore.{endpoint_name}.{operation}.post", - [ + ( parent_ctx, params, time_estimate, @@ -105,7 +102,7 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, result, config.botocore.propagation_enabled, extract_DD_json, - ], + ), ) except Exception as e: @@ -156,7 +153,7 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, ) as ctx, ctx.span, ): - core.dispatch("botocore.patched_kinesis_api_call.started", [ctx]) + core.dispatch("botocore.patched_kinesis_api_call.started", (ctx,)) if is_kinesis_put_operation: records_to_process = select_records_for_injection(params, bool(config.botocore["distributed_tracing"])) @@ -165,25 +162,25 @@ def _patched_kinesis_api_call(parent_ctx, original_func, instance, args, kwargs, try: if not is_getrecords_call: - core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", [params]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", (params,)) result = original_func(*args, **kwargs) - core.dispatch(f"botocore.{endpoint_name}.{operation}.post", [params, result]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.post", (params, result)) if getrecords_error: raise getrecords_error - core.dispatch("botocore.patched_kinesis_api_call.success", [ctx, result]) + core.dispatch("botocore.patched_kinesis_api_call.success", (ctx, result)) return result except botocore.exceptions.ClientError as e: core.dispatch( "botocore.patched_kinesis_api_call.exception", - [ + ( ctx, e.response, botocore.exceptions.ClientError, config.botocore.operations[ctx.span.resource].is_error_code, - ], + ), ) raise elif is_getrecords_call: diff --git a/ddtrace/contrib/internal/botocore/services/sqs.py b/ddtrace/contrib/internal/botocore/services/sqs.py index 3201d93c836..d3f00f37558 100644 --- a/ddtrace/contrib/internal/botocore/services/sqs.py +++ b/ddtrace/contrib/internal/botocore/services/sqs.py @@ -104,12 +104,12 @@ def _patched_sqs_api_call(parent_ctx, original_func, instance, args, kwargs, fun try: func_has_run = True - core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", [params]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", (params,)) # run the function to extract possible parent context before creating ExecutionContext result = original_func(*args, **kwargs) core.dispatch( f"botocore.{endpoint_name}.{operation}.post", - [parent_ctx, params, result, config.botocore.propagation_enabled, extract_DD_json], + (parent_ctx, params, result, config.botocore.propagation_enabled, extract_DD_json), ) except Exception as e: func_run_err = e @@ -161,18 +161,18 @@ def _patched_sqs_api_call(parent_ctx, original_func, instance, args, kwargs, fun ) as ctx, ctx.span, ): - core.dispatch("botocore.patched_sqs_api_call.started", [ctx]) + core.dispatch("botocore.patched_sqs_api_call.started", (ctx,)) if should_update_messages: update_messages(ctx, endpoint_service=endpoint_name) try: if not func_has_run: - core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", [params]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.pre", (params,)) result = original_func(*args, **kwargs) - core.dispatch(f"botocore.{endpoint_name}.{operation}.post", [params, result]) + core.dispatch(f"botocore.{endpoint_name}.{operation}.post", (params, result)) - core.dispatch("botocore.patched_sqs_api_call.success", [ctx, result]) + core.dispatch("botocore.patched_sqs_api_call.success", (ctx, result)) if func_run_err: raise func_run_err @@ -180,12 +180,12 @@ def _patched_sqs_api_call(parent_ctx, original_func, instance, args, kwargs, fun except botocore.exceptions.ClientError as e: core.dispatch( "botocore.patched_sqs_api_call.exception", - [ + ( ctx, e.response, botocore.exceptions.ClientError, config.botocore.operations[ctx.span.resource].is_error_code, - ], + ), ) raise elif func_has_run: diff --git a/ddtrace/contrib/internal/botocore/services/stepfunctions.py b/ddtrace/contrib/internal/botocore/services/stepfunctions.py index 6ecf8848176..83cfa5a55a3 100644 --- a/ddtrace/contrib/internal/botocore/services/stepfunctions.py +++ b/ddtrace/contrib/internal/botocore/services/stepfunctions.py @@ -34,7 +34,7 @@ def update_stepfunction_input(ctx: core.ExecutionContext, params: Any) -> None: return input_obj["_datadog"] = {} - core.dispatch("botocore.stepfunctions.update_input", [ctx, None, None, input_obj, None]) + core.dispatch("botocore.stepfunctions.update_input", (ctx, None, None, input_obj, None)) updated_input_obj = ctx.find_item(BOTOCORE_STEPFUNCTIONS_INPUT_KEY) if updated_input_obj: input_json_str = json.dumps(updated_input_obj) @@ -79,7 +79,7 @@ def patched_stepfunction_api_call(original_func, instance, args, kwargs: dict, f ) as ctx, ctx.span, ): - core.dispatch("botocore.patched_stepfunctions_api_call.started", [ctx]) + core.dispatch("botocore.patched_stepfunctions_api_call.started", (ctx,)) if should_update_input: update_stepfunction_input(ctx, params) @@ -89,11 +89,11 @@ def patched_stepfunction_api_call(original_func, instance, args, kwargs: dict, f except botocore.exceptions.ClientError as e: core.dispatch( "botocore.patched_stepfunctions_api_call.exception", - [ + ( ctx, e.response, botocore.exceptions.ClientError, config.botocore.operations[ctx.span.resource].is_error_code, - ], + ), ) raise diff --git a/ddtrace/contrib/internal/botocore/utils.py b/ddtrace/contrib/internal/botocore/utils.py index e577b7f3f7f..4d33f38aa2f 100644 --- a/ddtrace/contrib/internal/botocore/utils.py +++ b/ddtrace/contrib/internal/botocore/utils.py @@ -77,7 +77,7 @@ def update_eventbridge_detail(ctx: ExecutionContext) -> None: continue detail["_datadog"] = {} - core.dispatch("botocore.eventbridge.update_messages", [ctx, None, None, detail["_datadog"], None]) + core.dispatch("botocore.eventbridge.update_messages", (ctx, None, None, detail["_datadog"], None)) detail_json = json.dumps(detail) # check if detail size will exceed max size with headers @@ -91,7 +91,7 @@ def update_eventbridge_detail(ctx: ExecutionContext) -> None: def update_client_context(ctx: ExecutionContext) -> None: trace_headers = {} - core.dispatch("botocore.client_context.update_messages", [ctx, None, None, trace_headers, None]) + core.dispatch("botocore.client_context.update_messages", (ctx, None, None, trace_headers, None)) client_context_object = {} params = ctx["params"] if "ClientContext" in params: diff --git a/ddtrace/contrib/internal/kombu/patch.py b/ddtrace/contrib/internal/kombu/patch.py index f1ca090e851..619899f365e 100644 --- a/ddtrace/contrib/internal/kombu/patch.py +++ b/ddtrace/contrib/internal/kombu/patch.py @@ -129,7 +129,7 @@ def traced_receive(func, instance, args, kwargs): s.set_tags(extract_conn_tags(message.channel.connection)) s._set_attribute(kombux.ROUTING_KEY, message.delivery_info["routing_key"]) result = func(*args, **kwargs) - core.dispatch("kombu.amqp.receive.post", [instance, message, s]) + core.dispatch("kombu.amqp.receive.post", (instance, message, s)) return result @@ -161,6 +161,6 @@ def traced_publish(func, instance, args, kwargs): if config.kombu.distributed_tracing_enabled: propagator.inject(s.context, args[HEADER_POS]) core.dispatch( - "kombu.amqp.publish.pre", [args, kwargs, s] + "kombu.amqp.publish.pre", (args, kwargs, s) ) # Has to happen after trace injection for actual payload size return func(*args, **kwargs) diff --git a/ddtrace/contrib/internal/molten/wrappers.py b/ddtrace/contrib/internal/molten/wrappers.py index 7cc3e0d0cbd..9972f51c6d5 100644 --- a/ddtrace/contrib/internal/molten/wrappers.py +++ b/ddtrace/contrib/internal/molten/wrappers.py @@ -71,6 +71,6 @@ def match(self, *args, **kwargs): if route_and_params is not None: route, params = route_and_params route.handler = trace_func(func_name(route.handler))(route.handler) - core.dispatch("molten.router.match", [route]) + core.dispatch("molten.router.match", (route,)) return route, params return route_and_params diff --git a/ddtrace/contrib/internal/rq/patch.py b/ddtrace/contrib/internal/rq/patch.py index 66b847ffc16..025b0772e3a 100644 --- a/ddtrace/contrib/internal/rq/patch.py +++ b/ddtrace/contrib/internal/rq/patch.py @@ -82,7 +82,7 @@ def traced_queue_enqueue_job(rq, pin, func, instance, args, kwargs): ): # If the queue is_async then add distributed tracing headers to the job if instance.is_async: - core.dispatch("rq.queue.enqueue_job", [ctx, job.meta]) + core.dispatch("rq.queue.enqueue_job", (ctx, job.meta)) return func(*args, **kwargs) @@ -143,12 +143,12 @@ def traced_perform_job(rq, pin, func, instance, args, kwargs): except Exception: job_failed = False span_tags = {"job.status": status or "None", "job.origin": job.origin} - core.dispatch("rq.worker.perform_job", [ctx, job_failed, span_tags]) + core.dispatch("rq.worker.perform_job", (ctx, job_failed, span_tags)) finally: # Force flush to agent since the process `os.exit()`s # immediately after this method returns - core.dispatch("rq.worker.after.perform.job", [ctx]) + core.dispatch("rq.worker.after.perform.job", (ctx,)) @trace_utils.with_traced_module diff --git a/ddtrace/contrib/internal/trace_utils.py b/ddtrace/contrib/internal/trace_utils.py index d0a35be989f..60ddcf7cddf 100644 --- a/ddtrace/contrib/internal/trace_utils.py +++ b/ddtrace/contrib/internal/trace_utils.py @@ -518,7 +518,7 @@ def set_http_meta( core.dispatch( "set_http_meta_for_asm", - [ + ( span, request_ip, raw_uri, @@ -534,7 +534,7 @@ def set_http_meta( response_cookies, peer_ip, headers_are_case_sensitive, - ], + ), ) if route is not None: diff --git a/ddtrace/contrib/internal/valkey_utils.py b/ddtrace/contrib/internal/valkey_utils.py index b7b2bf22806..3d305eddc11 100644 --- a/ddtrace/contrib/internal/valkey_utils.py +++ b/ddtrace/contrib/internal/valkey_utils.py @@ -79,4 +79,4 @@ async def _run_valkey_command_async(ctx: core.ExecutionContext, func, args, kwar rowcount = determine_row_count(valkey_command=valkey_command, result=result) if valkey_command not in ROW_RETURNING_COMMANDS: rowcount = None - core.dispatch("valkey.async_command.post", [ctx, rowcount]) + core.dispatch("valkey.async_command.post", (ctx, rowcount))