From d34076a47ec2faa9b096fa13e471c892a00a7ab0 Mon Sep 17 00:00:00 2001 From: Hashim1999164 <64767361+Hashim1999164@users.noreply.github.com> Date: Thu, 20 Aug 2026 00:45:53 +0500 Subject: [PATCH] Preserve staticmethod when AutoTracingPlugin rebinds class members. --- src/google/adk/plugins/auto_tracing_plugin.py | 16 ++++++++------ .../plugins/test_auto_tracing_plugin.py | 21 ++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/google/adk/plugins/auto_tracing_plugin.py b/src/google/adk/plugins/auto_tracing_plugin.py index df993524b0f..b1cabbf46c9 100644 --- a/src/google/adk/plugins/auto_tracing_plugin.py +++ b/src/google/adk/plugins/auto_tracing_plugin.py @@ -167,13 +167,17 @@ def _rebind( if getattr(fn, auto_tracing_helpers.WRAPPED_ATTR, False): return try: - setattr( - owner, - name, - auto_tracing_helpers.build_tracing_wrapper( - fn, self._tracer, self._caps - ), + wrapper = auto_tracing_helpers.build_tracing_wrapper( + fn, self._tracer, self._caps ) + # inspect.getmembers unwraps staticmethod to a plain function. + # Reapply the descriptor so instance access does not bind self. + raw = getattr(owner, "__dict__", {}).get(name) + if isinstance(raw, staticmethod): + wrapper = staticmethod(wrapper) + elif isinstance(raw, classmethod): + wrapper = classmethod(wrapper) + setattr(owner, name, wrapper) except (AttributeError, TypeError) as exc: logger.info( "AutoTracingPlugin: cannot rebind %s.%s: %s", diff --git a/tests/unittests/plugins/test_auto_tracing_plugin.py b/tests/unittests/plugins/test_auto_tracing_plugin.py index 3e5dd27e1be..819701b5cf0 100644 --- a/tests/unittests/plugins/test_auto_tracing_plugin.py +++ b/tests/unittests/plugins/test_auto_tracing_plugin.py @@ -58,7 +58,20 @@ async def _async_method(unused_self, x: int) -> int: _method.__module__ = _FIXTURE_MODULE_NAME _async_method.__module__ = _FIXTURE_MODULE_NAME - cls = type("C", (), {"method": _method, "async_method": _async_method}) + + def _static(a, b=None): + return ("static", a, b) + + _static.__module__ = _FIXTURE_MODULE_NAME + cls = type( + "C", + (), + { + "method": _method, + "async_method": _async_method, + "static": staticmethod(_static), + }, + ) cls.__module__ = _FIXTURE_MODULE_NAME module.sync_fn = _sync_fn @@ -145,6 +158,12 @@ def _instrument( return plugin +def test_staticmethod_does_not_bind_instance(fixture): + _instrument(fixture.tracer) + assert fixture.module.C.static(a=1) == ("static", 1, None) + assert fixture.module.C().static(a=1) == ("static", 1, None) + + @pytest.mark.parametrize( "run_fn,expected_substr", [