diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py index 14d6540061..46839bc1fb 100644 --- a/scripts/populate_tox/populate_tox.py +++ b/scripts/populate_tox/populate_tox.py @@ -1,15 +1,13 @@ import functools -import subprocess -import sys import time from collections import defaultdict from datetime import datetime, timedelta -from importlib import import_module from pathlib import Path import requests from jinja2 import Environment, FileSystemLoader +from sentry_sdk.integrations import _MIN_VERSIONS from sentry_sdk.utils import parse_version from dependencies import DEPENDENCIES @@ -147,15 +145,19 @@ def __init__(self, version, metadata=None): self.parsed = None self.python_versions = [] - if not self.raw.split('.')[-1].isnumeric(): - # TODO: allow some prereleases (only the most recent one, not too old and not when an equivalent/newer stable release is available) - return + if isinstance(version, tuple): + self.parsed = version + self.raw = ".".join([str(v) for v in self.parsed]) + else: + if not self.raw.split(".")[-1].isnumeric(): + # TODO: allow some prereleases (only the most recent one, not too old and not when an equivalent/newer stable release is available) + return - try: - self.parsed = parse_version(version) - except Exception: - print(f'Failed to parse version {version}') - pass + try: + self.parsed = parse_version(version) + except Exception: + print(f"Failed to parse version {version}") + pass @property def major(self): @@ -210,7 +212,16 @@ def fetch_package(package: str) -> dict: return pypi_data.json() -def get_releases(pypi_data: dict) -> list[Version]: +def get_releases(integration: str, pypi_data: dict) -> list[Version]: + min_supported = _MIN_VERSIONS.get(integration) + if min_supported: + min_supported = Version(min_supported) + print(f"Minimum supported version for {integration} is {min_supported}.") + else: + print( + f"{integration} doesn't have a minimum version. Maybe we should define one?" + ) + versions = [] for release, metadata in pypi_data["releases"].items(): @@ -225,6 +236,9 @@ def get_releases(pypi_data: dict) -> list[Version]: if not version.valid: continue + if min_supported and version < min_supported: + continue + # XXX don't consider yanked stuff for i, saved_version in enumerate(versions): @@ -308,9 +322,7 @@ def _requires_python_to_python_versions( return versions -def determine_python_versions( - pypi_data: dict -) -> list[str]: +def determine_python_versions(pypi_data: dict) -> list[str]: package = pypi_data["info"]["name"] try: @@ -375,7 +387,7 @@ def write_tox_file(packages: dict) -> None: if __name__ == "__main__": - print('Finding out the lowest and highest Python version supported by the SDK...') + print("Finding out the lowest and highest Python version supported by the SDK...") sentry_sdk_python_support = determine_python_versions(fetch_package("sentry_sdk")) LOWEST_SUPPORTED_PYTHON_VERSION = sentry_sdk_python_support[0] HIGHEST_SUPPORTED_PYTHON_VERSION = sentry_sdk_python_support[-1] @@ -401,7 +413,7 @@ def write_tox_file(packages: dict) -> None: pypi_data = fetch_package(package) - releases = get_releases(pypi_data) + releases = get_releases(integration, pypi_data) if not releases: print("Found no supported releases.") continue @@ -416,9 +428,7 @@ def write_tox_file(packages: dict) -> None: for release in test_releases: release_pypi_data = fetch_release(package, release) release.python_versions = pick_python_versions_to_test( - determine_python_versions( - release_pypi_data - ) + determine_python_versions(release_pypi_data) ) if not release.python_versions: print(f"Release {release} has no Python versions, skipping.") diff --git a/scripts/populate_tox/requirements.txt b/scripts/populate_tox/requirements.txt index 59f6e13f1c..6d2892e8f3 100644 --- a/scripts/populate_tox/requirements.txt +++ b/scripts/populate_tox/requirements.txt @@ -1,2 +1,3 @@ +jinja2 requests sentry_sdk diff --git a/tox.ini b/tox.ini index 6294f3546c..63a5c362ae 100644 --- a/tox.ini +++ b/tox.ini @@ -32,9 +32,9 @@ envlist = # === Integrations === # ~~~ AI ~~~ - {py3.8,py3.13}-anthropic-v0.2.9 - {py3.7,py3.12}-anthropic-v0.14.1 - {py3.7,py3.12}-anthropic-v0.28.1 + {py3.7,py3.12}-anthropic-v0.16.0 + {py3.7,py3.12}-anthropic-v0.25.9 + {py3.7,py3.12}-anthropic-v0.34.2 {py3.8,py3.12}-anthropic-v0.42.0 {py3.6,py3.13}-cohere-v0.0.8 @@ -68,10 +68,10 @@ envlist = {py3.6,py3.8}-aws_lambda-v2.1.3 # ~~~ Cloud ~~~ - {py3.6,py3.7}-boto3-v1.11.9 - {py3.6,py3.8}-boto3-v1.17.112 - {py3.7,py3.11}-boto3-v1.24.96 - {py3.8,py3.13}-boto3-v1.35.94 + {py3.6,py3.7}-boto3-v1.12.9 + {py3.6,py3.10}-boto3-v1.18.65 + {py3.7,py3.11}-boto3-v1.26.9 + {py3.8,py3.13}-boto3-v1.35.95 {py3.6,py3.8}-chalice-v1.13.1 {py3.6,py3.8}-chalice-v1.19.0 @@ -79,9 +79,9 @@ envlist = {py3.8,py3.12}-chalice-v1.31.3 # ~~~ DBs ~~~ - {py3.6,py3.7}-asyncpg-v0.20.1 {py3.6,py3.9}-asyncpg-v0.23.0 - {py3.6,py3.10}-asyncpg-v0.26.0 + {py3.6,py3.10}-asyncpg-v0.25.0 + {py3.7,py3.10}-asyncpg-v0.27.0 {py3.8,py3.12}-asyncpg-v0.30.0 {py3.6,py3.9}-clickhouse-driver-v0.1.5 @@ -121,24 +121,20 @@ envlist = {py3.8,py3.13}-unleash-v6.0.1 # ~~~ GraphQL ~~~ - {py3.6,py3.8}-ariadne-v0.10.0 - {py3.7,py3.10}-ariadne-v0.15.1 {py3.8,py3.11}-ariadne-v0.20.1 + {py3.8,py3.12}-ariadne-v0.21 + {py3.8,py3.12}-ariadne-v0.22 {py3.8,py3.12}-ariadne-v0.24.0 - {py3.6,py3.8}-gql-v0.3.0 - {py3.6,py3.8}-gql-v2.0.0 - {py3.6,py3.10}-gql-v3.2.0 + {py3.6,py3.10}-gql-v3.4.1 {py3.7,py3.12}-gql-v3.5.0 - {py3.6,py3.7}-graphene-v2.1.9 - {py3.6,py3.10}-graphene-v3.1.1 {py3.6,py3.10}-graphene-v3.3 {py3.8,py3.13}-graphene-v3.4.3 - {py3.7}-strawberry-v0.20.3 - {py3.7,py3.10}-strawberry-v0.96.0 - {py3.7,py3.11}-strawberry-v0.175.1 + {py3.8,py3.11}-strawberry-v0.209.8 + {py3.8,py3.12}-strawberry-v0.225.1 + {py3.8,py3.12}-strawberry-v0.241.0 {py3.9,py3.13}-strawberry-v0.256.1 # ~~~ Network ~~~ @@ -158,9 +154,9 @@ envlist = {py3.8,py3.12}-requests-v2.32.3 # ~~~ Tasks ~~~ - {py3.6}-arq-v0.15.1 - {py3.6,py3.9}-arq-v0.21 + {py3.7,py3.10}-arq-v0.23 {py3.7,py3.11}-arq-v0.24.0 + {py3.7,py3.11}-arq-v0.25.0 {py3.8,py3.12}-arq-v0.26.3 {py3.6,py3.7}-beam-v2.18.0 @@ -168,9 +164,9 @@ envlist = {py3.7,py3.10}-beam-v2.46.0 {py3.9,py3.12}-beam-v2.61.0 - {py3.6,py3.7}-celery-v4.3.1 - {py3.6,py3.8}-celery-v5.0.6 - {py3.7,py3.10}-celery-v5.2.7 + {py3.6,py3.8}-celery-v4.4.7 + {py3.6,py3.9}-celery-v5.1.2 + {py3.8,py3.12}-celery-v5.3.6 {py3.8,py3.12}-celery-v5.4.0 {py3.6,py3.7}-dramatiq-v1.8.1 @@ -183,8 +179,9 @@ envlist = {py3.6,py3.11}-huey-v2.4.5 {py3.6,py3.12}-huey-v2.5.2 - {py3.6,py3.9}-ray-v1.13.0 - {py3.8,py3.11}-ray-v2.20.0 + {py3.7,py3.10}-ray-v2.7.2 + {py3.8,py3.11}-ray-v2.21.0 + {py3.8,py3.11}-ray-v2.33.0 {py3.9,py3.12}-ray-v2.40.0 {py3.6,py3.8}-rq-v1.2.2 @@ -231,9 +228,9 @@ envlist = {py3.8,py3.13}-falcon-v4.0.2 {py3.8,py3.11}-litestar-v2.0.1 - {py3.8,py3.12}-litestar-v2.4.5 - {py3.8,py3.12}-litestar-v2.8.3 - {py3.8,py3.12}-litestar-v2.13.0 + {py3.8,py3.12}-litestar-v2.5.5 + {py3.8,py3.12}-litestar-v2.10.0 + {py3.8,py3.13}-litestar-v2.14.0 {py3.6,py3.9}-pyramid-v1.10.8 {py3.6,py3.11}-pyramid-v2.0.2 @@ -315,9 +312,9 @@ deps = # === Integrations === # ~~~ AI ~~~ - anthropic-v0.2.9: anthropic==0.2.9 - anthropic-v0.14.1: anthropic==0.14.1 - anthropic-v0.28.1: anthropic==0.28.1 + anthropic-v0.16.0: anthropic==0.16.0 + anthropic-v0.25.9: anthropic==0.25.9 + anthropic-v0.34.2: anthropic==0.34.2 anthropic-v0.42.0: anthropic==0.42.0 anthropic: httpx anthropic: pytest-asyncio @@ -364,10 +361,10 @@ deps = aws_lambda: boto3 # ~~~ Cloud ~~~ - boto3-v1.11.9: boto3==1.11.9 - boto3-v1.17.112: boto3==1.17.112 - boto3-v1.24.96: boto3==1.24.96 - boto3-v1.35.94: boto3==1.35.94 + boto3-v1.12.9: boto3==1.12.9 + boto3-v1.18.65: boto3==1.18.65 + boto3-v1.26.9: boto3==1.26.9 + boto3-v1.35.95: boto3==1.35.95 chalice-v1.13.1: chalice==1.13.1 chalice-v1.19.0: chalice==1.19.0 @@ -376,9 +373,9 @@ deps = chalice: pytest-chalice==0.0.5 # ~~~ DBs ~~~ - asyncpg-v0.20.1: asyncpg==0.20.1 asyncpg-v0.23.0: asyncpg==0.23.0 - asyncpg-v0.26.0: asyncpg==0.26.0 + asyncpg-v0.25.0: asyncpg==0.25.0 + asyncpg-v0.27.0: asyncpg==0.27.0 asyncpg-v0.30.0: asyncpg==0.30.0 asyncpg: pytest-asyncio @@ -423,21 +420,17 @@ deps = unleash-v6.0.1: UnleashClient==6.0.1 # ~~~ GraphQL ~~~ - ariadne-v0.10.0: ariadne==0.10.0 - ariadne-v0.15.1: ariadne==0.15.1 ariadne-v0.20.1: ariadne==0.20.1 + ariadne-v0.21: ariadne==0.21 + ariadne-v0.22: ariadne==0.22 ariadne-v0.24.0: ariadne==0.24.0 ariadne: fastapi ariadne: flask ariadne: httpx - gql-v0.3.0: gql[all]==0.3.0 - gql-v2.0.0: gql[all]==2.0.0 - gql-v3.2.0: gql[all]==3.2.0 + gql-v3.4.1: gql[all]==3.4.1 gql-v3.5.0: gql[all]==3.5.0 - graphene-v2.1.9: graphene==2.1.9 - graphene-v3.1.1: graphene==3.1.1 graphene-v3.3: graphene==3.3 graphene-v3.4.3: graphene==3.4.3 graphene: blinker @@ -445,9 +438,9 @@ deps = graphene: flask graphene: httpx - strawberry-v0.20.3: strawberry-graphql[fastapi,flask]==0.20.3 - strawberry-v0.96.0: strawberry-graphql[fastapi,flask]==0.96.0 - strawberry-v0.175.1: strawberry-graphql[fastapi,flask]==0.175.1 + strawberry-v0.209.8: strawberry-graphql[fastapi,flask]==0.209.8 + strawberry-v0.225.1: strawberry-graphql[fastapi,flask]==0.225.1 + strawberry-v0.241.0: strawberry-graphql[fastapi,flask]==0.241.0 strawberry-v0.256.1: strawberry-graphql[fastapi,flask]==0.256.1 strawberry: fastapi strawberry: flask @@ -475,9 +468,9 @@ deps = requests-v2.32.3: requests==2.32.3 # ~~~ Tasks ~~~ - arq-v0.15.1: arq==0.15.1 - arq-v0.21: arq==0.21 + arq-v0.23: arq==0.23 arq-v0.24.0: arq==0.24.0 + arq-v0.25.0: arq==0.25.0 arq-v0.26.3: arq==0.26.3 arq: pydantic arq: fakeredis>=2.2.0,<2.8 @@ -489,9 +482,9 @@ deps = beam-v2.46.0: apache-beam==2.46.0 beam-v2.61.0: apache-beam==2.61.0 - celery-v4.3.1: celery==4.3.1 - celery-v5.0.6: celery==5.0.6 - celery-v5.2.7: celery==5.2.7 + celery-v4.4.7: celery==4.4.7 + celery-v5.1.2: celery==5.1.2 + celery-v5.3.6: celery==5.3.6 celery-v5.4.0: celery==5.4.0 celery: importlib-metadata celery: newrelic @@ -507,8 +500,9 @@ deps = huey-v2.4.5: huey==2.4.5 huey-v2.5.2: huey==2.5.2 - ray-v1.13.0: ray==1.13.0 - ray-v2.20.0: ray==2.20.0 + ray-v2.7.2: ray==2.7.2 + ray-v2.21.0: ray==2.21.0 + ray-v2.33.0: ray==2.33.0 ray-v2.40.0: ray==2.40.0 rq-v1.2.2: rq==1.2.2 @@ -580,9 +574,9 @@ deps = falcon-v4.0.2: falcon==4.0.2 litestar-v2.0.1: litestar==2.0.1 - litestar-v2.4.5: litestar==2.4.5 - litestar-v2.8.3: litestar==2.8.3 - litestar-v2.13.0: litestar==2.13.0 + litestar-v2.5.5: litestar==2.5.5 + litestar-v2.10.0: litestar==2.10.0 + litestar-v2.14.0: litestar==2.14.0 litestar: pytest-asyncio litestar: python-multipart litestar: requests