diff --git a/sentry_sdk/profiler.py b/sentry_sdk/profiler.py index aafb4129bb..660e2aac4c 100644 --- a/sentry_sdk/profiler.py +++ b/sentry_sdk/profiler.py @@ -202,14 +202,21 @@ def get_frame_name(frame): # in 3.11+, there is a frame.f_code.co_qualname that # we should consider using instead where possible + f_code = frame.f_code # co_name only contains the frame name. If the frame was a method, # the class name will NOT be included. - name = frame.f_code.co_name + name = f_code.co_name # if it was a method, we can get the class name by inspecting # the f_locals for the `self` argument try: - if "self" in frame.f_locals: + if ( + # the co_varnames start with the frame's positional arguments + # and we expect the first to be `self` if its an instance method + f_code.co_varnames + and f_code.co_varnames[0] == "self" + and "self" in frame.f_locals + ): return "{}.{}".format(frame.f_locals["self"].__class__.__name__, name) except AttributeError: pass @@ -217,7 +224,13 @@ def get_frame_name(frame): # if it was a class method, (decorated with `@classmethod`) # we can get the class name by inspecting the f_locals for the `cls` argument try: - if "cls" in frame.f_locals: + if ( + # the co_varnames start with the frame's positional arguments + # and we expect the first to be `cls` if its a class method + f_code.co_varnames + and f_code.co_varnames[0] == "cls" + and "cls" in frame.f_locals + ): return "{}.{}".format(frame.f_locals["cls"].__name__, name) except AttributeError: pass diff --git a/tests/test_profiler.py b/tests/test_profiler.py index 2cd50e9a86..305d134b14 100644 --- a/tests/test_profiler.py +++ b/tests/test_profiler.py @@ -85,10 +85,25 @@ class GetFrame: def instance_method(self): return inspect.currentframe() + def instance_method_wrapped(self): + def wrapped(): + self + return inspect.currentframe() + + return wrapped + @classmethod def class_method(cls): return inspect.currentframe() + @classmethod + def class_method_wrapped(cls): + def wrapped(): + cls + return inspect.currentframe() + + return wrapped + @staticmethod def static_method(): return inspect.currentframe() @@ -112,11 +127,21 @@ def static_method(): "GetFrame.instance_method", id="instance_method", ), + pytest.param( + GetFrame().instance_method_wrapped()(), + "wrapped", + id="instance_method_wrapped", + ), pytest.param( GetFrame().class_method(), "GetFrame.class_method", id="class_method", ), + pytest.param( + GetFrame().class_method_wrapped()(), + "wrapped", + id="class_method_wrapped", + ), pytest.param( GetFrame().static_method(), "GetFrame.static_method",