diff --git a/.github/workflows/test-integrations-ai.yml b/.github/workflows/test-integrations-ai.yml index 6e06e6067c..bceadb6886 100644 --- a/.github/workflows/test-integrations-ai.yml +++ b/.github/workflows/test-integrations-ai.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-ai-latest: - name: AI (latest) + test-ai: + name: AI timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.7","3.9","3.11","3.12","3.13"] + python-version: ["3.6","3.7","3.8","3.9","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 @@ -47,98 +47,31 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test anthropic latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-anthropic-latest" - - name: Test cohere latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-cohere-latest" - - name: Test langchain latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-langchain-latest" - - name: Test openai latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-openai-latest" - - name: Test huggingface_hub latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-huggingface_hub-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov + - name: Test anthropic if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-ai-pinned: - name: AI (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.8","3.9","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test anthropic pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-anthropic" - - name: Test cohere pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-anthropic" + - name: Test cohere + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-cohere" - - name: Test langchain pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-cohere" + - name: Test langchain + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-langchain" - - name: Test openai pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-langchain" + - name: Test openai + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-openai" - - name: Test huggingface_hub pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-openai" + - name: Test huggingface_hub + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-huggingface_hub" + ./scripts/runtox.sh "py${{ matrix.python-version }}-huggingface_hub" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -167,13 +100,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned AI tests passed - needs: test-ai-pinned + name: All AI tests passed + needs: test-ai # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-ai-pinned.result, 'failure') || contains(needs.test-ai-pinned.result, 'skipped') + if: contains(needs.test-ai.result, 'failure') || contains(needs.test-ai.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-aws.yml b/.github/workflows/test-integrations-aws.yml index eae488776a..65a59fa9cd 100644 --- a/.github/workflows/test-integrations-aws.yml +++ b/.github/workflows/test-integrations-aws.yml @@ -54,8 +54,8 @@ jobs: - name: Check permissions on repo branch if: github.event_name == 'push' run: true - test-aws-pinned: - name: AWS (pinned) + test-aws: + name: AWS timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: @@ -82,10 +82,11 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test aws_lambda pinned + - name: Test aws_lambda + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-aws_lambda" + ./scripts/runtox.sh "py${{ matrix.python-version }}-aws_lambda" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -114,13 +115,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned AWS tests passed - needs: test-aws-pinned + name: All AWS tests passed + needs: test-aws # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-aws-pinned.result, 'failure') || contains(needs.test-aws-pinned.result, 'skipped') + if: contains(needs.test-aws.result, 'failure') || contains(needs.test-aws.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-cloud.yml b/.github/workflows/test-integrations-cloud.yml index af089caede..fbb961d38b 100644 --- a/.github/workflows/test-integrations-cloud.yml +++ b/.github/workflows/test-integrations-cloud.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-cloud-latest: - name: Cloud (latest) + test-cloud: + name: Cloud timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.8","3.11","3.12","3.13"] + python-version: ["3.6","3.7","3.8","3.9","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 @@ -47,90 +47,26 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test boto3 latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-boto3-latest" - - name: Test chalice latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-chalice-latest" - - name: Test cloud_resource_context latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-cloud_resource_context-latest" - - name: Test gcp latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-gcp-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov + - name: Test boto3 if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-cloud-pinned: - name: Cloud (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.9","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test boto3 pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-boto3" - - name: Test chalice pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-boto3" + - name: Test chalice + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-chalice" - - name: Test cloud_resource_context pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-chalice" + - name: Test cloud_resource_context + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-cloud_resource_context" - - name: Test gcp pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-cloud_resource_context" + - name: Test gcp + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-gcp" + ./scripts/runtox.sh "py${{ matrix.python-version }}-gcp" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -159,13 +95,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Cloud tests passed - needs: test-cloud-pinned + name: All Cloud tests passed + needs: test-cloud # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-cloud-pinned.result, 'failure') || contains(needs.test-cloud-pinned.result, 'skipped') + if: contains(needs.test-cloud.result, 'failure') || contains(needs.test-cloud.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-common.yml b/.github/workflows/test-integrations-common.yml index d9e08bbeb8..ddb0d47cab 100644 --- a/.github/workflows/test-integrations-common.yml +++ b/.github/workflows/test-integrations-common.yml @@ -22,8 +22,8 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-common-pinned: - name: Common (pinned) + test-common: + name: Common timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: @@ -47,10 +47,11 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test common pinned + - name: Test common + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-common" + ./scripts/runtox.sh "py${{ matrix.python-version }}-common" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -79,13 +80,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Common tests passed - needs: test-common-pinned + name: All Common tests passed + needs: test-common # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-common-pinned.result, 'failure') || contains(needs.test-common-pinned.result, 'skipped') + if: contains(needs.test-common.result, 'failure') || contains(needs.test-common.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-dbs.yml b/.github/workflows/test-integrations-dbs.yml index f612b8fb14..0bad430091 100644 --- a/.github/workflows/test-integrations-dbs.yml +++ b/.github/workflows/test-integrations-dbs.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-dbs-latest: - name: DBs (latest) + test-dbs: + name: DBs timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.7","3.8","3.11","3.12","3.13"] + python-version: ["3.6","3.7","3.8","3.9","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 @@ -66,125 +66,36 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test asyncpg latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-asyncpg-latest" - - name: Test clickhouse_driver latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-clickhouse_driver-latest" - - name: Test pymongo latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-pymongo-latest" - - name: Test redis latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-redis-latest" - - name: Test redis_py_cluster_legacy latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-redis_py_cluster_legacy-latest" - - name: Test sqlalchemy latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-sqlalchemy-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov + - name: Test asyncpg if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-dbs-pinned: - name: DBs (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.8","3.9","3.10","3.11","3.12"] - # 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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - services: - postgres: - image: postgres - env: - POSTGRES_PASSWORD: sentry - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - # Maps tcp port 5432 on service container to the host - ports: - - 5432:5432 - env: - SENTRY_PYTHON_TEST_POSTGRES_HOST: localhost - SENTRY_PYTHON_TEST_POSTGRES_USER: postgres - SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - uses: getsentry/action-clickhouse-in-ci@v1.1 - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test asyncpg pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-asyncpg" - - name: Test clickhouse_driver pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-asyncpg" + - name: Test clickhouse_driver + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-clickhouse_driver" - - name: Test pymongo pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-clickhouse_driver" + - name: Test pymongo + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-pymongo" - - name: Test redis pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-pymongo" + - name: Test redis + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-redis" - - name: Test redis_py_cluster_legacy pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-redis" + - name: Test redis_py_cluster_legacy + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-redis_py_cluster_legacy" - - name: Test sqlalchemy pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-redis_py_cluster_legacy" + - name: Test sqlalchemy + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-sqlalchemy" + ./scripts/runtox.sh "py${{ matrix.python-version }}-sqlalchemy" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -213,13 +124,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned DBs tests passed - needs: test-dbs-pinned + name: All DBs tests passed + needs: test-dbs # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-dbs-pinned.result, 'failure') || contains(needs.test-dbs-pinned.result, 'skipped') + if: contains(needs.test-dbs.result, 'failure') || contains(needs.test-dbs.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-flags.yml b/.github/workflows/test-integrations-flags.yml index 0460868473..80b1f358a3 100644 --- a/.github/workflows/test-integrations-flags.yml +++ b/.github/workflows/test-integrations-flags.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-flags-latest: - name: Flags (latest) + test-flags: + name: Flags timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.8","3.12","3.13"] + python-version: ["3.8","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 @@ -47,82 +47,21 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test launchdarkly latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-launchdarkly-latest" - - name: Test openfeature latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-openfeature-latest" - - name: Test unleash latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-unleash-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov + - name: Test launchdarkly if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-flags-pinned: - name: Flags (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.8","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test launchdarkly pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-launchdarkly" - - name: Test openfeature pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-launchdarkly" + - name: Test openfeature + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-openfeature" - - name: Test unleash pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-openfeature" + - name: Test unleash + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-unleash" + ./scripts/runtox.sh "py${{ matrix.python-version }}-unleash" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -151,13 +90,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Flags tests passed - needs: test-flags-pinned + name: All Flags tests passed + needs: test-flags # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-flags-pinned.result, 'failure') || contains(needs.test-flags-pinned.result, 'skipped') + if: contains(needs.test-flags.result, 'failure') || contains(needs.test-flags.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-graphql.yml b/.github/workflows/test-integrations-graphql.yml index d239b2ed6c..bcda4b82f1 100644 --- a/.github/workflows/test-integrations-graphql.yml +++ b/.github/workflows/test-integrations-graphql.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-graphql-latest: - name: GraphQL (latest) + test-graphql: + name: GraphQL timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.7","3.8","3.12","3.13"] + 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 @@ -47,90 +47,26 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test ariadne latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-ariadne-latest" - - name: Test gql latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-gql-latest" - - name: Test graphene latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-graphene-latest" - - name: Test strawberry latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-strawberry-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov + - name: Test ariadne if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-graphql-pinned: - name: GraphQL (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.7","3.8","3.11","3.12"] - # 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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test ariadne pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-ariadne" - - name: Test gql pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-ariadne" + - name: Test gql + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-gql" - - name: Test graphene pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-gql" + - name: Test graphene + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-graphene" - - name: Test strawberry pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-graphene" + - name: Test strawberry + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-strawberry" + ./scripts/runtox.sh "py${{ matrix.python-version }}-strawberry" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -159,13 +95,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned GraphQL tests passed - needs: test-graphql-pinned + name: All GraphQL tests passed + needs: test-graphql # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-graphql-pinned.result, 'failure') || contains(needs.test-graphql-pinned.result, 'skipped') + if: contains(needs.test-graphql.result, 'failure') || contains(needs.test-graphql.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-misc.yml b/.github/workflows/test-integrations-misc.yml index 9461ea506c..97e0ec0188 100644 --- a/.github/workflows/test-integrations-misc.yml +++ b/.github/workflows/test-integrations-misc.yml @@ -22,84 +22,8 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-misc-latest: - name: Misc (latest) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.8","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test loguru latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-loguru-latest" - - name: Test opentelemetry latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-opentelemetry-latest" - - name: Test potel latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-potel-latest" - - name: Test pure_eval latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-pure_eval-latest" - - name: Test trytond latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-trytond-latest" - - name: Test typer latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-typer-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-misc-pinned: - name: Misc (pinned) + test-misc: + name: Misc timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: @@ -123,30 +47,36 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test loguru pinned + - name: Test loguru + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-loguru" - - name: Test opentelemetry pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-loguru" + - name: Test opentelemetry + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-opentelemetry" - - name: Test potel pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-opentelemetry" + - name: Test potel + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-potel" - - name: Test pure_eval pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-potel" + - name: Test pure_eval + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-pure_eval" - - name: Test trytond pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-pure_eval" + - name: Test trytond + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-trytond" - - name: Test typer pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-trytond" + - name: Test typer + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-typer" + ./scripts/runtox.sh "py${{ matrix.python-version }}-typer" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -175,13 +105,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Misc tests passed - needs: test-misc-pinned + name: All Misc tests passed + needs: test-misc # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-misc-pinned.result, 'failure') || contains(needs.test-misc-pinned.result, 'skipped') + if: contains(needs.test-misc.result, 'failure') || contains(needs.test-misc.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-network.yml b/.github/workflows/test-integrations-network.yml index ab1c5b0658..6fe430cd8f 100644 --- a/.github/workflows/test-integrations-network.yml +++ b/.github/workflows/test-integrations-network.yml @@ -22,76 +22,8 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-network-latest: - name: Network (latest) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.8","3.9","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test gevent latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-gevent-latest" - - name: Test grpc latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-grpc-latest" - - name: Test httpx latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-httpx-latest" - - name: Test requests latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-requests-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-network-pinned: - name: Network (pinned) + test-network: + name: Network timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: @@ -115,22 +47,26 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test gevent pinned + - name: Test gevent + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-gevent" - - name: Test grpc pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-gevent" + - name: Test grpc + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-grpc" - - name: Test httpx pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-grpc" + - name: Test httpx + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-httpx" - - name: Test requests pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-httpx" + - name: Test requests + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-requests" + ./scripts/runtox.sh "py${{ matrix.python-version }}-requests" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -159,13 +95,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Network tests passed - needs: test-network-pinned + name: All Network tests passed + needs: test-network # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-network-pinned.result, 'failure') || contains(needs.test-network-pinned.result, 'skipped') + if: contains(needs.test-network.result, 'failure') || contains(needs.test-network.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-tasks.yml b/.github/workflows/test-integrations-tasks.yml index 8ecc7ab598..0dbed0ed51 100644 --- a/.github/workflows/test-integrations-tasks.yml +++ b/.github/workflows/test-integrations-tasks.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-tasks-latest: - name: Tasks (latest) + test-tasks: + name: Tasks timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.6","3.7","3.8","3.10","3.11","3.12","3.13"] + 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 @@ -49,124 +49,46 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test arq latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-arq-latest" - - name: Test beam latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-beam-latest" - - name: Test celery latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-celery-latest" - - name: Test dramatiq latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-dramatiq-latest" - - name: Test huey latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-huey-latest" - - name: Test ray latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-ray-latest" - - name: Test rq latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-rq-latest" - - name: Test spark latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-spark-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov + - name: Test arq if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-tasks-pinned: - name: Tasks (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.8","3.9","3.10","3.11","3.12"] - # 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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - 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 - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test arq pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-arq" - - name: Test beam pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-arq" + - name: Test beam + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-beam" - - name: Test celery pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-beam" + - name: Test celery + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-celery" - - name: Test dramatiq pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-celery" + - name: Test dramatiq + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-dramatiq" - - name: Test huey pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-dramatiq" + - name: Test huey + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-huey" - - name: Test ray pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-huey" + - name: Test ray + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-ray" - - name: Test rq pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-ray" + - name: Test rq + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-rq" - - name: Test spark pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-rq" + - name: Test spark + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-spark" + ./scripts/runtox.sh "py${{ matrix.python-version }}-spark" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -195,13 +117,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Tasks tests passed - needs: test-tasks-pinned + name: All Tasks tests passed + needs: test-tasks # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-tasks-pinned.result, 'failure') || contains(needs.test-tasks-pinned.result, 'skipped') + if: contains(needs.test-tasks.result, 'failure') || contains(needs.test-tasks.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-web-1.yml b/.github/workflows/test-integrations-web-1.yml index 2dc5f361de..0d4811b1e2 100644 --- a/.github/workflows/test-integrations-web-1.yml +++ b/.github/workflows/test-integrations-web-1.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-web_1-latest: - name: Web 1 (latest) + test-web_1: + name: Web 1 timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.8","3.10","3.12","3.13"] + python-version: ["3.6","3.7","3.8","3.9","3.10","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 @@ -65,108 +65,26 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test django latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-django-latest" - - name: Test flask latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-flask-latest" - - name: Test starlette latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-starlette-latest" - - name: Test fastapi latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-fastapi-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov + - name: Test django if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-web_1-pinned: - name: Web 1 (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.8","3.9","3.10","3.11","3.12"] - # 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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - services: - postgres: - image: postgres - env: - POSTGRES_PASSWORD: sentry - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - # Maps tcp port 5432 on service container to the host - ports: - - 5432:5432 - env: - SENTRY_PYTHON_TEST_POSTGRES_HOST: localhost - SENTRY_PYTHON_TEST_POSTGRES_USER: postgres - SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test django pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-django" - - name: Test flask pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-django" + - name: Test flask + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-flask" - - name: Test starlette pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-flask" + - name: Test starlette + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-starlette" - - name: Test fastapi pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-starlette" + - name: Test fastapi + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-fastapi" + ./scripts/runtox.sh "py${{ matrix.python-version }}-fastapi" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -195,13 +113,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Web 1 tests passed - needs: test-web_1-pinned + name: All Web 1 tests passed + needs: test-web_1 # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-web_1-pinned.result, 'failure') || contains(needs.test-web_1-pinned.result, 'skipped') + if: contains(needs.test-web_1.result, 'failure') || contains(needs.test-web_1.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/.github/workflows/test-integrations-web-2.yml b/.github/workflows/test-integrations-web-2.yml index 2b3204ae80..47488b883b 100644 --- a/.github/workflows/test-integrations-web-2.yml +++ b/.github/workflows/test-integrations-web-2.yml @@ -22,14 +22,14 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/dist-serverless jobs: - test-web_2-latest: - name: Web 2 (latest) + test-web_2: + name: Web 2 timeout-minutes: 30 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.6","3.7","3.8","3.9","3.11","3.12","3.13"] + python-version: ["3.6","3.7","3.8","3.9","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 @@ -47,138 +47,56 @@ jobs: - name: Erase coverage run: | coverage erase - - name: Test aiohttp latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-aiohttp-latest" - - name: Test asgi latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-asgi-latest" - - name: Test bottle latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-bottle-latest" - - name: Test falcon latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-falcon-latest" - - name: Test litestar latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-litestar-latest" - - name: Test pyramid latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-pyramid-latest" - - name: Test quart latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-quart-latest" - - name: Test sanic latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-sanic-latest" - - name: Test starlite latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-starlite-latest" - - name: Test tornado latest - run: | - set -x # print commands that are executed - ./scripts/runtox.sh "py${{ matrix.python-version }}-tornado-latest" - - name: Generate coverage XML (Python 3.6) - if: ${{ !cancelled() && matrix.python-version == '3.6' }} - run: | - export COVERAGE_RCFILE=.coveragerc36 - coverage combine .coverage-sentry-* - coverage xml --ignore-errors - - name: Generate coverage XML - if: ${{ !cancelled() && matrix.python-version != '3.6' }} - run: | - coverage combine .coverage-sentry-* - coverage xml - - name: Upload coverage to Codecov + - name: Test aiohttp if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5.1.2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: coverage.xml - # make sure no plugins alter our coverage reports - plugin: noop - verbose: true - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: .junitxml - verbose: true - test-web_2-pinned: - name: Web 2 (pinned) - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - python-version: ["3.6","3.7","3.8","3.9","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 - # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877 - os: [ubuntu-20.04] - steps: - - uses: actions/checkout@v4.2.2 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Setup Test Env - run: | - pip install "coverage[toml]" tox - - name: Erase coverage - run: | - coverage erase - - name: Test aiohttp pinned run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-aiohttp" - - name: Test asgi pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-aiohttp" + - name: Test asgi + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-asgi" - - name: Test bottle pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-asgi" + - name: Test bottle + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-bottle" - - name: Test falcon pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-bottle" + - name: Test falcon + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-falcon" - - name: Test litestar pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-falcon" + - name: Test litestar + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-litestar" - - name: Test pyramid pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-litestar" + - name: Test pyramid + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-pyramid" - - name: Test quart pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-pyramid" + - name: Test quart + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-quart" - - name: Test sanic pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-quart" + - name: Test sanic + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-sanic" - - name: Test starlite pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-sanic" + - name: Test starlite + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-starlite" - - name: Test tornado pinned + ./scripts/runtox.sh "py${{ matrix.python-version }}-starlite" + - name: Test tornado + if: ${{ !cancelled() }} run: | set -x # print commands that are executed - ./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-tornado" + ./scripts/runtox.sh "py${{ matrix.python-version }}-tornado" - name: Generate coverage XML (Python 3.6) if: ${{ !cancelled() && matrix.python-version == '3.6' }} run: | @@ -207,13 +125,13 @@ jobs: files: .junitxml verbose: true check_required_tests: - name: All pinned Web 2 tests passed - needs: test-web_2-pinned + name: All Web 2 tests passed + needs: test-web_2 # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-web_2-pinned.result, 'failure') || contains(needs.test-web_2-pinned.result, 'skipped') + if: contains(needs.test-web_2.result, 'failure') || contains(needs.test-web_2.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/populate_tox/__init__.py b/scripts/populate_tox/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/populate_tox/dependencies.py b/scripts/populate_tox/dependencies.py new file mode 100644 index 0000000000..b6872e691d --- /dev/null +++ b/scripts/populate_tox/dependencies.py @@ -0,0 +1,406 @@ +# The DEPENDENCIES dictionary defines the test dependencies of each integration +# test suite. +# +# The format is: +# ``` +# integration_name: { +# "package": name_of_main_package_on_pypi, +# "deps": { +# rule1: [package1, package2, ...], +# rule2: [package3, package4, ...], +# } +# } +# ``` +# +# The following can be set as a rule: +# - `*`: packages will be always installed +# - a version bound on the main package (e.g. `<=0.32`): packages will only be installed if the main package falls into the version bounds specified +# - specific Python version(s) in the form `py3.8,py3.9`: packages will only be installed if the Python version matches one from the list +# +# Rules can be used to specify version bounds on older versions of the main +# package's dependencies, for example. If e.g. Flask tests generally need +# Werkzeug and don't care about its version, but Flask older than 3.0 needs +# a specific Werkzeug version to work, you can say: +# +# ``` +# "flask": { +# "deps": { +# "*": ["Werkzeug"], +# "<3.0": ["Werkzeug<2.1.0"], +# } +# } +# ```` + + +DEPENDENCIES = { + "aiohttp": { + "package": "aiohttp", + "deps": {"*": ["pytest-aiohttp", "pytest-asyncio"]}, + }, + "anthropic": { + "package": "anthropic", + "deps": { + "*": ["pytest-asyncio"], + "<=0.32": ["httpx<0.28.0"], + }, + }, + "ariadne": { + "package": "ariadne", + "deps": { + "*": ["fastapi", "flask", "httpx"], + }, + }, + "arq": { + "package": "arq", + "deps": { + "*": ["fakeredis>=2.2.0,<2.8", "pytest-asyncio", "async-timeout"], + "<=0.25": ["pydantic<2"], + }, + }, + "asyncpg": { + "package": "asyncpg", + "deps": { + "*": ["pytest-asyncio"], + }, + }, + "beam": { + "package": "apache-beam", + "deps": { + "*": [], + }, + }, + "boto3": { + "package": "boto3", + "deps": { + "*": [], + }, + }, + "bottle": { + "package": "bottle", + "deps": { + "*": ["werkzeug<2.1.0"], + }, + }, + "celery": { + "package": "celery", + "deps": { + "*": ["newrelic", "redis"], + "py3.7": ["importlib-metata<5.0"], + }, + }, + "chalice": { + "package": "chalice", + "deps": { + "*": ["pytest-chalice==0.0.5"], + }, + }, + "clickhouse_driver": { + "package": "clickhouse-driver", + "deps": { + "*": [], + }, + }, + "cohere": { + "package": "cohere", + "deps": { + "*": ["httpx"], + }, + }, + "django": { + "package": "django", + "deps": { + "*": [ + "psycopg2-binary", + "werkzeug", + ], + ">=2.0,<3.0": ["six"], + "<=3.2": [ + "werkzeug<2.1.0", + "djangorestframework>=3.0.0,<4.0.0", + "pytest-django", + ], + ">=2.0": ["channels[daphne]"], + "<=3.0": ["pytest-django<4.0"], + ">=4.0": ["djangorestframework", "pytest-asyncio"], + }, + }, + "dramatiq": { + "package": "dramatiq", + "deps": {}, + }, + "falcon": { + "package": "falcon", + "deps": {}, + }, + "fastapi": { + "package": "fastapi", + "deps": { + "*": [ + "httpx", + "anyio<4.0.0", + "python-multipart", + "pytest-asyncio", + "requests", + ] + }, + }, + "flask": { + "package": "flask", + "deps": { + "*": ["flask-login", "werkzeug"], + "<3.0": ["werkzeug<2.1.0", "markupsafe<2.1.0"], + }, + }, + "gql": { + "package": "gql[all]", + "deps": {}, + }, + "graphene": { + "package": "graphene", + "deps": {"*": ["blinker", "fastapi", "flask", "httpx"]}, + }, + "grpc": { + "package": "grpcio", + "deps": { + "*": ["protobuf", "mypy-protobuf", "types-protobuf", "pytest-asyncio"] + }, + }, + "httpx": { + "package": "httpx", + "deps": { + "*": ["anyio<4.0.0", "pytest-httpx"], + "==0.16": ["pytest-httpx==0.10.0"], + "==0.18": ["pytest-httpx==0.12.0"], + "==0.20": ["pytest-httpx==0.14.0"], + "==0.22": ["pytest-httpx==0.19.0"], + "==0.23": ["pytest-httpx==0.21.0"], + "==0.24": ["pytest-httpx==0.22.0"], + "==0.25": ["pytest-httpx==0.25.0"], + }, + }, + "huey": { + "package": "huey", + "deps": { + "*": [], + }, + }, + "huggingface_hub": { + "package": "huggingface_hub", + "deps": {"*": []}, + }, + # XXX + # langchain-v0.1: openai~=1.0.0 + # langchain-v0.1: tiktoken~=0.6.0 + # langchain-v0.1: httpx<0.28.0 + # langchain-v0.3: langchain-community + # langchain-v0.3: tiktoken + # langchain-v0.3: openai + # langchain-{latest,notiktoken}: langchain + # langchain-{latest,notiktoken}: langchain-openai + # langchain-{latest,notiktoken}: openai>=1.6.1 + # langchain-latest: tiktoken~=0.6.0 + "langchain": { + "package": "langchain", + "deps": { + "*": ["openai", "tiktoken", "httpx"], + ">=0.3": ["langchain-community"], + }, + }, + "langchain_notiktoken": { + "package": "langchain", + "deps": { + "*": ["openai", "httpx"], + ">=0.3": ["langchain-community"], + }, + }, + "litestar": { + "package": "litestar", + "deps": { + "*": ["pytest-asyncio", "python-multipart", "requests", "cryptography"], + "<=2.6": ["httpx<0.28"], + }, + }, + "loguru": { + "package": "loguru", + "deps": { + "*": [], + }, + }, + # XXX + # openai-latest: tiktoken~=0.6.0 + "openai": { + "package": "openai", + "deps": { + "*": ["pytest-asyncio", "tiktoken", "httpx"], + "<=1.22": ["httpx<0.28.0"], + }, + }, + "openai_notiktoken": { + "package": "openai", + "deps": { + "*": ["pytest-asyncio", "httpx"], + "<=1.22": ["httpx<0.28.0"], + }, + }, + "openfeature": { + "package": "openfeature-sdk", + "deps": { + "*": [], + }, + }, + "launchdarkly": { + "package": "launchdarkly-server-sdk", + "deps": { + "*": [], + }, + }, + "opentelemetry": { + "package": "opentelemetry-distro", + "deps": { + "*": [], + }, + }, + "pure_eval": { + "package": "pure_eval", + "deps": { + "*": [], + }, + }, + "pymongo": { + "package": "pymongo", + "deps": { + "*": ["mockupdb"], + }, + }, + "pyramid": { + "package": "pyramid", + "deps": { + "*": ["werkzeug<2.1.0"], + }, + }, + "quart": { + "package": "quart", + "deps": { + "*": [ + "quart-auth", + "pytest-asyncio", + "werkzeug", + ], + "<=0.16": [ + "blinker<1.6", + "jinja2<3.1.0", + "Werkzeug<2.1.0", + "hypercorn<0.15.0", + ], + "py3.8": ["taskgroup==0.0.0a4"], + }, + }, + "ray": { + "package": "ray", + "deps": {}, + }, + "redis": { + "package": "redis", + "deps": { + "*": ["fakeredis!=1.7.4", "pytest<8.0.0", "pytest-asyncio"], + "py3.6,py3.7": [ + "fakeredis!=2.26.0" + ], # https://github.com/cunla/fakeredis-py/issues/341 + }, + }, + "redis_py_cluster_legacy": { + "package": "redis-py-cluster", + "deps": {}, + }, + "requests": { + "package": "requests", + "deps": {}, + }, + "rq": { + "package": "rq", + "deps": { + "*": ["fakeredis"], + "<0.13": [ + "fakeredis<1.0", + "redis<3.2.2", + ], # https://github.com/jamesls/fakeredis/issues/245 + ">=0.13,<=1.10": ["fakeredis>=1.0,<1.7.4"], + "py3.6,py3.7": [ + "fakeredis!=2.26.0" + ], # https://github.com/cunla/fakeredis-py/issues/341 + }, + }, + "sanic": { + "package": "sanic", + "deps": { + "*": ["websockets<11.0", "aiohttp", "sanic_testing", "aiocontextvars"], + ">=22.0": ["sanic_testing"], + "py3.6": ["aiocontextvars==0.2.1"], + }, + }, + "spark": { + "package": "pyspark", + "deps": {}, + }, + "starlette": { + "package": "starlette", + "deps": { + "*": [ + "pytest-asyncio", + "python-multipart", + "requests", + "anyio<4.0.0", + "jinja2", + "httpx", + ], + "<=0.36": ["httpx<0.28.0"], + }, + }, + "starlite": { + "package": "starlite", + "deps": { + "*": [ + "pytest-asyncio", + "pytest-multipart", + "requests", + "cryptography", + "pydantic<2.0.0", + "httpx<0.28", + ] + }, + }, + "sqlalchemy": { + "package": "sqlalchemy", + "deps": {}, + }, + "strawberry": { + "package": "strawberry-graphql[fastapi,flask]", + "deps": { + "*": ["fastapi", "flask", "httpx"], + }, + }, + "tornado": { + "package": "tornado", + "deps": { + "*": ["pytest"], + "<=6.4.1": [ + "pytest<8.2" + ], # https://github.com/tornadoweb/tornado/pull/3382 + }, + }, + "trytond": { + "package": "trytond", + "deps": { + "*": ["werkzeug"], + "<=5.0": ["werkzeug<1.0"], + }, + }, + "typer": { + "package": "typer", + "deps": {}, + }, + "unleash": { + "package": "UnleashClient", + "deps": {}, + }, +} diff --git a/scripts/populate_tox/populate_tox.py b/scripts/populate_tox/populate_tox.py new file mode 100644 index 0000000000..1aaa68c3e0 --- /dev/null +++ b/scripts/populate_tox/populate_tox.py @@ -0,0 +1,443 @@ +""" +This scripts populates tox.ini automatically using release data from PYPI. + +To add a new test target: +- add it to a group in GROUPs +- add it to DEPENDENCIES +""" + +import functools +import time +from collections import defaultdict +from datetime import datetime, timedelta +from packaging.specifiers import InvalidSpecifier, SpecifierSet +from packaging.version import Version +from pathlib import Path +from typing import Union + +import requests +from jinja2 import Environment, FileSystemLoader + +from sentry_sdk.integrations import _MIN_VERSIONS + +from dependencies import DEPENDENCIES + +# TODO: +# - put GROUPS someplace where both this script and split_tox_actions can use it +# - allow to specify version dependent dependencies +# - (optional) order by alphabet, not group then alphabet +# - clean up the hardcoded stuff in tox.ini +# - fix otel (since it only has prereleases) +# - better picking of releases (e.g., if multiple majors, pick from each, etc.) + +# Only consider package versions going back this far +CUTOFF = datetime.now() - timedelta(days=365 * 5) + +TOX_FILE = Path(__file__).resolve().parent.parent.parent / "tox.ini" +ENV = Environment( + loader=FileSystemLoader(Path(__file__).resolve().parent), + trim_blocks=True, + lstrip_blocks=True, +) + +PYPI_PROJECT_URL = "https://pypi.python.org/pypi/{project}/json" +PYPI_VERSION_URL = "https://pypi.python.org/pypi/{project}/{version}/json" +CLASSIFIER_PREFIX = "Programming Language :: Python :: " + +MAX_PYTHON_VERSION = "3.13" + +GROUPS = { + "Common": [ + "common", + ], + "AI": [ + "anthropic", + "cohere", + "langchain", + "langchain_notiktoken", + "openai", + "openai_notiktoken", + "huggingface_hub", + ], + "AWS": [ + # this is separate from Cloud Computing because only this one test suite + # needs to run with access to GitHub secrets + "aws_lambda", + ], + "Cloud": [ + "boto3", + "chalice", + "cloud_resource_context", + "gcp", + ], + "DBs": [ + "asyncpg", + "clickhouse_driver", + "pymongo", + "redis", + "redis_py_cluster_legacy", + "sqlalchemy", + ], + "Flags": [ + "launchdarkly", + "openfeature", + "unleash", + ], + "GraphQL": [ + "ariadne", + "gql", + "graphene", + "strawberry", + ], + "Network": [ + "gevent", + "grpc", + "httpx", + "requests", + ], + "Tasks": [ + "arq", + "beam", + "celery", + "dramatiq", + "huey", + "ray", + "rq", + "spark", + ], + "Web 1": [ + "django", + "flask", + "starlette", + "fastapi", + ], + "Web 2": [ + "aiohttp", + "asgi", + "bottle", + "falcon", + "litestar", + "pyramid", + "quart", + "sanic", + "starlite", + "tornado", + ], + "Misc": [ + "loguru", + "opentelemetry", + "potel", + "pure_eval", + "trytond", + "typer", + ], +} + +IGNORE = { + # Do not try auto-generating the tox entries for these. They will be + # hardcoded in tox.ini. + "asgi", + "aws_lambda", + "cloud_resource_context", + "common", + "gcp", + "gevent", + "potel", +} + + +@functools.cache +def fetch_package(package: str) -> dict: + """Fetch package metadata from PYPI.""" + url = PYPI_PROJECT_URL.format(project=package) + pypi_data = requests.get(url) + + if pypi_data.status_code != 200: + print(f"{package} not found") + + return pypi_data.json() + + +@functools.cache +def fetch_release(package: str, version: Version) -> dict: + url = PYPI_VERSION_URL.format(project=package, version=version) + pypi_data = requests.get(url) + + if pypi_data.status_code != 200: + print(f"{package} not found") + + return pypi_data.json() + + +def get_releases(integration: str, pypi_data: dict) -> list[Version]: + min_supported = _MIN_VERSIONS.get(integration) + if min_supported: + min_supported = Version(".".join(map(str, 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?" + ) + + releases = [] + + for release, metadata in pypi_data["releases"].items(): + if not metadata: + continue + + meta = metadata[0] + if datetime.fromisoformat(meta["upload_time"]) < CUTOFF: + continue + + if meta["yanked"]: + continue + + version = Version(release) + + if min_supported and version < min_supported: + continue + + if version.is_prerelease or version.is_postrelease: + # TODO: consider the newest prerelease unless obsolete + continue + + # The release listing that you get via the package endpoint doesn't + # contain all metadata for a release. `requires_python` is included, + # but classifiers are not (they require a separate call to the release + # endpoint). + # Some packages don't use `requires_python`, they supply classifiers + # instead. + version.python_versions = None + requires_python = meta.get("requires_python") + if requires_python: + try: + version.python_versions = supported_python_versions( + SpecifierSet(requires_python) + ) + except InvalidSpecifier: + continue + else: + # No requires_python. Let's fetch the metadata to see the classifiers. + # XXX do something with this. no need to fetch every release ever + release_metadata = fetch_release(package, version) + version.python_versions = supported_python_versions( + determine_python_versions(release_metadata) + ) + time.sleep(0.1) + + if not version.python_versions: + continue + + for i, saved_version in enumerate(releases): + if ( + version.major == saved_version.major + and version.minor == saved_version.minor + and version.micro > saved_version.micro + ): + # don't save all patch versions of a release, just the newest one + releases[i] = version + break + else: + releases.append(version) + + return sorted(releases) + + +def pick_releases_to_test(releases: list[Version]) -> list[Version]: + """Pick a handful of releases from a list of supported releases.""" + indexes = [ + 0, # oldest version supported + len(releases) // 3, + len(releases) // 3 * 2, + -1, # latest + ] + + filtered_releases = [] + + for i in indexes: + try: + if releases[i] not in filtered_releases: + filtered_releases.append(releases[i]) + except IndexError: + pass + + return filtered_releases + + +def supported_python_versions(python_versions: SpecifierSet) -> list[Version]: + """Get an intersection of python_versions and Python versions supported in the SDK.""" + supported = [] + + curr = MIN_PYTHON_VERSION + while curr <= MAX_PYTHON_VERSION: + if curr in python_versions: + supported.append(curr) + next = [int(v) for v in str(curr).split(".")] + next[1] += 1 + curr = Version(".".join(map(str, next))) + + return supported + + +def pick_python_versions_to_test(python_versions: list[Version]) -> list[Version]: + filtered_python_versions = [ + python_versions[0], + ] + + if len(python_versions) > 1: + filtered_python_versions.append(python_versions[-1]) + + return filtered_python_versions + + +def determine_python_versions(pypi_data: dict) -> Union[SpecifierSet, list[Version]]: + try: + classifiers = pypi_data["info"]["classifiers"] + except (AttributeError, KeyError): + return [] + + python_versions = [] + for classifier in classifiers: + if classifier.startswith(CLASSIFIER_PREFIX): + python_version = classifier[len(CLASSIFIER_PREFIX) :] + if "." in python_version: + # We don't care about stuff like + # Programming Language :: Python :: 3 :: Only, + # Programming Language :: Python :: 3, + # etc., we're only interested in specific versions, like 3.13 + python_versions.append(Version(python_version)) + + if python_versions: + python_versions.sort() + return python_versions + + try: + requires_python = pypi_data["info"]["requires_python"] + except (AttributeError, KeyError): + pass + + if requires_python: + return SpecifierSet(requires_python) + + return [] + + +def _render_python_versions(python_versions: list[Version]) -> str: + return ( + "{" + + ",".join(f"py{version.major}.{version.minor}" for version in python_versions) + + "}" + ) + + +def _render_dependencies(integration: str, releases: list[Version]) -> list[str]: + rendered = [] + for constraint, deps in DEPENDENCIES[integration]["deps"].items(): + if constraint == "*": + for dep in deps: + rendered.append(f"{integration}: {dep}") + elif constraint.startswith("py3"): + for dep in deps: + rendered.append(f"{constraint}-{integration}: {dep}") + else: + restriction = SpecifierSet(constraint) + for release in releases: + if release in restriction: + for dep in deps: + rendered.append(f"{integration}-v{release}: {dep}") + + return rendered + + +def write_tox_file(packages: dict) -> None: + template = ENV.get_template("tox.jinja") + + context = {"groups": {}} + for group, integrations in packages.items(): + context["groups"][group] = [] + for integration in integrations: + context["groups"][group].append( + { + "name": integration["name"], + "package": integration["package"], + "extra": integration["extra"], + "releases": integration["releases"], + "dependencies": _render_dependencies( + integration["name"], integration["releases"] + ), + } + ) + + rendered = template.render(context) + + with open(TOX_FILE, "w") as file: + file.write(rendered) + + +if __name__ == "__main__": + print("Finding out the lowest and highest Python version supported by the SDK...") + sdk_python_versions = determine_python_versions(fetch_package("sentry_sdk")) + MIN_PYTHON_VERSION = sdk_python_versions[0] + MAX_PYTHON_VERSION = sdk_python_versions[-1] + print( + f"The SDK supports Python versions {MIN_PYTHON_VERSION} - {MAX_PYTHON_VERSION}." + ) + + packages = defaultdict(list) + + for group, integrations in GROUPS.items(): + for integration in integrations: + if integration in IGNORE: + continue + + print(f"Processing {integration}...") + + # Figure out the actual main package + package = DEPENDENCIES[integration]["package"] + extra = None + if "[" in package: + extra = package[package.find("[") + 1 : package.find("]")] + package = package[: package.find("[")] + + # Fetch data for the main package + pypi_data = fetch_package(package) + + # Get the list of all supported releases + releases = get_releases(integration, pypi_data) + if not releases: + print(" Found no supported releases.") + continue + + # Pick a handful of the supported releases to actually test against + # and fetch the PYPI data for each to determine which Python versions + # to test it on + test_releases = pick_releases_to_test(releases) + + for release in test_releases: + release_pypi_data = fetch_release(package, release) + release.python_versions = pick_python_versions_to_test( + release.python_versions + ) + if not release.python_versions: + print(f" Release {release} has no Python versions, skipping.") + release.rendered_python_versions = _render_python_versions( + release.python_versions + ) + + # Give PYPI some breathing room + time.sleep(0.25) + + test_releases = [ + release for release in test_releases if release.python_versions + ] + if test_releases: + packages[group].append( + { + "name": integration, + "package": package, + "extra": extra, + "releases": test_releases, + } + ) + + write_tox_file(packages) diff --git a/scripts/populate_tox/requirements.txt b/scripts/populate_tox/requirements.txt new file mode 100644 index 0000000000..6d2892e8f3 --- /dev/null +++ b/scripts/populate_tox/requirements.txt @@ -0,0 +1,3 @@ +jinja2 +requests +sentry_sdk diff --git a/scripts/populate_tox/tox.jinja b/scripts/populate_tox/tox.jinja new file mode 100644 index 0000000000..079b67f80f --- /dev/null +++ b/scripts/populate_tox/tox.jinja @@ -0,0 +1,220 @@ +# Tox (http://codespeak.net/~hpk/tox/) is a tool for running tests +# in multiple virtualenvs. This configuration file will run the +# test suite on all supported python versions. To use it, "pip install tox" +# and then run "tox" from this directory. +# +# This file has been generated from a template +# by scripts/populate_tox/populate_tox.py. Any changes to the file should be made +# in the script and the file regenerated. + +[tox] +requires = + # This version introduced using pip 24.1 which does not work with older Celery and HTTPX versions. + virtualenv<20.26.3 +envlist = + # === 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 + + # === Cloud Resource Context === + {py3.6,py3.12,py3.13}-cloud_resource_context + + # ==== GCP === + {py3.7}-gcp + + # === Asgi === + {py3.7,py3.12,py3.13}-asgi + + # OpenTelemetry Experimental (POTel) + {py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-potel + + # AWS Lambda + # The aws_lambda tests deploy to the real AWS and have their own + # matrix of Python versions to run the test lambda function in. + # see `lambda_runtime` fixture in tests/integrations/aws_lambda.py + {py3.9}-aws_lambda + + # === Integrations === + {% for group, integrations in groups.items() %} + # ~~~ {{ group }} ~~~ + {% for integration in integrations %} + {% for release in integration.releases %} + {{ release.rendered_python_versions }}-{{ integration.name }}-v{{ release }} + {% endfor %} + + {% endfor %} + {% endfor %} + +[testenv] +deps = + # if you change requirements-testing.txt and your change is not being reflected + # in what's installed by tox (when running tox locally), try running tox + # with the -r flag + -r requirements-testing.txt + + linters: -r requirements-linting.txt + linters: werkzeug<2.3.0 + + # === Common === + py3.8-common: hypothesis + 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}-common: pytest<7.0.0 + {py3.8,py3.9,py3.10,py3.11,py3.12,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 + {py3.12}-gevent: gevent + # 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}-gevent: pytest<7.0.0 + {py3.8,py3.9,py3.10,py3.11,py3.12}-gevent: pytest + + # === Asgi === + asgi: pytest-asyncio + asgi: async-asgi-testclient + + # OpenTelemetry Experimental (POTel) + potel: -e .[opentelemetry-experimental] + + # AWS Lambda + aws_lambda: boto3 + + # === Integrations === + {% for group, integrations in groups.items() %} + # ~~~ {{ group }} ~~~ + {% for integration in integrations %} + {% for release in integration.releases %} + {% if integration.extra %} + {{ integration.name }}-v{{ release }}: {{ integration.package }}[{{ integration.extra }}]=={{ release }} + {% else %} + {{ integration.name }}-v{{ release }}: {{ integration.package }}=={{ release }} + {% endif %} + {% endfor %} + {% for dep in integration.dependencies %} + {{ dep }} + {% endfor %} + + {% endfor %} + {% endfor %} + + +setenv = + PYTHONDONTWRITEBYTECODE=1 + OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES + COVERAGE_FILE=.coverage-sentry-{envname} + py3.6: COVERAGE_RCFILE=.coveragerc36 + + django: DJANGO_SETTINGS_MODULE=tests.integrations.django.myapp.settings + + common: TESTPATH=tests + gevent: TESTPATH=tests + aiohttp: TESTPATH=tests/integrations/aiohttp + anthropic: TESTPATH=tests/integrations/anthropic + ariadne: TESTPATH=tests/integrations/ariadne + arq: TESTPATH=tests/integrations/arq + asgi: TESTPATH=tests/integrations/asgi + asyncpg: TESTPATH=tests/integrations/asyncpg + aws_lambda: TESTPATH=tests/integrations/aws_lambda + beam: TESTPATH=tests/integrations/beam + boto3: TESTPATH=tests/integrations/boto3 + bottle: TESTPATH=tests/integrations/bottle + celery: TESTPATH=tests/integrations/celery + chalice: TESTPATH=tests/integrations/chalice + clickhouse_driver: TESTPATH=tests/integrations/clickhouse_driver + cohere: TESTPATH=tests/integrations/cohere + cloud_resource_context: TESTPATH=tests/integrations/cloud_resource_context + django: TESTPATH=tests/integrations/django + dramatiq: TESTPATH=tests/integrations/dramatiq + falcon: TESTPATH=tests/integrations/falcon + fastapi: TESTPATH=tests/integrations/fastapi + flask: TESTPATH=tests/integrations/flask + gcp: TESTPATH=tests/integrations/gcp + gql: TESTPATH=tests/integrations/gql + graphene: TESTPATH=tests/integrations/graphene + grpc: TESTPATH=tests/integrations/grpc + httpx: TESTPATH=tests/integrations/httpx + huey: TESTPATH=tests/integrations/huey + huggingface_hub: TESTPATH=tests/integrations/huggingface_hub + langchain: TESTPATH=tests/integrations/langchain + launchdarkly: TESTPATH=tests/integrations/launchdarkly + litestar: TESTPATH=tests/integrations/litestar + loguru: TESTPATH=tests/integrations/loguru + openai: TESTPATH=tests/integrations/openai + openfeature: TESTPATH=tests/integrations/openfeature + opentelemetry: TESTPATH=tests/integrations/opentelemetry + potel: TESTPATH=tests/integrations/opentelemetry + pure_eval: TESTPATH=tests/integrations/pure_eval + pymongo: TESTPATH=tests/integrations/pymongo + pyramid: TESTPATH=tests/integrations/pyramid + quart: TESTPATH=tests/integrations/quart + ray: TESTPATH=tests/integrations/ray + redis: TESTPATH=tests/integrations/redis + redis_py_cluster_legacy: TESTPATH=tests/integrations/redis_py_cluster_legacy + requests: TESTPATH=tests/integrations/requests + rq: TESTPATH=tests/integrations/rq + sanic: TESTPATH=tests/integrations/sanic + spark: TESTPATH=tests/integrations/spark + starlette: TESTPATH=tests/integrations/starlette + starlite: TESTPATH=tests/integrations/starlite + sqlalchemy: TESTPATH=tests/integrations/sqlalchemy + strawberry: TESTPATH=tests/integrations/strawberry + tornado: TESTPATH=tests/integrations/tornado + trytond: TESTPATH=tests/integrations/trytond + typer: TESTPATH=tests/integrations/typer + socket: TESTPATH=tests/integrations/socket + +passenv = + SENTRY_PYTHON_TEST_AWS_ACCESS_KEY_ID + SENTRY_PYTHON_TEST_AWS_SECRET_ACCESS_KEY + SENTRY_PYTHON_TEST_POSTGRES_HOST + SENTRY_PYTHON_TEST_POSTGRES_USER + SENTRY_PYTHON_TEST_POSTGRES_PASSWORD + SENTRY_PYTHON_TEST_POSTGRES_NAME + +usedevelop = True + +extras = + bottle: bottle + falcon: falcon + flask: flask + pymongo: pymongo + +basepython = + py3.6: python3.6 + py3.7: python3.7 + py3.8: python3.8 + py3.9: python3.9 + py3.10: python3.10 + py3.11: python3.11 + py3.12: python3.12 + py3.13: python3.13 + + # Python version is pinned here because flake8 actually behaves differently + # depending on which version is used. You can patch this out to point to + # some random Python 3 binary, but then you get guaranteed mismatches with + # CI. Other tools such as mypy and black have options that pin the Python + # version. + linters: python3.12 + +commands = + {py3.7,py3.8}-boto3: pip install urllib3<2.0.0 + + ; https://github.com/pallets/flask/issues/4455 + {py3.7,py3.8,py3.9,py3.10,py3.11}-flask-v{1}: pip install "itsdangerous>=0.24,<2.0" "markupsafe<2.0.0" "jinja2<3.1.1" + + ; Running `pytest` as an executable suffers from an import error + ; when loading tests in scenarios. In particular, django fails to + ; load the settings from the test module. + python -m pytest {env:TESTPATH} -o junit_suite_name={envname} {posargs} + +[testenv:linters] +commands = + flake8 tests sentry_sdk + black --check tests sentry_sdk + mypy sentry_sdk diff --git a/scripts/runtox.sh b/scripts/runtox.sh index 6acf4406fb..ea857b211c 100755 --- a/scripts/runtox.sh +++ b/scripts/runtox.sh @@ -13,25 +13,9 @@ else TOXPATH=./.venv/bin/tox fi -excludelatest=false -for arg in "$@" -do - if [ "$arg" = "--exclude-latest" ]; then - excludelatest=true - shift - break - fi -done - searchstring="$1" +ENV="$($TOXPATH -l | grep -- "$searchstring" | tr $'\n' ',')" -if $excludelatest; then - echo "Excluding latest" - ENV="$($TOXPATH -l | grep -- "$searchstring" | grep -v -- '-latest' | tr $'\n' ',')" -else - echo "Including latest" - ENV="$($TOXPATH -l | grep -- "$searchstring" | tr $'\n' ',')" -fi if [ -z "${ENV}" ]; then echo "No targets found. Skipping." diff --git a/scripts/split_tox_gh_actions/split_tox_gh_actions.py b/scripts/split_tox_gh_actions/split_tox_gh_actions.py index 1537ad8389..2845f5c4ec 100755 --- a/scripts/split_tox_gh_actions/split_tox_gh_actions.py +++ b/scripts/split_tox_gh_actions/split_tox_gh_actions.py @@ -151,13 +151,11 @@ def main(fail_on_changes): old_hash = get_files_hash() print("Parsing tox.ini...") - py_versions_pinned, py_versions_latest = parse_tox() + py_versions = parse_tox() if fail_on_changes: print("Checking if all frameworks belong in a group...") - missing_frameworks = find_frameworks_missing_from_groups( - py_versions_pinned, py_versions_latest - ) + missing_frameworks = find_frameworks_missing_from_groups(py_versions) if missing_frameworks: raise RuntimeError( "Please add the following frameworks to the corresponding group " @@ -167,9 +165,7 @@ def main(fail_on_changes): print("Rendering templates...") for group, frameworks in GROUPS.items(): - contents = render_template( - group, frameworks, py_versions_pinned, py_versions_latest - ) + contents = render_template(group, frameworks, py_versions) filename = write_file(contents, group) print(f"Created {filename}") @@ -197,8 +193,7 @@ def parse_tox(): if line.strip() and not line.strip().startswith("#") ] - py_versions_pinned = defaultdict(set) - py_versions_latest = defaultdict(set) + py_versions = defaultdict(set) for line in lines: # normalize lines @@ -206,33 +201,25 @@ def parse_tox(): try: # parse tox environment definition - try: - (raw_python_versions, framework, framework_versions) = line.split("-") - except ValueError: - (raw_python_versions, framework) = line.split("-") - framework_versions = [] + raw_python_versions, framework = line.split("-")[0], line.split("-")[1] # collect python versions to test the framework in raw_python_versions = set( raw_python_versions.replace("{", "").replace("}", "").split(",") ) - if "latest" in framework_versions: - py_versions_latest[framework] |= raw_python_versions - else: - py_versions_pinned[framework] |= raw_python_versions + py_versions[framework] |= raw_python_versions except ValueError: print(f"ERROR reading line {line}") - py_versions_pinned = _normalize_py_versions(py_versions_pinned) - py_versions_latest = _normalize_py_versions(py_versions_latest) + py_versions = _normalize_py_versions(py_versions) - return py_versions_pinned, py_versions_latest + return py_versions -def find_frameworks_missing_from_groups(py_versions_pinned, py_versions_latest): +def find_frameworks_missing_from_groups(py_versions): frameworks_in_a_group = _union(GROUPS.values()) - all_frameworks = set(py_versions_pinned.keys()) | set(py_versions_latest.keys()) + all_frameworks = set(py_versions.keys()) return all_frameworks - frameworks_in_a_group @@ -272,23 +259,17 @@ def _union(seq): return reduce(lambda x, y: set(x) | set(y), seq) -def render_template(group, frameworks, py_versions_pinned, py_versions_latest): +def render_template(group, frameworks, py_versions): template = ENV.get_template("base.jinja") - categories = set() - py_versions = defaultdict(set) + all_py_versions = set() for framework in frameworks: - if py_versions_pinned[framework]: - categories.add("pinned") - py_versions["pinned"] |= set(py_versions_pinned[framework]) - if py_versions_latest[framework]: - categories.add("latest") - py_versions["latest"] |= set(py_versions_latest[framework]) + if py_versions[framework]: + all_py_versions |= set(py_versions[framework]) context = { "group": group, "frameworks": frameworks, - "categories": sorted(categories), "needs_aws_credentials": bool(set(frameworks) & FRAMEWORKS_NEEDING_AWS), "needs_clickhouse": bool(set(frameworks) & FRAMEWORKS_NEEDING_CLICKHOUSE), "needs_postgres": bool(set(frameworks) & FRAMEWORKS_NEEDING_POSTGRES), @@ -296,10 +277,9 @@ def render_template(group, frameworks, py_versions_pinned, py_versions_latest): "needs_github_secrets": bool( set(frameworks) & FRAMEWORKS_NEEDING_GITHUB_SECRETS ), - "py_versions": { - category: [f'"{version}"' for version in _normalize_py_versions(versions)] - for category, versions in py_versions.items() - }, + "py_versions": [ + f'"{version}"' for version in _normalize_py_versions(all_py_versions) + ], } rendered = template.render(context) rendered = postprocess_template(rendered) diff --git a/scripts/split_tox_gh_actions/templates/base.jinja b/scripts/split_tox_gh_actions/templates/base.jinja index e69b6f9134..3ce3ca023a 100644 --- a/scripts/split_tox_gh_actions/templates/base.jinja +++ b/scripts/split_tox_gh_actions/templates/base.jinja @@ -52,9 +52,7 @@ jobs: {% include "check_permissions.jinja" %} {% endif %} -{% for category in categories %} {% include "test_group.jinja" %} -{% endfor %} {% include "check_required.jinja" %} {% endwith %} diff --git a/scripts/split_tox_gh_actions/templates/check_required.jinja b/scripts/split_tox_gh_actions/templates/check_required.jinja index ddb47cddf1..cff51b2023 100644 --- a/scripts/split_tox_gh_actions/templates/check_required.jinja +++ b/scripts/split_tox_gh_actions/templates/check_required.jinja @@ -1,13 +1,11 @@ check_required_tests: - name: All pinned {{ group }} tests passed - {% if "pinned" in categories %} - needs: test-{{ group | replace(" ", "_") | lower }}-pinned - {% endif %} + name: All {{ group }} tests passed + needs: test-{{ group | replace(" ", "_") | lower }} # Always run this, even if a dependent job failed if: always() runs-on: ubuntu-20.04 steps: - name: Check for failures - if: contains(needs.test-{{ lowercase_group }}-pinned.result, 'failure') || contains(needs.test-{{ lowercase_group }}-pinned.result, 'skipped') + if: contains(needs.test-{{ lowercase_group }}.result, 'failure') || contains(needs.test-{{ lowercase_group }}.result, 'skipped') run: | echo "One of the dependent jobs has failed. You may need to re-run it." && exit 1 diff --git a/scripts/split_tox_gh_actions/templates/test_group.jinja b/scripts/split_tox_gh_actions/templates/test_group.jinja index 186d70c9fd..f04d36f853 100644 --- a/scripts/split_tox_gh_actions/templates/test_group.jinja +++ b/scripts/split_tox_gh_actions/templates/test_group.jinja @@ -1,11 +1,11 @@ - test-{{ lowercase_group }}-{{ category }}: - name: {{ group }} ({{ category }}) + test-{{ lowercase_group }}: + name: {{ group }} timeout-minutes: 30 runs-on: {% raw %}${{ matrix.os }}{% endraw %} strategy: fail-fast: false matrix: - python-version: [{{ py_versions.get(category)|join(",") }}] + python-version: [{{ py_versions|join(",") }}] # 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 @@ -67,14 +67,11 @@ coverage erase {% for framework in frameworks %} - - name: Test {{ framework }} {{ category }} + - name: Test {{ framework }} + {% raw %}if: ${{ !cancelled() }}{% endraw %} run: | set -x # print commands that are executed - {% if category == "pinned" %} - ./scripts/runtox.sh --exclude-latest "{% raw %}py${{ matrix.python-version }}{% endraw %}-{{ framework }}" - {% elif category == "latest" %} - ./scripts/runtox.sh "{% raw %}py${{ matrix.python-version }}{% endraw %}-{{ framework }}-latest" - {% endif %} + ./scripts/runtox.sh "{% raw %}py${{ matrix.python-version }}{% endraw %}-{{ framework }}" {% endfor %} - name: Generate coverage XML (Python 3.6) diff --git a/sentry_sdk/integrations/__init__.py b/sentry_sdk/integrations/__init__.py index 683382bb9a..4dfbd37249 100644 --- a/sentry_sdk/integrations/__init__.py +++ b/sentry_sdk/integrations/__init__.py @@ -118,28 +118,37 @@ def iter_default_integrations(with_auto_enabling_integrations): del _generate_default_integrations_iterator - _MIN_VERSIONS = { "aiohttp": (3, 4), "anthropic": (0, 16), "ariadne": (0, 20), "arq": (0, 23), "asyncpg": (0, 23), - "boto3": (1, 12), # this is actually the botocore version + "beam": (2, 12), + "boto3": (1, 12), # botocore "bottle": (0, 12), "celery": (4, 4, 7), + "chalice": (1, 16, 0), "clickhouse_driver": (0, 2, 0), "django": (1, 8), "falcon": (1, 4), + "fastapi": (0, 79, 0), "flask": (0, 10), "gql": (3, 4, 1), "graphene": (3, 3), + "grpc": (1, 21, 1), # grpcio + "huggingface_hub": (0, 22), + "langchain": (0, 0, 210), + "launchdarkly": (9, 8, 0), + "openai": (1, 0, 0), + "openfeature": (0, 7, 1), "ray": (2, 7, 0), "rq": (0, 6), "sanic": (0, 8), "sqlalchemy": (1, 2), "strawberry": (0, 209, 5), "tornado": (6, 0), + "unleash": (6, 0, 1), } diff --git a/sentry_sdk/integrations/chalice.py b/sentry_sdk/integrations/chalice.py index 0754d1f13b..59010b142e 100644 --- a/sentry_sdk/integrations/chalice.py +++ b/sentry_sdk/integrations/chalice.py @@ -101,7 +101,6 @@ class ChaliceIntegration(Integration): @staticmethod def setup_once(): # type: () -> None - version = parse_version(CHALICE_VERSION) if version is None: diff --git a/tox.ini b/tox.ini index 95c09a573e..e5a21ff70f 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,10 @@ # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. +# +# This file has been generated from a template +# by scripts/populate_tox/populate_tox.py. Any changes to the file should be made +# in the script and the file regenerated. [tox] requires = @@ -14,42 +18,17 @@ envlist = # === Gevent === {py3.6,py3.8,py3.10,py3.11,py3.12}-gevent - # === Integrations === - # General format is {pythonversion}-{integrationname}-v{frameworkversion} - # 1 blank line between different integrations - # Each framework version should only be mentioned once. I.e: - # {py3.7,py3.10}-django-v{3.2} - # {py3.10}-django-v{4.0} - # instead of: - # {py3.7}-django-v{3.2} - # {py3.7,py3.10}-django-v{3.2,4.0} - # - # At a minimum, we should test against at least the lowest - # and the latest supported version of a framework. - - # AIOHTTP - {py3.7}-aiohttp-v{3.4} - {py3.7,py3.9,py3.11}-aiohttp-v{3.8} - {py3.8,py3.12,py3.13}-aiohttp-latest - - # Anthropic - {py3.8,py3.11,py3.12}-anthropic-v{0.16,0.28,0.40} - {py3.7,py3.11,py3.12}-anthropic-latest - - # Ariadne - {py3.8,py3.11}-ariadne-v{0.20} - {py3.8,py3.12,py3.13}-ariadne-latest - - # Arq - {py3.7,py3.11}-arq-v{0.23} - {py3.7,py3.12,py3.13}-arq-latest - - # Asgi + # === Cloud Resource Context === + {py3.6,py3.12,py3.13}-cloud_resource_context + + # ==== GCP === + {py3.7}-gcp + + # === Asgi === {py3.7,py3.12,py3.13}-asgi - # asyncpg - {py3.7,py3.10}-asyncpg-v{0.23} - {py3.8,py3.11,py3.12}-asyncpg-latest + # OpenTelemetry Experimental (POTel) + {py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-potel # AWS Lambda # The aws_lambda tests deploy to the real AWS and have their own @@ -57,242 +36,242 @@ envlist = # see `lambda_runtime` fixture in tests/integrations/aws_lambda.py {py3.9}-aws_lambda - # Beam - {py3.7}-beam-v{2.12} - {py3.8,py3.11}-beam-latest - - # Boto3 - {py3.6,py3.7}-boto3-v{1.12} - {py3.7,py3.11,py3.12}-boto3-v{1.23} - {py3.11,py3.12}-boto3-v{1.34} - {py3.11,py3.12,py3.13}-boto3-latest - - # Bottle - {py3.6,py3.9}-bottle-v{0.12} - {py3.6,py3.12,py3.13}-bottle-latest - - # Celery - {py3.6,py3.8}-celery-v{4} - {py3.6,py3.8}-celery-v{5.0} - {py3.7,py3.10}-celery-v{5.1,5.2} - {py3.8,py3.11,py3.12}-celery-v{5.3,5.4,5.5} - {py3.8,py3.12,py3.13}-celery-latest - - # Chalice - {py3.6,py3.9}-chalice-v{1.16} - {py3.8,py3.12,py3.13}-chalice-latest - - # Clickhouse Driver - {py3.8,py3.11}-clickhouse_driver-v{0.2.0} - {py3.8,py3.12,py3.13}-clickhouse_driver-latest - - # Cloud Resource Context - {py3.6,py3.12,py3.13}-cloud_resource_context - - # Cohere - {py3.9,py3.11,py3.12}-cohere-v5 - {py3.9,py3.11,py3.12}-cohere-latest - - # Django - # - Django 1.x - {py3.6,py3.7}-django-v{1.11} - # - Django 2.x - {py3.6,py3.7}-django-v{2.0} - {py3.6,py3.9}-django-v{2.2} - # - Django 3.x - {py3.6,py3.9}-django-v{3.0} - {py3.6,py3.9,py3.11}-django-v{3.2} - # - Django 4.x - {py3.8,py3.11,py3.12}-django-v{4.0,4.1,4.2} - # - Django 5.x - {py3.10,py3.11,py3.12}-django-v{5.0,5.1} - {py3.10,py3.12,py3.13}-django-latest - - # dramatiq - {py3.6,py3.9}-dramatiq-v{1.13} - {py3.7,py3.10,py3.11}-dramatiq-v{1.15} - {py3.8,py3.11,py3.12}-dramatiq-v{1.17} - {py3.8,py3.11,py3.12}-dramatiq-latest - - # Falcon - {py3.6,py3.7}-falcon-v{1,1.4,2} - {py3.6,py3.11,py3.12}-falcon-v{3} - {py3.8,py3.11,py3.12}-falcon-v{4} - {py3.7,py3.11,py3.12}-falcon-latest - - # FastAPI - {py3.7,py3.10}-fastapi-v{0.79} - {py3.8,py3.12,py3.13}-fastapi-latest - - # Flask - {py3.6,py3.8}-flask-v{1} - {py3.8,py3.11,py3.12}-flask-v{2} - {py3.10,py3.11,py3.12}-flask-v{3} - {py3.10,py3.12,py3.13}-flask-latest - - # GCP - {py3.7}-gcp - - # GQL - {py3.7,py3.11}-gql-v{3.4} - {py3.7,py3.12,py3.13}-gql-latest - - # Graphene - {py3.7,py3.11}-graphene-v{3.3} - {py3.7,py3.12,py3.13}-graphene-latest - - # gRPC - {py3.7,py3.9}-grpc-v{1.39} - {py3.7,py3.10}-grpc-v{1.49} - {py3.7,py3.11}-grpc-v{1.59} - {py3.8,py3.11,py3.12}-grpc-latest - - # HTTPX - {py3.6,py3.9}-httpx-v{0.16,0.18} - {py3.6,py3.10}-httpx-v{0.20,0.22} - {py3.7,py3.11,py3.12}-httpx-v{0.23,0.24} - {py3.9,py3.11,py3.12}-httpx-v{0.25,0.27} - {py3.9,py3.12,py3.13}-httpx-latest - - # Huey - {py3.6,py3.11,py3.12}-huey-v{2.0} - {py3.6,py3.12,py3.13}-huey-latest - - # Huggingface Hub - {py3.9,py3.12,py3.13}-huggingface_hub-{v0.22} - {py3.9,py3.12,py3.13}-huggingface_hub-latest - - # Langchain - {py3.9,py3.11,py3.12}-langchain-v0.1 - {py3.9,py3.11,py3.12}-langchain-v0.3 - {py3.9,py3.11,py3.12}-langchain-latest - {py3.9,py3.11,py3.12}-langchain-notiktoken - - # LaunchDarkly - {py3.8,py3.12,py3.13}-launchdarkly-v9.8.0 - {py3.8,py3.12,py3.13}-launchdarkly-latest - - # Litestar - {py3.8,py3.11}-litestar-v{2.0} - {py3.8,py3.11,py3.12}-litestar-v{2.6} - {py3.8,py3.11,py3.12}-litestar-v{2.12} - {py3.8,py3.11,py3.12}-litestar-latest - - # Loguru - {py3.6,py3.11,py3.12}-loguru-v{0.5} - {py3.6,py3.12,py3.13}-loguru-latest - - # OpenAI - {py3.9,py3.11,py3.12}-openai-v1.0 - {py3.9,py3.11,py3.12}-openai-v1.22 - {py3.9,py3.11,py3.12}-openai-v1.55 - {py3.9,py3.11,py3.12}-openai-latest - {py3.9,py3.11,py3.12}-openai-notiktoken - - # OpenFeature - {py3.8,py3.12,py3.13}-openfeature-v0.7 - {py3.8,py3.12,py3.13}-openfeature-latest - - # OpenTelemetry (OTel) - {py3.7,py3.9,py3.12,py3.13}-opentelemetry - - # OpenTelemetry Experimental (POTel) - {py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-potel + # === Integrations === + # ~~~ AI ~~~ + {py3.7,py3.13}-anthropic-v0.16.0 + {py3.7,py3.13}-anthropic-v0.25.9 + {py3.7,py3.13}-anthropic-v0.34.2 + {py3.8,py3.13}-anthropic-v0.42.0 + + {py3.6,py3.13}-cohere-v0.0.8 + {py3.7,py3.13}-cohere-v4.4.2 + {py3.8,py3.13}-cohere-v4.38 + {py3.9,py3.13}-cohere-v5.13.6 + + {py3.9,py3.13}-langchain-v0.0.354 + {py3.9,py3.13}-langchain-v0.1.20 + {py3.9,py3.13}-langchain-v0.2.17 + {py3.9,py3.13}-langchain-v0.3.14 + + {py3.9,py3.13}-langchain_notiktoken-v0.0.99 + {py3.9,py3.13}-langchain_notiktoken-v0.1.9 + {py3.9,py3.13}-langchain_notiktoken-v0.2.9 + {py3.9,py3.13}-langchain_notiktoken-v0.3.14 + + {py3.8,py3.13}-openai-v1.0.1 + {py3.8,py3.13}-openai-v1.21.2 + {py3.8,py3.13}-openai-v1.40.8 + {py3.8,py3.13}-openai-v1.59.6 + + {py3.6,py3.13}-openai_notiktoken-v0.1.3 + {py3.8,py3.13}-openai_notiktoken-v1.2.4 + {py3.8,py3.13}-openai_notiktoken-v1.31.2 + {py3.8,py3.13}-openai_notiktoken-v1.59.6 + + {py3.8,py3.13}-huggingface_hub-v0.22.2 + {py3.8,py3.13}-huggingface_hub-v0.24.7 + {py3.8,py3.13}-huggingface_hub-v0.26.5 + {py3.8,py3.13}-huggingface_hub-v0.27.1 + + # ~~~ Cloud ~~~ + {py3.6,py3.7}-boto3-v1.12.9 + {py3.6,py3.13}-boto3-v1.18.65 + {py3.7,py3.13}-boto3-v1.26.9 + {py3.8,py3.13}-boto3-v1.35.97 + + {py3.6,py3.8}-chalice-v1.16.0 + {py3.6,py3.8}-chalice-v1.21.9 + {py3.6,py3.9}-chalice-v1.26.6 + {py3.8,py3.12}-chalice-v1.31.3 + + # ~~~ DBs ~~~ + {py3.6,py3.13}-asyncpg-v0.23.0 + {py3.6,py3.13}-asyncpg-v0.25.0 + {py3.7,py3.13}-asyncpg-v0.27.0 + {py3.8,py3.13}-asyncpg-v0.30.0 + + {py3.7,py3.13}-clickhouse_driver-v0.2.9 + + {py3.6,py3.9}-pymongo-v3.11.4 + {py3.7,py3.13}-pymongo-v4.1.1 + {py3.7,py3.13}-pymongo-v4.5.0 + {py3.8,py3.13}-pymongo-v4.10.1 + + {py3.6,py3.13}-redis-v3.4.1 + {py3.6,py3.13}-redis-v4.2.2 + {py3.7,py3.13}-redis-v4.6.0 + {py3.8,py3.13}-redis-v5.2.1 + + {py3.6,py3.13}-redis_py_cluster_legacy-v2.1.3 + + {py3.6,py3.13}-sqlalchemy-v1.3.24 + {py3.6,py3.13}-sqlalchemy-v1.4.9 + {py3.6,py3.13}-sqlalchemy-v1.4.54 + {py3.7,py3.13}-sqlalchemy-v2.0.37 + + # ~~~ Flags ~~~ + {py3.8,py3.13}-launchdarkly-v9.8.1 + {py3.8,py3.13}-launchdarkly-v9.9.0 + + {py3.8,py3.13}-openfeature-v0.7.4 + + {py3.8,py3.13}-unleash-v6.0.1 + + # ~~~ GraphQL ~~~ + {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.10}-gql-v3.4.1 + {py3.7,py3.12}-gql-v3.5.0 + + {py3.6,py3.10}-graphene-v3.3 + {py3.8,py3.13}-graphene-v3.4.3 + + {py3.8,py3.13}-strawberry-v0.209.8 + {py3.8,py3.13}-strawberry-v0.225.1 + {py3.8,py3.13}-strawberry-v0.241.0 + {py3.9,py3.13}-strawberry-v0.258.0 + + # ~~~ Network ~~~ + {py3.6,py3.8}-grpc-v1.27.2 + {py3.6,py3.9}-grpc-v1.40.0 + {py3.7,py3.13}-grpc-v1.55.3 + {py3.8,py3.13}-grpc-v1.69.0 + + {py3.6,py3.13}-httpx-v0.11.1 + {py3.6,py3.13}-httpx-v0.17.1 + {py3.7,py3.13}-httpx-v0.23.3 + {py3.8,py3.13}-httpx-v0.28.1 + + {py3.6,py3.13}-requests-v2.23.0 + {py3.6,py3.13}-requests-v2.26.0 + {py3.7,py3.13}-requests-v2.29.0 + {py3.8,py3.13}-requests-v2.32.3 + + # ~~~ Tasks ~~~ + {py3.6,py3.13}-arq-v0.23 + {py3.7,py3.13}-arq-v0.24.0 + {py3.7,py3.13}-arq-v0.25.0 + {py3.8,py3.13}-arq-v0.26.3 + + {py3.6,py3.13}-beam-v2.18.0 + {py3.6,py3.13}-beam-v2.32.0 + {py3.7,py3.13}-beam-v2.46.0 + {py3.9,py3.13}-beam-v2.61.0 + + {py3.6,py3.13}-celery-v4.4.7 + {py3.6,py3.13}-celery-v5.1.2 + {py3.8,py3.13}-celery-v5.3.6 + {py3.8,py3.13}-celery-v5.4.0 + + {py3.6,py3.13}-dramatiq-v1.8.1 + {py3.6,py3.13}-dramatiq-v1.11.0 + {py3.7,py3.13}-dramatiq-v1.14.2 + {py3.8,py3.13}-dramatiq-v1.17.1 + + {py3.6,py3.7}-huey-v2.2.0 + {py3.6,py3.7}-huey-v2.3.2 + {py3.6,py3.11}-huey-v2.4.5 + {py3.6,py3.12}-huey-v2.5.2 + + {py3.7,py3.10}-ray-v2.7.2 + {py3.8,py3.13}-ray-v2.21.0 + {py3.8,py3.13}-ray-v2.33.0 + {py3.9,py3.13}-ray-v2.40.0 + + {py3.6,py3.13}-rq-v1.2.2 + {py3.6,py3.13}-rq-v1.7.0 + {py3.6,py3.13}-rq-v1.12.0 + {py3.8,py3.13}-rq-v2.1.0 + + {py3.6,py3.7}-spark-v2.4.8 + {py3.6,py3.13}-spark-v3.1.3 + {py3.7,py3.13}-spark-v3.3.4 + {py3.8,py3.13}-spark-v3.5.4 + + # ~~~ Web 1 ~~~ + {py3.6,py3.7}-django-v1.11.29 + {py3.6,py3.13}-django-v3.1.14 + {py3.8,py3.13}-django-v4.1.9 + {py3.10,py3.13}-django-v5.1.4 + + {py3.6,py3.13}-flask-v1.1.4 + {py3.7,py3.13}-flask-v2.1.3 + {py3.8,py3.13}-flask-v2.3.3 + {py3.9,py3.13}-flask-v3.1.0 + + {py3.6,py3.13}-starlette-v0.13.8 + {py3.7,py3.13}-starlette-v0.24.0 + {py3.8,py3.13}-starlette-v0.35.1 + {py3.9,py3.13}-starlette-v0.45.2 + + {py3.7,py3.13}-fastapi-v0.79.1 + {py3.7,py3.13}-fastapi-v0.91.0 + {py3.7,py3.13}-fastapi-v0.103.2 + {py3.8,py3.13}-fastapi-v0.115.6 + + # ~~~ Web 2 ~~~ + {py3.6,py3.13}-aiohttp-v3.6.3 + {py3.6,py3.13}-aiohttp-v3.8.6 + {py3.8,py3.13}-aiohttp-v3.10.9 + {py3.9,py3.13}-aiohttp-v3.11.11 + + {py3.6,py3.7}-bottle-v0.12.25 + {py3.6,py3.9}-bottle-v0.13.2 + + {py3.6,py3.13}-falcon-v3.0.1 + {py3.6,py3.13}-falcon-v3.1.3 + {py3.8,py3.13}-falcon-v4.0.2 + + {py3.8,py3.13}-litestar-v2.0.1 + {py3.8,py3.13}-litestar-v2.5.5 + {py3.8,py3.13}-litestar-v2.10.0 + {py3.8,py3.13}-litestar-v2.14.0 + + {py3.6,py3.13}-pyramid-v1.10.8 + {py3.6,py3.13}-pyramid-v2.0.2 + + {py3.7,py3.13}-quart-v0.11.5 + {py3.7,py3.13}-quart-v0.14.1 + {py3.7,py3.13}-quart-v0.17.0 + {py3.9,py3.13}-quart-v0.20.0 + + {py3.6,py3.13}-sanic-v19.12.5 + {py3.7,py3.13}-sanic-v21.6.2 + {py3.7,py3.13}-sanic-v22.12.0 + {py3.8,py3.13}-sanic-v24.12.0 + + {py3.7,py3.13}-starlite-v0.1.6 + {py3.7,py3.13}-starlite-v1.12.0 + {py3.7,py3.13}-starlite-v1.32.0 + {py3.8,py3.13}-starlite-v1.51.16 + + {py3.6,py3.13}-tornado-v6.0.4 + {py3.6,py3.13}-tornado-v6.1 + {py3.7,py3.13}-tornado-v6.2 + {py3.8,py3.13}-tornado-v6.4.2 + + # ~~~ Misc ~~~ + {py3.6,py3.13}-loguru-v0.4.1 + {py3.6,py3.13}-loguru-v0.5.3 + {py3.6,py3.13}-loguru-v0.6.0 + {py3.6,py3.13}-loguru-v0.7.3 + + {py3.6,py3.9}-pure_eval-v0.1.1 + {py3.7,py3.13}-pure_eval-v0.2.3 + + {py3.6,py3.13}-trytond-v5.0.63 + {py3.6,py3.13}-trytond-v5.8.16 + {py3.7,py3.13}-trytond-v6.6.9 + {py3.8,py3.13}-trytond-v7.4.3 + + {py3.6,py3.13}-typer-v0.0.9 + {py3.6,py3.13}-typer-v0.4.2 + {py3.6,py3.13}-typer-v0.9.4 + {py3.7,py3.13}-typer-v0.15.1 - # pure_eval - {py3.6,py3.12,py3.13}-pure_eval - - # PyMongo (Mongo DB) - {py3.6}-pymongo-v{3.1} - {py3.6,py3.9}-pymongo-v{3.12} - {py3.6,py3.11}-pymongo-v{4.0} - {py3.7,py3.11,py3.12}-pymongo-v{4.3,4.7} - {py3.7,py3.12,py3.13}-pymongo-latest - - # Pyramid - {py3.6,py3.11}-pyramid-v{1.6} - {py3.6,py3.11,py3.12}-pyramid-v{1.10} - {py3.6,py3.11,py3.12}-pyramid-v{2.0} - {py3.6,py3.11,py3.12}-pyramid-latest - - # Quart - {py3.7,py3.11}-quart-v{0.16} - {py3.8,py3.11,py3.12}-quart-v{0.19} - {py3.8,py3.12,py3.13}-quart-latest - - # Ray - {py3.10,py3.11}-ray-v{2.34} - {py3.10,py3.11}-ray-latest - - # Redis - {py3.6,py3.8}-redis-v{3} - {py3.7,py3.8,py3.11}-redis-v{4} - {py3.7,py3.11,py3.12}-redis-v{5} - {py3.7,py3.12,py3.13}-redis-latest - - # Redis Cluster - {py3.6,py3.8}-redis_py_cluster_legacy-v{1,2} - # no -latest, not developed anymore - - # Requests - {py3.6,py3.8,py3.12,py3.13}-requests - - # RQ (Redis Queue) - {py3.6}-rq-v{0.6} - {py3.6,py3.9}-rq-v{0.13,1.0} - {py3.6,py3.11}-rq-v{1.5,1.10} - {py3.7,py3.11,py3.12}-rq-v{1.15,1.16} - {py3.7,py3.12,py3.13}-rq-latest - - # Sanic - {py3.6,py3.7}-sanic-v{0.8} - {py3.6,py3.8}-sanic-v{20} - {py3.8,py3.11,py3.12}-sanic-v{24.6} - {py3.9,py3.12,py3.13}-sanic-latest - - # Spark - {py3.8,py3.10,py3.11}-spark-v{3.1,3.3,3.5} - {py3.8,py3.10,py3.11,py3.12}-spark-latest - - # Starlette - {py3.7,py3.10}-starlette-v{0.19} - {py3.7,py3.11}-starlette-v{0.24,0.28} - {py3.8,py3.11,py3.12}-starlette-v{0.32,0.36,0.40} - {py3.8,py3.12,py3.13}-starlette-latest - - # Starlite - {py3.8,py3.11}-starlite-v{1.48,1.51} - # 1.51.14 is the last starlite version; the project continues as litestar - - # SQL Alchemy - {py3.6,py3.9}-sqlalchemy-v{1.2,1.4} - {py3.7,py3.11}-sqlalchemy-v{2.0} - {py3.7,py3.12,py3.13}-sqlalchemy-latest - - # Strawberry - {py3.8,py3.11}-strawberry-v{0.209} - {py3.8,py3.11,py3.12}-strawberry-v{0.222} - {py3.8,py3.12,py3.13}-strawberry-latest - - # Tornado - {py3.8,py3.11,py3.12}-tornado-v{6.0} - {py3.8,py3.11,py3.12}-tornado-v{6.2} - {py3.8,py3.11,py3.12}-tornado-latest - - # Trytond - {py3.6}-trytond-v{4} - {py3.6,py3.8}-trytond-v{5} - {py3.6,py3.11}-trytond-v{6} - {py3.8,py3.11,py3.12}-trytond-v{7} - {py3.8,py3.12,py3.13}-trytond-latest - - # Typer - {py3.7,py3.12,py3.13}-typer-v{0.15} - {py3.7,py3.12,py3.13}-typer-latest - - # Unleash - {py3.8,py3.12,py3.13}-unleash-v6.0.1 - {py3.8,py3.12,py3.13}-unleash-latest [testenv] deps = @@ -322,421 +301,387 @@ deps = {py3.6,py3.7}-gevent: pytest<7.0.0 {py3.8,py3.9,py3.10,py3.11,py3.12}-gevent: pytest - # === Integrations === - - # AIOHTTP - aiohttp-v3.4: aiohttp~=3.4.0 - aiohttp-v3.8: aiohttp~=3.8.0 - aiohttp-latest: aiohttp - aiohttp: pytest-aiohttp - aiohttp-v3.8: pytest-asyncio - aiohttp-latest: pytest-asyncio - - # Anthropic - anthropic: pytest-asyncio - anthropic-v{0.16,0.28}: httpx<0.28.0 - anthropic-v0.16: anthropic~=0.16.0 - anthropic-v0.28: anthropic~=0.28.0 - anthropic-v0.40: anthropic~=0.40.0 - anthropic-latest: anthropic - - # Ariadne - ariadne-v0.20: ariadne~=0.20.0 - ariadne-latest: ariadne - ariadne: fastapi - ariadne: flask - ariadne: httpx - - # Arq - arq-v0.23: arq~=0.23.0 - arq-v0.23: pydantic<2 - arq-latest: arq - arq: fakeredis>=2.2.0,<2.8 - arq: pytest-asyncio - arq: async-timeout - - # Asgi + # === Asgi === asgi: pytest-asyncio asgi: async-asgi-testclient - # Asyncpg - asyncpg-v0.23: asyncpg~=0.23.0 - asyncpg-latest: asyncpg - asyncpg: pytest-asyncio + # OpenTelemetry Experimental (POTel) + potel: -e .[opentelemetry-experimental] # AWS Lambda aws_lambda: boto3 - # Beam - beam-v2.12: apache-beam~=2.12.0 - beam-latest: apache-beam + # === Integrations === + # ~~~ AI ~~~ + 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: pytest-asyncio + anthropic-v0.16.0: httpx<0.28.0 + anthropic-v0.25.9: httpx<0.28.0 + + cohere-v0.0.8: cohere==0.0.8 + cohere-v4.4.2: cohere==4.4.2 + cohere-v4.38: cohere==4.38 + cohere-v5.13.6: cohere==5.13.6 + cohere: httpx + + langchain-v0.0.354: langchain==0.0.354 + langchain-v0.1.20: langchain==0.1.20 + langchain-v0.2.17: langchain==0.2.17 + langchain-v0.3.14: langchain==0.3.14 + langchain: openai + langchain: tiktoken + langchain: httpx + langchain-v0.3.14: langchain-community + + langchain_notiktoken-v0.0.99: langchain==0.0.99 + langchain_notiktoken-v0.1.9: langchain==0.1.9 + langchain_notiktoken-v0.2.9: langchain==0.2.9 + langchain_notiktoken-v0.3.14: langchain==0.3.14 + langchain_notiktoken: openai + langchain_notiktoken: httpx + langchain_notiktoken-v0.3.14: langchain-community + + openai-v1.0.1: openai==1.0.1 + openai-v1.21.2: openai==1.21.2 + openai-v1.40.8: openai==1.40.8 + openai-v1.59.6: openai==1.59.6 + openai: pytest-asyncio + openai: tiktoken + openai: httpx + openai-v1.0.1: httpx<0.28.0 + openai-v1.21.2: httpx<0.28.0 + + openai_notiktoken-v0.1.3: openai==0.1.3 + openai_notiktoken-v1.2.4: openai==1.2.4 + openai_notiktoken-v1.31.2: openai==1.31.2 + openai_notiktoken-v1.59.6: openai==1.59.6 + openai_notiktoken: pytest-asyncio + openai_notiktoken: httpx + openai_notiktoken-v0.1.3: httpx<0.28.0 + openai_notiktoken-v1.2.4: httpx<0.28.0 + + huggingface_hub-v0.22.2: huggingface_hub==0.22.2 + huggingface_hub-v0.24.7: huggingface_hub==0.24.7 + huggingface_hub-v0.26.5: huggingface_hub==0.26.5 + huggingface_hub-v0.27.1: huggingface_hub==0.27.1 + + # ~~~ Cloud ~~~ + 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.97: boto3==1.35.97 + + chalice-v1.16.0: chalice==1.16.0 + chalice-v1.21.9: chalice==1.21.9 + chalice-v1.26.6: chalice==1.26.6 + chalice-v1.31.3: chalice==1.31.3 + chalice: pytest-chalice==0.0.5 + + # ~~~ DBs ~~~ + asyncpg-v0.23.0: asyncpg==0.23.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 - # Boto3 - boto3-v1.12: boto3~=1.12.0 - boto3-v1.23: boto3~=1.23.0 - boto3-v1.34: boto3~=1.34.0 - boto3-latest: boto3 + clickhouse_driver-v0.2.9: clickhouse-driver==0.2.9 - # Bottle - bottle: Werkzeug<2.1.0 - bottle-v0.12: bottle~=0.12.0 - bottle-latest: bottle + pymongo-v3.11.4: pymongo==3.11.4 + pymongo-v4.1.1: pymongo==4.1.1 + pymongo-v4.5.0: pymongo==4.5.0 + pymongo-v4.10.1: pymongo==4.10.1 + pymongo: mockupdb - # Celery - celery: redis - celery-v4: Celery~=4.0 - celery-v5.0: Celery~=5.0.0 - celery-v5.1: Celery~=5.1.0 - celery-v5.2: Celery~=5.2.0 - celery-v5.3: Celery~=5.3.0 - celery-v5.4: Celery~=5.4.0 - # TODO: update when stable is out - celery-v5.5: Celery==5.5.0rc3 - celery-latest: Celery + redis-v3.4.1: redis==3.4.1 + redis-v4.2.2: redis==4.2.2 + redis-v4.6.0: redis==4.6.0 + redis-v5.2.1: redis==5.2.1 + redis: fakeredis!=1.7.4 + redis: pytest<8.0.0 + redis: pytest-asyncio + py3.6,py3.7-redis: fakeredis!=2.26.0 - celery: newrelic - {py3.7}-celery: importlib-metadata<5.0 + redis_py_cluster_legacy-v2.1.3: redis-py-cluster==2.1.3 - # Chalice - chalice: pytest-chalice==0.0.5 - chalice-v1.16: chalice~=1.16.0 - chalice-latest: chalice + sqlalchemy-v1.3.24: sqlalchemy==1.3.24 + sqlalchemy-v1.4.9: sqlalchemy==1.4.9 + sqlalchemy-v1.4.54: sqlalchemy==1.4.54 + sqlalchemy-v2.0.37: sqlalchemy==2.0.37 - # Clickhouse Driver - clickhouse_driver-v0.2.0: clickhouse_driver~=0.2.0 - clickhouse_driver-latest: clickhouse_driver + # ~~~ Flags ~~~ + launchdarkly-v9.8.1: launchdarkly-server-sdk==9.8.1 + launchdarkly-v9.9.0: launchdarkly-server-sdk==9.9.0 - # Cohere - cohere-v5: cohere~=5.3.3 - cohere-latest: cohere + openfeature-v0.7.4: openfeature-sdk==0.7.4 - # Django - django: psycopg2-binary - django-v{1.11,2.0,2.1,2.2,3.0,3.1,3.2}: djangorestframework>=3.0.0,<4.0.0 - django-v{2.0,2.2,3.0,3.2,4.0,4.1,4.2,5.0,5.1}: channels[daphne] - django-v{2.2,3.0}: six - django-v{1.11,2.0,2.2,3.0,3.2}: Werkzeug<2.1.0 - django-v{1.11,2.0,2.2,3.0}: pytest-django<4.0 - django-v{3.2,4.0,4.1,4.2,5.0,5.1}: pytest-django - django-v{4.0,4.1,4.2,5.0,5.1}: djangorestframework - django-v{4.0,4.1,4.2,5.0,5.1}: pytest-asyncio - django-v{4.0,4.1,4.2,5.0,5.1}: Werkzeug - django-latest: djangorestframework - django-latest: pytest-asyncio - django-latest: pytest-django - django-latest: Werkzeug - django-latest: channels[daphne] - - django-v1.11: Django~=1.11.0 - django-v2.0: Django~=2.0.0 - django-v2.2: Django~=2.2.0 - django-v3.0: Django~=3.0.0 - django-v3.2: Django~=3.2.0 - django-v4.0: Django~=4.0.0 - django-v4.1: Django~=4.1.0 - django-v4.2: Django~=4.2.0 - django-v5.0: Django~=5.0.0 - django-v5.1: Django==5.1rc1 - django-latest: Django - - # dramatiq - dramatiq-v1.13: dramatiq>=1.13,<1.14 - dramatiq-v1.15: dramatiq>=1.15,<1.16 - dramatiq-v1.17: dramatiq>=1.17,<1.18 - dramatiq-latest: dramatiq - - # Falcon - falcon-v1.4: falcon~=1.4.0 - falcon-v1: falcon~=1.0 - falcon-v2: falcon~=2.0 - falcon-v3: falcon~=3.0 - falcon-v4: falcon~=4.0 - falcon-latest: falcon - - # FastAPI - fastapi: httpx - # (this is a dependency of httpx) - fastapi: anyio<4.0.0 - fastapi: pytest-asyncio - fastapi: python-multipart - fastapi: requests - fastapi-v{0.79}: fastapi~=0.79.0 - fastapi-latest: fastapi + unleash-v6.0.1: UnleashClient==6.0.1 - # Flask - flask: flask-login - flask-v{1,2.0}: Werkzeug<2.1.0 - flask-v{1,2.0}: markupsafe<2.1.0 - flask-v{3}: Werkzeug - flask-v1: Flask~=1.0 - flask-v2: Flask~=2.0 - flask-v3: Flask~=3.0 - flask-latest: Flask - - # GQL - gql-v{3.4}: gql[all]~=3.4.0 - gql-latest: gql[all] - - # Graphene + # ~~~ GraphQL ~~~ + 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-v3.4.1: gql[all]==3.4.1 + gql-v3.5.0: gql[all]==3.5.0 + + graphene-v3.3: graphene==3.3 + graphene-v3.4.3: graphene==3.4.3 graphene: blinker graphene: fastapi graphene: flask graphene: httpx - graphene-v{3.3}: graphene~=3.3.0 - graphene-latest: graphene - # gRPC + 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.258.0: strawberry-graphql[fastapi,flask]==0.258.0 + strawberry: fastapi + strawberry: flask + strawberry: httpx + + # ~~~ Network ~~~ + grpc-v1.27.2: grpcio==1.27.2 + grpc-v1.40.0: grpcio==1.40.0 + grpc-v1.55.3: grpcio==1.55.3 + grpc-v1.69.0: grpcio==1.69.0 grpc: protobuf grpc: mypy-protobuf grpc: types-protobuf grpc: pytest-asyncio - grpc-v1.39: grpcio~=1.39.0 - grpc-v1.49: grpcio~=1.49.1 - grpc-v1.59: grpcio~=1.59.0 - grpc-latest: grpcio - - # HTTPX - httpx-v0.16: pytest-httpx==0.10.0 - httpx-v0.18: pytest-httpx==0.12.0 - httpx-v0.20: pytest-httpx==0.14.0 - httpx-v0.22: pytest-httpx==0.19.0 - httpx-v0.23: pytest-httpx==0.21.0 - httpx-v0.24: pytest-httpx==0.22.0 - httpx-v0.25: pytest-httpx==0.25.0 - httpx: pytest-httpx - # anyio is a dep of httpx + + httpx-v0.11.1: httpx==0.11.1 + httpx-v0.17.1: httpx==0.17.1 + httpx-v0.23.3: httpx==0.23.3 + httpx-v0.28.1: httpx==0.28.1 httpx: anyio<4.0.0 - httpx-v0.16: httpx~=0.16.0 - httpx-v0.18: httpx~=0.18.0 - httpx-v0.20: httpx~=0.20.0 - httpx-v0.22: httpx~=0.22.0 - httpx-v0.23: httpx~=0.23.0 - httpx-v0.24: httpx~=0.24.0 - httpx-v0.25: httpx~=0.25.0 - httpx-v0.27: httpx~=0.27.0 - httpx-latest: httpx - - # Huey - huey-v2.0: huey~=2.0.0 - huey-latest: huey - - # Huggingface Hub - huggingface_hub-v0.22: huggingface_hub~=0.22.2 - huggingface_hub-latest: huggingface_hub - - # Langchain - langchain-v0.1: openai~=1.0.0 - langchain-v0.1: langchain~=0.1.11 - langchain-v0.1: tiktoken~=0.6.0 - langchain-v0.1: httpx<0.28.0 - langchain-v0.3: langchain~=0.3.0 - langchain-v0.3: langchain-community - langchain-v0.3: tiktoken - langchain-v0.3: openai - langchain-{latest,notiktoken}: langchain - langchain-{latest,notiktoken}: langchain-openai - langchain-{latest,notiktoken}: openai>=1.6.1 - langchain-latest: tiktoken~=0.6.0 - - # Litestar + httpx: pytest-httpx + + requests-v2.23.0: requests==2.23.0 + requests-v2.26.0: requests==2.26.0 + requests-v2.29.0: requests==2.29.0 + requests-v2.32.3: requests==2.32.3 + + # ~~~ Tasks ~~~ + 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: fakeredis>=2.2.0,<2.8 + arq: pytest-asyncio + arq: async-timeout + arq-v0.23: pydantic<2 + arq-v0.24.0: pydantic<2 + arq-v0.25.0: pydantic<2 + + beam-v2.18.0: apache-beam==2.18.0 + beam-v2.32.0: apache-beam==2.32.0 + beam-v2.46.0: apache-beam==2.46.0 + beam-v2.61.0: apache-beam==2.61.0 + + 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: newrelic + celery: redis + py3.7-celery: importlib-metata<5.0 + + dramatiq-v1.8.1: dramatiq==1.8.1 + dramatiq-v1.11.0: dramatiq==1.11.0 + dramatiq-v1.14.2: dramatiq==1.14.2 + dramatiq-v1.17.1: dramatiq==1.17.1 + + huey-v2.2.0: huey==2.2.0 + huey-v2.3.2: huey==2.3.2 + huey-v2.4.5: huey==2.4.5 + huey-v2.5.2: huey==2.5.2 + + 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 + rq-v1.7.0: rq==1.7.0 + rq-v1.12.0: rq==1.12.0 + rq-v2.1.0: rq==2.1.0 + rq: fakeredis + rq-v1.2.2: fakeredis>=1.0,<1.7.4 + rq-v1.7.0: fakeredis>=1.0,<1.7.4 + py3.6,py3.7-rq: fakeredis!=2.26.0 + + spark-v2.4.8: pyspark==2.4.8 + spark-v3.1.3: pyspark==3.1.3 + spark-v3.3.4: pyspark==3.3.4 + spark-v3.5.4: pyspark==3.5.4 + + # ~~~ Web 1 ~~~ + django-v1.11.29: django==1.11.29 + django-v3.1.14: django==3.1.14 + django-v4.1.9: django==4.1.9 + django-v5.1.4: django==5.1.4 + django: psycopg2-binary + django: werkzeug + django-v1.11.29: werkzeug<2.1.0 + django-v1.11.29: djangorestframework>=3.0.0,<4.0.0 + django-v1.11.29: pytest-django + django-v3.1.14: werkzeug<2.1.0 + django-v3.1.14: djangorestframework>=3.0.0,<4.0.0 + django-v3.1.14: pytest-django + django-v3.1.14: channels[daphne] + django-v4.1.9: channels[daphne] + django-v5.1.4: channels[daphne] + django-v1.11.29: pytest-django<4.0 + django-v4.1.9: djangorestframework + django-v4.1.9: pytest-asyncio + django-v5.1.4: djangorestframework + django-v5.1.4: pytest-asyncio + + flask-v1.1.4: flask==1.1.4 + flask-v2.1.3: flask==2.1.3 + flask-v2.3.3: flask==2.3.3 + flask-v3.1.0: flask==3.1.0 + flask: flask-login + flask: werkzeug + flask-v1.1.4: werkzeug<2.1.0 + flask-v1.1.4: markupsafe<2.1.0 + flask-v2.1.3: werkzeug<2.1.0 + flask-v2.1.3: markupsafe<2.1.0 + flask-v2.3.3: werkzeug<2.1.0 + flask-v2.3.3: markupsafe<2.1.0 + + starlette-v0.13.8: starlette==0.13.8 + starlette-v0.24.0: starlette==0.24.0 + starlette-v0.35.1: starlette==0.35.1 + starlette-v0.45.2: starlette==0.45.2 + starlette: pytest-asyncio + starlette: python-multipart + starlette: requests + starlette: anyio<4.0.0 + starlette: jinja2 + starlette: httpx + starlette-v0.13.8: httpx<0.28.0 + starlette-v0.24.0: httpx<0.28.0 + starlette-v0.35.1: httpx<0.28.0 + + fastapi-v0.79.1: fastapi==0.79.1 + fastapi-v0.91.0: fastapi==0.91.0 + fastapi-v0.103.2: fastapi==0.103.2 + fastapi-v0.115.6: fastapi==0.115.6 + fastapi: httpx + fastapi: anyio<4.0.0 + fastapi: python-multipart + fastapi: pytest-asyncio + fastapi: requests + + # ~~~ Web 2 ~~~ + aiohttp-v3.6.3: aiohttp==3.6.3 + aiohttp-v3.8.6: aiohttp==3.8.6 + aiohttp-v3.10.9: aiohttp==3.10.9 + aiohttp-v3.11.11: aiohttp==3.11.11 + aiohttp: pytest-aiohttp + aiohttp: pytest-asyncio + + bottle-v0.12.25: bottle==0.12.25 + bottle-v0.13.2: bottle==0.13.2 + bottle: werkzeug<2.1.0 + + falcon-v3.0.1: falcon==3.0.1 + falcon-v3.1.3: falcon==3.1.3 + falcon-v4.0.2: falcon==4.0.2 + + litestar-v2.0.1: litestar==2.0.1 + 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 litestar: cryptography - litestar-v{2.0,2.6}: httpx<0.28 - litestar-v2.0: litestar~=2.0.0 - litestar-v2.6: litestar~=2.6.0 - litestar-v2.12: litestar~=2.12.0 - litestar-latest: litestar - - # Loguru - loguru-v0.5: loguru~=0.5.0 - loguru-latest: loguru - - # OpenAI - openai: pytest-asyncio - openai-v1.0: openai~=1.0.0 - openai-v1.0: tiktoken - openai-v1.0: httpx<0.28.0 - openai-v1.22: openai~=1.22.0 - openai-v1.22: tiktoken - openai-v1.22: httpx<0.28.0 - openai-v1.55: openai~=1.55.0 - openai-v1.55: tiktoken - openai-latest: openai - openai-latest: tiktoken~=0.6.0 - openai-notiktoken: openai - - # OpenFeature - openfeature-v0.7: openfeature-sdk~=0.7.1 - openfeature-latest: openfeature-sdk - - # LaunchDarkly - launchdarkly-v9.8.0: launchdarkly-server-sdk~=9.8.0 - launchdarkly-latest: launchdarkly-server-sdk - - # Unleash - unleash-v6.0.1: UnleashClient~=6.0.1 - unleash-latest: UnleashClient - - # OpenTelemetry (OTel) - opentelemetry: opentelemetry-distro - - # OpenTelemetry Experimental (POTel) - potel: -e .[opentelemetry-experimental] + litestar-v2.0.1: httpx<0.28 + litestar-v2.5.5: httpx<0.28 - # pure_eval - pure_eval: pure_eval + pyramid-v1.10.8: pyramid==1.10.8 + pyramid-v2.0.2: pyramid==2.0.2 + pyramid: werkzeug<2.1.0 - # PyMongo (MongoDB) - pymongo: mockupdb - pymongo-v3.1: pymongo~=3.1.0 - pymongo-v3.13: pymongo~=3.13.0 - pymongo-v4.0: pymongo~=4.0.0 - pymongo-v4.3: pymongo~=4.3.0 - pymongo-v4.7: pymongo~=4.7.0 - pymongo-latest: pymongo - - # Pyramid - pyramid: Werkzeug<2.1.0 - pyramid-v1.6: pyramid~=1.6.0 - pyramid-v1.10: pyramid~=1.10.0 - pyramid-v2.0: pyramid~=2.0.0 - pyramid-latest: pyramid - - # Quart + quart-v0.11.5: quart==0.11.5 + quart-v0.14.1: quart==0.14.1 + quart-v0.17.0: quart==0.17.0 + quart-v0.20.0: quart==0.20.0 quart: quart-auth quart: pytest-asyncio - quart-v0.16: blinker<1.6 - quart-v0.16: jinja2<3.1.0 - quart-v0.16: Werkzeug<2.1.0 - quart-v0.16: hypercorn<0.15.0 - quart-v0.16: quart~=0.16.0 - quart-v0.19: Werkzeug>=3.0.0 - quart-v0.19: quart~=0.19.0 - {py3.8}-quart: taskgroup==0.0.0a4 - quart-latest: quart - - # Ray - ray-v2.34: ray~=2.34.0 - ray-latest: ray - - # Redis - redis: fakeredis!=1.7.4 - redis: pytest<8.0.0 - {py3.6,py3.7}-redis: fakeredis!=2.26.0 # https://github.com/cunla/fakeredis-py/issues/341 - {py3.7,py3.8,py3.9,py3.10,py3.11,py3.12,py3.13}-redis: pytest-asyncio - redis-v3: redis~=3.0 - redis-v4: redis~=4.0 - redis-v5: redis~=5.0 - redis-latest: redis - - # Redis Cluster - redis_py_cluster_legacy-v1: redis-py-cluster~=1.0 - redis_py_cluster_legacy-v2: redis-py-cluster~=2.0 - - # Requests - requests: requests>=2.0 - - # RQ (Redis Queue) - # https://github.com/jamesls/fakeredis/issues/245 - rq-v{0.6}: fakeredis<1.0 - rq-v{0.6}: redis<3.2.2 - rq-v{0.13,1.0,1.5,1.10}: fakeredis>=1.0,<1.7.4 - rq-v{1.15,1.16}: fakeredis - {py3.6,py3.7}-rq-v{1.15,1.16}: fakeredis!=2.26.0 # https://github.com/cunla/fakeredis-py/issues/341 - rq-latest: fakeredis - {py3.6,py3.7}-rq-latest: fakeredis!=2.26.0 # https://github.com/cunla/fakeredis-py/issues/341 - rq-v0.6: rq~=0.6.0 - rq-v0.13: rq~=0.13.0 - rq-v1.0: rq~=1.0.0 - rq-v1.5: rq~=1.5.0 - rq-v1.10: rq~=1.10.0 - rq-v1.15: rq~=1.15.0 - rq-v1.16: rq~=1.16.0 - rq-latest: rq - - # Sanic + quart: werkzeug + quart-v0.11.5: blinker<1.6 + quart-v0.11.5: jinja2<3.1.0 + quart-v0.11.5: Werkzeug<2.1.0 + quart-v0.11.5: hypercorn<0.15.0 + quart-v0.14.1: blinker<1.6 + quart-v0.14.1: jinja2<3.1.0 + quart-v0.14.1: Werkzeug<2.1.0 + quart-v0.14.1: hypercorn<0.15.0 + py3.8-quart: taskgroup==0.0.0a4 + + sanic-v19.12.5: sanic==19.12.5 + sanic-v21.6.2: sanic==21.6.2 + sanic-v22.12.0: sanic==22.12.0 + sanic-v24.12.0: sanic==24.12.0 sanic: websockets<11.0 sanic: aiohttp - sanic-v{24.6}: sanic_testing - sanic-latest: sanic_testing - {py3.6}-sanic: aiocontextvars==0.2.1 - sanic-v0.8: sanic~=0.8.0 - sanic-v20: sanic~=20.0 - sanic-v24.6: sanic~=24.6.0 - sanic-latest: sanic - - # Spark - spark-v3.1: pyspark~=3.1.0 - spark-v3.3: pyspark~=3.3.0 - spark-v3.5: pyspark~=3.5.0 - # TODO: update to ~=4.0.0 once stable is out - spark-v4.0: pyspark==4.0.0.dev2 - spark-latest: pyspark - - # Starlette - starlette: pytest-asyncio - starlette: python-multipart - starlette: requests - # (this is a dependency of httpx) - starlette: anyio<4.0.0 - starlette: jinja2 - starlette-v{0.19,0.24,0.28,0.32,0.36}: httpx<0.28.0 - starlette-v0.40: httpx - starlette-latest: httpx - starlette-v0.19: starlette~=0.19.0 - starlette-v0.24: starlette~=0.24.0 - starlette-v0.28: starlette~=0.28.0 - starlette-v0.32: starlette~=0.32.0 - starlette-v0.36: starlette~=0.36.0 - starlette-v0.40: starlette~=0.40.0 - starlette-latest: starlette - - # Starlite + sanic: sanic_testing + sanic: aiocontextvars + sanic-v22.12.0: sanic_testing + sanic-v24.12.0: sanic_testing + py3.6-sanic: aiocontextvars==0.2.1 + + starlite-v0.1.6: starlite==0.1.6 + starlite-v1.12.0: starlite==1.12.0 + starlite-v1.32.0: starlite==1.32.0 + starlite-v1.51.16: starlite==1.51.16 starlite: pytest-asyncio - starlite: python-multipart + starlite: pytest-multipart starlite: requests starlite: cryptography starlite: pydantic<2.0.0 starlite: httpx<0.28 - starlite-v{1.48}: starlite~=1.48.0 - starlite-v{1.51}: starlite~=1.51.0 - - # SQLAlchemy - sqlalchemy-v1.2: sqlalchemy~=1.2.0 - sqlalchemy-v1.4: sqlalchemy~=1.4.0 - sqlalchemy-v2.0: sqlalchemy~=2.0.0 - sqlalchemy-latest: sqlalchemy - # Strawberry - strawberry: fastapi - strawberry: flask - strawberry: httpx - strawberry-v0.209: strawberry-graphql[fastapi,flask]~=0.209.0 - strawberry-v0.222: strawberry-graphql[fastapi,flask]~=0.222.0 - strawberry-latest: strawberry-graphql[fastapi,flask] - - # Tornado - # Tornado <6.4.1 is incompatible with Pytest ≥8.2 - # See https://github.com/tornadoweb/tornado/pull/3382. - tornado-{v6.0,v6.2}: pytest<8.2 - tornado-v6.0: tornado~=6.0.0 - tornado-v6.2: tornado~=6.2.0 - tornado-latest: tornado - - # Trytond + tornado-v6.0.4: tornado==6.0.4 + tornado-v6.1: tornado==6.1 + tornado-v6.2: tornado==6.2 + tornado-v6.4.2: tornado==6.4.2 + tornado: pytest + tornado-v6.0.4: pytest<8.2 + tornado-v6.1: pytest<8.2 + tornado-v6.2: pytest<8.2 + + # ~~~ Misc ~~~ + loguru-v0.4.1: loguru==0.4.1 + loguru-v0.5.3: loguru==0.5.3 + loguru-v0.6.0: loguru==0.6.0 + loguru-v0.7.3: loguru==0.7.3 + + pure_eval-v0.1.1: pure_eval==0.1.1 + pure_eval-v0.2.3: pure_eval==0.2.3 + + trytond-v5.0.63: trytond==5.0.63 + trytond-v5.8.16: trytond==5.8.16 + trytond-v6.6.9: trytond==6.6.9 + trytond-v7.4.3: trytond==7.4.3 trytond: werkzeug - trytond-v4: werkzeug<1.0 - trytond-v4: trytond~=4.0 - trytond-v5: trytond~=5.0 - trytond-v6: trytond~=6.0 - trytond-v7: trytond~=7.0 - trytond-latest: trytond - # Typer - typer-v0.15: typer~=0.15.0 - typer-latest: typer + typer-v0.0.9: typer==0.0.9 + typer-v0.4.2: typer==0.4.2 + typer-v0.9.4: typer==0.9.4 + typer-v0.15.1: typer==0.15.1 + + setenv = PYTHONDONTWRITEBYTECODE=1 @@ -801,7 +746,6 @@ setenv = tornado: TESTPATH=tests/integrations/tornado trytond: TESTPATH=tests/integrations/trytond typer: TESTPATH=tests/integrations/typer - unleash: TESTPATH=tests/integrations/unleash socket: TESTPATH=tests/integrations/socket passenv =