Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Python bindings for hugr-model. #1959

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

feat: Python bindings for hugr-model. #1959

wants to merge 7 commits into from

Conversation

zrho
Copy link
Contributor

@zrho zrho commented Mar 10, 2025

This PR introduces Python bindings to hugr-model.

  • Python representation of the hugr model AST as simple dataclasses.
  • Conversion between the Python and Rust AST.
  • Pretty printing and parsing of the AST via the Rust implementation.
  • Binary serialisation and deserialisation of the AST via the Rust implementation.
  • Export of the hugr-py data structures into the Python AST.

Until spec ambiguities about uniqueness of names are decided, the export procedure mangles the names of symbols by adding the id of the defining node.

@zrho zrho force-pushed the zrho/model-python branch from f8f574a to a9b846a Compare March 10, 2025 15:52
@hugrbot
Copy link
Collaborator

hugrbot commented Mar 10, 2025

This PR contains breaking changes to the public Rust API.
Please deprecate the old API instead (if possible), or mark the PR with a ! to indicate a breaking change.

cargo-semver-checks summary

Copy link

codecov bot commented Mar 10, 2025

Codecov Report

Attention: Patch coverage is 24.65582% with 602 lines in your changes missing coverage. Please review.

Project coverage is 82.55%. Comparing base (6bd7665) to head (fb1ac5f).

Files with missing lines Patch % Lines
hugr-model/src/v0/ast/python.rs 0.00% 246 Missing ⚠️
hugr-py/src/hugr/model/export.py 9.66% 215 Missing ⚠️
hugr-model/src/v0/mod.rs 0.00% 78 Missing ⚠️
hugr-py/src/hugr/tys.py 44.26% 34 Missing ⚠️
hugr-py/src/hugr/model/__init__.py 90.44% 13 Missing ⚠️
hugr-py/src/hugr/val.py 43.75% 9 Missing ⚠️
hugr-py/src/hugr/hugr/base.py 42.85% 4 Missing ⚠️
hugr-py/src/hugr/std/collections/array.py 75.00% 1 Missing ⚠️
hugr-py/src/hugr/std/float.py 66.66% 1 Missing ⚠️
hugr-py/src/hugr/std/int.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1959      +/-   ##
==========================================
- Coverage   83.73%   82.55%   -1.19%     
==========================================
  Files         209      212       +3     
  Lines       39266    40061     +795     
  Branches    35937    36265     +328     
==========================================
+ Hits        32879    33071     +192     
- Misses       4541     5144     +603     
  Partials     1846     1846              
Flag Coverage Δ
python 85.69% <40.85%> (-6.35%) ⬇️
rust 82.22% <1.51%> (-0.75%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zrho zrho force-pushed the zrho/model-python branch 3 times, most recently from 49fd266 to f7c4ba4 Compare March 19, 2025 18:27
@zrho zrho force-pushed the zrho/model-python branch from 357e227 to c50986d Compare March 20, 2025 13:25
@zrho zrho force-pushed the zrho/model-python branch from c50986d to 7485182 Compare March 20, 2025 13:26
@zrho zrho force-pushed the zrho/model-python branch from fb1ac5f to 93ee945 Compare March 20, 2025 15:02
@zrho zrho marked this pull request as ready for review March 20, 2025 15:13
@zrho zrho requested a review from a team as a code owner March 20, 2025 15:13
@zrho zrho requested a review from croyzor March 20, 2025 15:13
@ss2165
Copy link
Member

ss2165 commented Mar 20, 2025

related #882

@@ -4,7 +4,7 @@ use std::str::FromStr;

use hugr::std_extensions::std_reg;
use hugr_core::{export::export_hugr, import::import_hugr};
use hugr_model::v0 as model;
use hugr_model::v0::{self as model};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff?

Suggested change
use hugr_model::v0::{self as model};
use hugr_model::v0 as model;

@@ -29,6 +29,7 @@ pest_derive = { workspace = true }
pretty = { workspace = true }
smol_str = { workspace = true, features = ["serde"] }
thiserror.workspace = true
pyo3 = { workspace = true, optional = true }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Make the feature list explicit (so it's easier to read)

Suggested change
pyo3 = { workspace = true, optional = true }
pyo3 = { workspace = true, optional = true }
[features]
pyo3 = ["dep:pyo3"]

Comment on lines +1 to +6
[package]
name = "hugr-py"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding publish = false here, to ensure this never gets released as a crate.

Suggested change
[package]
name = "hugr-py"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[package]
name = "hugr-py"
version = "0.0.0"
edition = { workspace = true }
rust-version = { workspace = true }
publish = false
[lints]
workspace = true

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or this may also be a good place to start using edition2024 (and msrv 1.85) :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive-by: Can you remove the upper bound from the requires-python here?

[tool.maturin]
features = ["pyo3/extension-module"]
python-source = "src/"
module-name = "hugr._hugr"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pyright lint config imported from tket2

Suggested change
module-name = "hugr._hugr"
module-name = "hugr._hugr"
[tool.pyright]
# Rust bindings have typing stubs but no python source code.
reportMissingModuleSource = "none"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing docstrings

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing docstrings

@@ -82,6 +91,10 @@ def resolve(self, registry: ext.ExtensionRegistry) -> Type:
"""Resolve types in the type using the given registry."""
return self

def to_model(self) -> model.Term | model.Splice:
"""Convert the type to a model Term."""
raise NotImplementedError(self)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The absence of implementations for Type, TypeParam, TypeArg seem like significant omissions! Is there a reasoning behind it?

@@ -103,6 +116,10 @@ def _to_serial(self) -> stys.TypeTypeParam:
def __str__(self) -> str:
return str(self.bound)

def to_model(self) -> model.Term:
# Note that we drop the bound.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we dropping the bounds here and in BoundedNatParam?

@@ -656,6 +759,10 @@ def _to_serial(self) -> stys.Qubit:
def __repr__(self) -> str:
return "Qubit"

def to_model(self) -> model.Term:
# TODO: Is this the correct name?
return model.Apply("prelude.Qubit", [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In hugr-core it's lowercase "qubit"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants