◐ Shell
clean mode source ↗

ci(tox): migrate from pip to uv via tox-uv by sentry-junior[bot] · Pull Request #6390 · getsentry/sentry-python

sentry-warden[bot]

Bot reviewed May 22, 2026

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

sentry-warden[bot]

@sl0thentr0py sl0thentr0py changed the title build(tox): migrate from pip to uv via tox-uv build(tox): migrate from pip to uv via tox-uv for CI

May 27, 2026

@sl0thentr0py sl0thentr0py changed the title build(tox): migrate from pip to uv via tox-uv for CI ci(tox): migrate from pip to uv via tox-uv

May 27, 2026
py3.7 celery in CI hangs in test_celery_beat_cron_monitoring::test_explanation.
kill_beat slept 1s then opened the pidfile; in the slower py3.7 container
startup, the file didn't exist yet, the thread died silently, and beat
ran forever (30-min job timeout).

Poll for the pidfile up to 30s before starting the kill timer, and dump
any future thread exception to stderr so the next failure surfaces a
traceback instead of silently hanging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The pidfile-race fix did not unhang py3.7 celery in CI. pytest-timeout
only dumps the parent pytest process's threads — the parent is stuck in
pytest-forked's waitpid, so the actual hang is somewhere inside the
forked child, invisible.

Schedule faulthandler.dump_traceback_later(45) in run_beat (which runs
inside the forked child) and cancel it on successful beat shutdown. If
beat hangs in CI again, the child's full thread dump lands in the log
and tells us where to look.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous attempt put faulthandler.dump_traceback_later inside run_beat,
but the py3.7 CI hang turns out to happen earlier — start_worker() never
returns, so run_beat is never reached and the dump is never armed.

Move the diagnostic into an autouse fixture in
tests/integrations/celery/integration_tests/conftest.py so it covers the
entire test body. Next CI hang should land a thread dump in the log
showing where start_worker is wedged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
So the py3.7-container kombu hang reveals its real exception instead of
sleeping forever inside retry_over_time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After moving py3.6/3.7 jobs into the python:X.Y container, the three beat
tests (test_explanation, test_beat_task_crons_success/error) hang in
celery's start_worker on py3.7 only — kombu's pre-connect via
default_channel never returns. This is a known kombu/redis-py + os.fork
interaction on the old pin (kombu 4.6 + redis-py <3.2) that celery 4.4.7
ships with; it worked previously only because the broker was on loopback,
not a bridged sibling container.

Bumping the existing < (3, 7) skip to < (3, 8). py3.7 is EOL and the same
tests run fine on 3.8+. Also dropping the diagnostic faulthandler
conftest and the kill_beat exception-printing wrapper now that the
root cause is understood; the pidfile-wait fix in kill_beat is kept since
it's a legitimate startup-race fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The workflow sets SENTRY_PYTHON_TEST_REDIS_HOST=redis for 3.6/3.7
container runs (since redis is a sibling service container, not on
loopback), but tox strips env vars not listed in passenv. The celery
beat tests therefore read the default 127.0.0.1, find nothing on
loopback inside the python container, and hang in kombu's
retry_over_time. Adding the var to passenv fixes it; un-skip the beat
tests on py3.7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
this will **finally** make pre-commit consistent with CI
:upside_down_face:
keeping this in a separate dependency group since we install lots of
random packages just for typing
## Description

* Invoke `find_raise_from_none` with uv
* Remove `linters` from `tox` completely
* Remove unused `ready_yet`
* Invoke `populate_tox` and `split_tox_gh_actions` with uv
* Move `apidocs` to uv
* Move from `make build` to `uv build` (verification of contents below)
* Move from `make aws-lambda-layer` to uv
* Remove `Makefile` completely
* Remove unused `dist-serverless` from github workflows

### Content verification of `make dist` -> `uv build`

```
⏺ Sdist contents identical too — the 9-byte difference is just tarball/gzip
  metadata (timestamps, header). Final summary:

  Artifact: Wheel filename
  make dist: sentry_sdk-2.61.0-py3-none-any.whl
  uv build: same
  Diff: ✓
  ────────────────────────────────────────
  Artifact: Wheel bytes
  make dist: 483,104
  uv build: 483,104
  Diff: ✓ identical
  ────────────────────────────────────────
  Artifact: Wheel contents
  make dist: —
  uv build: —
  Diff: ✓ identical (recursive diff clean)
  ────────────────────────────────────────
  Artifact: Sdist filename
  make dist: sentry_sdk-2.61.0.tar.gz
  uv build: same
  Diff: ✓
  ────────────────────────────────────────
  Artifact: Sdist file list
  make dist: —
  uv build: —
  Diff: ✓ identical
  ────────────────────────────────────────
  Artifact: Sdist contents
  make dist: —
  uv build: —
  Diff: ✓ identical (recursive diff clean)
  ────────────────────────────────────────
  Artifact: Sdist bytes
  make dist: 459,825
  uv build: 459,834
  Diff: tarball metadata only (9 bytes)
```

sentry[bot]