From bd7e67a59df3c6a8eede15c8a62f4f555d539c9a Mon Sep 17 00:00:00 2001 From: Mark Koch <48097969+mark-koch@users.noreply.github.com> Date: Thu, 16 May 2024 09:39:44 +0100 Subject: [PATCH] feat: Upgrade Hugr and start using the shared Pydantic model (#201) This PR makes Guppy depend on Hugr at main as a path for upgrading to v0.4. Closes #198 Most of the edits are related to changes in the Pydantic model. However, we also had to get rid of `TypeApply` since this no longer exists in Hugr. Therefore, Guppy now rejects all programs that use polymorphic functions as values if the type arguments cannot be inferred --- guppylang/compiler/cfg_compiler.py | 40 +- guppylang/compiler/core.py | 2 +- guppylang/compiler/expr_compiler.py | 72 +- guppylang/compiler/func_compiler.py | 6 +- guppylang/compiler/stmt_compiler.py | 2 +- guppylang/decorator.py | 5 +- guppylang/definition/common.py | 2 +- guppylang/definition/custom.py | 29 +- guppylang/definition/declaration.py | 26 +- guppylang/definition/function.py | 24 +- guppylang/definition/ty.py | 6 +- guppylang/definition/value.py | 22 +- guppylang/hugr/ops.py | 474 ------------- guppylang/hugr/raw.py | 23 - guppylang/hugr/tys.py | 306 -------- guppylang/hugr/val.py | 60 -- guppylang/{hugr => hugr_builder}/__init__.py | 0 guppylang/{hugr => hugr_builder}/hugr.py | 278 +++++--- guppylang/{hugr => hugr_builder}/visualise.py | 17 +- guppylang/module.py | 2 +- guppylang/prelude/_internal.py | 117 ++-- guppylang/prelude/builtins.py | 64 +- guppylang/prelude/quantum.py | 14 +- guppylang/tys/arg.py | 5 +- guppylang/tys/builtin.py | 19 +- guppylang/tys/const.py | 5 +- guppylang/tys/param.py | 10 +- guppylang/tys/ty.py | 63 +- poetry.lock | 657 +++++++++--------- pyproject.toml | 6 +- scripts/__init__.py | 0 scripts/generate_schema.py | 15 - tests/error/iter_errors/end_missing.py | 6 +- tests/error/iter_errors/end_wrong_type.py | 6 +- tests/error/iter_errors/hasnext_missing.py | 6 +- tests/error/iter_errors/hasnext_wrong_type.py | 6 +- tests/error/iter_errors/iter_missing.py | 4 +- tests/error/iter_errors/iter_wrong_type.py | 4 +- tests/error/iter_errors/next_missing.py | 6 +- tests/error/iter_errors/next_wrong_type.py | 6 +- tests/error/util.py | 6 +- tests/hugr/test_dummy_nodes.py | 19 +- tests/integration/test_basic.py | 10 +- tests/integration/test_comprehension.py | 16 +- tests/integration/test_linear.py | 6 +- tests/integration/test_poly.py | 3 + tests/integration/test_py.py | 3 + tests/util.py | 2 +- validator/Cargo.lock | 509 ++++++++++++-- validator/Cargo.toml | 3 +- validator/src/lib.rs | 3 + 51 files changed, 1365 insertions(+), 1630 deletions(-) delete mode 100644 guppylang/hugr/ops.py delete mode 100644 guppylang/hugr/raw.py delete mode 100644 guppylang/hugr/tys.py delete mode 100644 guppylang/hugr/val.py rename guppylang/{hugr => hugr_builder}/__init__.py (100%) rename guppylang/{hugr => hugr_builder}/hugr.py (76%) rename guppylang/{hugr => hugr_builder}/visualise.py (94%) delete mode 100644 scripts/__init__.py delete mode 100644 scripts/generate_schema.py diff --git a/guppylang/compiler/cfg_compiler.py b/guppylang/compiler/cfg_compiler.py index b5793c5e..53de3da9 100644 --- a/guppylang/compiler/cfg_compiler.py +++ b/guppylang/compiler/cfg_compiler.py @@ -12,9 +12,9 @@ ) from guppylang.compiler.expr_compiler import ExprCompiler from guppylang.compiler.stmt_compiler import StmtCompiler -from guppylang.hugr.hugr import CFNode, Hugr, Node, OutPortV +from guppylang.hugr_builder.hugr import CFNode, Hugr, Node, OutPortV from guppylang.tys.builtin import is_bool_type -from guppylang.tys.ty import SumType, TupleType, type_to_row +from guppylang.tys.ty import SumType, row_to_type, type_to_row if TYPE_CHECKING: from collections.abc import Sequence @@ -65,9 +65,8 @@ def compile_bb( branch_port = ExprCompiler(graph, globals).compile(bb.branch_pred, dfg) else: # Even if we don't branch, we still have to add a `Sum(())` predicates - unit = graph.add_make_tuple([], parent=block).out_port(0) branch_port = graph.add_tag( - variants=[TupleType([])], tag=0, inp=unit, parent=block + variants=[[]], tag=0, inputs=[], parent=block ).out_port(0) # Finally, we have to add the block output. @@ -92,7 +91,11 @@ def compile_bb( graph=graph, unit_sum=branch_port, output_vars=[ - [v for v in row if not v.ty.linear or is_return_var(v.name)] + [ + v + for v in sort_vars(row) + if not v.ty.linear or is_return_var(v.name) + ] for row in bb.sig.output_rows ], dfg=dfg, @@ -133,30 +136,23 @@ def choose_vars_for_tuple_sum( ) -> OutPortV: """Selects an output based on a TupleSum. - Given `unit_sum: Sum((), (), ...)` and output variable sets `#s1, #s2, ...`, - constructs a TupleSum value of type `Sum(Tuple(#s1), Tuple(#s2), ...)`. + Given `unit_sum: Sum(*(), *(), ...)` and output variable rows `#s1, #s2, ...`, + constructs a TupleSum value of type `Sum(#s1, #s2, ...)`. """ assert isinstance(unit_sum.ty, SumType) or is_bool_type(unit_sum.ty) assert len(output_vars) == ( len(unit_sum.ty.element_types) if isinstance(unit_sum.ty, SumType) else 2 ) - tuples = [ - graph.add_make_tuple( - inputs=[dfg[v.name].port for v in sort_vars(vs) if v.name in dfg], - parent=dfg.node, - ).out_port(0) - for vs in output_vars - ] - tys = [t.ty for t in tuples] - conditional = graph.add_conditional( - cond_input=unit_sum, inputs=tuples, parent=dfg.node - ) - for i, _ty in enumerate(tys): + assert all(not v.ty.linear for var_row in output_vars for v in var_row) + conditional = graph.add_conditional(cond_input=unit_sum, inputs=[], parent=dfg.node) + tys = [[v.ty for v in var_row] for var_row in output_vars] + for i, var_row in enumerate(output_vars): case = graph.add_case(conditional) - inp = graph.add_input(output_tys=tys, parent=case).out_port(i) - tag = graph.add_tag(variants=tys, tag=i, inp=inp, parent=case).out_port(0) + graph.add_input(output_tys=[], parent=case) + inputs = [dfg[v.name].port for v in var_row] + tag = graph.add_tag(variants=tys, tag=i, inputs=inputs, parent=case).out_port(0) graph.add_output(inputs=[tag], parent=case) - return conditional.add_out_port(SumType(tys)) + return conditional.add_out_port(SumType([row_to_type(row) for row in tys])) def compare_var(x: Variable, y: Variable) -> int: diff --git a/guppylang/compiler/core.py b/guppylang/compiler/core.py index f39fe1ac..fa1f47cb 100644 --- a/guppylang/compiler/core.py +++ b/guppylang/compiler/core.py @@ -5,7 +5,7 @@ from guppylang.ast_util import AstNode from guppylang.checker.core import Variable from guppylang.definition.common import CompiledDef, DefId -from guppylang.hugr.hugr import DFContainingNode, Hugr, OutPortV +from guppylang.hugr_builder.hugr import DFContainingNode, Hugr, OutPortV @dataclass diff --git a/guppylang/compiler/expr_compiler.py b/guppylang/compiler/expr_compiler.py index e219d3da..4e756f83 100644 --- a/guppylang/compiler/expr_compiler.py +++ b/guppylang/compiler/expr_compiler.py @@ -2,7 +2,9 @@ import json from collections.abc import Iterator from contextlib import contextmanager -from typing import Any +from typing import Any, TypeGuard, TypeVar + +from hugr.serialization import ops from guppylang.ast_util import AstVisitor, get_type, with_loc, with_type from guppylang.cfg.builder import tmp_vars @@ -13,8 +15,13 @@ ) from guppylang.definition.value import CompiledCallableDef, CompiledValueDef from guppylang.error import GuppyError, InternalGuppyError -from guppylang.hugr import ops, val -from guppylang.hugr.hugr import DFContainingNode, OutPortV, VNode +from guppylang.hugr_builder.hugr import ( + UNDEFINED, + DFContainingNode, + DummyOp, + OutPortV, + VNode, +) from guppylang.nodes import ( DesugaredGenerator, DesugaredListComp, @@ -149,6 +156,12 @@ def visit_LocalName(self, node: LocalName) -> OutPortV: def visit_GlobalName(self, node: GlobalName) -> OutPortV: defn = self.globals[node.def_id] assert isinstance(defn, CompiledValueDef) + if isinstance(defn, CompiledCallableDef) and defn.ty.parametrized: + raise GuppyError( + "Usage of polymorphic functions as dynamic higher-order values is not " + "supported yet", + node, + ) return defn.load(self.dfg, self.graph, self.globals, node) def visit_Name(self, node: ast.Name) -> OutPortV: @@ -162,7 +175,7 @@ def visit_Tuple(self, node: ast.Tuple) -> OutPortV: def visit_List(self, node: ast.List) -> OutPortV: # Note that this is a list literal (i.e. `[e1, e2, ...]`), not a comprehension return self.graph.add_node( - ops.DummyOp(name="MakeList"), inputs=[self.visit(e) for e in node.elts] + DummyOp("MakeList"), inputs=[self.visit(e) for e in node.elts] ).add_out_port(get_type(node)) def _unpack_tuple(self, wire: OutPortV) -> list[OutPortV]: @@ -243,9 +256,11 @@ def visit_Call(self, node: ast.Call) -> OutPortV: raise InternalGuppyError("Node should have been removed during type checking.") def visit_TypeApply(self, node: TypeApply) -> OutPortV: - func = self.visit(node.value) - assert isinstance(func.ty, FunctionType) - ta = self.graph.add_type_apply(func, node.inst, self.dfg.node).out_port(0) + # For now, we can only TypeApply global FunctionDefs/Decls. + if not isinstance(node.value, GlobalName): + raise InternalGuppyError("Dynamic TypeApply not supported yet!") + defn = self.globals[node.value.def_id] + assert isinstance(defn, CompiledCallableDef) # We have to be very careful here: If we instantiate `foo: forall T. T -> T` # with a tuple type `tuple[A, B]`, we get the type `tuple[A, B] -> tuple[A, B]`. @@ -254,22 +269,25 @@ def visit_TypeApply(self, node: TypeApply) -> OutPortV: # function with a single output port typed `tuple[A, B]`. # TODO: We would need to do manual monomorphisation in that case to obtain a # function that returns two ports as expected - if instantiation_needs_unpacking(func.ty, node.inst): + if instantiation_needs_unpacking(defn.ty, node.inst): raise GuppyError( "Generic function instantiations returning rows are not supported yet", node, ) - return ta + return defn.load_with_args(node.inst, self.dfg, self.graph, self.globals, node) def visit_UnaryOp(self, node: ast.UnaryOp) -> OutPortV: # The only case that is not desugared by the type checker is the `not` operation # since it is not implemented via a dunder method if isinstance(node.op, ast.Not): arg = self.visit(node.operand) - return self.graph.add_node( - ops.CustomOp(extension="logic", op_name="Not", args=[]), inputs=[arg] - ).add_out_port(bool_type()) + op = ops.CustomOp( + extension="logic", op_name="Not", args=[], parent=UNDEFINED + ) + return self.graph.add_node(ops.OpType(op), inputs=[arg]).add_out_port( + bool_type() + ) raise InternalGuppyError("Node should have been removed during type checking.") @@ -281,7 +299,7 @@ def visit_DesugaredListComp(self, node: DesugaredListComp) -> OutPortV: # Make up a name for the list under construction and bind it to an empty list list_ty = get_type(node) list_name = with_type(list_ty, with_loc(node, LocalName(id=next(tmp_vars)))) - empty_list = self.graph.add_node(ops.DummyOp(name="MakeList")) + empty_list = self.graph.add_node(DummyOp("MakeList")) self.dfg[list_name.id] = PortVariable( list_name.id, empty_list.add_out_port(list_ty), node, None ) @@ -292,7 +310,7 @@ def compile_generators(elt: ast.expr, gens: list[DesugaredGenerator]) -> None: if not gens: list_port, elt_port = self.visit(list_name), self.visit(elt) push = self.graph.add_node( - ops.DummyOp(name="Push"), inputs=[list_port, elt_port] + DummyOp("Push"), inputs=[list_port, elt_port] ) self.dfg[list_name.id].port = push.add_out_port(list_port.ty) return @@ -348,7 +366,7 @@ def instantiation_needs_unpacking(func_ty: FunctionType, inst: Inst) -> bool: return False -def python_value_to_hugr(v: Any, exp_ty: Type) -> val.Value | None: +def python_value_to_hugr(v: Any, exp_ty: Type) -> ops.Value | None: """Turns a Python value into a Hugr value. Returns None if the Python value cannot be represented in Guppy. @@ -373,15 +391,13 @@ def python_value_to_hugr(v: Any, exp_ty: Type) -> val.Value | None: python_value_to_hugr(elt, ty) for elt, ty in zip(elts, exp_ty.element_types) ] - if any(value is None for value in vs): - return None - return val.Tuple(vs=vs) + if doesnt_contain_none(vs): + return ops.Value(ops.TupleValue(vs=vs)) case list(elts): assert is_list_type(exp_ty) - return list_value( - [python_value_to_hugr(elt, get_element_type(exp_ty)) for elt in elts], - get_element_type(exp_ty).to_hugr(), - ) + vs = [python_value_to_hugr(elt, get_element_type(exp_ty)) for elt in elts] + if doesnt_contain_none(vs): + return list_value(vs, get_element_type(exp_ty)) case _: # Pytket conversion is an optional feature try: @@ -393,7 +409,15 @@ def python_value_to_hugr(v: Any, exp_ty: Type) -> val.Value | None: ) hugr = json.loads(Tk2Circuit(v).to_hugr_json()) - return val.FunctionVal(hugr=hugr) + return ops.Value(ops.FunctionValue(hugr=hugr)) except ImportError: pass - return None + return None + + +T = TypeVar("T") + + +def doesnt_contain_none(xs: list[T | None]) -> TypeGuard[list[T]]: + """Checks if a list contains `None`.""" + return all(x is not None for x in xs) diff --git a/guppylang/compiler/func_compiler.py b/guppylang/compiler/func_compiler.py index 2edfa572..ce4cf460 100644 --- a/guppylang/compiler/func_compiler.py +++ b/guppylang/compiler/func_compiler.py @@ -6,7 +6,7 @@ DFContainer, PortVariable, ) -from guppylang.hugr.hugr import DFContainingVNode, Hugr +from guppylang.hugr_builder.hugr import DFContainingVNode, Hugr from guppylang.nodes import CheckedNestedFunctionDef from guppylang.tys.ty import FunctionType, type_to_row @@ -60,7 +60,7 @@ def compile_local_func_def( # the function itself, then we provide the partially applied function as a local # variable if len(captured) > 0 and func.name in func.cfg.live_before[func.cfg.entry_bb]: - loaded = graph.add_load_constant(def_node.out_port(0), def_node).out_port(0) + loaded = graph.add_load_function(def_node.out_port(0), [], def_node).out_port(0) partial = graph.add_partial( loaded, [def_input.out_port(i) for i in range(len(captured))], def_node ) @@ -93,7 +93,7 @@ def compile_local_func_def( ) # Finally, load the function into the local data-flow graph - loaded = graph.add_load_constant(def_node.out_port(0), dfg.node).out_port(0) + loaded = graph.add_load_function(def_node.out_port(0), [], dfg.node).out_port(0) if len(captured) > 0: loaded = graph.add_partial( loaded, [dfg[v.name].port for v in captured], dfg.node diff --git a/guppylang/compiler/stmt_compiler.py b/guppylang/compiler/stmt_compiler.py index f5890746..155471fd 100644 --- a/guppylang/compiler/stmt_compiler.py +++ b/guppylang/compiler/stmt_compiler.py @@ -11,7 +11,7 @@ ) from guppylang.compiler.expr_compiler import ExprCompiler from guppylang.error import InternalGuppyError -from guppylang.hugr.hugr import Hugr, OutPortV +from guppylang.hugr_builder.hugr import Hugr, OutPortV from guppylang.nodes import CheckedNestedFunctionDef from guppylang.tys.ty import TupleType diff --git a/guppylang/decorator.py b/guppylang/decorator.py index 4339f787..994b224a 100644 --- a/guppylang/decorator.py +++ b/guppylang/decorator.py @@ -5,6 +5,8 @@ from types import ModuleType from typing import Any, TypeVar +from hugr.serialization import ops, tys + from guppylang.ast_util import has_empty_body from guppylang.definition.common import DefId from guppylang.definition.custom import ( @@ -21,8 +23,7 @@ from guppylang.definition.struct import RawStructDef from guppylang.definition.ty import OpaqueTypeDef, TypeDef from guppylang.error import GuppyError, MissingModuleError, pretty_errors -from guppylang.hugr import ops, tys -from guppylang.hugr.hugr import Hugr +from guppylang.hugr_builder.hugr import Hugr from guppylang.module import GuppyModule, PyFunc FuncDefDecorator = Callable[[PyFunc], RawFunctionDef] diff --git a/guppylang/definition/common.py b/guppylang/definition/common.py index f6e3988f..9a5cf561 100644 --- a/guppylang/definition/common.py +++ b/guppylang/definition/common.py @@ -5,7 +5,7 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, ClassVar, TypeAlias -from guppylang.hugr.hugr import Hugr, Node +from guppylang.hugr_builder.hugr import Hugr, Node if TYPE_CHECKING: from guppylang.checker.core import Globals diff --git a/guppylang/definition/custom.py b/guppylang/definition/custom.py index 61c53fbc..67789fe0 100644 --- a/guppylang/definition/custom.py +++ b/guppylang/definition/custom.py @@ -2,6 +2,8 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field +from hugr.serialization import ops + from guppylang.ast_util import AstNode, get_type, with_loc, with_type from guppylang.checker.core import Context, Globals from guppylang.checker.expr_checker import check_call, synthesize_call @@ -10,8 +12,7 @@ from guppylang.definition.common import ParsableDef from guppylang.definition.value import CompiledCallableDef from guppylang.error import GuppyError, InternalGuppyError -from guppylang.hugr import ops -from guppylang.hugr.hugr import Hugr, Node, OutPortV +from guppylang.hugr_builder.hugr import Hugr, Node, OutPortV from guppylang.nodes import GlobalCall from guppylang.tys.subst import Inst, Subst from guppylang.tys.ty import FunctionType, NoneType, Type, type_to_row @@ -123,8 +124,13 @@ def synthesize_call( new_node, ty = self.call_checker.synthesize(args) return with_type(ty, with_loc(node, new_node)), ty - def load( - self, dfg: "DFContainer", graph: Hugr, globals: CompiledGlobals, node: AstNode + def load_with_args( + self, + type_args: Inst, + dfg: "DFContainer", + graph: Hugr, + globals: CompiledGlobals, + node: AstNode, ) -> OutPortV: """Loads the custom function as a value into a local dataflow graph. @@ -138,12 +144,7 @@ def load( "This function does not support usage in a higher-order context", node, ) - - if self.ty.parametrized: - raise InternalGuppyError( - "Can't yet generate higher-order versions of custom functions. This " - "requires generic function *definitions*" - ) + assert len(self.ty.params) == len(type_args) # Find the module node by walking up the hierarchy module: Node = dfg.node @@ -159,7 +160,7 @@ def load( def_node = graph.add_def(self.ty, module, self.name) _, inp_ports = graph.add_input_with_ports(list(self.ty.inputs), def_node) returns = self.compile_call( - inp_ports, [], DFContainer(def_node, {}), graph, globals, node + inp_ports, type_args, DFContainer(def_node, {}), graph, globals, node ) graph.add_output(returns, parent=def_node) @@ -251,14 +252,14 @@ def compile(self, args: list[OutPortV]) -> list[OutPortV]: class OpCompiler(CustomCallCompiler): """Call compiler for functions that are directly implemented via Hugr ops.""" - op: ops.BaseOp + op: ops.OpType - def __init__(self, op: ops.BaseOp) -> None: + def __init__(self, op: ops.OpType) -> None: self.op = op def compile(self, args: list[OutPortV]) -> list[OutPortV]: node = self.graph.add_node( - self.op.model_copy(), inputs=args, parent=self.dfg.node + self.op.model_copy(deep=True), inputs=args, parent=self.dfg.node ) return_ty = get_type(self.node) return [node.add_out_port(ty) for ty in type_to_row(return_ty)] diff --git a/guppylang/definition/declaration.py b/guppylang/definition/declaration.py index 8e6fddf4..13ccc06a 100644 --- a/guppylang/definition/declaration.py +++ b/guppylang/definition/declaration.py @@ -10,7 +10,7 @@ from guppylang.definition.function import PyFunc, parse_py_func from guppylang.definition.value import CallableDef, CompiledCallableDef from guppylang.error import GuppyError -from guppylang.hugr.hugr import Hugr, Node, OutPortV, VNode +from guppylang.hugr_builder.hugr import Hugr, Node, OutPortV, VNode from guppylang.nodes import GlobalCall from guppylang.tys.subst import Inst, Subst from guppylang.tys.ty import Type, type_to_row @@ -79,12 +79,18 @@ class CompiledFunctionDecl(CheckedFunctionDecl, CompiledCallableDef): hugr_node: VNode - def load( - self, dfg: DFContainer, graph: Hugr, globals: CompiledGlobals, node: AstNode + def load_with_args( + self, + type_args: Inst, + dfg: DFContainer, + graph: Hugr, + globals: CompiledGlobals, + node: AstNode, ) -> OutPortV: """Loads the function as a value into a local Hugr dataflow graph.""" - assert self.hugr_node is not None - return graph.add_load_constant(self.hugr_node.out_port(0), dfg.node).out_port(0) + return graph.add_load_function( + self.hugr_node.out_port(0), type_args, dfg.node + ).out_port(0) def compile_call( self, @@ -96,13 +102,5 @@ def compile_call( node: AstNode, ) -> list[OutPortV]: """Compiles a call to the function.""" - assert self.hugr_node is not None - # TODO: Hugr should probably allow us to pass type args to `Call`, so we can - # avoid loading the function to manually add a `TypeApply` - if type_args: - func = self.load(dfg, graph, globals, node) - func = graph.add_type_apply(func, type_args, dfg.node) - call = graph.add_indirect_call(func.out_port(0), args, dfg.node) - else: - call = graph.add_call(self.hugr_node.out_port(0), args, dfg.node) + call = graph.add_call(self.hugr_node.out_port(0), args, type_args, dfg.node) return [call.out_port(i) for i in range(len(type_to_row(self.ty.output)))] diff --git a/guppylang/definition/function.py b/guppylang/definition/function.py index 312a25b7..3c3c4b6d 100644 --- a/guppylang/definition/function.py +++ b/guppylang/definition/function.py @@ -15,7 +15,7 @@ from guppylang.definition.common import CheckableDef, CompilableDef, ParsableDef from guppylang.definition.value import CallableDef, CompiledCallableDef from guppylang.error import GuppyError -from guppylang.hugr.hugr import DFContainingVNode, Hugr, Node, OutPortV +from guppylang.hugr_builder.hugr import DFContainingVNode, Hugr, Node, OutPortV from guppylang.nodes import GlobalCall from guppylang.tys.subst import Inst, Subst from guppylang.tys.ty import FunctionType, Type, type_to_row @@ -130,11 +130,18 @@ class CompiledFunctionDef(CheckedFunctionDef, CompiledCallableDef): hugr_node: DFContainingVNode - def load( - self, dfg: DFContainer, graph: Hugr, globals: CompiledGlobals, node: AstNode + def load_with_args( + self, + type_args: Inst, + dfg: DFContainer, + graph: Hugr, + globals: CompiledGlobals, + node: AstNode, ) -> OutPortV: """Loads the function as a value into a local Hugr dataflow graph.""" - return graph.add_load_constant(self.hugr_node.out_port(0)).out_port(0) + return graph.add_load_function( + self.hugr_node.out_port(0), type_args, dfg.node + ).out_port(0) def compile_call( self, @@ -146,14 +153,7 @@ def compile_call( node: AstNode, ) -> list[OutPortV]: """Compiles a call to the function.""" - # TODO: Hugr should probably allow us to pass type args to `Call`, so we can - # avoid loading the function to manually add a `TypeApply` - if type_args: - func = self.load(dfg, graph, globals, node) - func = graph.add_type_apply(func, type_args, dfg.node) - call = graph.add_indirect_call(func.out_port(0), args, dfg.node) - else: - call = graph.add_call(self.hugr_node.out_port(0), args, dfg.node) + call = graph.add_call(self.hugr_node.out_port(0), args, type_args, dfg.node) return [call.out_port(i) for i in range(len(type_to_row(self.ty.output)))] def compile_inner(self, graph: Hugr, globals: CompiledGlobals) -> None: diff --git a/guppylang/definition/ty.py b/guppylang/definition/ty.py index 4d1c6026..f430fe7d 100644 --- a/guppylang/definition/ty.py +++ b/guppylang/definition/ty.py @@ -3,13 +3,13 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING +from hugr.serialization import tys + from guppylang.ast_util import AstNode from guppylang.definition.common import CompiledDef, Definition -from guppylang.hugr import tys -from guppylang.hugr.tys import Type from guppylang.tys.arg import Argument from guppylang.tys.param import Parameter, check_all_args -from guppylang.tys.ty import OpaqueType +from guppylang.tys.ty import OpaqueType, Type if TYPE_CHECKING: from guppylang.checker.core import Globals diff --git a/guppylang/definition/value.py b/guppylang/definition/value.py index fa491733..801763be 100644 --- a/guppylang/definition/value.py +++ b/guppylang/definition/value.py @@ -6,7 +6,7 @@ from guppylang.ast_util import AstNode from guppylang.definition.common import CompiledDef, Definition from guppylang.error import GuppyError -from guppylang.hugr.hugr import Hugr, OutPortV +from guppylang.hugr_builder.hugr import Hugr, OutPortV from guppylang.tys.subst import Inst, Subst from guppylang.tys.ty import FunctionType, Type @@ -73,3 +73,23 @@ def compile_call( node: AstNode, ) -> list[OutPortV]: """Compiles a call to the function.""" + + @abstractmethod + def load_with_args( + self, + type_args: Inst, + dfg: "DFContainer", + graph: Hugr, + globals: "CompiledGlobals", + node: AstNode, + ) -> OutPortV: + """Loads the function into a local Hugr dataflow graph. + + Requires an instantiation for all function parameters. + """ + + def load( + self, dfg: "DFContainer", graph: Hugr, globals: "CompiledGlobals", node: AstNode + ) -> OutPortV: + """Loads the defined value into a local Hugr dataflow graph.""" + return self.load_with_args([], dfg, graph, globals, node) diff --git a/guppylang/hugr/ops.py b/guppylang/hugr/ops.py deleted file mode 100644 index a3ae730e..00000000 --- a/guppylang/hugr/ops.py +++ /dev/null @@ -1,474 +0,0 @@ -import inspect -import sys -from abc import ABC -from typing import Annotated, Any, Literal, cast - -from pydantic import BaseModel, Field -from typing_extensions import TypeAliasType - -import guppylang.hugr.tys as tys - -from .tys import ( - ExtensionId, - ExtensionSet, - FunctionType, - PolyFuncType, - Type, - TypeRow, -) -from .val import Value - -NodeID = int - - -class BaseOp(ABC, BaseModel): - """Base class for ops that store their node's input/output types""" - - # Parent node index of node the op belongs to, used only at serialization time - parent: NodeID = 0 - input_extensions: ExtensionSet | None = None - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - """Hook to insert type information from the input and output ports into the - op""" - - def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None: - """Hook to insert type information from a child dataflow graph""" - - def display_name(self) -> str: - """Name of the op for visualisation""" - return self.__class__.__name__ - - -class DummyOp(BaseOp): - """Nodes used inside dataflow containers (DFG, Conditional, TailLoop, def, - BasicBlock).""" - - op: Literal["DummyOp"] = "DummyOp" - name: str - - def display_name(self) -> str: - return f'"{self.name}"' - - -# ---------------------------------------------------------- -# --------------- Module level operations ------------------ -# ---------------------------------------------------------- - - -class Module(BaseOp): - """The root of a module, parent of all other `ModuleOp`s.""" - - op: Literal["Module"] = "Module" - - -class FuncDefn(BaseOp): - """A function definition. Children nodes are the body of the definition.""" - - op: Literal["FuncDefn"] = "FuncDefn" - - name: str - signature: PolyFuncType = Field(default_factory=PolyFuncType.empty) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert len(in_types) == 0 - assert len(out_types) == 1 - out = out_types[0] - assert isinstance(out, PolyFuncType) - self.signature = out # TODO: Extensions - - -class FuncDecl(BaseOp): - """External function declaration, linked at runtime.""" - - op: Literal["FuncDecl"] = "FuncDecl" - name: str - signature: PolyFuncType = Field(default_factory=PolyFuncType.empty) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert len(in_types) == 0 - assert len(out_types) == 1 - out = out_types[0] - assert isinstance(out, PolyFuncType) - self.signature = out - - -class Const(BaseOp): - """A constant value definition.""" - - op: Literal["Const"] = "Const" - value: Value - typ: Type - - -# ----------------------------------------------- -# --------------- BasicBlock types ------------------ -# ----------------------------------------------- - - -class DataflowBlock(BaseOp): - """A CFG basic block node. The signature is that of the internal Dataflow - graph.""" - - op: Literal["DataflowBlock"] = "DataflowBlock" - inputs: TypeRow = Field(default_factory=list) - other_outputs: TypeRow = Field(default_factory=list) - tuple_sum_rows: list[TypeRow] = Field(default_factory=list) - extension_delta: ExtensionSet = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - # The types will be all None because it's not dataflow, but we only care about - # the number of outputs. Note that we don't make use of the HUGR feature where - # the variant data is appended to successor input. Thus, `predicate_variants` - # will only contain empty rows. - num_cases = len(out_types) - self.tuple_sum_rows = [[] for _ in range(num_cases)] - - def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None: - self.inputs = inputs - pred = outputs[0] - assert isinstance(pred, tys.UnitSum | tys.GeneralSum) - if isinstance(pred, tys.UnitSum): - self.tuple_sum_rows = [[] for _ in range(cast(tys.UnitSum, pred).size)] - else: - assert isinstance(pred, tys.GeneralSum) - self.tuple_sum_rows = [] - for variant in pred.row: - assert isinstance(variant, tys.TupleType) - self.tuple_sum_rows.append(variant.inner) - self.other_outputs = outputs[1:] - - -class ExitBlock(BaseOp): - """The single exit node of the CFG, has no children, stores the types of - the CFG node output.""" - - op: Literal["ExitBlock"] = "ExitBlock" - cfg_outputs: TypeRow - - -# --------------------------------------------- -# --------------- DataflowOp ------------------ -# --------------------------------------------- - - -class DataflowOp(BaseOp): - pass - - -class Input(DataflowOp): - """An input node. The outputs of this node are the inputs to the function.""" - - op: Literal["Input"] = "Input" - types: TypeRow = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert len(in_types) == 0 - self.types = list(out_types) - - -class Output(DataflowOp): - """An output node. The inputs are the outputs of the function.""" - - op: Literal["Output"] = "Output" - types: TypeRow = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert len(out_types) == 0 - self.types = list(in_types) - - -class Call(DataflowOp): - """ - Call a function directly. - - The first port is connected to the def/declare of the function being called - directly, with a `ConstE` edge. The signature of the remaining ports matches - the function being called. - """ - - op: Literal["Call"] = "Call" - signature: FunctionType = Field(default_factory=FunctionType.empty) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - # The constE edge comes after the value inputs - fun_ty = in_types[-1] - assert isinstance(fun_ty, PolyFuncType) - fun_ty = cast(PolyFuncType, fun_ty) - assert len(fun_ty.params) == 0 - self.signature = fun_ty.body - - -class CallIndirect(DataflowOp): - """Call a function indirectly. - - Like call, but the first input is a standard dataflow graph type.""" - - op: Literal["CallIndirect"] = "CallIndirect" - signature: FunctionType = Field(default_factory=FunctionType.empty) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - fun_ty = in_types[0] - assert isinstance(fun_ty, PolyFuncType) - fun_ty = cast(PolyFuncType, fun_ty) - assert len(fun_ty.params) == 0 - assert len(fun_ty.body.input) == len(in_types) - 1 - assert len(fun_ty.body.output) == len(out_types) - self.signature = fun_ty.body - - -class LoadConstant(DataflowOp): - """Load a static constant in to the local dataflow graph.""" - - op: Literal["LoadConstant"] = "LoadConstant" - datatype: Type - - -class LeafOp(DataflowOp): - """Simple operation that has only value inputs+outputs and (potentially) StateOrder - edges.""" - - op: Literal["LeafOp"] = "LeafOp" - - -class DFG(DataflowOp): - """A simply nested dataflow graph.""" - - op: Literal["DFG"] = "DFG" - signature: FunctionType = Field(default_factory=FunctionType.empty) - - def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None: - self.signature = FunctionType( - input=list(inputs), output=list(outputs), extension_reqs=[] - ) - - -# ------------------------------------------------ -# --------------- ControlFlowOp ------------------ -# ------------------------------------------------ - - -class Conditional(DataflowOp): - """Conditional operation, defined by child `Case` nodes for each branch.""" - - op: Literal["Conditional"] = "Conditional" - tuple_sum_rows: list[TypeRow] = Field( - default_factory=list - ) # The possible rows of the predicate input - other_inputs: TypeRow = Field(default_factory=list) # Remaining input types - outputs: TypeRow = Field(default_factory=list) # Output types - # Extensions used to produce the outputs - extension_delta: ExtensionSet = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - # First port is a predicate, i.e. a sum of tuple types. We need to unpack - # those into a list of type rows - pred = in_types[0] - if isinstance(pred, tys.UnitSum): - self.tuple_sum_rows = [[] for _ in range(cast(tys.UnitSum, pred).size)] - else: - assert isinstance(pred, tys.GeneralSum) - self.tuple_sum_rows = [] - for ty in pred.row: - assert isinstance(ty, tys.TupleType) - self.tuple_sum_rows.append(ty.inner) - self.other_inputs = list(in_types[1:]) - self.outputs = list(out_types) - - -class Case(BaseOp): - """Case ops - nodes valid inside Conditional nodes.""" - - op: Literal["Case"] = "Case" - # The signature of the contained dataflow graph. - signature: FunctionType = Field(default_factory=FunctionType.empty) - - def insert_child_dfg_signature(self, inputs: TypeRow, outputs: TypeRow) -> None: - self.signature = tys.FunctionType( - input=list(inputs), output=list(outputs), extension_reqs=[] - ) - - -class TailLoop(DataflowOp): - """Tail-controlled loop.""" - - op: Literal["TailLoop"] = "TailLoop" - just_inputs: TypeRow = Field(default_factory=list) # Types that are only input - just_outputs: TypeRow = Field(default_factory=list) # Types that are only output - # Types that are appended to both input and output: - rest: TypeRow = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert in_types == out_types - # self.just_inputs = list(in_types) - # self.just_outputs = list(out_types) - self.rest = list(in_types) - - -class CFG(DataflowOp): - """A dataflow node which is defined by a child CFG.""" - - op: Literal["CFG"] = "CFG" - signature: FunctionType = Field(default_factory=FunctionType.empty) - - def insert_port_types(self, inputs: TypeRow, outputs: TypeRow) -> None: - self.signature = FunctionType( - input=list(inputs), output=list(outputs), extension_reqs=[] - ) - - -ControlFlowOp = Conditional | TailLoop | CFG - - -# ----------------------------------------- -# --------------- LeafOp ------------------ -# ----------------------------------------- - - -class CustomOp(LeafOp): - """A user-defined operation that can be downcasted by the extensions that define - it.""" - - lop: Literal["CustomOp"] = "CustomOp" - extension: ExtensionId - op_name: str - signature: tys.FunctionType = Field(default_factory=tys.FunctionType.empty) - description: str = "" - args: list[tys.TypeArg] = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - self.signature = tys.FunctionType(input=list(in_types), output=list(out_types)) - - def display_name(self) -> str: - return self.op_name - - -class Noop(LeafOp): - """A no-op operation.""" - - lop: Literal["Noop"] = "Noop" - ty: Type - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - assert len(in_types) == 1 - assert len(out_types) == 1 - assert in_types[0] == out_types[0] # type: ignore[operator] # mypy doesn't understand the type union - self.ty = in_types[0] - - -class MakeTuple(LeafOp): - """An operation that packs all its inputs into a tuple.""" - - lop: Literal["MakeTuple"] = "MakeTuple" - tys: TypeRow = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - # If we have a single order edge as input, this is a unit - if in_types == [None]: - in_types = [] - self.tys = list(in_types) - - -class UnpackTuple(LeafOp): - """An operation that packs all its inputs into a tuple.""" - - lop: Literal["UnpackTuple"] = "UnpackTuple" - tys: TypeRow = Field(default_factory=list) - - def insert_port_types(self, in_types: TypeRow, out_types: TypeRow) -> None: - self.tys = list(out_types) - - -class Tag(LeafOp): - """An operation that creates a tagged sum value from one of its variants.""" - - lop: Literal["Tag"] = "Tag" - tag: int # The variant to create. - variants: TypeRow # The variants of the sum type. - - -class TypeApply(LeafOp): - """Fixes some TypeParams of a polymorphic type by providing TypeArgs""" - - lop: Literal["TypeApply"] = "TypeApply" - ta: "TypeApplication" - - -class TypeApplication(BaseModel): - """Records details of an application of a PolyFuncType to some TypeArgs and the - result (a less-, but still potentially-, polymorphic type). - - Note that Guppy only generates full type applications, where the result is a - monomorphic type. Partial type applications are not used by Guppy. - """ - - input: PolyFuncType - args: list[tys.TypeTypeArg] - output: PolyFuncType - - -LeafOpUnion = TypeAliasType( - "LeafOpUnion", - Annotated[ - (CustomOp | Noop | MakeTuple | UnpackTuple | Tag | TypeApply), - Field(discriminator="lop"), - ], -) - - -OpType = TypeAliasType( - "OpType", - Annotated[ - ( - Module - | Case - | FuncDefn - | FuncDecl - | Const - | DummyOp - | DataflowBlock - | ExitBlock - | Conditional - | TailLoop - | CFG - | Input - | Output - | Call - | CallIndirect - | LoadConstant - | LeafOpUnion - | DFG - ), - Field(discriminator="op"), - ], -) - - -# -------------------------------------- -# --------------- OpDef ---------------- -# -------------------------------------- - - -class OpDef(BaseOp, populate_by_name=True): - """Serializable definition for dynamically loaded operations.""" - - name: str # Unique identifier of the operation. - description: str # Human readable description of the operation. - inputs: list[tuple[str | None, Type]] - outputs: list[tuple[str | None, Type]] - misc: dict[str, Any] # Miscellaneous data associated with the operation. - def_: str | None = Field( - ..., alias="def" - ) # (YAML?)-encoded definition of the operation. - extension_reqs: ExtensionSet # Resources required to execute this operation. - - -# Now that all classes are defined, we need to update the ForwardRefs in all type -# annotations. We use some inspect magic to find all classes defined in this file. -classes = inspect.getmembers( - sys.modules[__name__], - lambda member: inspect.isclass(member) and member.__module__ == __name__, -) -for _, c in classes: - if issubclass(c, BaseModel): - c.model_rebuild() diff --git a/guppylang/hugr/raw.py b/guppylang/hugr/raw.py deleted file mode 100644 index 3a56dea5..00000000 --- a/guppylang/hugr/raw.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Any, Literal - -from pydantic import BaseModel - -from guppylang.hugr.ops import NodeID, OpType - -Port = tuple[NodeID, int | None] # (node, offset) -Edge = tuple[Port, Port] - - -class RawHugr(BaseModel): - version: Literal["v0"] = "v0" - nodes: list[OpType] - edges: list[Edge] - - def to_json(self) -> str: - """Return a JSON representation of the Hugr.""" - return self.model_dump_json() - - @classmethod - def load_json(cls, json: dict[Any, Any]) -> "RawHugr": - """Decode a JSON-encoded Hugr.""" - return cls(**json) diff --git a/guppylang/hugr/tys.py b/guppylang/hugr/tys.py deleted file mode 100644 index 98874cbd..00000000 --- a/guppylang/hugr/tys.py +++ /dev/null @@ -1,306 +0,0 @@ -import inspect -import sys -from enum import Enum -from typing import Annotated, Any, Literal - -from pydantic import ( - BaseModel, - Field, - ValidationError, - ValidationInfo, - ValidatorFunctionWrapHandler, - WrapValidator, -) -from pydantic_core import PydanticCustomError -from typing_extensions import TypeAliasType - - -def _json_custom_error_validator( - value: Any, handler: ValidatorFunctionWrapHandler, _info: ValidationInfo -) -> Any: - """Simplify the error message to avoid a gross error stemming - from exhaustive checking of all union options. - - As suggested at - https://docs.pydantic.dev/latest/concepts/types/#named-recursive-types - - - Used to define named recursive alias types. - """ - try: - return handler(value) - except ValidationError as err: - raise PydanticCustomError( - "invalid_json", - "Input is not valid json", - ) from err - - -ExtensionId = str -ExtensionSet = list[ # TODO: Set not supported by MessagePack. Is list correct here? - ExtensionId -] - - -# -------------------------------------------- -# --------------- TypeParam ------------------ -# -------------------------------------------- - - -class TypeTypeParam(BaseModel): - tp: Literal["Type"] = "Type" - b: "TypeBound" - - -class BoundedNatParam(BaseModel): - tp: Literal["BoundedNat"] = "BoundedNat" - bound: int | None - - -class OpaqueParam(BaseModel): - tp: Literal["Opaque"] = "Opaque" - ty: "Opaque" - - -class ListParam(BaseModel): - tp: Literal["List"] = "List" - param: "TypeParam" - - -class TupleParam(BaseModel): - tp: Literal["Tuple"] = "Tuple" - params: list["TypeParam"] - - -TypeParam = TypeAliasType( - "TypeParam", - Annotated[ - TypeTypeParam | BoundedNatParam | OpaqueParam | ListParam | TupleParam, - Field(discriminator="tp"), - WrapValidator(_json_custom_error_validator), - ], -) - - -# ------------------------------------------ -# --------------- TypeArg ------------------ -# ------------------------------------------ - - -class CustomTypeArg(BaseModel): - typ: None # TODO - value: str - - -class TypeTypeArg(BaseModel): - tya: Literal["Type"] = "Type" - ty: "Type" - - -class BoundedNatArg(BaseModel): - tya: Literal["BoundedNat"] = "BoundedNat" - n: int - - -class OpaqueArg(BaseModel): - tya: Literal["Opaque"] = "Opaque" - arg: CustomTypeArg - - -class SequenceArg(BaseModel): - tya: Literal["Sequence"] = "Sequence" - args: list["TypeArg"] - - -class ExtensionsArg(BaseModel): - tya: Literal["Extensions"] = "Extensions" - es: ExtensionSet - - -TypeArg = TypeAliasType( - "TypeArg", - Annotated[ - TypeTypeArg | BoundedNatArg | OpaqueArg | SequenceArg | ExtensionsArg, - Field(discriminator="tya"), - WrapValidator(_json_custom_error_validator), - ], -) - - -# -------------------------------------------- -# --------------- Container ------------------ -# -------------------------------------------- - - -class MultiContainer(BaseModel): - ty: "Type" - - -class Array(MultiContainer): - """Known size array of""" - - t: Literal["Array"] = "Array" - len: int - - -class TupleType(BaseModel): - """Product type, known-size tuple over elements of type row""" - - t: Literal["Tuple"] = "Tuple" - inner: "TypeRow" - - -class UnitSum(BaseModel): - """Simple predicate where all variants are empty tuples""" - - t: Literal["Sum"] = "Sum" - - s: Literal["Unit"] = "Unit" - size: int - - -class GeneralSum(BaseModel): - """General sum type that explicitly stores the types of the variants""" - - t: Literal["Sum"] = "Sum" - - s: Literal["General"] = "General" - row: "TypeRow" - - -Sum = Annotated[UnitSum | GeneralSum, Field(discriminator="s")] -# ---------------------------------------------- -# --------------- ClassicType ------------------ -# ---------------------------------------------- - - -class Variable(BaseModel): - """A type variable identified by a de Bruijn index.""" - - t: Literal["V"] = "V" - i: int - b: "TypeBound" - - -class USize(BaseModel): - """Unsigned integer size type.""" - - t: Literal["I"] = "I" - - -class FunctionType(BaseModel): - """A graph encoded as a value. It contains a concrete signature and a set of - required resources.""" - - input: "TypeRow" # Value inputs of the function. - output: "TypeRow" # Value outputs of the function. - # The extension requirements which are added by the operation - extension_reqs: "ExtensionSet" = Field(default_factory=list) - - @classmethod - def empty(cls) -> "FunctionType": - return FunctionType(input=[], output=[], extension_reqs=[]) - - -class PolyFuncType(BaseModel): - """A graph encoded as a value. It contains a concrete signature and a set of - required resources.""" - - t: Literal["G"] = "G" - - # The declared type parameters, i.e., these must be instantiated with the same - # number of TypeArgs before the function can be called. Note that within the body, - # variable (DeBruijn) index 0 is element 0 of this array, i.e. the variables are - # bound from right to left. - params: list[TypeParam] - - # Template for the function. May contain variables up to length of `params` - body: FunctionType - - @classmethod - def empty(cls) -> "PolyFuncType": - return PolyFuncType(params=[], body=FunctionType.empty()) - - -class TypeBound(Enum): - Eq = "E" - Copyable = "C" - Any = "A" - - @staticmethod - def join(*bs: "TypeBound") -> "TypeBound": - """Computes the least upper bound for a sequence of bounds.""" - res = TypeBound.Eq - for b in bs: - if b == TypeBound.Any: - return TypeBound.Any - if res == TypeBound.Eq: - res = b - return res - - -class Opaque(BaseModel): - """An opaque operation that can be downcasted by the extensions that define it.""" - - t: Literal["Opaque"] = "Opaque" - extension: ExtensionId - id: str # Unique identifier of the opaque type. - args: list[TypeArg] - bound: TypeBound - - -# ---------------------------------------------- -# --------------- LinearType ------------------- -# ---------------------------------------------- - - -class Qubit(BaseModel): - """A qubit.""" - - t: Literal["Q"] = "Q" - - -Type = TypeAliasType( - "Type", - Annotated[ - Qubit | Variable | USize | PolyFuncType | Array | TupleType | Sum | Opaque, - Field(discriminator="t"), - WrapValidator(_json_custom_error_validator), - ], -) - - -# ------------------------------------------- -# --------------- TypeRow ------------------- -# ------------------------------------------- - -TypeRow = list[Type] - - -# ------------------------------------------- -# --------------- Signature ----------------- -# ------------------------------------------- - - -class Signature(BaseModel): - """Describes the edges required to/from a node. - - This includes both the concept of "signature" in the spec, and also the target - (value) of a call (constant). - """ - - signature: "PolyFuncType" # The underlying signature - - # The extensions which are associated with all the inputs and carried through - input_extensions: ExtensionSet - - -# Now that all classes are defined, we need to update the ForwardRefs in all type -# annotations. We use some inspect magic to find all classes defined in this file. -classes = inspect.getmembers( - sys.modules[__name__], - lambda member: inspect.isclass(member) and member.__module__ == __name__, -) -for _, c in classes: - if issubclass(c, BaseModel): - c.model_rebuild() diff --git a/guppylang/hugr/val.py b/guppylang/hugr/val.py deleted file mode 100644 index c59313b8..00000000 --- a/guppylang/hugr/val.py +++ /dev/null @@ -1,60 +0,0 @@ -import inspect -import sys -from typing import Annotated, Any, Literal - -from pydantic import BaseModel, Field -from typing_extensions import TypeAliasType - -CustomConst = Any # TODO - - -class ExtensionVal(BaseModel): - """An extension constant value, that can check it is of a given [CustomType].""" - - v: Literal["Extension"] = "Extension" - c: tuple[CustomConst] - - -class FunctionVal(BaseModel): - """A higher-order function value.""" - - v: Literal["Function"] = "Function" - hugr: Any # TODO - - -class Tuple(BaseModel): - """A tuple.""" - - v: Literal["Tuple"] = "Tuple" - vs: list["Value"] - - -class Sum(BaseModel): - """A Sum variant - - For any Sum type where this value meets the type of the variant indicated by the tag - """ - - v: Literal["Sum"] = "Sum" - tag: int - value: "Value" - - -Value = TypeAliasType( - "Value", - Annotated[ - ExtensionVal | FunctionVal | Tuple | Sum, - Field(discriminator="v"), - ], -) - - -# Now that all classes are defined, we need to update the ForwardRefs in all type -# annotations. We use some inspect magic to find all classes defined in this file. -classes = inspect.getmembers( - sys.modules[__name__], - lambda member: inspect.isclass(member) and member.__module__ == __name__, -) -for _, c in classes: - if issubclass(c, BaseModel): - c.model_rebuild() diff --git a/guppylang/hugr/__init__.py b/guppylang/hugr_builder/__init__.py similarity index 100% rename from guppylang/hugr/__init__.py rename to guppylang/hugr_builder/__init__.py diff --git a/guppylang/hugr/hugr.py b/guppylang/hugr_builder/hugr.py similarity index 76% rename from guppylang/hugr/hugr.py rename to guppylang/hugr_builder/hugr.py index 4e0f798b..88ba20ae 100644 --- a/guppylang/hugr/hugr.py +++ b/guppylang/hugr_builder/hugr.py @@ -6,17 +6,19 @@ from typing import Any, Optional import networkx as nx # type: ignore[import-untyped] +from hugr.serialization import SerialHugr, ops, tys +from hugr.serialization import serial_hugr as raw +from hugr.serialization.ops import OpType -import guppylang.hugr.ops as ops -import guppylang.hugr.raw as raw -from guppylang.hugr import val from guppylang.tys.subst import Inst from guppylang.tys.ty import ( FunctionType, SumType, TupleType, Type, + TypeRow, row_to_type, + rows_to_hugr, type_to_row, ) @@ -68,6 +70,21 @@ class OutPortCF(OutPort): """A control-flow output port.""" +class DummyOp(OpType): + """A dummy Hugr op that is replaced with a call to a dummy function declaration + during serialisation. + + This is a placeholder for ops that aren't yet available in Hugr. + """ + + root: str # type: ignore[assignment] + + @property + def name(self) -> str: + """The name of the dummy op.""" + return self.root + + Edge = tuple[OutPort, InPort] TypeList = list[Type] @@ -81,7 +98,7 @@ class Node(ABC): """ idx: NodeIdx - op: ops.BaseOp + op: ops.OpType parent: Optional["Node"] meta_data: dict[str, Any] @@ -103,8 +120,7 @@ def in_port(self, offset: PortOffset | None) -> InPort: def out_port(self, offset: PortOffset | None) -> OutPort: """Returns the output port at the given offset.""" - @abstractmethod - def update_op(self) -> None: + def update_op(self) -> None: # noqa: B027 """Updates the op type associated with this node with additional information. This should be called before serialisation. @@ -180,9 +196,15 @@ def update_op(self) -> None: Feeds type information from the in- and out-ports to the operation class to update signature information. This function must be called before serialisation. """ - in_types = [t.to_hugr() for t in self.in_port_types] - out_types = [t.to_hugr() for t in self.out_port_types] - self.op.insert_port_types(in_types, out_types) + # We can't call `to_hugr()` on polymorphic function types, so we have to skip + # ops that have connected `Function` edges. + has_poly_func_edge = isinstance( + self.op.root, ops.FuncDecl | ops.FuncDefn | ops.Call | ops.LoadFunction + ) + if isinstance(self.op.root, ops.BaseOp) and not has_poly_func_edge: + in_types = [t.to_hugr() for t in self.in_port_types] + out_types = [t.to_hugr() for t in self.out_port_types] + self.op.root.insert_port_types(in_types, out_types) super().update_op() @@ -243,11 +265,12 @@ def update_op(self) -> None: """ assert self.input_child is not None assert self.output_child is not None + assert isinstance(self.op.root, ops.BaseOp) # Input and output node may have extra order edges connected, so we filter # `None`s here ins = [ty.to_hugr() for ty in self.input_child.out_port_types] outs = [ty.to_hugr() for ty in self.output_child.in_port_types] - self.op.insert_child_dfg_signature(inputs=ins, outputs=outs) + self.op.root.insert_child_dfg_signature(inputs=ins, outputs=outs) super().update_op() @@ -262,6 +285,8 @@ class BlockNode(DFContainingNode, CFNode): OrderEdge = tuple["Node", "Node"] ORDER_EDGE_KEY = (-1, -1) +UNDEFINED: ops.NodeID = -1 + class Hugr: """Hierarchical unified graph representation.""" @@ -279,7 +304,9 @@ def __init__(self, name: str | None = None) -> None: self._graph = nx.MultiDiGraph() self._children = {-1: []} self.root = self.add_node( - op=ops.Module(), meta_data={"name": name}, parent=None + op=ops.OpType(ops.Module(parent=UNDEFINED)), + meta_data={"name": name}, + parent=None, ) @contextmanager @@ -301,7 +328,7 @@ def _insert_node(self, node: Node, inputs: list[OutPortV] | None = None) -> None def add_node( self, - op: ops.BaseOp, + op: ops.OpType, input_types: TypeList | None = None, output_types: TypeList | None = None, parent: Node | None = None, @@ -354,11 +381,11 @@ def set_root_name(self, name: str) -> VNode: return self.root def add_constant( - self, value: val.Value, ty: Type, parent: Node | None = None + self, value: ops.Value, ty: Type, parent: Node | None = None ) -> VNode: """Adds a constant node holding a given value to the graph.""" return self.add_node( - ops.Const(value=value, typ=ty.to_hugr()), [], [ty], parent, None + ops.OpType(ops.Const(v=value, parent=UNDEFINED)), [], [ty], parent, None ) def add_input( @@ -366,7 +393,9 @@ def add_input( ) -> VNode: """Adds an `Input` node to the graph.""" parent = parent or self._default_parent - node = self.add_node(ops.Input(), [], output_tys, parent) + node = self.add_node( + ops.OpType(ops.Input(parent=UNDEFINED)), [], output_tys, parent + ) if isinstance(parent, DFContainingNode): parent.input_child = node return node @@ -387,7 +416,9 @@ def add_output( ) -> VNode: """Adds an `Output` node to the graph.""" parent = parent or self._default_parent - node = self.add_node(ops.Output(), input_tys, [], parent, inputs) + node = self.add_node( + ops.OpType(ops.Output(parent=UNDEFINED)), input_tys, [], parent, inputs + ) if isinstance(parent, DFContainingNode): parent.output_child = node return node @@ -396,7 +427,7 @@ def add_block(self, parent: Node | None, num_successors: int = 0) -> BlockNode: """Adds a `Block` node to the graph.""" node = BlockNode( idx=self._graph.number_of_nodes(), - op=ops.DataflowBlock(), + op=ops.OpType(ops.DataflowBlock(parent=UNDEFINED, sum_rows=[])), parent=parent, meta_data={}, ) @@ -410,7 +441,7 @@ def add_exit(self, output_tys: TypeList, parent: Node) -> CFNode: outputs = [ty.to_hugr() for ty in output_tys] node = CFNode( idx=self._graph.number_of_nodes(), - op=ops.ExitBlock(cfg_outputs=outputs), + op=ops.OpType(ops.ExitBlock(cfg_outputs=outputs, parent=UNDEFINED)), parent=parent, meta_data={}, ) @@ -419,15 +450,19 @@ def add_exit(self, output_tys: TypeList, parent: Node) -> CFNode: def add_dfg(self, parent: Node) -> DFContainingVNode: """Adds a nested dataflow `DFG` node to the graph.""" - return self._add_dfg_node(ops.DFG(), [], [], parent) + return self._add_dfg_node(ops.OpType(ops.DFG(parent=UNDEFINED)), [], [], parent) def add_case(self, parent: Node) -> DFContainingVNode: """Adds a `Case` node to the graph.""" - return self._add_dfg_node(ops.Case(), [], [], parent) + return self._add_dfg_node( + ops.OpType(ops.Case(parent=UNDEFINED)), [], [], parent + ) def add_cfg(self, parent: Node, inputs: list[OutPortV]) -> VNode: """Adds a nested control-flow `CFG` node to the graph.""" - return self.add_node(ops.CFG(), [], [], parent, inputs) + return self.add_node( + ops.OpType(ops.CFG(parent=UNDEFINED)), [], [], parent, inputs + ) def add_conditional( self, @@ -437,20 +472,30 @@ def add_conditional( ) -> VNode: """Adds a `Conditional` node to the graph.""" inputs = [cond_input, *inputs] - return self.add_node(ops.Conditional(), None, None, parent, inputs) + return self.add_node( + ops.OpType(ops.Conditional(sum_rows=[], parent=UNDEFINED)), + None, + None, + parent, + inputs, + ) def add_tail_loop( self, inputs: list[OutPortV], parent: Node | None = None ) -> DFContainingVNode: """Adds a `TailLoop` node to the graph.""" - return self._add_dfg_node(ops.TailLoop(), None, None, parent, inputs) + return self._add_dfg_node( + ops.OpType(ops.TailLoop(parent=UNDEFINED)), None, None, parent, inputs + ) def add_make_tuple( self, inputs: list[OutPortV], parent: Node | None = None ) -> VNode: """Adds a `MakeTuple` node to the graph.""" ty = TupleType([port.ty for port in inputs]) - return self.add_node(ops.MakeTuple(), None, [ty], parent, inputs) + return self.add_node( + ops.OpType(ops.MakeTuple(parent=UNDEFINED)), None, [ty], parent, inputs + ) def add_unpack_tuple( self, input_tuple: OutPortV, parent: Node | None = None @@ -458,7 +503,7 @@ def add_unpack_tuple( """Adds an `UnpackTuple` node to the graph.""" assert isinstance(input_tuple.ty, TupleType) return self.add_node( - ops.UnpackTuple(), + ops.OpType(ops.UnpackTuple(parent=UNDEFINED)), None, list(input_tuple.ty.element_types), parent, @@ -466,13 +511,22 @@ def add_unpack_tuple( ) def add_tag( - self, variants: TypeList, tag: int, inp: OutPortV, parent: Node | None = None + self, + variants: Sequence[TypeRow], + tag: int, + inputs: list[OutPortV], + parent: Node | None = None, ) -> VNode: """Adds a `Tag` node to the graph.""" - types = [ty.to_hugr() for ty in variants] - assert inp.ty == variants[tag] + assert all(inp.ty == ty for inp, ty in zip(inputs, variants[tag])) + hugr_variants = rows_to_hugr(variants) + out_ty = SumType([row_to_type(row) for row in variants]) return self.add_node( - ops.Tag(tag=tag, variants=types), None, [SumType(variants)], parent, [inp] + ops.OpType(ops.Tag(tag=tag, variants=hugr_variants, parent=UNDEFINED)), + None, + [out_ty], + parent, + inputs, ) def add_load_constant( @@ -480,23 +534,50 @@ def add_load_constant( ) -> VNode: """Adds a `LoadConstant` node to the graph.""" return self.add_node( - ops.LoadConstant(datatype=const_port.ty.to_hugr()), + ops.OpType( + ops.LoadConstant(datatype=const_port.ty.to_hugr(), parent=UNDEFINED) + ), None, [const_port.ty], parent, [const_port], ) + def add_load_function( + self, def_port: OutPortV, inst: Inst, parent: Node | None = None + ) -> VNode: + """Adds a `LoadFunction` node to the graph.""" + assert isinstance(def_port.ty, FunctionType) + assert len(def_port.ty.params) == len(inst) + instantiation = def_port.ty.instantiate(inst) + op = ops.LoadFunction( + func_sig=def_port.ty.to_hugr_poly(), + type_args=[arg.to_hugr() for arg in inst], + signature=tys.FunctionType(input=[], output=[instantiation.to_hugr()]), + parent=UNDEFINED, + ) + return self.add_node(ops.OpType(op), None, [instantiation], parent, [def_port]) + def add_call( - self, def_port: OutPortV, args: list[OutPortV], parent: Node | None = None + self, + def_port: OutPortV, + args: list[OutPortV], + inst: Inst, + parent: Node | None = None, ) -> VNode: """Adds a `Call` node to the graph.""" assert isinstance(def_port.ty, FunctionType) - + instantiation = def_port.ty.instantiate(inst) + op = ops.Call( + func_sig=def_port.ty.to_hugr_poly(), + type_args=[arg.to_hugr() for arg in inst], + instantiation=instantiation.to_hugr().root, + parent=UNDEFINED, + ) return self.add_node( - ops.Call(), + ops.OpType(op), None, - list(type_to_row(def_port.ty.output)), + list(type_to_row(instantiation.output)), parent, [*args, def_port], ) @@ -508,7 +589,7 @@ def add_indirect_call( assert isinstance(fun_port.ty, FunctionType) return self.add_node( - ops.CallIndirect(), + ops.OpType(ops.CallIndirect(parent=UNDEFINED)), None, list(type_to_row(fun_port.ty.output)), parent, @@ -530,37 +611,20 @@ def add_partial( else None, ) return self.add_node( - ops.DummyOp(name="partial"), None, [new_ty], parent, [*inputs, def_port] - ) - - def add_type_apply( - self, func_port: OutPortV, args: Inst, parent: Node | None = None - ) -> VNode: - """Adds a `TypeApply` node to the graph.""" - assert isinstance(func_port.ty, FunctionType) - assert len(func_port.ty.params) == len(args) - result_ty = func_port.ty.instantiate(args) - ta = ops.TypeApplication( - input=func_port.ty.to_hugr(), - args=[arg.to_hugr() for arg in args], - output=result_ty.to_hugr(), - ) - return self.add_node( - ops.TypeApply(ta=ta), - inputs=[func_port], - output_types=[result_ty], - parent=parent, + DummyOp("partial"), None, [new_ty], parent, [*inputs, def_port] ) def add_def( self, fun_ty: FunctionType, parent: Node | None, name: str ) -> DFContainingVNode: - """Adds a `Def` node to the graph.""" - return self._add_dfg_node(ops.FuncDefn(name=name), [], [fun_ty], parent, None) + """Adds a `FucnDefn` node to the graph.""" + op = ops.FuncDefn(name=name, signature=fun_ty.to_hugr_poly(), parent=UNDEFINED) + return self._add_dfg_node(ops.OpType(op), [], [fun_ty], parent, None) def add_declare(self, fun_ty: FunctionType, parent: Node, name: str) -> VNode: - """Adds a `Declare` node to the graph.""" - return self.add_node(ops.FuncDecl(name=name), [], [fun_ty], parent, None) + """Adds a `FuncDecl` node to the graph.""" + op = ops.FuncDecl(name=name, signature=fun_ty.to_hugr_poly(), parent=UNDEFINED) + return self.add_node(ops.OpType(op), [], [fun_ty], parent, None) def add_edge(self, src_port: OutPort, tgt_port: InPort) -> None: """Adds an edge between two ports.""" @@ -664,7 +728,7 @@ def remove_dummy_nodes(self) -> "Hugr": raise ValueError("Dummy node removal requires a module root node") used_names: dict[str, int] = {} for n in list(self.nodes()): - if isinstance(n, VNode) and isinstance(n.op, ops.DummyOp): + if isinstance(n, VNode) and isinstance(n.op, DummyOp): name = n.op.name fun_ty = FunctionType( list(n.in_port_types), row_to_type(n.out_port_types) @@ -675,46 +739,27 @@ def remove_dummy_nodes(self) -> "Hugr": else: used_names[name] = 0 decl = self.add_declare(fun_ty, self.root, name) - n.op = ops.Call() + n.op = ops.OpType( + ops.Call( + func_sig=fun_ty.to_hugr_poly(), + type_args=[], + instantiation=fun_ty.to_hugr().root, + parent=UNDEFINED, + ) + ) self.add_edge(decl.out_port(0), n.add_in_port(fun_ty)) return self def insert_order_edges(self) -> "Hugr": - """Adds state edges to all dataflow ops without inputs outputs. + """Adds order edges to the source and target inter-graph edges. - We add state edges connecting them to the input or output node of the DFG. - This action must be performed before serialisation. + This ensures that the source is executed before the target. This action must be + performed before serialisation. """ - for n in self.nodes(): - if isinstance(n.op, ops.DataflowOp) and isinstance( - n.parent, DFContainingNode - ): - if all( - next(self.in_edges(p), None) is None for p in n.in_ports - ) and not isinstance(n.op, ops.Input): - assert n.parent.input_child is not None - self.add_order_edge(n.parent.input_child, n) - if all( - next(self.out_edges(p), None) is None for p in n.out_ports - ) and not isinstance(n.op, ops.Output): - assert n.parent.output_child is not None - self.add_order_edge(n, n.parent.output_child) - # Special case: Call ops for functions without any arguments are - # only connected to the top-level def/declare and also need an - # order edge - if isinstance(n.op, ops.Call) and n.num_in_ports == 1: # noqa: SIM114 - assert n.parent.input_child is not None - self.add_order_edge(n.parent.input_child, n) - # Special case: Load constant ops always need an order edge - elif isinstance(n.op, ops.LoadConstant): - assert n.parent.input_child is not None - self.add_order_edge(n.parent.input_child, n) - - # Also add order edges for non-local edges for src, tgt in list(self.edges()): # Exclude CF and constant edges if isinstance(src, OutPortCF) or isinstance( - src.node.op, ops.FuncDecl | ops.FuncDefn | ops.Const + src.node.op.root, ops.FuncDecl | ops.FuncDefn | ops.Const ): continue @@ -730,8 +775,11 @@ def insert_order_edges(self) -> "Hugr": self.add_order_edge(src.node, node) return self - def to_raw(self) -> raw.RawHugr: + def to_raw(self) -> SerialHugr: """Returns the raw representation of this HUGR for serialisation.""" + if self.root is None: + raise ValueError("Serial Hugr requires a root node") + self.remove_dummy_nodes() self.insert_order_edges() # Hugr requires that Input/Output nodes are the first/second children in a DFG. @@ -746,23 +794,29 @@ def to_raw(self) -> raw.RawHugr: indices = itertools.count() raw_index: dict[int, ops.NodeID] = {} all_nodes = self.nodes() - root_node = next(all_nodes) for n in all_nodes: - if isinstance(n.op, ops.Input): - input_nodes.append(n) - elif isinstance(n.op, ops.Output): - output_nodes.append(n) - elif ( - isinstance(n.op, ops.DataflowBlock) - and next(self.in_edges(n.in_port(None)), None) is None - ): - entry_nodes.append(n) - elif isinstance(n.op, ops.ExitBlock): - exit_nodes.append(n) - else: - remaining_nodes.append(n) + if n is self.root: + continue + match n.op.root: + case ops.Input(): + input_nodes.append(n) + case ops.Output(): + output_nodes.append(n) + # We can detect entry BBs by looking for BBs without incoming edges + # since Guppy will never generate an edge pointing back to the entry. + # Also, Guppy errors on unreachable code, so we will never generate + # interior BBs without incoming edges. Hence, there are also no false + # positives. + case ops.DataflowBlock() if next( + self.in_edges(n.in_port(None)), None + ) is None: + entry_nodes.append(n) + case ops.ExitBlock(): + exit_nodes.append(n) + case _: + remaining_nodes.append(n) for n in itertools.chain( - iter([root_node]), + iter([self.root]), iter(entry_nodes), iter(exit_nodes), iter(input_nodes), @@ -771,13 +825,15 @@ def to_raw(self) -> raw.RawHugr: ): raw_index[n.idx] = next(indices) - nodes: list[ops.OpType] = [ops.Module()] * self._graph.number_of_nodes() + nodes: list[ops.OpType] = [ + ops.OpType(ops.Module(parent=UNDEFINED)) + ] * self._graph.number_of_nodes() for n in self.nodes(): idx = raw_index[n.idx] # Nodes without parent have themselves as parent in the serialised format parent = n.parent or n n.update_op() - n.op.parent = raw_index[parent.idx] + n.op.root.parent = raw_index[parent.idx] nodes[idx] = n.op edges: list[raw.Edge] = [] @@ -792,9 +848,7 @@ def to_raw(self) -> raw.RawHugr: for src, tgt in self.order_edges(): edges.append(((raw_index[src.idx], None), (raw_index[tgt.idx], None))) - if self.root is None: - raise ValueError("Raw Hugr requires a root node") - return raw.RawHugr(nodes=nodes, edges=edges) + return SerialHugr(nodes=nodes, edges=edges) def serialize(self) -> str: """Serialize this Hugr in JSON format.""" diff --git a/guppylang/hugr/visualise.py b/guppylang/hugr_builder/visualise.py similarity index 94% rename from guppylang/hugr/visualise.py rename to guppylang/hugr_builder/visualise.py index bf47e540..c9b50920 100644 --- a/guppylang/hugr/visualise.py +++ b/guppylang/hugr_builder/visualise.py @@ -12,7 +12,7 @@ MaybeAssignmentDomain, ) from guppylang.cfg.bb import BB -from guppylang.hugr.hugr import Hugr, InPort, Node, OutPort, OutPortV +from guppylang.hugr_builder.hugr import DummyOp, Hugr, InPort, Node, OutPort, OutPortV if TYPE_CHECKING: from guppylang.cfg.cfg import CFG @@ -63,13 +63,8 @@ - - - +
- - {node_label}{node_data} - -
{node_label}{node_data}
@@ -172,7 +167,7 @@ def viz_node(node: Node, hugr: Hugr, graph: gv.Digraph) -> None: viz_node(child, hugr, sub) html_label = _format_html_label( node_back_color=_COLOURS["edge"], - node_label=node.op.display_name(), + node_label=node.op.root.display_name(), node_data=data, border_colour=_COLOURS["port_border"], inputs_row=_html_ports(in_ports, _INPUT_PREFIX) @@ -187,7 +182,9 @@ def viz_node(node: Node, hugr: Hugr, graph: gv.Digraph) -> None: else: html_label = _format_html_label( node_back_color=_COLOURS["node"], - node_label=node.op.display_name(), + node_label=node.op.name + if isinstance(node.op, DummyOp) + else node.op.root.display_name(), node_data=data, inputs_row=_html_ports(in_ports, _INPUT_PREFIX) if len(in_ports) > 0 diff --git a/guppylang/module.py b/guppylang/module.py index dacc89d6..2e4025ef 100644 --- a/guppylang/module.py +++ b/guppylang/module.py @@ -22,7 +22,7 @@ from guppylang.definition.parameter import TypeVarDef from guppylang.definition.ty import TypeDef from guppylang.error import GuppyError, pretty_errors -from guppylang.hugr.hugr import Hugr +from guppylang.hugr_builder.hugr import Hugr PyFunc = Callable[..., Any] PyFuncDefOrDecl = tuple[bool, PyFunc] diff --git a/guppylang/prelude/_internal.py b/guppylang/prelude/_internal.py index f4bc1ee2..72507f80 100644 --- a/guppylang/prelude/_internal.py +++ b/guppylang/prelude/_internal.py @@ -1,6 +1,6 @@ import ast -from typing import Any, Literal +from hugr.serialization import ops, tys from pydantic import BaseModel from guppylang.ast_util import AstNode, get_type, with_loc, with_type @@ -15,93 +15,120 @@ from guppylang.definition.ty import TypeDef from guppylang.definition.value import CallableDef from guppylang.error import GuppyError, GuppyTypeError -from guppylang.hugr import ops, tys, val -from guppylang.hugr.hugr import OutPortV +from guppylang.hugr_builder.hugr import UNDEFINED, OutPortV from guppylang.nodes import GlobalCall -from guppylang.tys.builtin import bool_type +from guppylang.tys.builtin import bool_type, list_type from guppylang.tys.subst import Subst from guppylang.tys.ty import FunctionType, OpaqueType, Type, unify INT_WIDTH = 6 # 2^6 = 64 bit -hugr_int_type = tys.Opaque( - extension="arithmetic.int.types", - id="int", - args=[tys.BoundedNatArg(n=INT_WIDTH)], - bound=tys.TypeBound.Eq, +hugr_int_type = tys.Type( + tys.Opaque( + extension="arithmetic.int.types", + id="int", + args=[tys.TypeArg(tys.BoundedNatArg(n=INT_WIDTH))], + bound=tys.TypeBound.Eq, + ) ) -hugr_float_type = tys.Opaque( - extension="arithmetic.float.types", - id="float64", - args=[], - bound=tys.TypeBound.Copyable, +hugr_float_type = tys.Type( + tys.Opaque( + extension="arithmetic.float.types", + id="float64", + args=[], + bound=tys.TypeBound.Copyable, + ) ) -class ConstIntS(BaseModel): - """Hugr representation of signed integers in the arithmetic extension.""" +class ConstInt(BaseModel): + """Hugr representation of signed and unsigned integers in the arithmetic extension. + + Hugr always uses a u64 for the value. The interpretation is: + - as an unsigned integer, (value mod `2^N`); + - as a signed integer, (value mod `2^(N-1) - 2^(N-1)*a`) + where `N = 2^log_width` and `a` is the (N-1)th bit of `x` (counting from 0 = least + significant bit). + """ - c: Literal["ConstIntS"] = "ConstIntS" log_width: int value: int -class ConstF64(BaseModel): - """Hugr representation of floats in the arithmetic extension.""" - - c: Literal["ConstF64"] = "ConstF64" - value: float - - -class ListValue(BaseModel): - """Hugr representation of floats in the arithmetic extension.""" - - c: Literal["ListValue"] = "ListValue" - value: tuple[list[Any], tys.Type] - - -def bool_value(b: bool) -> val.Value: +def bool_value(b: bool) -> ops.Value: """Returns the Hugr representation of a boolean value.""" - return val.Sum(tag=int(b), value=val.Tuple(vs=[])) + unit = ops.Value(ops.TupleValue(vs=[])) + return ops.Value( + ops.SumValue(tag=int(b), typ=tys.SumType(tys.UnitSum(size=2)), vs=[unit]) + ) -def int_value(i: int) -> val.Value: +def int_value(i: int) -> ops.Value: """Returns the Hugr representation of an integer value.""" - return val.ExtensionVal(c=(ConstIntS(log_width=INT_WIDTH, value=i),)) + return ops.Value( + ops.ExtensionValue( + extensions=["arithmetic.int.types"], + typ=hugr_int_type, + value=ops.CustomConst( + c="ConstInt", v=ConstInt(log_width=INT_WIDTH, value=i) + ), + ) + ) -def float_value(f: float) -> val.Value: +def float_value(f: float) -> ops.Value: """Returns the Hugr representation of a float value.""" - return val.ExtensionVal(c=(ConstF64(value=f),)) + return ops.Value( + ops.ExtensionValue( + extensions=["arithmetic.float.types"], + typ=hugr_float_type, + value=ops.CustomConst(c="ConstF64", v=f), + ) + ) -def list_value(v: list[val.Value], ty: tys.Type) -> val.Value: +def list_value(v: list[ops.Value], ty: Type) -> ops.Value: """Returns the Hugr representation of a list value.""" - return val.ExtensionVal(c=(ListValue(value=(v, ty)),)) + return ops.Value( + ops.ExtensionValue( + extensions=["Collections"], + typ=list_type(ty).to_hugr(), + value=ops.CustomConst(c="ListValue", v=(v, ty.to_hugr())), + ) + ) def logic_op(op_name: str, args: list[tys.TypeArg] | None = None) -> ops.OpType: """Utility method to create Hugr logic ops.""" - return ops.CustomOp(extension="logic", op_name=op_name, args=args or []) + return ops.OpType( + ops.CustomOp( + extension="logic", op_name=op_name, args=args or [], parent=UNDEFINED + ) + ) def int_op( op_name: str, ext: str = "arithmetic.int", num_params: int = 1 ) -> ops.OpType: """Utility method to create Hugr integer arithmetic ops.""" - return ops.CustomOp( - extension=ext, - op_name=op_name, - args=num_params * [tys.BoundedNatArg(n=INT_WIDTH)], + return ops.OpType( + ops.CustomOp( + extension=ext, + op_name=op_name, + args=num_params * [tys.TypeArg(tys.BoundedNatArg(n=INT_WIDTH))], + parent=UNDEFINED, + ) ) def float_op(op_name: str, ext: str = "arithmetic.float") -> ops.OpType: """Utility method to create Hugr integer arithmetic ops.""" - return ops.CustomOp(extension=ext, op_name=op_name, args=[]) + return ops.OpType( + ops.CustomOp(extension=ext, op_name=op_name, args=[], parent=UNDEFINED) + ) class CoercingChecker(DefaultCallChecker): diff --git a/guppylang/prelude/builtins.py b/guppylang/prelude/builtins.py index 58cb51df..1d017fe6 100644 --- a/guppylang/prelude/builtins.py +++ b/guppylang/prelude/builtins.py @@ -2,9 +2,11 @@ # mypy: disable-error-code="empty-body, misc, override, valid-type, no-untyped-def" +from hugr.serialization import tys + from guppylang.decorator import guppy from guppylang.definition.custom import DefaultCallChecker, NoopCompiler -from guppylang.hugr import ops, tys +from guppylang.hugr_builder.hugr import DummyOp from guppylang.module import GuppyModule from guppylang.prelude._internal import ( CallableChecker, @@ -34,7 +36,7 @@ @guppy.extend_type(builtins, bool_type_def) class Bool: - @guppy.hugr_op(builtins, logic_op("And", [tys.BoundedNatArg(n=2)])) + @guppy.hugr_op(builtins, logic_op("And", [tys.TypeArg(tys.BoundedNatArg(n=2))])) def __and__(self: bool, other: bool) -> bool: ... @guppy.custom(builtins, NoopCompiler()) @@ -46,7 +48,7 @@ def __int__(self: bool) -> int: ... @guppy.custom(builtins, checker=DunderChecker("__bool__"), higher_order_value=False) def __new__(x): ... - @guppy.hugr_op(builtins, logic_op("Or", [tys.BoundedNatArg(n=2)])) + @guppy.hugr_op(builtins, logic_op("Or", [tys.TypeArg(tys.BoundedNatArg(n=2))])) def __or__(self: bool, other: bool) -> bool: ... @@ -124,7 +126,7 @@ def __or__(self: int, other: int) -> int: ... @guppy.custom(builtins, NoopCompiler()) def __pos__(self: int) -> int: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="ipow")) # TODO + @guppy.hugr_op(builtins, DummyOp("ipow")) # TODO def __pow__(self: int, other: int) -> int: ... @guppy.hugr_op(builtins, int_op("iadd"), ReversingChecker()) @@ -156,7 +158,7 @@ def __ror__(self: int, other: int) -> int: ... @guppy.custom(builtins, NoopCompiler()) def __round__(self: int) -> int: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="ipow"), ReversingChecker()) # TODO + @guppy.hugr_op(builtins, DummyOp("ipow"), ReversingChecker()) # TODO def __rpow__(self: int, other: int) -> int: ... @guppy.hugr_op( @@ -255,7 +257,7 @@ def __new__(x): ... @guppy.custom(builtins, NoopCompiler(), CoercingChecker()) def __pos__(self: float) -> float: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="fpow")) # TODO + @guppy.hugr_op(builtins, DummyOp("fpow")) # TODO def __pow__(self: float, other: float) -> float: ... @guppy.hugr_op(builtins, float_op("fadd"), ReversingChecker(CoercingChecker())) @@ -275,11 +277,11 @@ def __rmod__(self: float, other: float) -> float: ... @guppy.hugr_op(builtins, float_op("fmul"), ReversingChecker(CoercingChecker())) def __rmul__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="fround")) # TODO + @guppy.hugr_op(builtins, DummyOp("fround")) # TODO def __round__(self: float) -> float: ... @guppy.hugr_op( - builtins, ops.DummyOp(name="fpow"), ReversingChecker(DefaultCallChecker()) + builtins, DummyOp("fpow"), ReversingChecker(DefaultCallChecker()) ) # TODO def __rpow__(self: float, other: float) -> float: ... @@ -303,34 +305,34 @@ def __trunc__(self: float) -> float: ... @guppy.extend_type(builtins, list_type_def) class List: - @guppy.hugr_op(builtins, ops.DummyOp(name="Concat")) + @guppy.hugr_op(builtins, DummyOp("Concat")) def __add__(self: list[T], other: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="IsEmpty")) + @guppy.hugr_op(builtins, DummyOp("IsEmpty")) def __bool__(self: list[T]) -> bool: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Contains")) + @guppy.hugr_op(builtins, DummyOp("Contains")) def __contains__(self: list[T], el: T) -> bool: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="AssertEmpty")) + @guppy.hugr_op(builtins, DummyOp("AssertEmpty")) def __end__(self: list[T]) -> None: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Lookup")) + @guppy.hugr_op(builtins, DummyOp("Lookup")) def __getitem__(self: list[T], idx: int) -> T: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="IsNonEmpty")) + @guppy.hugr_op(builtins, DummyOp("IsNonEmpty")) def __hasnext__(self: list[T]) -> tuple[bool, list[T]]: ... @guppy.custom(builtins, NoopCompiler()) def __iter__(self: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Length")) + @guppy.hugr_op(builtins, DummyOp("Length")) def __len__(self: list[T]) -> int: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Repeat")) + @guppy.hugr_op(builtins, DummyOp("Repeat")) def __mul__(self: list[T], other: int) -> list[T]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Pop")) + @guppy.hugr_op(builtins, DummyOp("Pop")) def __next__(self: list[T]) -> tuple[T, list[T]]: ... @guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) @@ -339,10 +341,10 @@ def __new__(x): ... @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) def __setitem__(self: list[T], idx: int, value: T) -> None: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Append"), ReversingChecker()) + @guppy.hugr_op(builtins, DummyOp("Append"), ReversingChecker()) def __radd__(self: list[T], other: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Repeat"), ReversingChecker()) + @guppy.hugr_op(builtins, DummyOp("Repeat"), ReversingChecker()) def __rmul__(self: list[T], other: int) -> list[T]: ... @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) @@ -354,13 +356,13 @@ def clear(self: list[T]) -> None: ... @guppy.custom(builtins, NoopCompiler()) # Can be noop since lists are immutable def copy(self: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Count")) + @guppy.hugr_op(builtins, DummyOp("Count")) def count(self: list[T], elt: T) -> int: ... @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) def extend(self: list[T], seq: None) -> None: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Find")) + @guppy.hugr_op(builtins, DummyOp("Find")) def index(self: list[T], elt: T) -> int: ... @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) @@ -381,40 +383,40 @@ def sort(self: list[T]) -> None: ... @guppy.extend_type(builtins, linst_type_def) class Linst: - @guppy.hugr_op(builtins, ops.DummyOp(name="Append")) + @guppy.hugr_op(builtins, DummyOp("Append")) def __add__(self: linst[L], other: linst[L]) -> linst[L]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="AssertEmpty")) + @guppy.hugr_op(builtins, DummyOp("AssertEmpty")) def __end__(self: linst[L]) -> None: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="IsNonempty")) + @guppy.hugr_op(builtins, DummyOp("IsNonempty")) def __hasnext__(self: linst[L]) -> tuple[bool, linst[L]]: ... @guppy.custom(builtins, NoopCompiler()) def __iter__(self: linst[L]) -> linst[L]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Length")) + @guppy.hugr_op(builtins, DummyOp("Length")) def __len__(self: linst[L]) -> tuple[int, linst[L]]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Pop")) + @guppy.hugr_op(builtins, DummyOp("Pop")) def __next__(self: linst[L]) -> tuple[L, linst[L]]: ... @guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) def __new__(x): ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Append"), ReversingChecker()) + @guppy.hugr_op(builtins, DummyOp("Append"), ReversingChecker()) def __radd__(self: linst[L], other: linst[L]) -> linst[L]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Repeat"), ReversingChecker()) + @guppy.hugr_op(builtins, DummyOp("Repeat"), ReversingChecker()) def __rmul__(self: linst[L], other: int) -> linst[L]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Push")) + @guppy.hugr_op(builtins, DummyOp("Push")) def append(self: linst[L], elt: L) -> linst[L]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="PopAt")) + @guppy.hugr_op(builtins, DummyOp("PopAt")) def pop(self: linst[L], idx: int) -> tuple[L, linst[L]]: ... - @guppy.hugr_op(builtins, ops.DummyOp(name="Reverse")) + @guppy.hugr_op(builtins, DummyOp("Reverse")) def reverse(self: linst[L]) -> linst[L]: ... @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) diff --git a/guppylang/prelude/quantum.py b/guppylang/prelude/quantum.py index 16e0f638..15e8d011 100644 --- a/guppylang/prelude/quantum.py +++ b/guppylang/prelude/quantum.py @@ -2,9 +2,11 @@ # mypy: disable-error-code="empty-body, misc" +from hugr.serialization import ops, tys +from hugr.serialization.tys import TypeBound + from guppylang.decorator import guppy -from guppylang.hugr import ops, tys -from guppylang.hugr.tys import TypeBound +from guppylang.hugr_builder.hugr import UNDEFINED from guppylang.module import GuppyModule from guppylang.prelude._internal import MeasureCompiler @@ -13,12 +15,16 @@ def quantum_op(op_name: str) -> ops.OpType: """Utility method to create Hugr quantum ops.""" - return ops.CustomOp(extension="quantum.tket2", op_name=op_name, args=[]) + return ops.OpType( + ops.CustomOp( + extension="quantum.tket2", op_name=op_name, args=[], parent=UNDEFINED + ) + ) @guppy.type( quantum, - tys.Opaque(extension="prelude", id="qubit", args=[], bound=TypeBound.Any), + tys.Type(tys.Opaque(extension="prelude", id="qubit", args=[], bound=TypeBound.Any)), linear=True, ) class qubit: diff --git a/guppylang/tys/arg.py b/guppylang/tys/arg.py index ddcd7a71..1b782e6f 100644 --- a/guppylang/tys/arg.py +++ b/guppylang/tys/arg.py @@ -2,7 +2,8 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, TypeAlias -from guppylang.hugr import tys +from hugr.serialization import tys + from guppylang.tys.common import ToHugr, Transformable, Transformer, Visitor from guppylang.tys.const import Const from guppylang.tys.var import ExistentialVar @@ -47,7 +48,7 @@ def unsolved_vars(self) -> set[ExistentialVar]: def to_hugr(self) -> tys.TypeArg: """Computes the Hugr representation of the argument.""" - return tys.TypeTypeArg(ty=self.ty.to_hugr()) + return tys.TypeArg(tys.TypeTypeArg(ty=self.ty.to_hugr())) def visit(self, visitor: Visitor) -> None: """Accepts a visitor on this argument.""" diff --git a/guppylang/tys/builtin.py b/guppylang/tys/builtin.py index 54461471..2c984496 100644 --- a/guppylang/tys/builtin.py +++ b/guppylang/tys/builtin.py @@ -2,11 +2,12 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, Literal +from hugr.serialization import tys + from guppylang.ast_util import AstNode from guppylang.definition.common import DefId from guppylang.definition.ty import OpaqueTypeDef, TypeDef from guppylang.error import GuppyError -from guppylang.hugr import tys from guppylang.tys.arg import Argument, TypeArg from guppylang.tys.param import TypeParam from guppylang.tys.ty import FunctionType, NoneType, OpaqueType, TupleType, Type @@ -98,15 +99,17 @@ def check_instantiate( return super().check_instantiate(args, globals, loc) -def _list_to_hugr(args: Sequence[Argument]) -> tys.Opaque: - return tys.Opaque( +def _list_to_hugr(args: Sequence[Argument]) -> tys.Type: + # Type checker ensures that we get a single arg of kind type + [arg] = args + assert isinstance(arg, TypeArg) + ty = tys.Opaque( extension="Collections", id="List", - args=[arg.to_hugr() for arg in args], - bound=tys.TypeBound.join( - *(arg.ty.hugr_bound for arg in args if isinstance(arg, TypeArg)) - ), + args=[arg.to_hugr()], + bound=arg.ty.hugr_bound, ) + return tys.Type(ty) callable_type_def = _CallableTypeDef(DefId.fresh(), None) @@ -118,7 +121,7 @@ def _list_to_hugr(args: Sequence[Argument]) -> tys.Opaque: defined_at=None, params=[], always_linear=False, - to_hugr=lambda _: tys.UnitSum(size=2), + to_hugr=lambda _: tys.Type(tys.SumType(tys.UnitSum(size=2))), ) linst_type_def = OpaqueTypeDef( id=DefId.fresh(), diff --git a/guppylang/tys/const.py b/guppylang/tys/const.py index 3d2feacb..358490cc 100644 --- a/guppylang/tys/const.py +++ b/guppylang/tys/const.py @@ -2,8 +2,9 @@ from dataclasses import dataclass from typing import TYPE_CHECKING +from hugr.serialization import ops + from guppylang.error import InternalGuppyError -from guppylang.hugr import val from guppylang.tys.var import BoundVar, ExistentialVar if TYPE_CHECKING: @@ -36,7 +37,7 @@ class ConstValue(Const): # Hugr encoding of the value # TODO: We might need a Guppy representation of this... - value: val.Value + value: ops.Value @dataclass(frozen=True) diff --git a/guppylang/tys/param.py b/guppylang/tys/param.py index 8b53bfee..0e5a2d11 100644 --- a/guppylang/tys/param.py +++ b/guppylang/tys/param.py @@ -3,12 +3,12 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, TypeAlias +from hugr.serialization import tys +from hugr.serialization.tys import TypeBound from typing_extensions import Self from guppylang.ast_util import AstNode from guppylang.error import GuppyError, GuppyTypeError, InternalGuppyError -from guppylang.hugr import tys -from guppylang.hugr.tys import TypeBound from guppylang.tys.arg import Argument, ConstArg, TypeArg from guppylang.tys.common import ToHugr from guppylang.tys.var import ExistentialVar @@ -122,8 +122,10 @@ def to_bound(self, idx: int | None = None) -> Argument: def to_hugr(self) -> tys.TypeParam: """Computes the Hugr representation of the parameter.""" - return tys.TypeTypeParam( - b=tys.TypeBound.Any if self.can_be_linear else TypeBound.Copyable + return tys.TypeParam( + tys.TypeTypeParam( + b=tys.TypeBound.Any if self.can_be_linear else TypeBound.Copyable + ) ) diff --git a/guppylang/tys/ty.py b/guppylang/tys/ty.py index c4d4bfd9..5b176120 100644 --- a/guppylang/tys/ty.py +++ b/guppylang/tys/ty.py @@ -4,9 +4,10 @@ from functools import cached_property from typing import TYPE_CHECKING, TypeAlias, cast +from hugr.serialization import tys +from hugr.serialization.tys import TypeBound + from guppylang.error import InternalGuppyError -from guppylang.hugr import tys -from guppylang.hugr.tys import TypeBound from guppylang.tys.arg import Argument, ConstArg, TypeArg from guppylang.tys.common import ToHugr, Transformable, Transformer, Visitor from guppylang.tys.const import ExistentialConstVar @@ -149,7 +150,7 @@ def hugr_bound(self) -> tys.TypeBound: def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" - return tys.Variable(i=self.idx, b=self.hugr_bound) + return tys.Type(tys.Variable(i=self.idx, b=self.hugr_bound)) def visit(self, visitor: Visitor) -> None: """Accepts a visitor on this type.""" @@ -222,7 +223,7 @@ class NoneType(TypeBase): def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" - return tys.TupleType(inner=[]) + return TupleType([]).to_hugr() def visit(self, visitor: Visitor) -> None: """Accepts a visitor on this type.""" @@ -270,10 +271,27 @@ def parametrized(self) -> bool: def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" + if self.parametrized: + raise InternalGuppyError( + "Tried to convert parametrised function type to Hugr. Use " + "`to_hugr_poly` instead" + ) + return tys.Type(self._to_hugr_function_type()) + + def to_hugr_poly(self) -> tys.PolyFuncType: + """Computes the Hugr `PolyFuncType` representation of the type.""" + func_ty = self._to_hugr_function_type() + return tys.PolyFuncType(params=[p.to_hugr() for p in self.params], body=func_ty) + + def _to_hugr_function_type(self) -> tys.FunctionType: + """Helper method to compute the Hugr `FunctionType` representation of the type. + + The resulting `FunctionType` can then be embedded into a Hugr `Type` or a Hugr + `PolyFuncType`. + """ ins = [t.to_hugr() for t in self.inputs] outs = [t.to_hugr() for t in type_to_row(self.output)] - func_ty = tys.FunctionType(input=ins, output=outs, extension_reqs=[]) - return tys.PolyFuncType(params=[p.to_hugr() for p in self.params], body=func_ty) + return tys.FunctionType(input=ins, output=outs) def visit(self, visitor: Visitor) -> None: """Accepts a visitor on this type.""" @@ -346,7 +364,12 @@ def intrinsically_linear(self) -> bool: def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" - return tys.TupleType(inner=[ty.to_hugr() for ty in self.element_types]) + # Tuples are encoded as a unary sum. Note that we need to make a copy of this + # tuple with `preserve=False` to ensure that it can be broken up into a row (if + # this tuple was created by instantiating a type variable, it is still + # represented as a *row* sum). + tuple_ty = TupleType(self.element_types, preserve=False) + return SumType([tuple_ty]).to_hugr() def transform(self, transformer: Transformer) -> "Type": """Accepts a transformer on this type.""" @@ -377,12 +400,13 @@ def intrinsically_linear(self) -> bool: def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" - if all( - isinstance(e, TupleType) and len(e.element_types) == 0 - for e in self.element_types - ): - return tys.UnitSum(size=len(self.element_types)) - return tys.GeneralSum(row=[t.to_hugr() for t in self.element_types]) + rows = [type_to_row(ty) for ty in self.element_types] + sum_inner: tys.UnitSum | tys.GeneralSum + if all(len(row) == 0 for row in rows): + sum_inner = tys.UnitSum(size=len(rows)) + else: + sum_inner = tys.GeneralSum(rows=rows_to_hugr(rows)) + return tys.Type(tys.SumType(sum_inner)) def transform(self, transformer: Transformer) -> "Type": """Accepts a transformer on this type.""" @@ -446,8 +470,7 @@ def intrinsically_linear(self) -> bool: def to_hugr(self) -> tys.Type: """Computes the Hugr representation of the type.""" - - return tys.TupleType(inner=[f.ty.to_hugr() for f in self.fields]) + return TupleType([f.ty for f in self.fields]).to_hugr() def transform(self, transformer: Transformer) -> "Type": """Accepts a transformer on this type.""" @@ -495,6 +518,16 @@ def type_to_row(ty: Type) -> TypeRow: return [ty] +def row_to_hugr(row: TypeRow) -> tys.TypeRow: + """Computes the Hugr representation of a type row.""" + return [ty.to_hugr() for ty in row] + + +def rows_to_hugr(rows: Sequence[TypeRow]) -> list[tys.TypeRow]: + """Computes the Hugr representation of a sequence of rows.""" + return [row_to_hugr(row) for row in rows] + + def unify(s: Type, t: Type, subst: "Subst | None") -> "Subst | None": """Computes a most general unifier for two types. diff --git a/poetry.lock b/poetry.lock index 3aa89a53..1a1f633e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -38,13 +38,13 @@ files = [ [[package]] name = "babel" -version = "2.14.0" +version = "2.15.0" description = "Internationalization utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] [package.extras] @@ -205,63 +205,63 @@ files = [ [[package]] name = "coverage" -version = "7.4.3" +version = "7.5.1" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, - {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, - {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, - {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, - {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, - {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, - {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, - {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, - {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, - {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, - {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, - {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, - {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, - {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, + {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, + {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, + {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, + {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, + {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, + {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, + {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, + {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, + {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, + {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, + {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, + {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, + {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, + {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, ] [package.dependencies] @@ -283,24 +283,24 @@ files = [ [[package]] name = "docutils" -version = "0.20.1" +version = "0.21.2" description = "Docutils -- Python Documentation Utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, + {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, + {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, ] [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -308,35 +308,35 @@ test = ["pytest (>=6)"] [[package]] name = "filelock" -version = "3.13.1" +version = "3.14.0" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, + {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] name = "graphviz" -version = "0.20.1" +version = "0.20.3" description = "Simple Python interface for Graphviz" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, - {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, + {file = "graphviz-0.20.3-py3-none-any.whl", hash = "sha256:81f848f2904515d8cd359cc611faba817598d2feaac4027b266aa3eda7b3dde5"}, + {file = "graphviz-0.20.3.zip", hash = "sha256:09d6bc81e6a9fa392e7ba52135a9d49f1ed62526f96499325930e87ca1b5925d"}, ] [package.extras] dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] -docs = ["sphinx (>=5)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] -test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>=3)"] +docs = ["sphinx (>=5,<7)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] +test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] [[package]] name = "guppyval" @@ -351,15 +351,29 @@ develop = false type = "directory" url = "validator" +[[package]] +name = "hugr" +version = "0.2.0a1" +description = "Quantinuum's common representation for quantum programs" +optional = false +python-versions = ">=3.10" +files = [ + {file = "hugr-0.2.0a1-py3-none-any.whl", hash = "sha256:1cb599e33aa12d3bee475bdf2304b38fcbdf05059bc32fc7cdcfaa596a6dde7f"}, + {file = "hugr-0.2.0a1.tar.gz", hash = "sha256:82d708f39615a345f1e10ea9560883734b93d91bda9ec878aeb8c33db0bbd712"}, +] + +[package.dependencies] +pydantic = ">=2.7.0,<2.8.0" + [[package]] name = "identify" -version = "2.5.35" +version = "2.5.36" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"}, - {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"}, + {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, + {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, ] [package.extras] @@ -502,24 +516,24 @@ files = [ [[package]] name = "maturin" -version = "1.4.0" +version = "1.5.1" description = "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" optional = false python-versions = ">=3.7" files = [ - {file = "maturin-1.4.0-py3-none-linux_armv6l.whl", hash = "sha256:b84bee85620e1b7b662a7af71289f7f6c23df8269e42c0f76882676dfc9c733f"}, - {file = "maturin-1.4.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:076970a73da7fa3648204a584cd347b899c1ea67f8124b212bccd06728e63ed9"}, - {file = "maturin-1.4.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f8eded83abdb30b2b6ae6d32c80b8192bdd8bcfec0ebfacee6ac02434aa499d6"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:ff95a4494d9e57b6e74d4d7f8a9a2ee8ed29bd7f0e61855656ad959a432c0efc"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:16239a7648ef17976585353e381840c18e650d352576ed9545abca407d65e534"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:77428c043d585f038f4b056c4d617e00a8027b49598ab6d065b8f6b9b9b8d144"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:b4b2f006db1e92687c814576029157dcc2d97b5750fd35fd4f3aabb97e36444f"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:ffe4e967080ceb83c156e73a37d3974b30cad01c376a86dc39a76a0c6bccf9b0"}, - {file = "maturin-1.4.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01473dc30aed8f2cee3572b3e99e3ea75bf09c84b028bf6077f7643a189699c8"}, - {file = "maturin-1.4.0-py3-none-win32.whl", hash = "sha256:e669ba5984c15e29b8545b295ba6738974180b44f47f5d9e75569a5ce6b8add5"}, - {file = "maturin-1.4.0-py3-none-win_amd64.whl", hash = "sha256:e2c1b157397ef3721b9c2f3f24d9a5a60bd84322aac13b4dd0704a80448741b0"}, - {file = "maturin-1.4.0-py3-none-win_arm64.whl", hash = "sha256:2979175a7eee837dc3a6931980b37ddc86b9ced54d600856668fc074ca2530ef"}, - {file = "maturin-1.4.0.tar.gz", hash = "sha256:ed12e1768094a7adeafc3a74ebdb8dc2201fa64c4e7e31f14cfc70378bf93790"}, + {file = "maturin-1.5.1-py3-none-linux_armv6l.whl", hash = "sha256:589e9b7024007e130b136ba6f1c2c8393a87e42cf968d12852913ab1e3c69ed3"}, + {file = "maturin-1.5.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a1abda07093b3c8ef897626166c02ed64e3e446c48460b28efb51833abf89cbb"}, + {file = "maturin-1.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:48a1fbbdc2514525f27d6d339ab97b098ede28759f8593d110c89cc07bbe40ed"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:96d96b1fa3a165db9ca539f764d31da8ebc92e31ca3a1dd6ccd50008d222bd96"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:786bf36a98c4e27cbebb1dc8e432c1bcbbb59e7a9719592cbb89e46a0ccd5bcc"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d821b37da759884ad09cfee4cd9deac10f4132744cc66e4d9190a1972233bc83"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:62133bf690555bbc8cc6b1c18a0c57b0ab2b4d68d3fcd320eb16df941563fe06"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:6bff165252b1fcc887679ddf7b71b5cc024327ba96ea893133be38c0ed38f163"}, + {file = "maturin-1.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c42a95466ffc3de0a3940cd20c57cf0c44fe5ea679375d73422afbb00236c64"}, + {file = "maturin-1.5.1-py3-none-win32.whl", hash = "sha256:d09538b4aa0da4b59fd47cb429003b45bfd5d801714adf1db2511bf8bdea532f"}, + {file = "maturin-1.5.1-py3-none-win_amd64.whl", hash = "sha256:a3db9054222ac79275e082b21cfd234b8e036714a4ff227a0a28f6a3ffa3744d"}, + {file = "maturin-1.5.1-py3-none-win_arm64.whl", hash = "sha256:acf528e51413f6ae489473d64116d8c83f140386349004949d29137c16a82193"}, + {file = "maturin-1.5.1.tar.gz", hash = "sha256:3dd834ece80edb866af18cbd4635e0ecac40139c726428d5f1849ae154b26dca"}, ] [package.dependencies] @@ -548,38 +562,38 @@ tests = ["pytest (>=4.6)"] [[package]] name = "mypy" -version = "1.8.0" +version = "1.10.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, ] [package.dependencies] @@ -606,20 +620,20 @@ files = [ [[package]] name = "networkx" -version = "3.2.1" +version = "3.3" description = "Python package for creating and manipulating graphs and networks" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, - {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, + {file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"}, + {file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9"}, ] [package.extras] -default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] @@ -683,39 +697,40 @@ files = [ [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, + {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -724,13 +739,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.6.2" +version = "3.7.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" files = [ - {file = "pre_commit-3.6.2-py2.py3-none-any.whl", hash = "sha256:ba637c2d7a670c10daedc059f5c49b5bd0aadbccfcd7ec15592cf9665117532c"}, - {file = "pre_commit-3.6.2.tar.gz", hash = "sha256:c3ef34f463045c88658c5b99f38c1e297abdcc0ff13f98d3370055fbbfabc67e"}, + {file = "pre_commit-3.7.0-py2.py3-none-any.whl", hash = "sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab"}, + {file = "pre_commit-3.7.0.tar.gz", hash = "sha256:e209d61b8acdcf742404408531f0c37d49d2c734fd7cff2d6076083d191cb060"}, ] [package.dependencies] @@ -742,18 +757,18 @@ virtualenv = ">=20.10.0" [[package]] name = "pydantic" -version = "2.7.0b1" +version = "2.7.1" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.0b1-py3-none-any.whl", hash = "sha256:c9cfcbfac6177f9e988fcffa727c42164ad03c3c8cd128057553c2d724fb6556"}, - {file = "pydantic-2.7.0b1.tar.gz", hash = "sha256:b0b45e2f249f7a304a8a3b724e03b206bd23ad584669fe31dbb3e38199fc9ff7"}, + {file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"}, + {file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.0" +pydantic-core = "2.18.2" typing-extensions = ">=4.6.1" [package.extras] @@ -761,90 +776,90 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.0" +version = "2.18.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c36ee17f0b85e98d5488a60bd4a022cb1e82f1995cc891bb371c1a15a52e5833"}, - {file = "pydantic_core-2.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3992d08de5ece507d334f166bd489eef46226ae26ecf890338a6bca710042d5e"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3e9cc290c91f300a435f7c8dca9ce8e492fb2f3c57dddef7aa8e56e5d33f962"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1d68106d504c34bc9971e6eca22ef603a95b4531449ee8460f136bc6a77dc7a3"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b5b8c26d5152be544ec9fcbac5087ffef1f3b831d0cba168016ac7e6063a29a"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84eee9cd65aadba8aa45d3a5f7ce09a9263d2c1788dbb6d40f4f5345f76f97a6"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac856c69bd2aefcaa1c29ebb7d3c191e9de7aad063284c1e760c43983ad18c3a"}, - {file = "pydantic_core-2.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b4a5de4867c582aa61ea7c83d977b9243c264c7e6c45d8b61dfb0f2bd243395"}, - {file = "pydantic_core-2.18.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6559ffbf66fae9d333aaf8c34b67e83912999781120c90e6aed59ae6077ed74f"}, - {file = "pydantic_core-2.18.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4e04cb00fdb79b6b8e1085d2152e1a2dfa21640f6a962476740e1542e07e8b0f"}, - {file = "pydantic_core-2.18.0-cp310-none-win32.whl", hash = "sha256:a83fd7a2983c9bb6bd1aec7257a8a96c29d48c30d9d8b8ae13a44155163dd42d"}, - {file = "pydantic_core-2.18.0-cp310-none-win_amd64.whl", hash = "sha256:5d8f4e95917439ba4398d9e2ce2be9f5840e91ea63ae018b3b148d48e99e99c1"}, - {file = "pydantic_core-2.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a99333701e0cf16ac8a646c92d5b9dc9f8cadd0a026f50bf0ddde34eede70bc3"}, - {file = "pydantic_core-2.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:647ce6122e6ae6b972076793851efd284c4b51b93ed4071d6735bcf44e663c03"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18b2dc6a2a027828377175613cfb3f69c40b347084886c2ca5bb1b713c3c0c1f"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8e179a23237f30452776ab3fd094fd0005f45615ab826c0bb077f5657f0e84db"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:569a28b5f7c5a1c9b9eea5b41f18f3e0235ec25212c4b7fa98add07e3b4fce2a"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca09d373225203c5849200019d7bb8fc50d4f466e9d10d67205c3e2da1221df6"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf5935716452b77a64e51f1344c34aab8c2e956ba32da9d038dc7f73e2262c7"}, - {file = "pydantic_core-2.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f5570b47048ad0421411e9bdf1b96eee8816aeaeea7c8db78877ecd9339685f"}, - {file = "pydantic_core-2.18.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a598c0786327db680ac04f8e5125cd4a729528713c09bb8fd0c40e66750bc89f"}, - {file = "pydantic_core-2.18.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7ee00b493cd28998d6cd6089e994f0cc08fed5113f5dd09b8bb8c27b5dc55c"}, - {file = "pydantic_core-2.18.0-cp311-none-win32.whl", hash = "sha256:7676ec76faab6c4dbc7fdaf644f70af27ccf1868c7157da352fb55206a35e4d3"}, - {file = "pydantic_core-2.18.0-cp311-none-win_amd64.whl", hash = "sha256:c21fe62521eaf617fbb04b0fcf9af085e8dc7ea3a3ee22da3af671475f29aed1"}, - {file = "pydantic_core-2.18.0-cp311-none-win_arm64.whl", hash = "sha256:c5ee382586174d3639092b32a1a7ba4cfdadd67b2539814ddc42542d6e622dd0"}, - {file = "pydantic_core-2.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c141b49350139f94a94d9268b82c0e7f91b05f1f479b785de1a5499460e68864"}, - {file = "pydantic_core-2.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e0ee55f7d521a8e7556217219112a1e9bc55b4484c8959c24e2e1a0da874d9"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88adc4fc547c8f8b0025974c27fd4671ec2f7ee375859a1c88313a8a63b4615e"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6399de345097e76a3d7420a25411939fb72fcc51890847c8b8599a43fd0b7439"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:83def986dea51011b9bad66b7481aabff5863cd05bd17cab4f228378d918292b"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ebe41d751e3347b5d5880498a965bd6523285ce5e7907d70de33c221dc347a4"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fc20e48c936e1453e2797b28044f4cd3004c98296294b4aac31170ff44b8496"}, - {file = "pydantic_core-2.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68827e0dc97c047e527dd6b86f5b4b1605faefa7a18d8f227d8f6754a6747f63"}, - {file = "pydantic_core-2.18.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d0bc6036cea7f7ba419ce1b8f2e0f8e27eddcde626fcad507edb5b7519073006"}, - {file = "pydantic_core-2.18.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c96ec95751deb156d036b348e1eef758e82326989d7e2e9fc9479d1f30b90da3"}, - {file = "pydantic_core-2.18.0-cp312-none-win32.whl", hash = "sha256:f527522a0e5470e04c75cc2f3bb272f6940acc9e426a38a6ec60ae708c1f6d58"}, - {file = "pydantic_core-2.18.0-cp312-none-win_amd64.whl", hash = "sha256:6ef640a492dad6fbe289eb91a88d7f67d6ca984db556ee1a3891a5fff4a412d2"}, - {file = "pydantic_core-2.18.0-cp312-none-win_arm64.whl", hash = "sha256:362f29ffcf78b20d2507bd39c348233a33cb0c9d70bbb26e85fc521690683e2c"}, - {file = "pydantic_core-2.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f1264b478a8e5283db4eea8344d53dc608dac862ea74b1f81d1edcd785451702"}, - {file = "pydantic_core-2.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4368aaa4d68acf489b67a7ecb0d6f8a0c478a4491e4eb8c2b9f352800322ed32"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabce6144cc2cd43e2363b463f6ba2979c7b77bad7e3ac732fc69b19e097ffcd"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:765b970000068ce5b42c7ffab0bcc86fd8ce141a9e3910c6f9b1bcdea158b233"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d0c402862402430378e72927763c5f71554db494006d32f15d48d80dca25ef1"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2b5c7eff2e1e4d97a5d7f2e399301e774d10f883fd355689f5e225c2283c42"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b39578677908dca286c7a6565512f0321dd4591a9bd013c34c3e3004316a814"}, - {file = "pydantic_core-2.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15c91b087938e1917e6f66c82928808312df403f869affb48a6d1fb9aca948c2"}, - {file = "pydantic_core-2.18.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:702ddde99e36cc25d674ae3bdd21aeab0460e7bdf3f587057db2240485e48366"}, - {file = "pydantic_core-2.18.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:26b9f7654f7d076e35f51f369b885efe877313d9d9fab3d6d291ad3ea25e10dd"}, - {file = "pydantic_core-2.18.0-cp38-none-win32.whl", hash = "sha256:d714d80d505db509781e686b1ec6ae0f0f4d0ce5ee3a91a75a41d4da2592276f"}, - {file = "pydantic_core-2.18.0-cp38-none-win_amd64.whl", hash = "sha256:7f4e623d413d78dac0e66f6aff68d6ea43993acd954fbb1840fffebf0ef3e90a"}, - {file = "pydantic_core-2.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:347efc12f055c44383d8b41e7ee72a6189156d9bfaa2952c349856432b3cae91"}, - {file = "pydantic_core-2.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d432e0c0177ae5b64f3c302b7a9a62b36b9abe3210d078540fd633d90144375b"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86e05c39ed6862d6864771f57d29e31ace0e91c3b8971bf5d53b2ed9156a025e"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4dd1aa6c7f3bea171d237a70abc105e3cda903c4ba95aea82bec11e59d45833e"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cfb9b1879cbf5a87b1b3be76ae312866b96adbc6b5c55c5e9a3934f1c0d242f"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aff8b042ce90ec873d7dd97302cadeac9768c0e536cf2452ee34e1c50a9e466d"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0a30b40b76306b58e951e2eaaafdd94292df188efe33c72fd1f503a1ea375a"}, - {file = "pydantic_core-2.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e1065cb8c9c14ea6a8c76c7c113b4d8173be2dca984c5a3ab0d6ce364ea8b502"}, - {file = "pydantic_core-2.18.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b2772b00d0d1a0e2bfe463526f23637dbc8c7fa3c80c43bca66fe4312406412a"}, - {file = "pydantic_core-2.18.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef52699c236366c4b18b485e9eecc3e5f215ef89b08e3e02a3a16a5abc97a69c"}, - {file = "pydantic_core-2.18.0-cp39-none-win32.whl", hash = "sha256:68b0ea179fc4ca681c651f272a9d0d42ad2a6e352f3d431c3cfba490719e40a0"}, - {file = "pydantic_core-2.18.0-cp39-none-win_amd64.whl", hash = "sha256:25b94e99e7aee8760c62a22e1dae2946318d2c44bdeb9be5f23ae1433cd6ba0f"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2269c1c4ab33b1cf091da878fbb739d00027649394c6c4e95a10faf5efec12b5"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:59f6a4444daed0265773ad6fed1495e212bb3b8e1157957b67505aa772645674"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ceb5a387c50d751dd25e677b5928b57ba69ee4151657369e3ead1664e12a02a"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9d9a17bdcf50312d3775bb60fe3c2f4b0fd5443b2705af58e491466fde291e3"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a91c26005f4950d09380c82fe12b7014ca56dbc4d32e4f5a3ca5d8879d68170"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:057cb50ccdcbeef19e517cfa4ac8be8b3220dcee153770bb52d266c219e1c3d3"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:70696bf40bb588f5d62b0e79fde72d432e909551c3f2f3bfcb1674d7cacc7007"}, - {file = "pydantic_core-2.18.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8a6d93401b503a54a4ce5ddc9ccd6f5b89b271b1fe0c72fc4428443b2451d765"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b496cab9ac75c8e7bda7d17e8a2d0db2f610dcced5ef465ef19122a17245b0f8"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:6d5c13ee3a9052f4ca8e7dd65dac9749c503dd96974ed1f908e0b933b9c689be"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0d86a800371db0590804881346b8610bd62c5f5396d544da5ae814a863a9e1b"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6598ed75a1ac49784a042af54cf2db3febfa2642717b12abaf6745339f69b5d7"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8ccf3e031d2dadf999d78d543d9ec9ce9fef40ae8a3c3a5a35041709d734d0d2"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:324018576490157103965281df89d287cbf18415fb3fcbb0a66efa23f2b5a497"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5b109e4a7828b7cd5fa7bb63c6125203711298d0b1f1b83d0f9786c7ce3d689b"}, - {file = "pydantic_core-2.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b770ae0d064a2d858f68c933217e01ea372de25685a52b4e98b26ea5684811c0"}, - {file = "pydantic_core-2.18.0.tar.gz", hash = "sha256:a6d075404af8b8feb42f86196e08053bfae282af2701321f36a1553e966ce1f0"}, + {file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"}, + {file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"}, + {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"}, + {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"}, + {file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"}, + {file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"}, + {file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"}, + {file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"}, + {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"}, + {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"}, + {file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"}, + {file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"}, + {file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"}, + {file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"}, + {file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"}, + {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"}, + {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"}, + {file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"}, + {file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"}, + {file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"}, + {file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"}, + {file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"}, + {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"}, + {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"}, + {file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"}, + {file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"}, + {file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"}, + {file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"}, + {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"}, + {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"}, + {file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"}, + {file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"}, + {file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"}, ] [package.dependencies] @@ -879,17 +894,16 @@ test = ["pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] @@ -934,26 +948,26 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale [[package]] name = "pytket" -version = "1.25.0" -description = "Python module for interfacing with the CQC tket library of quantum software" +version = "1.27.0" +description = "Quantum computing toolkit and interface to the TKET compiler" optional = false python-versions = ">=3.10" files = [ - {file = "pytket-1.25.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:3004271220655b6b29bbbfc2077288762da62355765402697f991e87edd8cf2e"}, - {file = "pytket-1.25.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:c9705cf3cbfd6b5fc6b0ead9c34e7dfa0826b2a98a94ab7c83d383057fc748c2"}, - {file = "pytket-1.25.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48add5959e2bf1027de40515233d7ec001f745b703adb1aedd22ee0a3a6d29ac"}, - {file = "pytket-1.25.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:313565b91a079c05d25fb708caeb20aa6f077bf3988798f66edf19914802016e"}, - {file = "pytket-1.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:340101ffafcabac43e7b2da2c9a0e389e6daf876c53552e3601a6d1e69758eed"}, - {file = "pytket-1.25.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:55ccc9597c34bb03ab723de90ad5cd224a57214c9123bfb584ed8860d9c16ff1"}, - {file = "pytket-1.25.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:f1d265d05803d7ff51d03fc7bd3a42de66de22e9c9456ce0bdc622b5516122c3"}, - {file = "pytket-1.25.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea008380d28895dbb42efabff9533f1f4840becc812311c03f935a5da71f30ba"}, - {file = "pytket-1.25.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18c51955b11f262e015a7a27c05e7021fd9ea1dd55ad0853ecc8c353f48732ba"}, - {file = "pytket-1.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:f20020bcb4f05e2c63cfddb3431cea7b431bebb8dd795caffd3dd6521c5a3a48"}, - {file = "pytket-1.25.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:8e8ab9f2bc25da5c9cf1ed5eac5e6303b9389a364ec8a0527e41110fb6b0d21e"}, - {file = "pytket-1.25.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:685475b7a2809c555167c7a20b7169f1fced26d8fb0a2658a407bd6bad6181ba"}, - {file = "pytket-1.25.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02f86826a41551d8471b01c5df2eb39ebec61f2296dffe2e4c9e6418aa2d1d9a"}, - {file = "pytket-1.25.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83241ece02065600d68207bae2818fca680bc87eb26a1647cdad97cf29f82cca"}, - {file = "pytket-1.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:c73381645c1b27bb2946707d7b58cf780a04330fc557d089a9bca8c8f466f1ca"}, + {file = "pytket-1.27.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2252a1dfd3b425d536480e8a17593c88c116511bd8749f0216ffb4087a94ecca"}, + {file = "pytket-1.27.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:36d93839b20dd0738dc92032d9c42cd74ad226089b9a835ee64ec98b6d0cfeb2"}, + {file = "pytket-1.27.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:497886d748884252a59a8173c213472967fefbca5ef05d97372394e95d9b078e"}, + {file = "pytket-1.27.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45c8bdf5f5f79fefbb6331a0febcd938dd297d103b62ccc8c9099a3799c0e846"}, + {file = "pytket-1.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:e0416874ad371db38a9da6b3bcbc7eb09ed90f353486c40d25098a93ac2fbcc3"}, + {file = "pytket-1.27.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:955c3bb4c83ae2fcf8da62d2f2c2e1348f8631070d6dc800c09df9cf13adb9f4"}, + {file = "pytket-1.27.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:a42ac781e154a0308af8faa7ab271406a40518cf24a9779a628849c1fac7a2b5"}, + {file = "pytket-1.27.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:759153b2cac05e7255662e0c83ac1d64223e183af4839806d8f31c8d0c9c00bd"}, + {file = "pytket-1.27.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:07064aaef484e6f45d2429fef314c32e874b9201513eb3cd42dd0dc3c64cc236"}, + {file = "pytket-1.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:3077eaa28307740188182af20ab42ecfec812b85a3b7d302367b9435f7f49a19"}, + {file = "pytket-1.27.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:86b1c42d5415c736ed172327ca18a314257ab3d925271d81c191521a72ce3ffb"}, + {file = "pytket-1.27.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:7f4460b8d5f738f748518200822149ed373d2ff6cafbddc96b4ec368fe017ff2"}, + {file = "pytket-1.27.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9359f760b1e9d5f4f8d13185d44fe4358a5e46046eca26af28f5b512b480a01"}, + {file = "pytket-1.27.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e604bc7700a9d26c2c2fb3ed9efcae3a6c7d21cc0f9622231ad0906ee70a388"}, + {file = "pytket-1.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:ef23ae37c134290ec110100a329dbe2d63f26286a6e37ed75c831adbb3ef9132"}, ] [package.dependencies] @@ -963,13 +977,13 @@ lark-parser = ">=0.7,<1.0" networkx = ">=2.8.8" numpy = ">=1.21.4,<2.0" qwasm = ">=1.0,<2.0" -scipy = ">=1.7.2,<2.0" +scipy = ">=1.13,<2.0" sympy = ">=1.6,<2.0" types-pkg-resources = "*" typing-extensions = ">=4.2,<5.0" [package.extras] -zx = ["autoray (>=0.6.1)", "quimb (>=1.5,<2.0)"] +zx = ["autoray (>=0.6.1)", "quimb (>=1.8,<2.0)"] [[package]] name = "pyyaml" @@ -996,7 +1010,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1068,86 +1081,86 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.4.2" +version = "0.4.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, - {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, - {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, - {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, - {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, + {file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"}, + {file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"}, + {file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"}, + {file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"}, + {file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"}, + {file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"}, ] [[package]] name = "scipy" -version = "1.12.0" +version = "1.13.0" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, - {file = "scipy-1.12.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5f00ebaf8de24d14b8449981a2842d404152774c1a1d880c901bf454cb8e2a1"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53958531a7c695ff66c2e7bb7b79560ffdc562e2051644c5576c39ff8efb563"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e32847e08da8d895ce09d108a494d9eb78974cf6de23063f93306a3e419960c"}, - {file = "scipy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1020cad92772bf44b8e4cdabc1df5d87376cb219742549ef69fc9fd86282dd"}, - {file = "scipy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:75ea2a144096b5e39402e2ff53a36fecfd3b960d786b7efd3c180e29c39e53f2"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}, - {file = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}, - {file = "scipy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}, - {file = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}, - {file = "scipy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:913d6e7956c3a671de3b05ccb66b11bc293f56bfdef040583a7221d9e22a2e35"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba1b0c7256ad75401c73e4b3cf09d1f176e9bd4248f0d3112170fb2ec4db067"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:730badef9b827b368f351eacae2e82da414e13cf8bd5051b4bdfd720271a5371"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6546dc2c11a9df6926afcbdd8a3edec28566e4e785b915e849348c6dd9f3f490"}, - {file = "scipy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:196ebad3a4882081f62a5bf4aeb7326aa34b110e533aab23e4374fcccb0890dc"}, - {file = "scipy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:b360f1b6b2f742781299514e99ff560d1fe9bd1bff2712894b52abe528d1fd1e"}, - {file = "scipy-1.12.0.tar.gz", hash = "sha256:4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba419578ab343a4e0a77c0ef82f088238a93eef141b2b8017e46149776dfad4d"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:22789b56a999265431c417d462e5b7f2b487e831ca7bef5edeb56efe4c93f86e"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f1432ba070e90d42d7fd836462c50bf98bd08bed0aa616c359eed8a04e3922"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8434f6f3fa49f631fae84afee424e2483289dfc30a47755b4b4e6b07b2633a4"}, + {file = "scipy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dcbb9ea49b0167de4167c40eeee6e167caeef11effb0670b554d10b1e693a8b9"}, + {file = "scipy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d2f7bb14c178f8b13ebae93f67e42b0a6b0fc50eba1cd8021c9b6e08e8fb1cd"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fbcf8abaf5aa2dc8d6400566c1a727aed338b5fe880cde64907596a89d576fa"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5e4a756355522eb60fcd61f8372ac2549073c8788f6114449b37e9e8104f15a5"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5acd8e1dbd8dbe38d0004b1497019b2dbbc3d70691e65d69615f8a7292865d7"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ff7dad5d24a8045d836671e082a490848e8639cabb3dbdacb29f943a678683d"}, + {file = "scipy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4dca18c3ffee287ddd3bc8f1dabaf45f5305c5afc9f8ab9cbfab855e70b2df5c"}, + {file = "scipy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a2f471de4d01200718b2b8927f7d76b5d9bde18047ea0fa8bd15c5ba3f26a1d6"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0de696f589681c2802f9090fff730c218f7c51ff49bf252b6a97ec4a5d19e8b"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b2a3ff461ec4756b7e8e42e1c681077349a038f0686132d623fa404c0bee2551"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf9fe63e7a4bf01d3645b13ff2aa6dea023d38993f42aaac81a18b1bda7a82a"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e7626dfd91cdea5714f343ce1176b6c4745155d234f1033584154f60ef1ff42"}, + {file = "scipy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:109d391d720fcebf2fbe008621952b08e52907cf4c8c7efc7376822151820820"}, + {file = "scipy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:8930ae3ea371d6b91c203b1032b9600d69c568e537b7988a3073dfe4d4774f21"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5407708195cb38d70fd2d6bb04b1b9dd5c92297d86e9f9daae1576bd9e06f602"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ac38c4c92951ac0f729c4c48c9e13eb3675d9986cc0c83943784d7390d540c78"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c74543c4fbeb67af6ce457f6a6a28e5d3739a87f62412e4a16e46f164f0ae5"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e286bf9ac422d6beb559bc61312c348ca9b0f0dae0d7c5afde7f722d6ea13d"}, + {file = "scipy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33fde20efc380bd23a78a4d26d59fc8704e9b5fd9b08841693eb46716ba13d86"}, + {file = "scipy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:45c08bec71d3546d606989ba6e7daa6f0992918171e2a6f7fbedfa7361c2de1e"}, + {file = "scipy-1.13.0.tar.gz", hash = "sha256:58569af537ea29d3f78e5abd18398459f195546bb3be23d16677fb26616cc11e"}, ] [package.dependencies] -numpy = ">=1.22.4,<1.29.0" +numpy = ">=1.22.4,<2.3" [package.extras] -dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "setuptools" -version = "69.1.1" +version = "69.5.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, + {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, + {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -1174,20 +1187,20 @@ files = [ [[package]] name = "sphinx" -version = "7.2.6" +version = "7.3.7" description = "Python documentation generator" optional = false python-versions = ">=3.9" files = [ - {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"}, - {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"}, + {file = "sphinx-7.3.7-py3-none-any.whl", hash = "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3"}, + {file = "sphinx-7.3.7.tar.gz", hash = "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc"}, ] [package.dependencies] -alabaster = ">=0.7,<0.8" +alabaster = ">=0.7.14,<0.8.0" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.21" +docutils = ">=0.18.1,<0.22" imagesize = ">=1.3" Jinja2 = ">=3.0" packaging = ">=21.0" @@ -1200,11 +1213,12 @@ sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" sphinxcontrib-serializinghtml = ">=1.1.9" +tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] -test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] +lint = ["flake8 (>=3.5.0)", "importlib_metadata", "mypy (==1.9.0)", "pytest (>=6.0)", "ruff (==0.3.7)", "sphinx-lint", "tomli", "types-docutils", "types-requests"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=6.0)", "setuptools (>=67.0)"] [[package]] name = "sphinx-book-theme" @@ -1343,11 +1357,14 @@ python-versions = ">=3.10" files = [] develop = false +[package.dependencies] +pytket = "1.27" + [package.source] type = "git" url = "https://github.com/CQCL/tket2.git" -reference = "9e941f3" -resolved_reference = "9e941f33489fcdd1f6f885989bfa65b2c0c2519c" +reference = "9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9" +resolved_reference = "9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9" [[package]] name = "tomli" @@ -1373,13 +1390,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.11.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, ] [[package]] @@ -1401,13 +1418,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.1" +version = "20.26.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, - {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, + {file = "virtualenv-20.26.1-py3-none-any.whl", hash = "sha256:7aa9982a728ae5892558bff6a2839c00b9ed145523ece2274fad6f414690ae75"}, + {file = "virtualenv-20.26.1.tar.gz", hash = "sha256:604bfdceaeece392802e6ae48e69cec49168b9c5f4a44e483963f9242eb0e78b"}, ] [package.dependencies] @@ -1416,10 +1433,10 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "d02a2bf959048a6770d8e1b75395717c72a884949abfb32e595405faeeb66592" +content-hash = "6cfb734694f5d0d842ccab47fe9238abe31f3179504def16cdbfe706df48e970" diff --git a/pyproject.toml b/pyproject.toml index 87534e5a..2b90e0e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ graphviz = "^0.20.1" networkx = "^3.2.1" pydantic = "^2.7.0b1" typing-extensions = "^4.9.0" +hugr = "~0.2.0a1" [tool.poetry.group.dev.dependencies] pytest = "^7.4.4" @@ -35,7 +36,7 @@ optional = true [tool.poetry.group.pytket.dependencies] pytket = { version = "^1.24.0" } -tket2-py = { git = "https://github.com/CQCL/tket2.git", rev = "9e941f3" } +tket2-py = { git = "https://github.com/CQCL/tket2.git", rev = "9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9" } [tool.poetry.group.docs] @@ -54,6 +55,3 @@ build-backend = "poetry.core.masonry.api" plugins = ["pydantic.mypy"] strict = true allow_redefinition = true -# mypy doesn't support TypeAliasType fully yet -# https://github.com/python/mypy/issues/16614 -disable_error_code = "valid-type" diff --git a/scripts/__init__.py b/scripts/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/scripts/generate_schema.py b/scripts/generate_schema.py deleted file mode 100644 index 38f70886..00000000 --- a/scripts/generate_schema.py +++ /dev/null @@ -1,15 +0,0 @@ -# dump json schema to a directory -# usage: python generate_schema.py -import json -import sys -from pathlib import Path - -from pydantic import TypeAdapter - -from guppylang.hugr.raw import RawHugr - -if __name__ == "__main__": - out_dir = Path(sys.argv[-1]) - - with (out_dir / "hugr_schema_v0.json").open("w") as f: - json.dump(TypeAdapter(RawHugr).json_schema(), f) diff --git a/tests/error/iter_errors/end_missing.py b/tests/error/iter_errors/end_missing.py index b4dadc23..e21b5b6c 100644 --- a/tests/error/iter_errors/end_missing.py +++ b/tests/error/iter_errors/end_missing.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator that is missing the `__end__` method.""" @@ -19,7 +19,7 @@ def __hasnext__(self: "MyIter") -> tuple[bool, "MyIter"]: ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/iter_errors/end_wrong_type.py b/tests/error/iter_errors/end_wrong_type.py index 547117d9..02c6248c 100644 --- a/tests/error/iter_errors/end_wrong_type.py +++ b/tests/error/iter_errors/end_wrong_type.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator where the `__end__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> "MyIter": ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/iter_errors/hasnext_missing.py b/tests/error/iter_errors/hasnext_missing.py index 1bf7e2a8..3b3f25e0 100644 --- a/tests/error/iter_errors/hasnext_missing.py +++ b/tests/error/iter_errors/hasnext_missing.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator that is missing the `__hasnext__` method.""" @@ -19,7 +19,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/iter_errors/hasnext_wrong_type.py b/tests/error/iter_errors/hasnext_wrong_type.py index f9095b39..0e96b983 100644 --- a/tests/error/iter_errors/hasnext_wrong_type.py +++ b/tests/error/iter_errors/hasnext_wrong_type.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator where the `__hasnext__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/iter_errors/iter_missing.py b/tests/error/iter_errors/iter_missing.py index 10f6c57b..41e923c7 100644 --- a/tests/error/iter_errors/iter_missing.py +++ b/tests/error/iter_errors/iter_missing.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType()) class MyType: """A non-iterable type.""" diff --git a/tests/error/iter_errors/iter_wrong_type.py b/tests/error/iter_errors/iter_wrong_type.py index fadfb1ab..64f837f8 100644 --- a/tests/error/iter_errors/iter_wrong_type.py +++ b/tests/error/iter_errors/iter_wrong_type.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """A type where the `__iter__` method has the wrong signature.""" diff --git a/tests/error/iter_errors/next_missing.py b/tests/error/iter_errors/next_missing.py index f06cb732..ec0f3f2c 100644 --- a/tests/error/iter_errors/next_missing.py +++ b/tests/error/iter_errors/next_missing.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator that is missing the `__next__` method.""" @@ -19,7 +19,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/iter_errors/next_wrong_type.py b/tests/error/iter_errors/next_wrong_type.py index 77184585..c1f8f53e 100644 --- a/tests/error/iter_errors/next_wrong_type.py +++ b/tests/error/iter_errors/next_wrong_type.py @@ -1,12 +1,12 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule +from guppylang.tys.ty import NoneType module = GuppyModule("test") -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator where the `__next__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, tys.TupleType(inner=[])) +@guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/util.py b/tests/error/util.py index c8d1090b..1eb6964f 100644 --- a/tests/error/util.py +++ b/tests/error/util.py @@ -1,10 +1,10 @@ import importlib.util import pathlib import pytest +from hugr.serialization import tys +from hugr.serialization.tys import TypeBound from guppylang.error import GuppyError -from guppylang.hugr import tys -from guppylang.hugr.tys import TypeBound from guppylang.module import GuppyModule import guppylang.decorator as decorator @@ -29,7 +29,7 @@ def run_error_test(file, capsys): @decorator.guppy.type( - util, tys.Opaque(extension="", id="", args=[], bound=TypeBound.Copyable) + util, tys.Type(tys.Opaque(extension="", id="", args=[], bound=TypeBound.Copyable)) ) class NonBool: pass diff --git a/tests/hugr/test_dummy_nodes.py b/tests/hugr/test_dummy_nodes.py index ab415da6..a6a5cc65 100644 --- a/tests/hugr/test_dummy_nodes.py +++ b/tests/hugr/test_dummy_nodes.py @@ -1,7 +1,8 @@ +from hugr.serialization import ops + from guppylang.tys.builtin import bool_type from guppylang.tys.ty import FunctionType, TupleType -from guppylang.hugr import ops -from guppylang.hugr.hugr import Hugr +from guppylang.hugr_builder.hugr import Hugr, DummyOp def test_single_dummy(): @@ -10,13 +11,13 @@ def test_single_dummy(): dfg = g.add_dfg(defn) inp = g.add_input([bool_type()], dfg).out_port(0) dummy = g.add_node( - ops.DummyOp(name="dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg + DummyOp("dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg ) g.add_output([dummy.out_port(0)], parent=dfg) g.remove_dummy_nodes() - [decl] = [n for n in g.nodes() if isinstance(n.op, ops.FuncDecl)] - assert decl.op.name == "dummy" + [decl] = [n for n in g.nodes() if isinstance(n.op.root, ops.FuncDecl)] + assert decl.op.root.name == "dummy" def test_unique_names(): @@ -29,13 +30,13 @@ def test_unique_names(): dfg = g.add_dfg(defn) inp = g.add_input([bool_type()], dfg).out_port(0) dummy1 = g.add_node( - ops.DummyOp(name="dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg + DummyOp("dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg ) dummy2 = g.add_node( - ops.DummyOp(name="dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg + DummyOp("dummy"), inputs=[inp], output_types=[bool_type()], parent=dfg ) g.add_output([dummy1.out_port(0), dummy2.out_port(0)], parent=dfg) g.remove_dummy_nodes() - [decl1, decl2] = [n for n in g.nodes() if isinstance(n.op, ops.FuncDecl)] - assert {decl1.op.name, decl2.op.name} == {"dummy", "dummy$1"} + [decl1, decl2] = [n for n in g.nodes() if isinstance(n.op.root, ops.FuncDecl)] + assert {decl1.op.root.name, decl2.op.root.name} == {"dummy", "dummy$1"} diff --git a/tests/integration/test_basic.py b/tests/integration/test_basic.py index c2f9c3c2..d69f54e6 100644 --- a/tests/integration/test_basic.py +++ b/tests/integration/test_basic.py @@ -1,5 +1,6 @@ +from hugr.serialization import ops + from guppylang.decorator import guppy -from guppylang.hugr import ops from guppylang.module import GuppyModule from tests.util import compile_guppy @@ -67,7 +68,9 @@ def test_func_def_name(): def func_name() -> None: return - [def_op] = [n.op for n in func_name.nodes() if isinstance(n.op, ops.FuncDefn)] + [def_op] = [ + n.op.root for n in func_name.nodes() if isinstance(n.op.root, ops.FuncDefn) + ] assert def_op.name == "func_name" @@ -78,6 +81,7 @@ def test_func_decl_name(): def func_name() -> None: ... [def_op] = [ - n.op for n in module.compile().nodes() if isinstance(n.op, ops.FuncDecl) + n.op.root for n in module.compile().nodes() + if isinstance(n.op.root, ops.FuncDecl) ] assert def_op.name == "func_name" diff --git a/tests/integration/test_comprehension.py b/tests/integration/test_comprehension.py index 234d39bb..2d471909 100644 --- a/tests/integration/test_comprehension.py +++ b/tests/integration/test_comprehension.py @@ -1,10 +1,12 @@ +from hugr.serialization import tys + from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule from guppylang.prelude.builtins import linst from guppylang.prelude.quantum import qubit, h, cx import guppylang.prelude.quantum as quantum +from guppylang.tys.ty import NoneType from tests.util import compile_guppy @@ -185,7 +187,7 @@ def test_linear_next_nonlinear_iter(validate): module = GuppyModule("test") module.load(quantum) - @guppy.type(module, tys.TupleType(inner=[])) + @guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator that yields linear values but is not linear itself.""" @@ -198,7 +200,7 @@ def __next__(self: "MyIter") -> tuple[qubit, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter") -> None: ... - @guppy.type(module, tys.TupleType(inner=[])) + @guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" @@ -219,7 +221,11 @@ def test_nonlinear_next_linear_iter(validate): @guppy.type( module, - tys.Opaque(extension="prelude", id="qubit", args=[], bound=tys.TypeBound.Any), + tys.Type( + tys.Opaque( + extension="prelude", id="qubit", args=[], bound=tys.TypeBound.Any + ) + ), linear=True, ) class MyIter: @@ -234,7 +240,7 @@ def __next__(self: "MyIter") -> tuple[int, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter") -> None: ... - @guppy.type(module, tys.TupleType(inner=[])) + @guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/integration/test_linear.py b/tests/integration/test_linear.py index e5088563..f5460287 100644 --- a/tests/integration/test_linear.py +++ b/tests/integration/test_linear.py @@ -1,11 +1,11 @@ from guppylang.decorator import guppy -from guppylang.hugr import tys from guppylang.module import GuppyModule from guppylang.prelude.builtins import linst from guppylang.prelude.quantum import qubit import guppylang.prelude.quantum as quantum from guppylang.prelude.quantum import h, cx, measure_return, measure, t +from guppylang.tys.ty import NoneType def test_id(validate): @@ -235,7 +235,7 @@ def test_for_nonlinear_break(validate): module = GuppyModule("test") module.load(quantum) - @guppy.type(module, tys.TupleType(inner=[])) + @guppy.type(module, NoneType().to_hugr()) class MyIter: """An iterator that yields linear values but is not linear itself.""" @@ -248,7 +248,7 @@ def __next__(self: "MyIter") -> tuple[qubit, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter") -> None: ... - @guppy.type(module, tys.TupleType(inner=[])) + @guppy.type(module, NoneType().to_hugr()) class MyType: """Type that produces the iterator above.""" diff --git a/tests/integration/test_poly.py b/tests/integration/test_poly.py index c3dd2c62..98107a32 100644 --- a/tests/integration/test_poly.py +++ b/tests/integration/test_poly.py @@ -1,5 +1,7 @@ from collections.abc import Callable +import pytest + from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.quantum import qubit @@ -259,6 +261,7 @@ def main() -> None: validate(module.compile()) +@pytest.mark.skip("Not yet supported") def test_higher_order_value(validate): module = GuppyModule("test") T = guppy.type_var(module, "T") diff --git a/tests/integration/test_py.py b/tests/integration/test_py.py index 3eb5cba3..ce6accf9 100644 --- a/tests/integration/test_py.py +++ b/tests/integration/test_py.py @@ -142,6 +142,9 @@ def foo(q1: qubit, q2: qubit, q3: qubit) -> tuple[qubit, qubit, qubit]: validate(module.compile()) +@pytest.mark.skip( + "Now requires a conversion pass to turn TKET1 measurements into TKET2 measurements" +) @pytest.mark.skipif(not tket2_installed, reason="Tket2 is not installed") def test_pytket_measure(validate): from pytket import Circuit diff --git a/tests/util.py b/tests/util.py index 3a45073e..ea6115f2 100644 --- a/tests/util.py +++ b/tests/util.py @@ -1,5 +1,5 @@ import guppylang -from guppylang.hugr.hugr import Hugr +from guppylang.hugr_builder.hugr import Hugr from guppylang.module import GuppyModule diff --git a/validator/Cargo.lock b/validator/Cargo.lock index 3eaba53c..1e918252 100644 --- a/validator/Cargo.lock +++ b/validator/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "approx" version = "0.4.0" @@ -45,6 +60,30 @@ dependencies = [ "wyz", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + [[package]] name = "cfg-if" version = "1.0.0" @@ -62,6 +101,20 @@ dependencies = [ "serde", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "context-iterators" version = "0.2.0" @@ -75,14 +128,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] -name = "delegate" -version = "0.11.0" +name = "core-foundation-sys" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4801d755ab05b6e25cbbf1afc342993aafa00e572409f9ee21633a19e609d9f" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", ] [[package]] @@ -160,14 +263,24 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "guppyval" version = "0.2.0" dependencies = [ + "hugr", "lazy_static", "pyo3", - "quantinuum-hugr", "serde_json", + "tket2", ] [[package]] @@ -191,6 +304,60 @@ dependencies = [ "utf8-width", ] +[[package]] +name = "hugr" +version = "0.4.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb1716e110d2d9d0ca23f79812e90486098ffee9aff5eac0a16346c23a609cc" +dependencies = [ + "bitvec", + "cgmath", + "context-iterators", + "delegate", + "derive_more", + "downcast-rs", + "enum_dispatch", + "html-escape", + "itertools", + "lazy_static", + "num-rational", + "paste", + "petgraph", + "portgraph", + "regex", + "serde", + "serde_json", + "serde_yaml", + "smol_str", + "strum", + "strum_macros", + "thiserror", + "typetag", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -228,6 +395,15 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -250,6 +426,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + [[package]] name = "memchr" version = "2.7.1" @@ -334,7 +516,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -353,20 +535,37 @@ dependencies = [ "indexmap", ] +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + [[package]] name = "portgraph" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79e1dbdf59146cb0941cbab3af7ecfe028c0976d96dc110964d770b88783b3b" +checksum = "e8ad1ebc029f8dfab4f023f14c7e41b3b3a257cf28b2928949153e563c9bf02c" dependencies = [ "bitvec", "context-iterators", - "delegate 0.11.0", + "delegate", "petgraph", "serde", "thiserror", ] +[[package]] +name = "priority-queue" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509354d8a769e8d0b567d6821b84495c60213162761a732d68ce87c964bd347f" +dependencies = [ + "autocfg", + "equivalent", + "indexmap", +] + [[package]] name = "proc-macro2" version = "1.0.76" @@ -436,37 +635,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "quantinuum-hugr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "277a0c87e40de34c82a31077d3adbe00ee218609295bac1c9e4cde9cfa6a22d2" -dependencies = [ - "bitvec", - "cgmath", - "context-iterators", - "delegate 0.12.0", - "derive_more", - "downcast-rs", - "enum_dispatch", - "html-escape", - "itertools", - "lazy_static", - "num-rational", - "paste", - "petgraph", - "portgraph", - "regex", - "serde", - "serde_json", - "serde_yaml", - "smol_str", - "strum", - "strum_macros", - "thiserror", - "typetag", -] - [[package]] name = "quote" version = "1.0.35" @@ -482,6 +650,26 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -612,11 +800,20 @@ dependencies = [ "serde", ] +[[package]] +name = "stringreader" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913e7b03d63752f6cdd2df77da36749d82669904798fe8944b9ec3d23f159905" + [[package]] name = "strum" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] [[package]] name = "strum_macros" @@ -685,6 +882,84 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "tket-json-rs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f62807960274a10068c64b213795f0009027c534ffe48924ca2e12d09acad8e7" +dependencies = [ + "serde", + "serde_json", + "strum", + "uuid", +] + +[[package]] +name = "tket2" +version = "0.0.0-alpha.1" +source = "git+https://github.com/CQCL/tket2.git?rev=9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9#9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9" +dependencies = [ + "bytemuck", + "cgmath", + "chrono", + "crossbeam-channel", + "csv", + "delegate", + "derive_more", + "downcast-rs", + "fxhash", + "hugr", + "itertools", + "lazy_static", + "num-rational", + "petgraph", + "portgraph", + "priority-queue", + "rayon", + "serde", + "serde_json", + "serde_yaml", + "smol_str", + "stringreader", + "strum", + "strum_macros", + "thiserror", + "tket-json-rs", + "tracing", + "typetag", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + [[package]] name = "typetag" version = "0.2.15" @@ -733,19 +1008,107 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "serde", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -754,42 +1117,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "wyz" version = "0.5.1" diff --git a/validator/Cargo.toml b/validator/Cargo.toml index 741430d5..6c1d5de5 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -quantinuum-hugr = "0.2.0" +hugr = "0.4.0-alpha.1" lazy_static = "1.4.0" serde_json = "1.0.111" +tket2 = { git = "https://github.com/CQCL/tket2.git", rev = "9f0de7bdecf8958f2ec3b42cf49ce79c4da605c9" } diff --git a/validator/src/lib.rs b/validator/src/lib.rs index e52f86eb..a730c6a1 100644 --- a/validator/src/lib.rs +++ b/validator/src/lib.rs @@ -2,6 +2,7 @@ use hugr::extension::{ExtensionRegistry, PRELUDE}; use hugr::std_extensions::arithmetic::{float_ops, float_types, int_ops, int_types}; use hugr::std_extensions::collections; use hugr::std_extensions::logic; +use tket2::extension::{TKET1_EXTENSION, TKET2_EXTENSION}; use lazy_static::lazy_static; use pyo3::prelude::*; @@ -14,6 +15,8 @@ lazy_static! { float_types::EXTENSION.to_owned(), float_ops::EXTENSION.to_owned(), collections::EXTENSION.to_owned(), + TKET1_EXTENSION.to_owned(), + TKET2_EXTENSION.to_owned(), ]) .unwrap(); }