diff --git a/.github/workflows/test-integrations-ai.yml b/.github/workflows/test-integrations-ai.yml index 6653e989be..e262ba1ebc 100644 --- a/.github/workflows/test-integrations-ai.yml +++ b/.github/workflows/test-integrations-ai.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -96,6 +97,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-aws-lambda.yml b/.github/workflows/test-integrations-aws-lambda.yml index 8f8cbc18f1..41ece507cd 100644 --- a/.github/workflows/test-integrations-aws-lambda.yml +++ b/.github/workflows/test-integrations-aws-lambda.yml @@ -71,6 +71,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-cloud-computing.yml b/.github/workflows/test-integrations-cloud-computing.yml index e2bab93dc1..97f56affe0 100644 --- a/.github/workflows/test-integrations-cloud-computing.yml +++ b/.github/workflows/test-integrations-cloud-computing.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -92,6 +93,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-common.yml b/.github/workflows/test-integrations-common.yml index 4b1b13f289..227358b253 100644 --- a/.github/workflows/test-integrations-common.yml +++ b/.github/workflows/test-integrations-common.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.6","3.7","3.8","3.9","3.10","3.11","3.12"] + python-version: ["3.6","3.7","3.8","3.9","3.10","3.11","3.12","3.13"] # python3.6 reached EOL and is no longer being supported on # new versions of hosted runners on Github Actions # ubuntu-20.04 is the last version that supported python3.6 @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-data-processing.yml b/.github/workflows/test-integrations-data-processing.yml index 5d768bb7d0..0ab85b686d 100644 --- a/.github/workflows/test-integrations-data-processing.yml +++ b/.github/workflows/test-integrations-data-processing.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Start Redis uses: supercharge/redis-github-action@1.8.0 - name: Setup Test Env @@ -102,6 +103,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Start Redis uses: supercharge/redis-github-action@1.8.0 - name: Setup Test Env diff --git a/.github/workflows/test-integrations-databases.yml b/.github/workflows/test-integrations-databases.yml index d0ecc89c94..91634ecc79 100644 --- a/.github/workflows/test-integrations-databases.yml +++ b/.github/workflows/test-integrations-databases.yml @@ -54,6 +54,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - uses: getsentry/action-clickhouse-in-ci@v1 - name: Setup Test Env run: | @@ -137,6 +138,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - uses: getsentry/action-clickhouse-in-ci@v1 - name: Setup Test Env run: | diff --git a/.github/workflows/test-integrations-graphql.yml b/.github/workflows/test-integrations-graphql.yml index dd17bf51ec..afa49ee142 100644 --- a/.github/workflows/test-integrations-graphql.yml +++ b/.github/workflows/test-integrations-graphql.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -92,6 +93,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-miscellaneous.yml b/.github/workflows/test-integrations-miscellaneous.yml index 982b8613c8..93114c8767 100644 --- a/.github/workflows/test-integrations-miscellaneous.yml +++ b/.github/workflows/test-integrations-miscellaneous.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -96,6 +97,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-networking.yml b/.github/workflows/test-integrations-networking.yml index ac36574425..12fb503379 100644 --- a/.github/workflows/test-integrations-networking.yml +++ b/.github/workflows/test-integrations-networking.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -92,6 +93,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-web-frameworks-1.yml b/.github/workflows/test-integrations-web-frameworks-1.yml index 743a97cfa0..f68aeea65c 100644 --- a/.github/workflows/test-integrations-web-frameworks-1.yml +++ b/.github/workflows/test-integrations-web-frameworks-1.yml @@ -54,6 +54,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -128,6 +129,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/.github/workflows/test-integrations-web-frameworks-2.yml b/.github/workflows/test-integrations-web-frameworks-2.yml index 09d179271a..970d5ca99e 100644 --- a/.github/workflows/test-integrations-web-frameworks-2.yml +++ b/.github/workflows/test-integrations-web-frameworks-2.yml @@ -36,6 +36,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox @@ -112,6 +113,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Setup Test Env run: | pip install coverage tox diff --git a/scripts/split-tox-gh-actions/templates/test_group.jinja b/scripts/split-tox-gh-actions/templates/test_group.jinja index dcf3a3734b..8d42d0c7eb 100644 --- a/scripts/split-tox-gh-actions/templates/test_group.jinja +++ b/scripts/split-tox-gh-actions/templates/test_group.jinja @@ -49,6 +49,7 @@ - uses: actions/setup-python@v5 with: python-version: {% raw %}${{ matrix.python-version }}{% endraw %} + allow-prereleases: true {% if needs_clickhouse %} - uses: getsentry/action-clickhouse-in-ci@v1 {% endif %} diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 2079be52cc..8a805d3d64 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -11,7 +11,6 @@ import threading import time from collections import namedtuple -from copy import copy from datetime import datetime from decimal import Decimal from functools import partial, partialmethod, wraps @@ -611,7 +610,7 @@ def serialize_frame( ) if include_local_variables: - rv["vars"] = copy(frame.f_locals) + rv["vars"] = frame.f_locals.copy() return rv @@ -1330,14 +1329,18 @@ def qualname_from_function(func): prefix, suffix = "", "" - if hasattr(func, "_partialmethod") and isinstance( - func._partialmethod, partialmethod - ): - prefix, suffix = "partialmethod()" - func = func._partialmethod.func - elif isinstance(func, partial) and hasattr(func.func, "__name__"): + if isinstance(func, partial) and hasattr(func.func, "__name__"): prefix, suffix = "partial()" func = func.func + else: + # The _partialmethod attribute of methods wrapped with partialmethod() was renamed to __partialmethod__ in CPython 3.13: + # https://github.com/python/cpython/pull/16600 + partial_method = getattr(func, "_partialmethod", None) or getattr( + func, "__partialmethod__", None + ) + if isinstance(partial_method, partialmethod): + prefix, suffix = "partialmethod()" + func = partial_method.func if hasattr(func, "__qualname__"): func_qualname = func.__qualname__ diff --git a/tests/test_client.py b/tests/test_client.py index 3be8b1e64b..571912ab12 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -33,6 +33,12 @@ from sentry_sdk._types import Event +maximum_python_312 = pytest.mark.skipif( + sys.version_info > (3, 12), + 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", +) + + class EnvelopeCapturedError(Exception): pass @@ -889,6 +895,7 @@ class FooError(Exception): assert exception["mechanism"]["meta"]["errno"]["number"] == 69 +@maximum_python_312 def test_non_string_variables(sentry_init, capture_events): """There is some extremely terrible code in the wild that inserts non-strings as variable names into `locals()`.""" diff --git a/tox.ini b/tox.ini index 216b9c6e5a..1377b747a3 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ requires = virtualenv<20.26.3 envlist = # === Common === - {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11,py3.12}-common + {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-common # === Gevent === {py3.6,py3.8,py3.10,py3.11,py3.12}-gevent @@ -271,11 +271,12 @@ deps = # === Common === py3.8-common: hypothesis - {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11,py3.12}-common: pytest-asyncio + {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-common: pytest-asyncio # See https://github.com/pytest-dev/pytest/issues/9621 # and https://github.com/pytest-dev/pytest-forked/issues/67 # for justification of the upper bound on pytest {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11,py3.12}-common: pytest<7.0.0 + py3.13-common: pytest # === Gevent === {py3.6,py3.7,py3.8,py3.9,py3.10,py3.11}-gevent: gevent>=22.10.0, <22.11.0