Skip to content

Commit

Permalink
chore: Replace poetry with uv (#557)
Browse files Browse the repository at this point in the history
Replaces the python project manager with `uv`.
For most commands that used poetry before, it just be as easy as
replacing `poetry {things}` with `uv {things}`.

Some notable exeptions:

- Instead of `poetry install --with extra1,extra2`,
  use `uv sync --extra extra1 --extra extra2`.
Note that will delete any extraneous packages/extras so the venv state
is deterministic.
  Add `--inexact` if you want to replicate the old poetry behaviour.

- `poetry shell` is no longer available. The preferred workflow is to
`uv run` / `uvx` things, to ensure you are always in sync with the
project definition.
If that's too annoying, it is always possible to `source
.venv/bin/activate`.

Updates the justfile, so using that should be the same as before.

---------

Co-authored-by: Seyon Sivarajah <seyon.sivarajah@quantinuum.com>
  • Loading branch information
aborgna-q and ss2165 authored Aug 27, 2024
1 parent 5038474 commit 685b4f7
Show file tree
Hide file tree
Showing 17 changed files with 1,234 additions and 1,381 deletions.
2 changes: 1 addition & 1 deletion .github/change-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ python:
- "tket2-py/**"
- "tket2-eccs/**"
- "pyproject.toml"
- "poetry.lock"
- "uv.lock"
8 changes: 8 additions & 0 deletions .github/script/install-uv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

# Installs a fixed UV version
#
# This reads the `UV_CACHE_DIR` environment variable if it is set,
# and stores the downloaded dependencies in that directory.

curl -LsSf https://astral.sh/uv/0.3.4/install.sh | sh
58 changes: 36 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ env:
CI: true # insta snapshots behave differently on ci
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
UV_CACHE_DIR: /tmp/.uv-cache

jobs:
# Check if changes were made to the relevant files.
Expand Down Expand Up @@ -82,23 +83,29 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: mozilla-actions/sccache-action@v0.0.5
- name: Install poetry
run: pipx install poetry
- name: Set up Python
- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: "poetry"
- name: Install the project libraries
# Note: We do not need to compile with maturin here,
# as we are only checking the Python code.
run: poetry install
python-version: '3.12'
- name: Restore uv cache
uses: actions/cache@v4
with:
path: ${{ env.UV_CACHE_DIR }}
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}
- name: Setup dependencies
run: uv sync --locked
- name: Type check with mypy
run: poetry run mypy .
run: uv run mypy .
- name: Check formatting with ruff
run: poetry run ruff format --check
run: uv run ruff format --check
- name: Lint with ruff
run: poetry run ruff check
run: uv run ruff check
- name: Minimize uv cache
run: uv cache prune --ci

benches:
name: Build benchmarks 🏋️
Expand Down Expand Up @@ -226,23 +233,30 @@ jobs:
- uses: mozilla-actions/sccache-action@v0.0.5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install poetry
run: pipx install poetry
- uses: actions/setup-python@v5
- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'poetry'
- name: Build pyo3 bindings
run: |
poetry install
poetry run maturin develop
python-version: '3.10'
- name: Restore uv cache
uses: actions/cache@v4
with:
path: ${{ env.UV_CACHE_DIR }}
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}
- name: Setup dependencies
run: uv sync --locked
- name: Run python tests with coverage instrumentation
run: poetry run pytest --cov=./ --cov-report=xml
run: uv run pytest --cov=./ --cov-report=xml
- name: Upload coverage output artifact
uses: actions/upload-artifact@v4
with:
name: py-coverage
path: coverage.xml
- name: Minimize uv cache
run: uv cache prune --ci

coverage-py:
name: Upload Python coverage 🐍
Expand Down
43 changes: 29 additions & 14 deletions .github/workflows/python-pure-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
strategy:
matrix:
target:
- { name: tket2-eccs, key_secret: PYPI_PUBLISH_TKET2_ECCS }
- { dir: tket2-eccs, name: tket2_eccs, key_secret: PYPI_PUBLISH_TKET2_ECCS }
steps:
# Check the release tag against the package name
#
Expand All @@ -35,41 +35,56 @@ jobs:
run: |
echo "run=$SHOULD_RUN" >> $GITHUB_OUTPUT
env:
SHOULD_RUN: ${{ github.event_name != 'release' || ( github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.name)) ) }}
SHOULD_RUN: ${{ github.event_name != 'release' || ( github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.dir)) ) }}

- uses: actions/checkout@v4
if: ${{ steps.check-tag.outputs.run == 'true' }}
- name: Run sccache-cache
if: ${{ steps.check-tag.outputs.run == 'true' }}
uses: mozilla-actions/sccache-action@v0.0.5
- name: Install poetry


- name: Set up uv
if: ${{ steps.check-tag.outputs.run == 'true' }}
run: pipx install poetry
- name: Set up Python '3.10'
run: .github/script/install-uv.sh
- name: Set up Python
if: ${{ steps.check-tag.outputs.run == 'true' }}
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: "poetry"
python-version: '3.12'

- name: Build sdist and wheels
if: ${{ steps.check-tag.outputs.run == 'true' }}
run: |
cd ${{ matrix.target.name }}
poetry build -o ../dist
cd ${{ matrix.target.dir }}
uvx --from build pyproject-build --installer uv --outdir ../dist
- name: Upload the built packages as artifacts
if: ${{ steps.check-tag.outputs.run == 'true' }}
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.target.name }}-sdist
name: build-${{ matrix.target.dir }}-sdist
path: |
dist/*.tar.gz
dist/*.whl
- name: Test installing the built wheels
if: ${{ steps.check-tag.outputs.run == 'true' }}
run: |
echo "Testing the newly built ${{ matrix.target.name }} wheels..."
uv run -f dist --with ${{ matrix.target.name }} --refresh-package ${{ matrix.target.name }} --no-project -- python -c "import ${{ matrix.target.name }}"
uvx twine check --strict dist/*
- name: Publish to PyPI
if: ${{ (github.event_name == 'release' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.name)) ) || (github.event_name == 'workflow_dispatch' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.name)) ) }}
if: ${{ (github.event_name == 'release' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.dir)) ) || (github.event_name == 'workflow_dispatch' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.target.dir)) ) }}
run: |
cd ${{ matrix.target.name }}
poetry config pypi-token.pypi ${{ secrets[matrix.target.key_secret] }}
poetry publish --dist-dir ../dist --skip-existing
echo "Publishing to PyPI..."
echo "Based on the following workflow variables, this is a new version tag push:"
echo " - event_name: ${{ github.event_name }}"
echo " - ref_type: ${{ github.ref_type }}"
echo " - ref: ${{ github.ref }}"
uvx twine upload --skip-existing --verbose dist/*
env:
TWINE_NON_INTERACTIVE: 1
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets[matrix.target.key_secret] }}
25 changes: 9 additions & 16 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,74 +34,67 @@ repos:

- repo: local
hooks:
- id: poetry-install
name: sync poetry deps
description: Ensure development tools are installed.
entry: poetry install --sync
language: system
files: poetry.lock
pass_filenames: false
- id: ruff-format
name: ruff format
description: Format python code with `ruff`.
entry: poetry run ruff format
entry: uv run ruff format
language: system
files: \.py$
pass_filenames: false
- id: ruff-check
name: ruff
description: Check python code with `ruff`.
entry: poetry run ruff check --fix --exit-non-zero-on-fix
entry: uv run ruff check --fix --exit-non-zero-on-fix
language: system
files: \.py$
pass_filenames: false
- id: mypy-check
name: mypy
description: Check python code with `mypy`.
entry: poetry run mypy .
entry: uv run mypy .
language: system
files: \.py$
pass_filenames: false
- id: cargo-fmt
name: cargo format
description: Format rust code with `cargo fmt`.
entry: poetry run -- cargo fmt --all -- --check
entry: uv run -- cargo fmt --all -- --check
language: system
files: \.rs$
pass_filenames: false
- id: cargo-check
name: cargo check
description: Check rust code with `cargo check`.
entry: poetry run -- cargo check --all --all-features --workspace
entry: uv run -- cargo check --all --all-features --workspace
language: system
files: \.rs$
pass_filenames: false
- id: cargo-test
name: cargo test
description: Run tests with `cargo test`.
entry: poetry run -- cargo test --all-features --workspace
entry: uv run -- cargo test --all-features --workspace
language: system
files: \.rs$
pass_filenames: false
- id: cargo-clippy
name: cargo clippy
description: Run clippy lints with `cargo clippy`.
entry: poetry run -- cargo clippy --all-features --all-targets --workspace -- -D warnings
entry: uv run -- cargo clippy --all-features --all-targets --workspace -- -D warnings
language: system
files: \.rs$
pass_filenames: false
- id: cargo-doc
name: cargo doc
description: Generate documentation with `cargo doc`.
entry: poetry run -- cargo doc --no-deps --all-features --workspace
entry: uv run -- cargo doc --no-deps --all-features --workspace
language: system
files: \.rs$
pass_filenames: false
- id: py-test
name: pytest
description: Run python tests
# Ensure that we are using the local version of `tket2-eccs` and not the one from PyPI
entry: poetry run -- sh -c "poetry install -C tket2-eccs && maturin develop && pytest --cov=./ --cov-report=html"
entry: uv run -- sh -c "maturin develop && pytest --cov=./ --cov-report=html"
language: system
files: \.py$
pass_filenames: false
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ To setup the environment manually you will need:

- Just: https://just.systems/
- Rust `>=1.75`: https://www.rust-lang.org/tools/install
- Poetry `>=1.8`: https://python-poetry.org/
- uv `>=0.3`: docs.astral.sh/uv/getting-started/installation

Once you have these installed, install the required python dependencies and setup pre-commit hooks with:

Expand Down
Loading

0 comments on commit 685b4f7

Please sign in to comment.