Skip to content

Conversation

@cqc-alec
Copy link
Collaborator

@cqc-alec cqc-alec commented Nov 14, 2025

Closes #2287 .

Testing:

  • All existing hugr-py tests that call validate() perform a round-trip, checking that the hashes of the start and end Hugrs (computed using the _NodeHash method defined in conftest.py) agree.
  • I exported all the Hugrs generated by tests in the guppylang repo (using just export-integration-tests) and tried importing them (1) using the old method via json and (2) using the new method, and checked that the hashes of the two imported Hugrs agree (using the same _NodeHash method).

There are a few TODO comments remaining in load.py which I could not see a way to resolve using the existing model. I will investigate these further and raise issues if necessary.

@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

❌ Patch coverage is 69.18845% with 224 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.35%. Comparing base (7c41f82) to head (aae3ff8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
hugr-py/src/hugr/model/load.py 70.23% 189 Missing ⚠️
hugr-py/src/hugr/tys.py 12.50% 14 Missing ⚠️
hugr-model/src/v0/binary/read.rs 0.00% 10 Missing ⚠️
hugr-py/src/hugr/model/__init__.py 76.31% 9 Missing ⚠️
hugr-py/src/hugr/envelope.py 83.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2683      +/-   ##
==========================================
- Coverage   83.55%   83.35%   -0.20%     
==========================================
  Files         266      267       +1     
  Lines       51761    52479     +718     
  Branches    47180    47190      +10     
==========================================
+ Hits        43251    43746     +495     
- Misses       6132     6355     +223     
  Partials     2378     2378              
Flag Coverage Δ
python 88.75% <70.15%> (-2.92%) ⬇️
rust 82.75% <0.00%> (-0.02%) ⬇️

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.

@cqc-alec cqc-alec marked this pull request as ready for review November 14, 2025 15:32
@cqc-alec cqc-alec requested a review from a team as a code owner November 14, 2025 15:32
@cqc-alec cqc-alec requested a review from croyzor November 14, 2025 15:32
Copy link
Contributor

@croyzor croyzor left a comment

Choose a reason for hiding this comment

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

Nice work!

def string_to_package(string: str) -> hugr.model.Package: ...
def package_to_bytes(package: hugr.model.Package) -> bytes: ...
def bytes_to_package(binary: bytes) -> hugr.model.Package: ...
def bytes_to_package(binary: bytes) -> tuple[hugr.model.Package, bytes]: ...
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be a breaking change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this doesn't count as a breaking change since the hugr._hugr module is underscored.

continue

try:
decoded = json.loads(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

I had no idea these definitions leaked outside the match block 🤯
I'd prefer if this logic was inside the first case branch anyway

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In two minds, but on balance I prefer this way, the advantage being much smaller match blocks and less indentation.


def import_node_in_module(self, node: model.Node, link_prefix: int) -> Node | None:
"""Import a model Node at the Hugr Module level."""
self.link_prefix = link_prefix
Copy link
Contributor

Choose a reason for hiding this comment

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

After all the hugrs are imported I think this should be unset. Maybe it could be an explicit enter/exit paradigm like with enter_symbol instead of a field?

case _:
error = f"Unexpected symbol in alias declaration: {symbol}"
raise ModelImportError(error)
return self.add_node(
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above: re: moving this logic into the relevant case branch

raise ModelImportError(error)
return self.add_node(
node,
AliasDecl(alias=name, bound=TypeBound.Copyable), # TODO which bound?
Copy link
Contributor

Choose a reason for hiding this comment

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

Good question... Seems like something we should fix in the spec

Copy link
Contributor

Choose a reason for hiding this comment

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

or add this field to model.DeclareAlias 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will create an issue for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

"""Import an entire CFG region from the model into the Hugr."""
[entry_link] = region.sources
entry_block_idx = None
for i, child in enumerate(region.children):
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we have a spec invariant that entry,exit are the 0,1 children?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, good point!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, actually ... this is true in the hugr graph, and it does appear to be true in the model as well ... but I'm not sure that it's guaranteed in the latter. So prefer to leave like this just in case.

@cqc-alec cqc-alec enabled auto-merge November 28, 2025 16:36
@cqc-alec cqc-alec added this pull request to the merge queue Nov 28, 2025
Merged via the queue into main with commit 6ea4abf Nov 28, 2025
29 of 30 checks passed
@cqc-alec cqc-alec deleted the ae/model.4 branch November 28, 2025 16:41
@hugrbot hugrbot mentioned this pull request Nov 28, 2025
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.

Read the binary format from Python

4 participants