Skip to content

Commit

Permalink
chore: Replace poetry with uv (#1465)
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 069abd7 commit 0dc2c9c
Show file tree
Hide file tree
Showing 18 changed files with 1,316 additions and 917 deletions.
2 changes: 1 addition & 1 deletion .github/change-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ python:
- *rust
- "hugr-py/**"
- "pyproject.toml"
- "poetry.lock"
- "uv.lock"
- "specification/schema/**"
- ".github/workflows/ci-py.yml"
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
144 changes: 77 additions & 67 deletions .github/workflows/ci-py.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env:
SCCACHE_GHA_ENABLED: "true"
HUGR_BIN_DIR: ${{ github.workspace }}/target/debug
HUGR_BIN: ${{ github.workspace }}/target/debug/hugr
UV_CACHE_DIR: /tmp/.uv-cache

jobs:
# Check if changes were made to the relevant files.
Expand Down Expand Up @@ -50,25 +51,34 @@ jobs:
- uses: actions/checkout@v4
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.5
- name: Install poetry
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}

- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"

- name: Install the project libraries
run: poetry install
- 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. Fail if the lockfile is outdated.
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

build_binary:
needs: changes
Expand All @@ -95,34 +105,63 @@ jobs:
test:
needs: [changes, build_binary]
if: ${{ needs.changes.outputs.python == 'true' }}
name: test python ${{ matrix.python-version }}
name: test python ${{ matrix.python-version.py }}
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ['3.10', '3.12']
python-version:
- { py: '3.10', coverage: false }
- { py: '3.12', coverage: true }
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}

- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
python-version: ${{ matrix.python-version.py }}
- 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: Install the project libraries
run: poetry install
- name: Download the hugr binary
uses: actions/download-artifact@v4
with:
name: hugr_binary
path: ${{env.HUGR_BIN_DIR}}

- name: Setup dependencies
run: uv sync

- name: Run tests
if: github.event_name == 'merge_group' || !matrix.python-version.coverage
run: |
chmod +x $HUGR_BIN
poetry run pytest
uv run pytest
- name: Run python tests with coverage instrumentation
if: github.event_name != 'merge_group' && matrix.python-version.coverage
run: |
chmod +x $HUGR_BIN
uv run pytest --cov=./ --cov-report=xml
- name: Upload python coverage to codecov.io
if: github.event_name != 'merge_group' && matrix.python-version.coverage
uses: codecov/codecov-action@v4
with:
files: coverage.xml
name: python
flags: python
token: ${{ secrets.CODECOV_TOKEN }}

- name: Minimize uv cache
run: uv cache prune --ci

# Ensure that the serialization schema is up to date
serialization-schema:
Expand All @@ -134,18 +173,28 @@ jobs:
- uses: actions/checkout@v4
- name: Run sccache-cache
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.10"
cache: "poetry"
- name: Install the project libraries
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

- name: Generate the updated schema
run: |
poetry run python scripts/generate_schema.py specification/schema/
uv run scripts/generate_schema.py specification/schema/
- name: Check if the schema is up to date
run: |
git diff --exit-code --name-only specification/schema/
Expand Down Expand Up @@ -181,42 +230,3 @@ jobs:
- name: Pass if required checks passed
run: |
echo "All required checks passed"
coverage:
needs: [changes, test]
# Run only if there are changes in the relevant files and the check job passed or was skipped
if: always() && !failure() && !cancelled() && needs.changes.outputs.python == 'true' && github.event_name != 'merge_group'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.5
- name: Install poetry
run: pipx install poetry
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: "poetry"

- name: Install the project libraries
run: poetry install
- name: Download the hugr binary
uses: actions/download-artifact@v4
with:
name: hugr_binary
path: ${{env.HUGR_BIN_DIR}}


- name: Run python tests with coverage instrumentation
run: |
chmod +x $HUGR_BIN
poetry run pytest --cov=./ --cov-report=xml
- name: Upload python coverage to codecov.io
uses: codecov/codecov-action@v4
with:
files: coverage.xml
name: python
flags: python
token: ${{ secrets.CODECOV_TOKEN }}
26 changes: 18 additions & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ concurrency:
group: "pages"
cancel-in-progress: true

env:
UV_CACHE_DIR: /tmp/.uv-cache

jobs:
build:
name: Build docs.
Expand All @@ -33,19 +36,26 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
- name: Install poetry
run: pipx install poetry
- name: Set up Python '3.10'

- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: "poetry"
- name: Install HUGR
run: poetry install --with docs
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: Build docs
run: |
cd docs
poetry run ./build.sh
uv run ./build.sh
- name: Upload artifact.
uses: actions/upload-pages-artifact@v3
with:
Expand Down
48 changes: 24 additions & 24 deletions .github/workflows/python-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,49 +25,49 @@ jobs:
strategy:
matrix:
package:
- 'hugr-py'
- { dir: 'hugr-py', name: 'hugr' }

steps:
- uses: actions/checkout@v4
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.5
- name: Install poetry
run: pipx install poetry
- name: Set up Python '3.10'

- name: Set up uv
run: .github/script/install-uv.sh
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: "poetry"
python-version: '3.12'

- name: Build sdist and wheels
run: |
cd ${{ matrix.package }}
poetry build -o ../dist
cd ${{ matrix.package.dir }}
uvx --from build pyproject-build --installer uv --outdir ../dist
- name: Upload the built packages as artifacts
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.package }}-sdist
name: build-${{ matrix.package.name }}-sdist
path: |
dist/*.tar.gz
dist/*.whl
- name: Publish to test instance of PyPI (dry-run)
if: ${{ (github.event_name == 'push' && github.ref_type == 'branch') || (github.event_name == 'workflow_dispatch' && github.ref_type == 'branch' ) }}
- name: Test installing the built wheels
run: |
echo "Doing a dry-run publish to test-pypi..."
echo "Based on the following workflow variables, this is not a hugr-py version tag push:"
echo " - event_name: ${{ github.event_name }}"
echo " - ref_type: ${{ github.ref_type }}"
echo " - ref: ${{ github.ref }}"
cd ${{ matrix.package }}
poetry config repositories.test-pypi https://test.pypi.org/legacy/
poetry config pypi-token.test-pypi ${{ secrets.PYPI_TEST_PUBLISH }}
poetry publish -r test-pypi --dist-dir ../dist --skip-existing --dry-run
echo "Testing the newly built ${{ matrix.package.name }} wheels..."
uv run -f dist --with ${{ matrix.package.name }} --refresh-package ${{ matrix.package.name }} --no-project -- python -c "import ${{ matrix.package.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.package)) ) || (github.event_name == 'workflow_dispatch' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.package)) ) }}
if: ${{ (github.event_name == 'release' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.package.dir))) || (github.event_name == 'workflow_dispatch' && github.ref_type == 'tag' && startsWith(github.ref, format('refs/tags/{0}-v', matrix.package.dir))) }}
run: |
cd ${{ matrix.package }}
poetry config pypi-token.pypi ${{ secrets.PYPI_PUBLISH }}
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.PYPI_PUBLISH }}
15 changes: 4 additions & 11 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,24 @@ 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
Expand Down Expand Up @@ -105,7 +98,7 @@ repos:
# We need to rebuild `hugr-cli` without the `extension_inference` feature
# to avoid test errors.
# TODO: Remove this once the issue is fixed.
entry: sh -c "cargo build -p hugr-cli && poetry run pytest"
entry: sh -c "cargo build -p hugr-cli && uv run pytest"
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, you can install the required python dependencies and setup pre-commit hooks with:

Expand Down
Loading

0 comments on commit 0dc2c9c

Please sign in to comment.