Skip to content

Commit 49b4cf3

Browse files
authored
fix(tests): Fix exception on copying frame.f_locals (Python 3.13) (#3271)
Starting from Python 3.13, `frame.f_locals` is not `dict` anymore, but `FrameLocalsProxy`, that cannot be copied using `copy.copy()`. In Python 3.13 and later, it should be copied using a method `.copy()`. The new way of copying works the same as the old one for versions of Python prior to 3.13, according to the documentation (both copying methods produce a shallow copy). Since Python 3.13, `FrameLocalsProxy` skips items of `locals()` that have non-`str` keys; this is a CPython implementation detail, so we hence disable `test_non_string_variables` test on Python 3.13. See: https://peps.python.org/pep-0667/ python/cpython#118921 python/cpython#118923 https://docs.python.org/3.13/whatsnew/3.13.html#porting-to-python-3-13 https://docs.python.org/3/library/copy.html https://github.com/python/cpython/blame/7b413952e817ae87bfda2ac85dd84d30a6ce743b/Objects/frameobject.c#L148
1 parent b9d1e3e commit 49b4cf3

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

Diff for: sentry_sdk/utils.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import threading
1212
import time
1313
from collections import namedtuple
14-
from copy import copy
1514
from datetime import datetime
1615
from decimal import Decimal
1716
from functools import partial, partialmethod, wraps
@@ -618,7 +617,7 @@ def serialize_frame(
618617
)
619618

620619
if include_local_variables:
621-
rv["vars"] = copy(frame.f_locals)
620+
rv["vars"] = frame.f_locals.copy()
622621

623622
return rv
624623

Diff for: tests/test_client.py

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
from sentry_sdk._types import Event
3232

3333

34+
maximum_python_312 = pytest.mark.skipif(
35+
sys.version_info > (3, 12),
36+
reason="Since Python 3.13, `FrameLocalsProxy` skips items of `locals()` that have non-`str` keys; this is a CPython implementation detail: https://github.com/python/cpython/blame/7b413952e817ae87bfda2ac85dd84d30a6ce743b/Objects/frameobject.c#L148",
37+
)
38+
39+
3440
class EnvelopeCapturedError(Exception):
3541
pass
3642

@@ -879,6 +885,7 @@ class FooError(Exception):
879885
assert exception["mechanism"]["meta"]["errno"]["number"] == 69
880886

881887

888+
@maximum_python_312
882889
def test_non_string_variables(sentry_init, capture_events):
883890
"""There is some extremely terrible code in the wild that
884891
inserts non-strings as variable names into `locals()`."""

0 commit comments

Comments
 (0)