From 25cbb85a0fc4572b47390ea980b9997e397fcc25 Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Mon, 19 Jan 2026 13:37:48 +0000 Subject: [PATCH 1/6] chore: move to justfile for test hugr generation --- devenv.nix | 8 ++----- integration/conftest.py | 2 +- integration/test_qsys_jobs.py | 42 +++++----------------------------- justfile | 17 ++++++++++++++ tests/data/example.hugr | Bin 9679 -> 0 bytes tests/data/example_hugr.hugr | Bin 0 -> 7283 bytes tests/data/example_hugr.py | 38 ++++++++++++++++++++++++++++++ tests/data/justfile | 14 ++++++++++++ 8 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 justfile delete mode 100644 tests/data/example.hugr create mode 100644 tests/data/example_hugr.hugr create mode 100644 tests/data/example_hugr.py create mode 100644 tests/data/justfile diff --git a/devenv.nix b/devenv.nix index e0dea5c9..10294c49 100644 --- a/devenv.nix +++ b/devenv.nix @@ -9,18 +9,14 @@ in pkgs-unstable.uv pkgs.commitizen pkgs.git + pkgs.just ]; dotenv.enable = true; # https://devenv.sh/scripts/ scripts.qfmt.exec = '' - echo -e "Running formatting, linting and typechecking ๐Ÿงน ๐Ÿ”ง \n" - - uv run ruff check --select I --fix - uv run ruff check - uv run ruff format - uv run mypy qnexus/ tests/ integration/ + just qfmt ''; scripts.qtest.exec = '' echo -e "Running unit tests ๐Ÿ“๐Ÿ”\n" diff --git a/integration/conftest.py b/integration/conftest.py index 1c095916..e1d44da0 100644 --- a/integration/conftest.py +++ b/integration/conftest.py @@ -463,7 +463,7 @@ def test_ref_serialisation( @pytest.fixture(name="qa_hugr_package") def qa_hugr_package_fixture() -> Package: - hugr_path = Path("tests/data/example.hugr").resolve() + hugr_path = Path("tests/data/example_hugr.hugr").resolve() return Package.from_bytes(hugr_path.read_bytes()) diff --git a/integration/test_qsys_jobs.py b/integration/test_qsys_jobs.py index 4ca941da..77778005 100644 --- a/integration/test_qsys_jobs.py +++ b/integration/test_qsys_jobs.py @@ -1,11 +1,9 @@ """Tests related to running jobs against QSys devices.""" -from typing import Any, Callable, ContextManager, cast +from typing import Callable, ContextManager, cast import pytest -from guppylang import guppy -from guppylang.std.builtins import result -from guppylang.std.quantum import cx, h, measure, qubit, x, z +from hugr.package import Package from hugr.qsystem.result import QsysResult from pytket.backends.backendinfo import BackendInfo from quantinuum_schemas.models.backend_config import ( @@ -24,36 +22,6 @@ ) -def prepare_teleportation() -> Any: - """Prepares the teleportation circuit.""" - - @guppy - def bell() -> tuple[qubit, qubit]: - """Constructs a bell state.""" - q1, q2 = qubit(), qubit() - h(q1) - cx(q1, q2) - return q1, q2 - - @guppy - def main() -> None: - src = qubit() - x(src) - alice, bob = bell() - - cx(src, alice) - h(src) - if measure(alice): - x(bob) - if measure(src): - z(bob) - - result("teleported", measure(bob)) - - main.check() - return main.compile() - - @pytest.mark.parametrize( "backend_config", [ @@ -70,6 +38,7 @@ def test_guppy_execution( test_case_name: str, create_project: Callable[[str], ContextManager[ProjectRef]], backend_config: BackendConfig, + qa_hugr_package: Package, ) -> None: """Test the execution of a guppy program on a next-generation QSys device.""" @@ -78,7 +47,7 @@ def test_guppy_execution( n_shots = 10 hugr_ref = qnx.hugr.upload( - hugr_package=prepare_teleportation(), + hugr_package=qa_hugr_package, name=f"hugr for {test_case_name}", project=project_ref, ) @@ -127,12 +96,13 @@ def test_guppy_execution( def test_hugr_costing( test_case_name: str, create_project: Callable[[str], ContextManager[ProjectRef]], + qa_hugr_package: Package, ) -> None: """Test the costing of a Hugr program on a cost checking device.""" with create_project(f"project for {test_case_name}") as project_ref: hugr_ref = qnx.hugr.upload( - hugr_package=prepare_teleportation(), + hugr_package=qa_hugr_package, name=f"hugr for {test_case_name}", project=project_ref, ) diff --git a/justfile b/justfile new file mode 100644 index 00000000..94f6c92a --- /dev/null +++ b/justfile @@ -0,0 +1,17 @@ +# List the available commands +help: + @just --list --justfile {{justfile()}} + +# Run basic formatting, linting and typechecking +qfmt: + echo -e "Running formatting, linting and typechecking ๐Ÿงน ๐Ÿ”ง \n" + + uv run ruff check --select I --fix + uv run ruff check + uv run ruff format + uv run mypy qnexus/ tests/ integration/ + +# Re-compile test hugr files. +recompile-test-files: + @echo "---- Recompiling example guppy programs ----" + just tests/data/recompile \ No newline at end of file diff --git a/tests/data/example.hugr b/tests/data/example.hugr deleted file mode 100644 index a1a6f80b867dfc588947846b2920c90fb26195e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9679 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 tuple[qubit, qubit]: + """Constructs a bell state.""" + q1, q2 = qubit(), qubit() + h(q1) + cx(q1, q2) + return q1, q2 + + +@guppy +def main() -> None: + src = qubit() + x(src) + alice, bob = bell() + + cx(src, alice) + h(src) + if measure(alice): + x(bob) + if measure(src): + z(bob) + + result("teleported", measure(bob)) + + +main.check() +program = main.compile_function() +Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/tests/data/justfile b/tests/data/justfile new file mode 100644 index 00000000..82e00e1d --- /dev/null +++ b/tests/data/justfile @@ -0,0 +1,14 @@ +# List the available commands +help: + @just --list --justfile {{justfile()}} + +# Re-generate all test hugr files. +recompile: recompile-hugrs + +# Re-generate all hugr files. +recompile-hugrs: + #!/usr/bin/env sh + for example in $(find . -type f -name "*.py"); do + echo "Re-generating $example" + uv run --no-project "$example" + done \ No newline at end of file From a947ba37bc46ea59d37d875dc7fb6ce4a840b7b3 Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Mon, 19 Jan 2026 13:41:22 +0000 Subject: [PATCH 2/6] chore: add README --- tests/data/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/data/README.md diff --git a/tests/data/README.md b/tests/data/README.md new file mode 100644 index 00000000..0f5e07fc --- /dev/null +++ b/tests/data/README.md @@ -0,0 +1,8 @@ +# Test programs + +This directory contains simple quantum programs used for testing. + +The compiled HUGR is stored (alongside the guppy python program) with a `.hugr` extension. + +Run `just recompile` in this directory (or `just recompile-test-hugrs` on +the root) to recompile the `.hugr` files. From 6c79a36fc515e61c8c69c58fd49804cbe5c2bbc4 Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Tue, 20 Jan 2026 16:20:36 +0000 Subject: [PATCH 3/6] chore: clean up post review --- integration/conftest.py | 2 +- tests/data/README.md | 2 +- tests/data/{example_hugr.py => example_bell.gpy.py} | 2 +- tests/data/{example_hugr.hugr => example_bell.hugr} | Bin tests/data/justfile | 6 +++--- 5 files changed, 6 insertions(+), 6 deletions(-) rename tests/data/{example_hugr.py => example_bell.gpy.py} (89%) rename tests/data/{example_hugr.hugr => example_bell.hugr} (100%) diff --git a/integration/conftest.py b/integration/conftest.py index e1d44da0..6fdf70f7 100644 --- a/integration/conftest.py +++ b/integration/conftest.py @@ -463,7 +463,7 @@ def test_ref_serialisation( @pytest.fixture(name="qa_hugr_package") def qa_hugr_package_fixture() -> Package: - hugr_path = Path("tests/data/example_hugr.hugr").resolve() + hugr_path = Path("tests/data/example_bell.hugr").resolve() return Package.from_bytes(hugr_path.read_bytes()) diff --git a/tests/data/README.md b/tests/data/README.md index 0f5e07fc..f86205ac 100644 --- a/tests/data/README.md +++ b/tests/data/README.md @@ -4,5 +4,5 @@ This directory contains simple quantum programs used for testing. The compiled HUGR is stored (alongside the guppy python program) with a `.hugr` extension. -Run `just recompile` in this directory (or `just recompile-test-hugrs` on +Run `just recompile` in this directory (or `just recompile-hugrs` on the root) to recompile the `.hugr` files. diff --git a/tests/data/example_hugr.py b/tests/data/example_bell.gpy.py similarity index 89% rename from tests/data/example_hugr.py rename to tests/data/example_bell.gpy.py index 83fd6eb0..a1bec27e 100644 --- a/tests/data/example_hugr.py +++ b/tests/data/example_bell.gpy.py @@ -35,4 +35,4 @@ def main() -> None: main.check() program = main.compile_function() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) +Path(argv[0]).with_suffix("").with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/tests/data/example_hugr.hugr b/tests/data/example_bell.hugr similarity index 100% rename from tests/data/example_hugr.hugr rename to tests/data/example_bell.hugr diff --git a/tests/data/justfile b/tests/data/justfile index 82e00e1d..59438129 100644 --- a/tests/data/justfile +++ b/tests/data/justfile @@ -3,12 +3,12 @@ help: @just --list --justfile {{justfile()}} # Re-generate all test hugr files. -recompile: recompile-hugrs +recompile: recompile-test-files # Re-generate all hugr files. -recompile-hugrs: +recompile-test-files: #!/usr/bin/env sh - for example in $(find . -type f -name "*.py"); do + for example in $(find . -type f -name "*.gpy.py"); do echo "Re-generating $example" uv run --no-project "$example" done \ No newline at end of file From a5d877d721df6afe87125a6d65fb7bbf9f9ce99e Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Tue, 20 Jan 2026 16:30:04 +0000 Subject: [PATCH 4/6] chore: fix unit tests --- pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest.ini b/pytest.ini index 6b6d4eb4..7f92fc30 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,4 +1,5 @@ [pytest] addopts = --strict-markers -n 2 --reruns 3 --cov=qnexus --cov-report= --cov-append --doctest-modules +norecursedirs = tests/data markers = create: marks tests as those that have side effects involving resource creation (deselect with '-m "not create"') From a631ea353a5db3307ff177bc4001b79289403794 Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Tue, 20 Jan 2026 17:40:39 +0000 Subject: [PATCH 5/6] chore: add comment --- tests/data/example_bell.gpy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/data/example_bell.gpy.py b/tests/data/example_bell.gpy.py index a1bec27e..e0ef2d36 100644 --- a/tests/data/example_bell.gpy.py +++ b/tests/data/example_bell.gpy.py @@ -35,4 +35,5 @@ def main() -> None: main.check() program = main.compile_function() +# remove the .gpy suffix and add .hugr Path(argv[0]).with_suffix("").with_suffix(".hugr").write_bytes(program.to_bytes()) From 6ea6a7ae40d5f8b97fae0e38619efa90279e011b Mon Sep 17 00:00:00 2001 From: vanyae-cqc Date: Wed, 21 Jan 2026 14:06:28 +0000 Subject: [PATCH 6/6] chore: fix readme --- tests/data/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/README.md b/tests/data/README.md index f86205ac..75b1a004 100644 --- a/tests/data/README.md +++ b/tests/data/README.md @@ -4,5 +4,5 @@ This directory contains simple quantum programs used for testing. The compiled HUGR is stored (alongside the guppy python program) with a `.hugr` extension. -Run `just recompile` in this directory (or `just recompile-hugrs` on +Run `just recompile` in this directory (or `just recompile-test-files` on the root) to recompile the `.hugr` files.