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. 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
General Notes
Thank you for contributing to sentry-python!
Please add tests to validate your changes, and lint your code using tox -e linters.
Running the test suite on your PR might require maintainer approval. Some tests (AWS Lambda) additionally require a maintainer to add a special label to run and will fail if the label is not present.
For maintainers
Sensitive test suites require maintainer review to ensure that tests do not compromise our secrets. This review must be repeated after any code revisions.
Before running sensitive test suites, please carefully check the PR. Then, apply the Trigger: tests using secrets label. The label will be removed after any code changes to enforce our policy requiring maintainers to review all code revisions before running sensitive tests.