Skip to content

Commit d2547ea

Browse files
fix(profiling): get_frame_name only look at arguments (#1684)
Looking for `self` and `cls` is not sufficient because they may have come from an outer scope. Make sure to check that they are coming from the frame's positional arguments. Co-authored-by: Anton Pirker <anton.pirker@sentry.io>
1 parent 29431f6 commit d2547ea

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

sentry_sdk/profiler.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,35 @@ def get_frame_name(frame):
202202
# in 3.11+, there is a frame.f_code.co_qualname that
203203
# we should consider using instead where possible
204204

205+
f_code = frame.f_code
205206
# co_name only contains the frame name. If the frame was a method,
206207
# the class name will NOT be included.
207-
name = frame.f_code.co_name
208+
name = f_code.co_name
208209

209210
# if it was a method, we can get the class name by inspecting
210211
# the f_locals for the `self` argument
211212
try:
212-
if "self" in frame.f_locals:
213+
if (
214+
# the co_varnames start with the frame's positional arguments
215+
# and we expect the first to be `self` if its an instance method
216+
f_code.co_varnames
217+
and f_code.co_varnames[0] == "self"
218+
and "self" in frame.f_locals
219+
):
213220
return "{}.{}".format(frame.f_locals["self"].__class__.__name__, name)
214221
except AttributeError:
215222
pass
216223

217224
# if it was a class method, (decorated with `@classmethod`)
218225
# we can get the class name by inspecting the f_locals for the `cls` argument
219226
try:
220-
if "cls" in frame.f_locals:
227+
if (
228+
# the co_varnames start with the frame's positional arguments
229+
# and we expect the first to be `cls` if its a class method
230+
f_code.co_varnames
231+
and f_code.co_varnames[0] == "cls"
232+
and "cls" in frame.f_locals
233+
):
221234
return "{}.{}".format(frame.f_locals["cls"].__name__, name)
222235
except AttributeError:
223236
pass

tests/test_profiler.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,25 @@ class GetFrame:
8585
def instance_method(self):
8686
return inspect.currentframe()
8787

88+
def instance_method_wrapped(self):
89+
def wrapped():
90+
self
91+
return inspect.currentframe()
92+
93+
return wrapped
94+
8895
@classmethod
8996
def class_method(cls):
9097
return inspect.currentframe()
9198

99+
@classmethod
100+
def class_method_wrapped(cls):
101+
def wrapped():
102+
cls
103+
return inspect.currentframe()
104+
105+
return wrapped
106+
92107
@staticmethod
93108
def static_method():
94109
return inspect.currentframe()
@@ -112,11 +127,21 @@ def static_method():
112127
"GetFrame.instance_method",
113128
id="instance_method",
114129
),
130+
pytest.param(
131+
GetFrame().instance_method_wrapped()(),
132+
"wrapped",
133+
id="instance_method_wrapped",
134+
),
115135
pytest.param(
116136
GetFrame().class_method(),
117137
"GetFrame.class_method",
118138
id="class_method",
119139
),
140+
pytest.param(
141+
GetFrame().class_method_wrapped()(),
142+
"wrapped",
143+
id="class_method_wrapped",
144+
),
120145
pytest.param(
121146
GetFrame().static_method(),
122147
"GetFrame.static_method",

0 commit comments

Comments
 (0)