Skip to content

Commit

Permalink
refactor: Restructure the python code (#211)
Browse files Browse the repository at this point in the history
- Renames `pyrs` → `tket2`. Closes #207.

- Adds a poetry configuration and makes sure all commands can be run
from the root.

- Expands the justfile and other development docs.
  `poetry run just pytest` will take care of everything.
  
- Enables ruff checks (lints and format) on CI.

- Fixes rust binding imports requiring duplicated `import pyrs.pyrs`.
Closes #208.
This was caused by the python `__init__.py` overriding the one
[generated by
maturin](https://www.maturin.rs/project_layout.html#mixed-rustpython-project).
  • Loading branch information
aborgna-q authored Nov 3, 2023
1 parent dc03c31 commit 4fe9e38
Show file tree
Hide file tree
Showing 34 changed files with 181 additions and 102 deletions.
19 changes: 17 additions & 2 deletions .github/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ fi

if ! cargo fmt -- --check
then
echo "There are some code style issues."
echo "Run cargo fmt first."
echo "There are some rust code style issues."
echo "Run `cargo fmt` first."
exit 1
fi

# Run `ruff` python formatting if it is available
if command -v ruff &> /dev/null && ! ruff format --check .
then
echo "There are some python code style issues."
echo "Run `ruff format .` first."
exit 1
fi

Expand All @@ -28,4 +36,11 @@ then
exit 1
fi

# Run `ruff` python linting if it is available
if command -v ruff &> /dev/null && ! ruff check .
then
echo "There are some python linting issues."
exit 1
fi

exit 0
28 changes: 15 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,22 @@ jobs:
with:
components: rustfmt, clippy
- uses: mozilla-actions/[email protected]
- name: Check formatting
- name: Check rust formatting
run: cargo fmt -- --check
- name: Check python formatting
uses: chartboost/ruff-action@v1
with:
args: format --check
- name: Run clippy
run: cargo clippy --all-targets --all-features --workspace -- -D warnings
- name: Build docs
run: cargo doc --no-deps --all-features
env:
RUSTDOCFLAGS: "-Dwarnings"
- name: Python lints
uses: chartboost/ruff-action@v1
with:
args: check

benches:
# Not required, we can ignore it for the merge queue check.
Expand Down Expand Up @@ -101,14 +109,11 @@ jobs:
cache: 'pip'
- name: Build pyo3 bindings
run: |
pip install -r requirements.txt
cd pyrs
pip install -r dev-requirements.txt
maturin build
pip install ../target/wheels/*.whl
pip install target/wheels/*.whl
- name: Test pyo3 bindings
run: |
cd pyrs
pytest
run: pytest

coverage:
if: github.event_name != 'merge_group'
Expand Down Expand Up @@ -149,15 +154,12 @@ jobs:
cache: 'pip'
- name: Build pyo3 bindings
run: |
pip install -r requirements.txt
pip install -r dev-requirements.txt
pip install pytest-cov
cd pyrs
maturin build
pip install ../target/wheels/*.whl
pip install target/wheels/*.whl
- name: Run python tests with coverage instrumentation
run: |
cd pyrs
pytest --cov=./ --cov-report=xml
run: pytest --cov=./ --cov-report=xml
- name: Upload python coverage to codecov.io
uses: codecov/codecov-action@v3
with:
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Build artifacts
/target
tket2-py/target/

# Lock files
Cargo.lock
pyrs/target/
poetry.lock

# Python caches
__pycache__
.ipynb_checkpoints

# Devenv
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ lto = "thin"

[workspace]
resolver = "2"
members = ["tket2", "pyrs", "compile-rewriter", "taso-optimiser"]
members = ["tket2", "tket2-py", "compile-rewriter", "taso-optimiser"]
default-members = ["tket2"]

[workspace.package]
Expand Down
44 changes: 18 additions & 26 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,24 @@ devenv shell
All the required dependencies should be available. You can automate loading the
shell by setting up [direnv](https://devenv.sh/automatic-shell-activation/).

### Manual setup
### Poetry setup

To setup the environment manually you will need:

- Rust: https://www.rust-lang.org/tools/install
- Rust 1.70+: https://www.rust-lang.org/tools/install

- Python 3.10+: https://www.python.org/downloads/
- Poetry: https://python-poetry.org/

It is advisable to use a virtual environment for keeping the python
environment isolated, see
[`venv`](https://docs.python.org/3/tutorial/venv.html) for more details.

Install the python development dependencies with:

```bash
pip install -r pyrs/dev-requirements.txt
```


You can use the git hook in [`.github/pre-commit`](.github/pre-commit) to automatically run the test and check formatting before committing.
To install it, run:

```bash
ln -s .github/pre-commit .git/hooks/pre-commit
# Or, to check before pushing instead
ln -s .github/pre-commit .git/hooks/pre-push
```
Simply run `poetry shell` to activate an environment with all the required dependencies.

## 🏃 Running the tests

To compile and test the rust code, run:
The repository root contains a Justfile with the most common development tasks.
Run `just` to see a list.

To manually compile and test the rust code, run:

```bash
cargo build
cargo test
```

Expand All @@ -78,11 +62,19 @@ cargo +nightly miri test
To run the python tests, run:

```bash
cd pyrs
maturin develop
pytest
```

You can use the script in [`.github/pre-commit`](.github/pre-commit) to run the test and formatting required by our CI.
To automatically check that before each commit, install it as a hook with:

```bash
ln -s .github/pre-commit .git/hooks/pre-commit
# Or, to check before pushing instead
ln -s .github/pre-commit .git/hooks/pre-push
```

## 💅 Coding Style

The rustfmt tool is used to enforce a consistent rust coding style. The CI will fail if the code is not formatted correctly. Python code is formatted with black.
Expand All @@ -93,7 +85,7 @@ To format your code, run:
# Format rust code
cargo fmt
# Format python code
black .
ruff format .
```

We also check for clippy warnings, which are a set of linting rules for rust. To run clippy, run:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Version 2 of the TKET compiler.
## Features

- `pyo3`
This optional feature enables some python bindings via pyo3. See the `pyrs` folder for more.
This optional feature enables some python bindings via pyo3. See the `tket2-py` folder for more.

- `portmatching`
This enables pattern matching using the `portmatching` crate.
Expand Down
5 changes: 3 additions & 2 deletions pyrs/dev-requirements.txt → dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Use common dependencies
# Runtime requirements
-r requirements.txt

# Development requirements
maturin # Build wheels
black # Code formatting
pytest # Unit testing
ruff # Code formatting
pytket # TKET1
jupyterlab # For running the examples
graphviz # Visualisation of Hugrs in the notebooks
2 changes: 1 addition & 1 deletion devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
enable = true;

venv.enable = true;
venv.requirements = "-r ${config.env.DEVENV_ROOT}/pyrs/dev-requirements.txt";
venv.requirements = "-r ${config.env.DEVENV_ROOT}/tket2-py/dev-requirements.txt";
};

# https://devenv.sh/pre-commit-hooks/
Expand Down
1 change: 0 additions & 1 deletion ext/symengine.rs
Submodule symengine.rs deleted from 05ae9c
32 changes: 28 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
# List the available commands
help:
@just --list --justfile {{justfile()}}

# Run all the rust tests
test:
cargo test
cargo test --all-features

# Auto-fix all clippy warnings
fix:
cargo clippy --fix --allow-staged
cargo clippy --all-targets --all-features --workspace --fix --allow-staged

# Build the python package wheels
pybuild:
maturin build --release

# Build the python package for local development
pydevelop:
maturin develop

# Run the python tests
pytest: pydevelop
pytest

# Run the pre-commit checks
check:
./.github/pre-commit

ptest:
(cd pyrs && maturin develop && pytest)
# Format the code
format:
cargo fmt
ruff format .
46 changes: 46 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[tool.poetry]
name = "tket2-py"
version = "0.1.0"
description = "pytket extension for the tket 2 compiler"
classifiers = [] # TODO
authors = [] # TODO
maintainers = [] # TODO
include = ["pyproject.toml"]
license = "Apache-2.0"
readme = "README.md"

packages = [{ include = "tket2-py" }]

[tool.poetry.dependencies]
python = ">=3.10"

[tool.poetry.dev-dependencies]
maturin = "^1.3.0"
pytket = "*"
pytest = "^7.1.2"
ruff = "^0.1.3"

[build-system]
requires = ["maturin~=1.3"]
build-backend = "maturin"

[project]
name = "tket2"
version = "0.1.0"
description = "pytket extension for the tket 2 compiler"
authors = [] # TODO
classifiers = [] # TODO
requires-python = ">=3.10"
license = "Apache-2.0"

[project.urls]
homepage = "https://github.com/CQCL/tket2"
repository = "https://github.com/CQCL/tket2"

[tool.maturin]
manifest-path = "tket2-py/Cargo.toml"
python-source = "tket2-py"

[tool.pytest.ini_options]
# Lark throws deprecation warnings for `src_parse` and `src_constants`.
filterwarnings = "ignore::DeprecationWarning:lark.*"
13 changes: 0 additions & 13 deletions pyrs/pyproject.toml

This file was deleted.

Empty file removed pyrs/pyrs/__init__.py
Empty file.
1 change: 0 additions & 1 deletion pyrs/requirements.txt

This file was deleted.

File renamed without changes.
File renamed without changes.
13 changes: 9 additions & 4 deletions pyrs/Cargo.toml → tket2-py/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
[package]
name = "pyrs"
version = "0.1.0"
edition = "2018"
name = "tket2-py"
edition = { workspace = true }
version = { workspace = true }
rust-version = { workspace = true }
homepage = { workspace = true }
license-file = { workspace = true }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "pyrs"
name = "tket2"
crate-type = ["cdylib"]

[dependencies]
Expand All @@ -17,3 +20,5 @@ quantinuum-hugr = { workspace = true }
portgraph = { workspace = true, features = ["pyo3", "serde"] }
pyo3 = { workspace = true, features = ["extension-module"] }
num_cpus = "1.16.0"
derive_more = "0.99.17"
itertools = { workspace = true }
4 changes: 2 additions & 2 deletions pyrs/README.md → tket2-py/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## pyrs
## tket2-py

This package uses [pyo3](https://pyo3.rs/v0.16.4/) and
[maturin](https://github.com/PyO3/maturin) to bind TKET2 functionality to
python as the `pyrs` package.
python as the `tket2` package.

Recommended:

Expand Down
File renamed without changes.
10 changes: 5 additions & 5 deletions pyrs/src/lib.rs → tket2-py/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ use pass::add_pass_module;

use hugr::Hugr;
use pyo3::prelude::*;
use tket2::{
portmatching::{pyo3::PyPatternMatch, CircuitPattern, PatternMatcher},
rewrite::CircuitRewrite,
};
use tket2::portmatching::pyo3::PyPatternMatch;
use tket2::portmatching::{CircuitPattern, PatternMatcher};
use tket2::rewrite::CircuitRewrite;

#[derive(Clone)]
#[pyclass]
Expand Down Expand Up @@ -66,7 +65,8 @@ impl RuleMatcher {

/// The Python bindings to TKET2.
#[pymodule]
fn pyrs(py: Python, m: &PyModule) -> PyResult<()> {
#[pyo3(name = "tket2")]
fn tket2_py(py: Python, m: &PyModule) -> PyResult<()> {
add_circuit_module(py, m)?;
add_pattern_module(py, m)?;
add_pass_module(py, m)?;
Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 4fe9e38

Please sign in to comment.