From 284a50ffbaa75a2134739d0d817d9661e2b573d1 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Tue, 17 Feb 2026 18:32:47 +0000 Subject: [PATCH 1/2] Add MetadataInline to GuppyMetadata --- .../src/guppylang_internals/definition/metadata.py | 7 ++++++- tests/definition/test_metadata.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/guppylang-internals/src/guppylang_internals/definition/metadata.py b/guppylang-internals/src/guppylang_internals/definition/metadata.py index 4d0280575..1705435ac 100644 --- a/guppylang-internals/src/guppylang_internals/definition/metadata.py +++ b/guppylang-internals/src/guppylang_internals/definition/metadata.py @@ -3,7 +3,7 @@ from abc import ABC from dataclasses import dataclass, field, fields -from typing import Any, ClassVar, Generic, TypeVar +from typing import Any, ClassVar, Generic, Literal, TypeVar from hugr.hugr.node_port import ToNode @@ -26,12 +26,17 @@ class MetadataMaxQubits(GuppyMetadataValue[int]): key = "tket.hint.max_qubits" +class MetadataInline(GuppyMetadataValue[Literal["always"]]): + key = "tket.inline" + + @dataclass(frozen=True, init=True, kw_only=True) class GuppyMetadata: """DTO for metadata within the scope of the guppy compiler for attachment to HUGR nodes. See `add_metadata`.""" max_qubits: MetadataMaxQubits = field(default_factory=MetadataMaxQubits, init=False) + inline: MetadataInline = field(default_factory=MetadataInline, init=False) @classmethod def reserved_keys(cls) -> set[str]: diff --git a/tests/definition/test_metadata.py b/tests/definition/test_metadata.py index a3fc5e479..ad4c90503 100644 --- a/tests/definition/test_metadata.py +++ b/tests/definition/test_metadata.py @@ -88,3 +88,14 @@ def test_add_metadata_property_max_qubits(): add_metadata(mock_hugr_node, guppy_metadata) assert mock_hugr_node.metadata == {"tket.hint.max_qubits": 5} + + +def test_add_metadata_property_inline(): + mock_hugr_node = Mock() + mock_hugr_node.metadata = {} + + guppy_metadata = GuppyMetadata() + guppy_metadata.inline.value = "always" + add_metadata(mock_hugr_node, guppy_metadata) + + assert mock_hugr_node.metadata == {"tket.inline": "always"} From 626f564978af7ece784698b551374534d19405f7 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 18 Feb 2026 14:37:42 +0000 Subject: [PATCH 2/2] Add to decorator, test --- guppylang/src/guppylang/decorator.py | 4 +++- tests/integration/test_metadata.py | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/integration/test_metadata.py diff --git a/guppylang/src/guppylang/decorator.py b/guppylang/src/guppylang/decorator.py index 8f90e6374..ba16cdf45 100644 --- a/guppylang/src/guppylang/decorator.py +++ b/guppylang/src/guppylang/decorator.py @@ -3,7 +3,7 @@ import inspect from collections.abc import Callable, Sequence from types import FrameType -from typing import Any, ParamSpec, TypedDict, TypeVar, cast, overload +from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, cast, overload from guppylang_internals.ast_util import annotate_location from guppylang_internals.compiler.core import ( @@ -93,6 +93,7 @@ class GuppyKwargs(TypedDict, total=False): dagger: bool power: bool max_qubits: int + inline: Literal["always"] class _Guppy: @@ -662,6 +663,7 @@ def _parse_kwargs(kwargs: GuppyKwargs) -> tuple[UnitaryFlags, GuppyMetadata]: metadata = GuppyMetadata() metadata.max_qubits.value = kwargs.pop("max_qubits", None) + metadata.inline.value = kwargs.pop("inline", None) if remaining := next(iter(kwargs), None): err = f"Unknown keyword argument: `{remaining}`" diff --git a/tests/integration/test_metadata.py b/tests/integration/test_metadata.py new file mode 100644 index 000000000..dd15dea0f --- /dev/null +++ b/tests/integration/test_metadata.py @@ -0,0 +1,22 @@ +from hugr.ops import FuncDefn + +from guppylang_internals.definition.metadata import MetadataInline +from guppylang.decorator import guppy +from guppylang.std.builtins import result +from guppylang.std.quantum import ( + qubit, + measure, +) + + +def test_hinted_inline(validate) -> None: + @guppy(inline="always") + def main() -> None: + result("c", measure(qubit())) + + compiled = main.compile_function() + validate(compiled) + + hugr = compiled.modules[0] + [fd] = [data for _, data in hugr.nodes() if isinstance(data.op, FuncDefn)] + assert fd.metadata[MetadataInline.key] == "always"