From cc8a424ad9a8b8c3c5a3b5cc700ccdb7a5ff8fa9 Mon Sep 17 00:00:00 2001 From: Mark Koch <48097969+mark-koch@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:56:53 +0100 Subject: [PATCH] feat!: Support implicit modules for all decorators and turn builtins into implicit module (#476) Closes #463. BREAKING CHANGE: The `GuppyModule` argument is now optional for all decorators and no longer the first positional argument. Removed the explicit module objects `builtins`, `quantum`, and `angle`. --------- Co-authored-by: Alan Lawrence --- guppylang/decorator.py | 223 ++++++-- guppylang/ipython_inspect.py | 10 +- guppylang/module.py | 1 + guppylang/prelude/angles.py | 36 +- guppylang/prelude/builtins.py | 530 +++++++++--------- guppylang/prelude/quantum.py | 52 +- tests/error/inout_errors/already_used.py | 4 +- tests/error/inout_errors/conflict.py | 4 +- tests/error/inout_errors/drop_after_call.py | 4 +- tests/error/inout_errors/moved.py | 4 +- tests/error/inout_errors/moved_assign.py | 4 +- tests/error/inout_errors/moved_if.py | 4 +- tests/error/inout_errors/moved_out.py | 4 +- tests/error/inout_errors/moved_out_if.py | 4 +- .../inout_errors/nested_call_right_to_left.py | 4 +- .../error/inout_errors/override_after_call.py | 4 +- tests/error/inout_errors/shadow.py | 4 +- tests/error/inout_errors/shadow_if.py | 4 +- .../error/inout_errors/struct_constructor.py | 4 +- .../inout_errors/subscript_not_setable.py | 4 +- tests/error/inout_errors/unused_after_call.py | 4 +- tests/error/iter_errors/end_missing.py | 4 +- tests/error/iter_errors/end_wrong_type.py | 4 +- tests/error/iter_errors/hasnext_missing.py | 4 +- tests/error/iter_errors/hasnext_wrong_type.py | 4 +- tests/error/iter_errors/iter_missing.py | 2 +- tests/error/iter_errors/iter_wrong_type.py | 2 +- tests/error/iter_errors/next_missing.py | 4 +- tests/error/iter_errors/next_wrong_type.py | 4 +- tests/error/linear_errors/unused_expr.err | 8 +- tests/error/linear_errors/unused_expr.py | 5 +- tests/error/linear_errors/while_unused.err | 8 +- tests/error/linear_errors/while_unused.py | 5 +- tests/error/misc_errors/extern_bad_type.err | 4 +- tests/error/misc_errors/extern_bad_type.py | 2 +- tests/error/misc_errors/nested_arg_flag.py | 4 +- tests/error/misc_errors/return_flag.py | 4 +- .../error/misc_errors/return_flag_callable.py | 4 +- tests/error/poly_errors/arg_mismatch1.py | 2 +- tests/error/poly_errors/arg_mismatch2.py | 2 +- tests/error/poly_errors/arg_mismatch3.py | 2 +- tests/error/poly_errors/define.py | 2 +- tests/error/poly_errors/free_return_var.py | 2 +- .../error/poly_errors/inst_return_mismatch.py | 2 +- .../inst_return_mismatch_nested.py | 2 +- tests/error/poly_errors/non_linear1.py | 2 +- tests/error/poly_errors/non_linear2.py | 2 +- tests/error/poly_errors/non_linear3.py | 6 +- tests/error/poly_errors/pass_poly_free.py | 2 +- tests/error/poly_errors/return_mismatch.py | 2 +- tests/error/poly_errors/right_to_left.py | 2 +- tests/error/py_errors/tket2_not_installed.py | 4 +- .../constructor_arg_mismatch_poly.py | 2 +- .../struct_errors/invalid_instantiate1.py | 2 +- .../struct_errors/invalid_instantiate2.py | 2 +- tests/error/struct_errors/mutate_classical.py | 4 +- tests/error/tensor_errors/poly_tensor.py | 2 +- tests/error/test_misc_errors.py | 2 +- tests/error/util.py | 2 +- tests/integration/modules/mod_a.py | 2 +- tests/integration/modules/mod_b.py | 2 +- tests/integration/modules/mod_c.py | 2 +- tests/integration/test_comprehension.py | 8 +- tests/integration/test_extern.py | 6 +- tests/integration/test_linear.py | 4 +- tests/integration/test_poly.py | 42 +- tests/integration/test_py.py | 3 +- tests/integration/test_struct.py | 6 +- tests/integration/test_tket.py | 3 +- 69 files changed, 596 insertions(+), 516 deletions(-) diff --git a/guppylang/decorator.py b/guppylang/decorator.py index 97bd35b7..80711e5d 100644 --- a/guppylang/decorator.py +++ b/guppylang/decorator.py @@ -30,16 +30,29 @@ from guppylang.definition.struct import RawStructDef from guppylang.definition.ty import OpaqueTypeDef, TypeDef from guppylang.error import GuppyError, MissingModuleError, pretty_errors -from guppylang.module import GuppyModule, PyFunc, find_guppy_module_in_py_module +from guppylang.ipython_inspect import get_ipython_globals, is_running_ipython +from guppylang.module import ( + GuppyModule, + PyClass, + PyFunc, + find_guppy_module_in_py_module, +) from guppylang.tys.subst import Inst from guppylang.tys.ty import NumericType -FuncDefDecorator = Callable[[PyFunc], RawFunctionDef] -FuncDeclDecorator = Callable[[PyFunc], RawFunctionDecl] -CustomFuncDecorator = Callable[[PyFunc], RawCustomFunctionDef] -ClassDecorator = Callable[[type], type] -OpaqueTypeDecorator = Callable[[type], OpaqueTypeDef] -StructDecorator = Callable[[type], RawStructDef] +S = TypeVar("S") +T = TypeVar("T") +Decorator = Callable[[S], T] + +FuncDefDecorator = Decorator[PyFunc, RawFunctionDef] +FuncDeclDecorator = Decorator[PyFunc, RawFunctionDecl] +CustomFuncDecorator = Decorator[PyFunc, RawCustomFunctionDef] +ClassDecorator = Decorator[PyClass, PyClass] +OpaqueTypeDecorator = Decorator[PyClass, OpaqueTypeDef] +StructDecorator = Decorator[PyClass, RawStructDef] + + +_JUPYTER_NOTEBOOK_MODULE = "" @dataclass(frozen=True) @@ -79,21 +92,33 @@ def __call__(self, arg: PyFunc | GuppyModule) -> FuncDefDecorator | RawFunctionD Optionally, the `GuppyModule` in which the function should be placed can be passed to the decorator. """ - if not isinstance(arg, GuppyModule): - # Decorator used without any arguments. - # We default to a module associated with the caller of the decorator. - f = arg - module = self.get_module() + + def dec(f: Callable[..., Any], module: GuppyModule) -> RawFunctionDef: return module.register_func_def(f) - if isinstance(arg, GuppyModule): - # Module passed. - def dec(f: Callable[..., Any]) -> RawFunctionDef: - return arg.register_func_def(f) + return self._with_optional_module(dec, arg) + + @overload # Always S != GuppyModule, hence ok to: + def _with_optional_module( # type: ignore[overload-overlap] + self, dec: Callable[[S, GuppyModule], T], arg: S + ) -> T: ... - return dec + @overload + def _with_optional_module( + self, dec: Callable[[S, GuppyModule], T], arg: GuppyModule + ) -> Decorator[S, T]: ... + + def _with_optional_module( + self, dec: Callable[[S, GuppyModule], T], arg: S | GuppyModule + ) -> Decorator[S, T] | T: + """Helper function to define decorators that take an optional `GuppyModule` + argument but no other arguments. - raise ValueError(f"Invalid arguments to `@guppy` decorator: {arg}") + For example, we allow `@guppy(module)` but also `@guppy`. + """ + if isinstance(arg, GuppyModule): + return lambda s: dec(s, arg) + return dec(arg, self.get_module()) def _get_python_caller(self, fn: PyFunc | None = None) -> ModuleIdentifier: """Returns an identifier for the Python file/module that called the decorator. @@ -104,27 +129,53 @@ def _get_python_caller(self, fn: PyFunc | None = None) -> ModuleIdentifier: filename = inspect.getfile(fn) module = inspect.getmodule(fn) else: - for s in inspect.stack(): - if s.filename != __file__: - filename = s.filename - module = inspect.getmodule(s.frame) - # Skip frames from the `pretty_error` decorator + frame = inspect.currentframe() + # loop to skip frames from the `pretty_error` decorator + while frame: + info = inspect.getframeinfo(frame) + if info and info.filename != __file__: + module = inspect.getmodule(frame) if module != guppylang.error: break + frame = frame.f_back else: raise GuppyError("Could not find a caller for the `@guppy` decorator") + + # Jupyter notebook cells all get different dummy filenames. However, + # we want the whole notebook to correspond to a single implicit + # Guppy module. + # TODO: Find a better way to detect if `filename` is a dummy name + # generated by Jupyter + filename = info.filename + if is_running_ipython() and not module and "ipykernel" in filename: + filename = _JUPYTER_NOTEBOOK_MODULE module_path = Path(filename) return ModuleIdentifier( module_path, module.__name__ if module else module_path.name, module ) + def init_module(self, import_builtins: bool = True) -> None: + """Manually initialises a Guppy module for the current Python file. + + Calling this method is only required when trying to define an empty module or + a module that doesn't include the builtins. + """ + module_id = self._get_python_caller() + if module_id in self._modules: + msg = f"Module {module_id.name} is already initialised" + raise GuppyError(msg) + self._modules[module_id] = GuppyModule(module_id.name, import_builtins) + @pretty_errors - def extend_type(self, module: GuppyModule, defn: TypeDef) -> ClassDecorator: + def extend_type( + self, defn: TypeDef, module: GuppyModule | None = None + ) -> ClassDecorator: """Decorator to add new instance functions to a type.""" - module._instance_func_buffer = {} + mod = module or self.get_module() + mod._instance_func_buffer = {} def dec(c: type) -> type: - module._register_buffered_instance_funcs(defn) + mod._register_buffered_instance_funcs(defn) return c return dec @@ -132,11 +183,11 @@ def dec(c: type) -> type: @pretty_errors def type( self, - module: GuppyModule, hugr_ty: ht.Type, name: str = "", linear: bool = False, bound: ht.TypeBound | None = None, + module: GuppyModule | None = None, ) -> OpaqueTypeDecorator: """Decorator to annotate a class definitions as Guppy types. @@ -144,11 +195,12 @@ def type( marked as linear. All `@guppy` annotated functions on the class are turned into instance functions. """ - module._instance_func_buffer = {} + mod = module or self.get_module() + mod._instance_func_buffer = {} def dec(c: type) -> OpaqueTypeDef: defn = OpaqueTypeDef( - DefId.fresh(module), + DefId.fresh(mod), name or c.__name__, None, [], @@ -156,28 +208,57 @@ def dec(c: type) -> OpaqueTypeDef: lambda _: hugr_ty, bound, ) - module.register_def(defn) - module._register_buffered_instance_funcs(defn) + mod.register_def(defn) + mod._register_buffered_instance_funcs(defn) return defn return dec - @pretty_errors - def struct(self, module: GuppyModule) -> StructDecorator: + @property + def struct( + self, + ) -> Callable[[PyClass | GuppyModule], StructDecorator | RawStructDef]: """Decorator to define a new struct.""" - module._instance_func_buffer = {} + # Note that this is a property. Thus, the code below is executed *before* + # the members of the decorated class are executed. + # At this point, we don't know if the user has called `@struct(module)` or + # just `@struct`. To be safe, we initialise the method buffer of the implicit + # module either way + caller_id = self._get_python_caller() + implicit_module_existed = caller_id in self._modules + implicit_module = self.get_module( + # But don't try to do implicit imports since we're not sure if this is + # actually an implicit module + resolve_implicit_imports=False + ) + implicit_module._instance_func_buffer = {} - def dec(cls: type) -> RawStructDef: + def dec(cls: type, module: GuppyModule) -> RawStructDef: defn = RawStructDef(DefId.fresh(module), cls.__name__, None, cls) module.register_def(defn) module._register_buffered_instance_funcs(defn) + # If we mistakenly initialised the method buffer of the implicit module + # we can just clear it here + if module != implicit_module: + assert implicit_module._instance_func_buffer == {} + implicit_module._instance_func_buffer = None + if not implicit_module_existed: + self._modules.pop(caller_id) return defn - return dec + def higher_dec(arg: GuppyModule | PyClass) -> StructDecorator | RawStructDef: + if isinstance(arg, GuppyModule): + arg._instance_func_buffer = {} + return self._with_optional_module(dec, arg) + + return higher_dec @pretty_errors - def type_var(self, module: GuppyModule, name: str, linear: bool = False) -> TypeVar: + def type_var( + self, name: str, linear: bool = False, module: GuppyModule | None = None + ) -> TypeVar: """Creates a new type variable in a module.""" + module = module or self.get_module() defn = TypeVarDef(DefId.fresh(module), name, None, linear) module.register_def(defn) # Return an actual Python `TypeVar` so it can be used as an actual type in code @@ -185,8 +266,9 @@ def type_var(self, module: GuppyModule, name: str, linear: bool = False) -> Type return TypeVar(name) @pretty_errors - def nat_var(self, module: GuppyModule, name: str) -> ConstVarDef: + def nat_var(self, name: str, module: GuppyModule | None = None) -> ConstVarDef: """Creates a new const nat variable in a module.""" + module = module or self.get_module() defn = ConstVarDef( DefId.fresh(module), name, None, NumericType(NumericType.Kind.Nat) ) @@ -196,11 +278,11 @@ def nat_var(self, module: GuppyModule, name: str) -> ConstVarDef: @pretty_errors def custom( self, - module: GuppyModule, compiler: CustomInoutCallCompiler | None = None, checker: CustomCallChecker | None = None, higher_order_value: bool = True, name: str = "", + module: GuppyModule | None = None, ) -> CustomFuncDecorator: """Decorator to add custom typing or compilation behaviour to function decls. @@ -208,6 +290,7 @@ def custom( that case, the function signature can be omitted if a custom call compiler is provided. """ + mod = module or self.get_module() def dec(f: PyFunc) -> RawCustomFunctionDef: func_ast, docstring = parse_py_func(f) @@ -218,25 +301,25 @@ def dec(f: PyFunc) -> RawCustomFunctionDef: ) call_checker = checker or DefaultCallChecker() func = RawCustomFunctionDef( - DefId.fresh(module), + DefId.fresh(mod), name or func_ast.name, func_ast, call_checker, compiler or NotImplementedCallCompiler(), higher_order_value, ) - module.register_def(func) + mod.register_def(func) return func return dec def hugr_op( self, - module: GuppyModule, op: Callable[[ht.FunctionType, Inst], ops.DataflowOp], checker: CustomCallChecker | None = None, higher_order_value: bool = True, name: str = "", + module: GuppyModule | None = None, ) -> CustomFuncDecorator: """Decorator to annotate function declarations as HUGR ops. @@ -249,20 +332,27 @@ def hugr_op( value. name: The name of the function. """ - return self.custom(module, OpCompiler(op), checker, higher_order_value, name) + return self.custom(OpCompiler(op), checker, higher_order_value, name, module) + + @overload + def declare(self, arg: GuppyModule) -> RawFunctionDecl: ... - def declare(self, module: GuppyModule) -> FuncDeclDecorator: + @overload + def declare(self, arg: PyFunc) -> FuncDeclDecorator: ... + + def declare(self, arg: GuppyModule | PyFunc) -> FuncDeclDecorator | RawFunctionDecl: """Decorator to declare functions""" - def dec(f: Callable[..., Any]) -> RawFunctionDecl: + def dec(f: Callable[..., Any], module: GuppyModule) -> RawFunctionDecl: return module.register_func_decl(f) - return dec + return self._with_optional_module(dec, arg) def constant( - self, module: GuppyModule, name: str, ty: str, value: hv.Value + self, name: str, ty: str, value: hv.Value, module: GuppyModule | None = None ) -> RawConstDef: """Adds a constant to a module, backed by a `hugr.val.Value`.""" + module = module or self.get_module() type_ast = _parse_expr_string(ty, f"Not a valid Guppy type: `{ty}`") defn = RawConstDef(DefId.fresh(module), name, None, type_ast, value) module.register_def(defn) @@ -270,13 +360,14 @@ def constant( def extern( self, - module: GuppyModule, name: str, ty: str, symbol: str | None = None, constant: bool = True, + module: GuppyModule | None = None, ) -> RawExternDef: """Adds an extern symbol to a module.""" + module = module or self.get_module() type_ast = _parse_expr_string(ty, f"Not a valid Guppy type: `{ty}`") defn = RawExternDef( DefId.fresh(module), name, None, symbol or name, constant, type_ast @@ -291,7 +382,9 @@ def load(self, m: ModuleType | GuppyModule) -> None: module = self._modules[caller] module.load_all(m) - def get_module(self, id: ModuleIdentifier | None = None) -> GuppyModule: + def get_module( + self, id: ModuleIdentifier | None = None, resolve_implicit_imports: bool = True + ) -> GuppyModule: """Returns the local GuppyModule.""" if id is None: id = self._get_python_caller() @@ -299,19 +392,29 @@ def get_module(self, id: ModuleIdentifier | None = None) -> GuppyModule: self._modules[id] = GuppyModule(id.name.split(".")[-1]) module = self._modules[id] # Update implicit imports - if id.module: - defs: dict[str, Definition | ModuleType] = {} - for x, value in id.module.__dict__.items(): - if isinstance(value, Definition) and value.id.module != module: - defs[x] = value - elif isinstance(value, ModuleType): - try: - other_module = find_guppy_module_in_py_module(value) + if resolve_implicit_imports: + globs: dict[str, Any] = {} + if id.module: + globs = id.module.__dict__ + # Jupyter notebooks are not made up of a single module, so we need to find + # it's globals by querying the ipython kernel + elif id.name == _JUPYTER_NOTEBOOK_MODULE: + globs = get_ipython_globals() + if globs: + defs: dict[str, Definition | ModuleType] = {} + for x, value in globs.items(): + if isinstance(value, Definition): + other_module = value.id.module if other_module and other_module != module: defs[x] = value - except GuppyError: - pass - module.load(**defs) + elif isinstance(value, ModuleType): + try: + other_module = find_guppy_module_in_py_module(value) + if other_module and other_module != module: + defs[x] = value + except GuppyError: + pass + module.load(**defs) return module def compile_module(self, id: ModuleIdentifier | None = None) -> hugr.ext.Package: diff --git a/guppylang/ipython_inspect.py b/guppylang/ipython_inspect.py index fcfb575c..9726f7f0 100644 --- a/guppylang/ipython_inspect.py +++ b/guppylang/ipython_inspect.py @@ -1,7 +1,7 @@ """Tools for inspecting source code when running in IPython.""" import ast -from typing import NamedTuple, cast +from typing import Any, NamedTuple, cast def is_running_ipython() -> bool: @@ -54,3 +54,11 @@ def find_ipython_def(name: str) -> IPythonDef | None: cell_name = f"In [{len(cell_sources) - i}]" return IPythonDef(node, cell_name, cell_source) return None + + +def get_ipython_globals() -> dict[str, Any]: + """Returns the globals of the current IPython kernel.""" + try: + return get_ipython().user_ns # type: ignore[name-defined, no-any-return] + except NameError: + raise RuntimeError("Not running in IPython") from None diff --git a/guppylang/module.py b/guppylang/module.py index a6680d68..beb5318e 100644 --- a/guppylang/module.py +++ b/guppylang/module.py @@ -29,6 +29,7 @@ from guppylang.definition.ty import TypeDef from guppylang.error import GuppyError, pretty_errors +PyClass = type PyFunc = Callable[..., Any] PyFuncDefOrDecl = tuple[bool, PyFunc] diff --git a/guppylang/prelude/angles.py b/guppylang/prelude/angles.py index 26ab1a31..fc8a8739 100644 --- a/guppylang/prelude/angles.py +++ b/guppylang/prelude/angles.py @@ -8,14 +8,10 @@ from hugr import val as hv from guppylang.decorator import guppy -from guppylang.module import GuppyModule from guppylang.prelude._internal.checker import CoercingChecker from guppylang.prelude._internal.compiler.angle import AngleOpCompiler from guppylang.prelude.builtins import nat -angles = GuppyModule("angles") - - _hugr_angle_type = ht.Opaque("angle", ht.TypeBound.Copyable, [], "tket2.quantum") @@ -32,32 +28,32 @@ def _hugr_angle_value(numerator: int, log_denominator: int) -> hv.Value: ) -pi = guppy.constant(angles, "pi", ty="angle", value=_hugr_angle_value(1, 1)) +pi = guppy.constant("pi", ty="angle", value=_hugr_angle_value(1, 1)) -@guppy.type(angles, _hugr_angle_type) +@guppy.type(_hugr_angle_type) class angle: """The type of angles represented as dyadic rational multiples of 2π.""" - @guppy.custom(angles, AngleOpCompiler("afromrad"), CoercingChecker()) + @guppy.custom(AngleOpCompiler("afromrad"), CoercingChecker()) def __new__(radians: float) -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("aadd")) + @guppy.custom(AngleOpCompiler("aadd")) def __add__(self: "angle", other: "angle") -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("asub")) + @guppy.custom(AngleOpCompiler("asub")) def __sub__(self: "angle", other: "angle") -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("aneg")) + @guppy.custom(AngleOpCompiler("aneg")) def __neg__(self: "angle") -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("atorad")) + @guppy.custom(AngleOpCompiler("atorad")) def __float__(self: "angle") -> float: ... - @guppy.custom(angles, AngleOpCompiler("aeq")) + @guppy.custom(AngleOpCompiler("aeq")) def __eq__(self: "angle", other: "angle") -> bool: ... - @guppy(angles) + @guppy @no_type_check def __mul__(self: "angle", other: int) -> "angle": if other < 0: @@ -65,12 +61,12 @@ def __mul__(self: "angle", other: int) -> "angle": else: return -self._nat_mul(nat(other)) - @guppy(angles) + @guppy @no_type_check def __rmul__(self: "angle", other: int) -> "angle": return self * other - @guppy(angles) + @guppy @no_type_check def __truediv__(self: "angle", other: int) -> "angle": if other < 0: @@ -78,22 +74,22 @@ def __truediv__(self: "angle", other: int) -> "angle": else: return -self._nat_div(nat(other)) - @guppy.custom(angles, AngleOpCompiler("amul")) + @guppy.custom(AngleOpCompiler("amul")) def _nat_mul(self: "angle", other: nat) -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("aneg")) + @guppy.custom(AngleOpCompiler("aneg")) def _nat_div(self: "angle", other: nat) -> "angle": ... - @guppy.custom(angles, AngleOpCompiler("aparts")) + @guppy.custom(AngleOpCompiler("aparts")) def _parts(self: "angle") -> tuple[nat, nat]: ... - @guppy(angles) + @guppy @no_type_check def numerator(self: "angle") -> nat: numerator, _ = self._parts() return numerator - @guppy(angles) + @guppy @no_type_check def log_denominator(self: "angle") -> nat: _, log_denominator = self._parts() diff --git a/guppylang/prelude/builtins.py b/guppylang/prelude/builtins.py index b02854b2..2a0ea7ee 100644 --- a/guppylang/prelude/builtins.py +++ b/guppylang/prelude/builtins.py @@ -9,7 +9,6 @@ from guppylang.decorator import guppy from guppylang.definition.custom import DefaultCallChecker, NoopCompiler from guppylang.error import GuppyError -from guppylang.module import GuppyModule from guppylang.prelude._internal.checker import ( ArrayLenChecker, CallableChecker, @@ -52,10 +51,10 @@ nat_type_def, ) -builtins = GuppyModule("builtins", import_builtins=False) +guppy.init_module(import_builtins=False) -T = guppy.type_var(builtins, "T") -L = guppy.type_var(builtins, "L", linear=True) +T = guppy.type_var("T") +L = guppy.type_var("L", linear=True) def py(*_args: Any) -> Any: @@ -92,533 +91,516 @@ def __init__(self, *args: _T): pass -@guppy.extend_type(builtins, bool_type_def) +@guppy.extend_type(bool_type_def) class Bool: - @guppy.hugr_op(builtins, logic_op("And")) + @guppy.hugr_op(logic_op("And")) def __and__(self: bool, other: bool) -> bool: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __bool__(self: bool) -> bool: ... - @guppy.hugr_op(builtins, logic_op("Eq")) + @guppy.hugr_op(logic_op("Eq")) def __eq__(self: bool, other: bool) -> bool: ... - @guppy.custom(builtins, IFromBoolCompiler()) + @guppy.custom(IFromBoolCompiler()) def __int__(self: bool) -> int: ... - @guppy.custom(builtins, IFromBoolCompiler()) + @guppy.custom(IFromBoolCompiler()) def __nat__(self: bool) -> nat: ... - @guppy.custom(builtins, checker=DunderChecker("__bool__"), higher_order_value=False) + @guppy.custom(checker=DunderChecker("__bool__"), higher_order_value=False) def __new__(x): ... - @guppy.hugr_op(builtins, logic_op("Or")) + @guppy.hugr_op(logic_op("Or")) def __or__(self: bool, other: bool) -> bool: ... - @guppy.hugr_op(builtins, unsupported_op("Xor")) # TODO: Missing op + @guppy.hugr_op(unsupported_op("Xor")) # TODO: Missing op def __xor__(self: bool, other: bool) -> bool: ... -@guppy.extend_type(builtins, nat_type_def) +@guppy.extend_type(nat_type_def) class Nat: - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __abs__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("iadd")) + @guppy.hugr_op(int_op("iadd")) def __add__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("iand")) + @guppy.hugr_op(int_op("iand")) def __and__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, IToBoolCompiler()) + @guppy.custom(IToBoolCompiler()) def __bool__(self: nat) -> bool: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __ceil__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("idivmod_u", n_vars=2)) + @guppy.hugr_op(int_op("idivmod_u", n_vars=2)) def __divmod__(self: nat, other: nat) -> tuple[nat, nat]: ... - @guppy.hugr_op(builtins, int_op("ieq")) + @guppy.hugr_op(int_op("ieq")) def __eq__(self: nat, other: nat) -> bool: ... - @guppy.hugr_op(builtins, int_op("convert_u", hugr.std.int.CONVERSIONS_EXTENSION)) + @guppy.hugr_op(int_op("convert_u", hugr.std.int.CONVERSIONS_EXTENSION)) def __float__(self: nat) -> float: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __floor__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("idiv_u")) + @guppy.hugr_op(int_op("idiv_u")) def __floordiv__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ige_u")) + @guppy.hugr_op(int_op("ige_u")) def __ge__(self: nat, other: nat) -> bool: ... - @guppy.hugr_op(builtins, int_op("igt_u")) + @guppy.hugr_op(int_op("igt_u")) def __gt__(self: nat, other: nat) -> bool: ... - @guppy.hugr_op(builtins, int_op("iu_to_s")) + @guppy.hugr_op(int_op("iu_to_s")) def __int__(self: nat) -> int: ... - @guppy.hugr_op(builtins, int_op("inot")) + @guppy.hugr_op(int_op("inot")) def __invert__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ile_u")) + @guppy.hugr_op(int_op("ile_u")) def __le__(self: nat, other: nat) -> bool: ... - @guppy.hugr_op(builtins, int_op("ishl", n_vars=2)) + @guppy.hugr_op(int_op("ishl", n_vars=2)) def __lshift__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ilt_u")) + @guppy.hugr_op(int_op("ilt_u")) def __lt__(self: nat, other: nat) -> bool: ... - @guppy.hugr_op(builtins, int_op("imod_u", n_vars=2)) + @guppy.hugr_op(int_op("imod_u", n_vars=2)) def __mod__(self: nat, other: nat) -> int: ... - @guppy.hugr_op(builtins, int_op("imul")) + @guppy.hugr_op(int_op("imul")) def __mul__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __nat__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ine")) + @guppy.hugr_op(int_op("ine")) def __ne__(self: nat, other: nat) -> bool: ... - @guppy.custom(builtins, checker=DunderChecker("__nat__"), higher_order_value=False) + @guppy.custom(checker=DunderChecker("__nat__"), higher_order_value=False) def __new__(x): ... - @guppy.hugr_op(builtins, int_op("ior")) + @guppy.hugr_op(int_op("ior")) def __or__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __pos__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ipow")) + @guppy.hugr_op(int_op("ipow")) def __pow__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("iadd"), ReversingChecker()) + @guppy.hugr_op(int_op("iadd"), ReversingChecker()) def __radd__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("iand"), ReversingChecker()) + @guppy.hugr_op(int_op("iand"), ReversingChecker()) def __rand__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op( - builtins, - int_op("idivmod_u"), - ReversingChecker(), - ) + @guppy.hugr_op(int_op("idivmod_u"), ReversingChecker()) def __rdivmod__(self: nat, other: nat) -> tuple[nat, nat]: ... - @guppy.hugr_op(builtins, int_op("idiv_u"), ReversingChecker()) + @guppy.hugr_op(int_op("idiv_u"), ReversingChecker()) def __rfloordiv__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ishl"), ReversingChecker()) + @guppy.hugr_op(int_op("ishl"), ReversingChecker()) def __rlshift__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("imod_u"), ReversingChecker()) + @guppy.hugr_op(int_op("imod_u"), ReversingChecker()) def __rmod__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("imul"), ReversingChecker()) + @guppy.hugr_op(int_op("imul"), ReversingChecker()) def __rmul__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ior"), ReversingChecker()) + @guppy.hugr_op(int_op("ior"), ReversingChecker()) def __ror__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __round__(self: nat) -> nat: ... - @guppy.hugr_op( - builtins, - int_op("ipow"), - ReversingChecker(), - ) + @guppy.hugr_op(int_op("ipow"), ReversingChecker()) def __rpow__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ishr"), ReversingChecker()) + @guppy.hugr_op(int_op("ishr"), ReversingChecker()) def __rrshift__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ishr")) + @guppy.hugr_op(int_op("ishr")) def __rshift__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("isub"), ReversingChecker()) + @guppy.hugr_op(int_op("isub"), ReversingChecker()) def __rsub__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, NatTruedivCompiler(), ReversingChecker()) + @guppy.custom(NatTruedivCompiler(), ReversingChecker()) def __rtruediv__(self: nat, other: nat) -> float: ... - @guppy.hugr_op(builtins, int_op("ixor"), ReversingChecker()) + @guppy.hugr_op(int_op("ixor"), ReversingChecker()) def __rxor__(self: nat, other: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("isub")) + @guppy.hugr_op(int_op("isub")) def __sub__(self: nat, other: nat) -> nat: ... - @guppy.custom(builtins, NatTruedivCompiler()) + @guppy.custom(NatTruedivCompiler()) def __truediv__(self: nat, other: nat) -> float: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __trunc__(self: nat) -> nat: ... - @guppy.hugr_op(builtins, int_op("ixor")) + @guppy.hugr_op(int_op("ixor")) def __xor__(self: nat, other: nat) -> nat: ... -@guppy.extend_type(builtins, int_type_def) +@guppy.extend_type(int_type_def) class Int: - @guppy.hugr_op(builtins, int_op("iabs")) # TODO: Maybe wrong? (signed vs unsigned!) + @guppy.hugr_op(int_op("iabs")) # TODO: Maybe wrong? (signed vs unsigned!) def __abs__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("iadd")) + @guppy.hugr_op(int_op("iadd")) def __add__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("iand")) + @guppy.hugr_op(int_op("iand")) def __and__(self: int, other: int) -> int: ... - @guppy.custom(builtins, IToBoolCompiler()) + @guppy.custom(IToBoolCompiler()) def __bool__(self: int) -> bool: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __ceil__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("idivmod_s")) + @guppy.hugr_op(int_op("idivmod_s")) def __divmod__(self: int, other: int) -> tuple[int, int]: ... - @guppy.hugr_op(builtins, int_op("ieq")) + @guppy.hugr_op(int_op("ieq")) def __eq__(self: int, other: int) -> bool: ... - @guppy.hugr_op(builtins, int_op("convert_s", hugr.std.int.CONVERSIONS_EXTENSION)) + @guppy.hugr_op(int_op("convert_s", hugr.std.int.CONVERSIONS_EXTENSION)) def __float__(self: int) -> float: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __floor__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("idiv_s")) + @guppy.hugr_op(int_op("idiv_s")) def __floordiv__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ige_s")) + @guppy.hugr_op(int_op("ige_s")) def __ge__(self: int, other: int) -> bool: ... - @guppy.hugr_op(builtins, int_op("igt_s")) + @guppy.hugr_op(int_op("igt_s")) def __gt__(self: int, other: int) -> bool: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __int__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("inot")) + @guppy.hugr_op(int_op("inot")) def __invert__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ile_s")) + @guppy.hugr_op(int_op("ile_s")) def __le__(self: int, other: int) -> bool: ... - @guppy.hugr_op(builtins, int_op("ishl")) # TODO: RHS is unsigned + @guppy.hugr_op(int_op("ishl")) # TODO: RHS is unsigned def __lshift__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ilt_s")) + @guppy.hugr_op(int_op("ilt_s")) def __lt__(self: int, other: int) -> bool: ... - @guppy.hugr_op(builtins, int_op("imod_s")) + @guppy.hugr_op(int_op("imod_s")) def __mod__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("imul")) + @guppy.hugr_op(int_op("imul")) def __mul__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("is_to_u")) # TODO + @guppy.hugr_op(int_op("is_to_u")) # TODO def __nat__(self: int) -> nat: ... - @guppy.hugr_op(builtins, int_op("ine")) + @guppy.hugr_op(int_op("ine")) def __ne__(self: int, other: int) -> bool: ... - @guppy.hugr_op(builtins, int_op("ineg")) + @guppy.hugr_op(int_op("ineg")) def __neg__(self: int) -> int: ... - @guppy.custom(builtins, checker=DunderChecker("__int__"), higher_order_value=False) + @guppy.custom(checker=DunderChecker("__int__"), higher_order_value=False) def __new__(x): ... - @guppy.hugr_op(builtins, int_op("ior")) + @guppy.hugr_op(int_op("ior")) def __or__(self: int, other: int) -> int: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __pos__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ipow")) + @guppy.hugr_op(int_op("ipow")) def __pow__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("iadd"), ReversingChecker()) + @guppy.hugr_op(int_op("iadd"), ReversingChecker()) def __radd__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("iand"), ReversingChecker()) + @guppy.hugr_op(int_op("iand"), ReversingChecker()) def __rand__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("idivmod_s"), ReversingChecker()) + @guppy.hugr_op(int_op("idivmod_s"), ReversingChecker()) def __rdivmod__(self: int, other: int) -> tuple[int, int]: ... - @guppy.hugr_op(builtins, int_op("idiv_s"), ReversingChecker()) + @guppy.hugr_op(int_op("idiv_s"), ReversingChecker()) def __rfloordiv__(self: int, other: int) -> int: ... - @guppy.hugr_op( - builtins, int_op("ishl"), ReversingChecker() - ) # TODO: RHS is unsigned + @guppy.hugr_op(int_op("ishl"), ReversingChecker()) # TODO: RHS is unsigned def __rlshift__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("imod_s"), ReversingChecker()) + @guppy.hugr_op(int_op("imod_s"), ReversingChecker()) def __rmod__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("imul"), ReversingChecker()) + @guppy.hugr_op(int_op("imul"), ReversingChecker()) def __rmul__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ior"), ReversingChecker()) + @guppy.hugr_op(int_op("ior"), ReversingChecker()) def __ror__(self: int, other: int) -> int: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __round__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ipow"), ReversingChecker()) + @guppy.hugr_op(int_op("ipow"), ReversingChecker()) def __rpow__(self: int, other: int) -> int: ... - @guppy.hugr_op( - builtins, int_op("ishr"), ReversingChecker() - ) # TODO: RHS is unsigned + @guppy.hugr_op(int_op("ishr"), ReversingChecker()) # TODO: RHS is unsigned def __rrshift__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ishr")) # TODO: RHS is unsigned + @guppy.hugr_op(int_op("ishr")) # TODO: RHS is unsigned def __rshift__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("isub"), ReversingChecker()) + @guppy.hugr_op(int_op("isub"), ReversingChecker()) def __rsub__(self: int, other: int) -> int: ... - @guppy.custom(builtins, IntTruedivCompiler(), ReversingChecker()) + @guppy.custom(IntTruedivCompiler(), ReversingChecker()) def __rtruediv__(self: int, other: int) -> float: ... - @guppy.hugr_op(builtins, int_op("ixor"), ReversingChecker()) + @guppy.hugr_op(int_op("ixor"), ReversingChecker()) def __rxor__(self: int, other: int) -> int: ... - @guppy.hugr_op(builtins, int_op("isub")) + @guppy.hugr_op(int_op("isub")) def __sub__(self: int, other: int) -> int: ... - @guppy.custom(builtins, IntTruedivCompiler()) + @guppy.custom(IntTruedivCompiler()) def __truediv__(self: int, other: int) -> float: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __trunc__(self: int) -> int: ... - @guppy.hugr_op(builtins, int_op("ixor")) + @guppy.hugr_op(int_op("ixor")) def __xor__(self: int, other: int) -> int: ... -@guppy.extend_type(builtins, float_type_def) +@guppy.extend_type(float_type_def) class Float: - @guppy.hugr_op(builtins, float_op("fabs"), CoercingChecker()) + @guppy.hugr_op(float_op("fabs"), CoercingChecker()) def __abs__(self: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fadd"), CoercingChecker()) + @guppy.hugr_op(float_op("fadd"), CoercingChecker()) def __add__(self: float, other: float) -> float: ... - @guppy.custom(builtins, FloatBoolCompiler(), CoercingChecker()) + @guppy.custom(FloatBoolCompiler(), CoercingChecker()) def __bool__(self: float) -> bool: ... - @guppy.hugr_op(builtins, float_op("fceil"), CoercingChecker()) + @guppy.hugr_op(float_op("fceil"), CoercingChecker()) def __ceil__(self: float) -> float: ... - @guppy.custom(builtins, FloatDivmodCompiler(), CoercingChecker()) + @guppy.custom(FloatDivmodCompiler(), CoercingChecker()) def __divmod__(self: float, other: float) -> tuple[float, float]: ... - @guppy.hugr_op(builtins, float_op("feq"), CoercingChecker()) + @guppy.hugr_op(float_op("feq"), CoercingChecker()) def __eq__(self: float, other: float) -> bool: ... - @guppy.custom(builtins, NoopCompiler(), CoercingChecker()) + @guppy.custom(NoopCompiler(), CoercingChecker()) def __float__(self: float) -> float: ... - @guppy.hugr_op(builtins, float_op("ffloor"), CoercingChecker()) + @guppy.hugr_op(float_op("ffloor"), CoercingChecker()) def __floor__(self: float) -> float: ... - @guppy.custom(builtins, FloatFloordivCompiler(), CoercingChecker()) + @guppy.custom(FloatFloordivCompiler(), CoercingChecker()) def __floordiv__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fge"), CoercingChecker()) + @guppy.hugr_op(float_op("fge"), CoercingChecker()) def __ge__(self: float, other: float) -> bool: ... - @guppy.hugr_op(builtins, float_op("fgt"), CoercingChecker()) + @guppy.hugr_op(float_op("fgt"), CoercingChecker()) def __gt__(self: float, other: float) -> bool: ... @guppy.hugr_op( - builtins, unsupported_op("trunc_s"), CoercingChecker() + unsupported_op("trunc_s"), CoercingChecker() ) # TODO `trunc_s` returns an option def __int__(self: float) -> int: ... - @guppy.hugr_op(builtins, float_op("fle"), CoercingChecker()) + @guppy.hugr_op(float_op("fle"), CoercingChecker()) def __le__(self: float, other: float) -> bool: ... - @guppy.hugr_op(builtins, float_op("flt"), CoercingChecker()) + @guppy.hugr_op(float_op("flt"), CoercingChecker()) def __lt__(self: float, other: float) -> bool: ... - @guppy.custom(builtins, FloatModCompiler(), CoercingChecker()) + @guppy.custom(FloatModCompiler(), CoercingChecker()) def __mod__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fmul"), CoercingChecker()) + @guppy.hugr_op(float_op("fmul"), CoercingChecker()) def __mul__(self: float, other: float) -> float: ... @guppy.hugr_op( - builtins, unsupported_op("trunc_u"), CoercingChecker() + unsupported_op("trunc_u"), CoercingChecker() ) # TODO `trunc_u` returns an option def __nat__(self: float) -> nat: ... - @guppy.hugr_op(builtins, float_op("fne"), CoercingChecker()) + @guppy.hugr_op(float_op("fne"), CoercingChecker()) def __ne__(self: float, other: float) -> bool: ... - @guppy.hugr_op(builtins, float_op("fneg"), CoercingChecker()) + @guppy.hugr_op(float_op("fneg"), CoercingChecker()) def __neg__(self: float) -> float: ... - @guppy.custom( - builtins, checker=DunderChecker("__float__"), higher_order_value=False - ) + @guppy.custom(checker=DunderChecker("__float__"), higher_order_value=False) def __new__(x): ... - @guppy.custom(builtins, NoopCompiler(), CoercingChecker()) + @guppy.custom(NoopCompiler(), CoercingChecker()) def __pos__(self: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fpow")) # TODO + @guppy.hugr_op(float_op("fpow")) # TODO def __pow__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fadd"), ReversingChecker(CoercingChecker())) + @guppy.hugr_op(float_op("fadd"), ReversingChecker(CoercingChecker())) def __radd__(self: float, other: float) -> float: ... - @guppy.custom(builtins, FloatDivmodCompiler(), ReversingChecker(CoercingChecker())) + @guppy.custom(FloatDivmodCompiler(), ReversingChecker(CoercingChecker())) def __rdivmod__(self: float, other: float) -> tuple[float, float]: ... - @guppy.custom( - builtins, FloatFloordivCompiler(), ReversingChecker(CoercingChecker()) - ) + @guppy.custom(FloatFloordivCompiler(), ReversingChecker(CoercingChecker())) def __rfloordiv__(self: float, other: float) -> float: ... - @guppy.custom(builtins, FloatModCompiler(), ReversingChecker(CoercingChecker())) + @guppy.custom(FloatModCompiler(), ReversingChecker(CoercingChecker())) def __rmod__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fmul"), ReversingChecker(CoercingChecker())) + @guppy.hugr_op(float_op("fmul"), ReversingChecker(CoercingChecker())) def __rmul__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fround")) # TODO + @guppy.hugr_op(float_op("fround")) # TODO def __round__(self: float) -> float: ... @guppy.hugr_op( - builtins, float_op("fpow"), ReversingChecker(DefaultCallChecker()), ) # TODO def __rpow__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fsub"), ReversingChecker(CoercingChecker())) + @guppy.hugr_op(float_op("fsub"), ReversingChecker(CoercingChecker())) def __rsub__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fdiv"), ReversingChecker(CoercingChecker())) + @guppy.hugr_op(float_op("fdiv"), ReversingChecker(CoercingChecker())) def __rtruediv__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fsub"), CoercingChecker()) + @guppy.hugr_op(float_op("fsub"), CoercingChecker()) def __sub__(self: float, other: float) -> float: ... - @guppy.hugr_op(builtins, float_op("fdiv"), CoercingChecker()) + @guppy.hugr_op(float_op("fdiv"), CoercingChecker()) def __truediv__(self: float, other: float) -> float: ... @guppy.hugr_op( - builtins, unsupported_op("trunc_s"), CoercingChecker() + unsupported_op("trunc_s"), CoercingChecker() ) # TODO `trunc_s` returns an option def __trunc__(self: float) -> float: ... -@guppy.extend_type(builtins, list_type_def) +@guppy.extend_type(list_type_def) class List: - @guppy.hugr_op(builtins, unsupported_op("Append")) + @guppy.hugr_op(unsupported_op("Append")) def __add__(self: list[T], other: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, unsupported_op("IsEmpty")) + @guppy.hugr_op(unsupported_op("IsEmpty")) def __bool__(self: list[T]) -> bool: ... - @guppy.hugr_op(builtins, unsupported_op("Contains")) + @guppy.hugr_op(unsupported_op("Contains")) def __contains__(self: list[T], el: T) -> bool: ... - @guppy.hugr_op(builtins, unsupported_op("AssertEmpty")) + @guppy.hugr_op(unsupported_op("AssertEmpty")) def __end__(self: list[T]) -> None: ... - @guppy.hugr_op(builtins, unsupported_op("Lookup")) + @guppy.hugr_op(unsupported_op("Lookup")) def __getitem__(self: list[T], idx: int) -> T: ... - @guppy.hugr_op(builtins, unsupported_op("IsNotEmpty")) + @guppy.hugr_op(unsupported_op("IsNotEmpty")) def __hasnext__(self: list[T]) -> tuple[bool, list[T]]: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __iter__(self: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, unsupported_op("Length")) + @guppy.hugr_op(unsupported_op("Length")) def __len__(self: list[T]) -> int: ... - @guppy.hugr_op(builtins, unsupported_op("Repeat")) + @guppy.hugr_op(unsupported_op("Repeat")) def __mul__(self: list[T], other: int) -> list[T]: ... - @guppy.hugr_op(builtins, unsupported_op("Pop")) + @guppy.hugr_op(unsupported_op("Pop")) def __next__(self: list[T]) -> tuple[T, list[T]]: ... - @guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) + @guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def __new__(x): ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def __setitem__(self: list[T], idx: int, value: T) -> None: ... - @guppy.hugr_op(builtins, unsupported_op("Append"), ReversingChecker()) + @guppy.hugr_op(unsupported_op("Append"), ReversingChecker()) def __radd__(self: list[T], other: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, unsupported_op("Repeat")) + @guppy.hugr_op(unsupported_op("Repeat")) def __rmul__(self: list[T], other: int) -> list[T]: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def append(self: list[T], elt: T) -> None: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def clear(self: list[T]) -> None: ... - @guppy.custom(builtins, NoopCompiler()) # Can be noop since lists are immutable + @guppy.custom(NoopCompiler()) # Can be noop since lists are immutable def copy(self: list[T]) -> list[T]: ... - @guppy.hugr_op(builtins, unsupported_op("Count")) + @guppy.hugr_op(unsupported_op("Count")) def count(self: list[T], elt: T) -> int: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def extend(self: list[T], seq: None) -> None: ... - @guppy.hugr_op(builtins, unsupported_op("Find")) + @guppy.hugr_op(unsupported_op("Find")) def index(self: list[T], elt: T) -> int: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def pop(self: list[T], idx: int) -> None: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def remove(self: list[T], elt: T) -> None: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def reverse(self: list[T]) -> None: ... - @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) + @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) def sort(self: list[T]) -> None: ... linst = list -@guppy.extend_type(builtins, linst_type_def) +@guppy.extend_type(linst_type_def) class Linst: - @guppy.hugr_op(builtins, unsupported_op("Append")) + @guppy.hugr_op(unsupported_op("Append")) def __add__(self: linst[L] @ owned, other: linst[L] @ owned) -> linst[L]: ... - @guppy.hugr_op(builtins, unsupported_op("AssertEmpty")) + @guppy.hugr_op(unsupported_op("AssertEmpty")) def __end__(self: linst[L] @ owned) -> None: ... - @guppy.hugr_op(builtins, unsupported_op("IsNotEmpty")) + @guppy.hugr_op(unsupported_op("IsNotEmpty")) def __hasnext__(self: linst[L] @ owned) -> tuple[bool, linst[L]]: ... - @guppy.custom(builtins, NoopCompiler()) + @guppy.custom(NoopCompiler()) def __iter__(self: linst[L] @ owned) -> linst[L]: ... - @guppy.hugr_op(builtins, unsupported_op("Length")) + @guppy.hugr_op(unsupported_op("Length")) def __len__(self: linst[L] @ owned) -> tuple[int, linst[L]]: ... - @guppy.hugr_op(builtins, unsupported_op("Pop")) + @guppy.hugr_op(unsupported_op("Pop")) def __next__(self: linst[L] @ owned) -> tuple[L, linst[L]]: ... @@ -628,346 +610,340 @@ def __next__(self: linst[L] @ owned) -> tuple[L, linst[L]]: ... # @guppy.hugr_op(builtins, unsupported_op("Append"), ReversingChecker()) # def __radd__(self: linst[L] @owned, other: linst[L] @owned) -> linst[L]: ... # -# @guppy.hugr_op(builtins, unsupported_op("Repeat")) +# @guppy.hugr_op(unsupported_op("Repeat")) # def __rmul__(self: linst[L] @owned, other: int) -> linst[L]: ... # -# @guppy.hugr_op(builtins, unsupported_op("Push")) +# @guppy.hugr_op(unsupported_op("Push")) # def append(self: linst[L] @owned, elt: L @owned) -> linst[L]: ... # -# @guppy.hugr_op(builtins, unsupported_op("PopAt")) +# @guppy.hugr_op(unsupported_op("PopAt")) # def pop(self: linst[L] @owned, idx: int) -> tuple[L, linst[L]]: ... # -# @guppy.hugr_op(builtins, unsupported_op("Reverse")) +# @guppy.hugr_op(unsupported_op("Reverse")) # def reverse(self: linst[L] @owned) -> linst[L]: ... # -# @guppy.custom(builtins, checker=FailingChecker("Guppy lists are immutable")) +# @guppy.custom(checker=FailingChecker("Guppy lists are immutable")) # def sort(self: linst[T] @owned) -> None: ... -n = guppy.nat_var(builtins, "n") +n = guppy.nat_var("n") -@guppy.extend_type(builtins, array_type_def) +@guppy.extend_type(array_type_def) class Array: - @guppy.custom(builtins, ArrayGetitemCompiler()) + @guppy.custom(ArrayGetitemCompiler()) def __getitem__(self: array[L, n], idx: int) -> L: ... - @guppy.custom(builtins, ArraySetitemCompiler()) + @guppy.custom(ArraySetitemCompiler()) def __setitem__(self: array[L, n], idx: int, value: L @ owned) -> None: ... - @guppy.custom(builtins, checker=ArrayLenChecker()) + @guppy.custom(checker=ArrayLenChecker()) def __len__(self: array[T, n]) -> int: ... - @guppy.custom( - builtins, NewArrayCompiler(), NewArrayChecker(), higher_order_value=False - ) + @guppy.custom(NewArrayCompiler(), NewArrayChecker(), higher_order_value=False) def __new__(): ... # TODO: This is a temporary hack until we have implemented the proper results mechanism. -@guppy.custom(builtins, checker=ResultChecker(), higher_order_value=False) +@guppy.custom(checker=ResultChecker(), higher_order_value=False) def result(tag, value): ... -@guppy.custom(builtins, checker=DunderChecker("__abs__"), higher_order_value=False) +@guppy.custom(checker=DunderChecker("__abs__"), higher_order_value=False) def abs(x): ... -@guppy.custom(builtins, checker=CallableChecker(), higher_order_value=False) +@guppy.custom(checker=CallableChecker(), higher_order_value=False) def callable(x): ... -@guppy.custom( - builtins, checker=DunderChecker("__divmod__", num_args=2), higher_order_value=False -) +@guppy.custom(checker=DunderChecker("__divmod__", num_args=2), higher_order_value=False) def divmod(x, y): ... -@guppy.custom(builtins, checker=DunderChecker("__len__"), higher_order_value=False) +@guppy.custom(checker=DunderChecker("__len__"), higher_order_value=False) def len(x): ... -@guppy.custom( - builtins, checker=DunderChecker("__pow__", num_args=2), higher_order_value=False -) +@guppy.custom(checker=DunderChecker("__pow__", num_args=2), higher_order_value=False) def pow(x, y): ... -@guppy.custom(builtins, checker=DunderChecker("__round__"), higher_order_value=False) +@guppy.custom(checker=DunderChecker("__round__"), higher_order_value=False) def round(x): ... # Python builtins that are not supported yet: -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def aiter(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def all(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def anext(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def any(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def bin(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def breakpoint(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def bytearray(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def bytes(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def chr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def classmethod(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def compile(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def complex(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def delattr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def dict(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def dir(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def enumerate(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def eval(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def exec(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def filter(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def format(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def forozenset(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def getattr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def globals(): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def hasattr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def hash(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def help(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def hex(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def id(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def input(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def isinstance(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def issubclass(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def iter(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def locals(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def map(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def max(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def memoryview(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def min(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def next(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def object(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def oct(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def open(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def ord(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def print(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def property(x): ... -@guppy.struct(builtins) +@guppy.struct class Range: stop: int - @guppy(builtins) + @guppy def __iter__(self: "Range") -> "RangeIter": return RangeIter(0, self.stop) # type: ignore[call-arg] -@guppy.struct(builtins) +@guppy.struct class RangeIter: next: int stop: int - @guppy(builtins) + @guppy def __iter__(self: "RangeIter") -> "RangeIter": return self - @guppy(builtins) + @guppy def __hasnext__(self: "RangeIter") -> tuple[bool, "RangeIter"]: return (self.next < self.stop, self) - @guppy(builtins) + @guppy def __next__(self: "RangeIter") -> tuple[int, "RangeIter"]: # Fine not to check bounds while we can only be called from inside a `for` loop. # if self.start >= self.stop: # raise StopIteration return (self.next, RangeIter(self.next + 1, self.stop)) # type: ignore[call-arg] - @guppy(builtins) + @guppy def __end__(self: "RangeIter") -> None: pass -@guppy(builtins) +@guppy def range(stop: int) -> Range: """Limited version of python range(). Only a single argument (stop/limit) is supported.""" return Range(stop) # type: ignore[call-arg] -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def repr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def reversed(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def set(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def setattr(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def slice(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def sorted(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def staticmethod(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def str(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def sum(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def super(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def type(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def vars(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def zip(x): ... -@guppy.custom(builtins, checker=UnsupportedChecker(), higher_order_value=False) +@guppy.custom(checker=UnsupportedChecker(), higher_order_value=False) def __import__(x): ... diff --git a/guppylang/prelude/quantum.py b/guppylang/prelude/quantum.py index 454ecd01..56bdf2e6 100644 --- a/guppylang/prelude/quantum.py +++ b/guppylang/prelude/quantum.py @@ -7,7 +7,6 @@ from hugr import tys as ht from guppylang.decorator import guppy -from guppylang.module import GuppyModule from guppylang.prelude._internal.compiler.quantum import ( HSERIES_EXTENSION, MeasureReturnCompiler, @@ -16,13 +15,10 @@ from guppylang.prelude.angles import angle from guppylang.prelude.builtins import owned -quantum = GuppyModule("quantum") -quantum.load(angle) - -@guppy.type(quantum, ht.Qubit, linear=True) +@guppy.type(ht.Qubit, linear=True) class qubit: - @guppy(quantum) + @guppy @no_type_check def __new__() -> "qubit": q = dirty_qubit() @@ -30,71 +26,71 @@ def __new__() -> "qubit": return q -@guppy.hugr_op(quantum, quantum_op("H")) +@guppy.hugr_op(quantum_op("H")) def h(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("CZ")) +@guppy.hugr_op(quantum_op("CZ")) def cz(control: qubit, target: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("CX")) +@guppy.hugr_op(quantum_op("CX")) def cx(control: qubit, target: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("T")) +@guppy.hugr_op(quantum_op("T")) def t(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("S")) +@guppy.hugr_op(quantum_op("S")) def s(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("X")) +@guppy.hugr_op(quantum_op("X")) def x(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Y")) +@guppy.hugr_op(quantum_op("Y")) def y(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Z")) +@guppy.hugr_op(quantum_op("Z")) def z(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Tdg")) +@guppy.hugr_op(quantum_op("Tdg")) def tdg(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Sdg")) +@guppy.hugr_op(quantum_op("Sdg")) def sdg(q: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("ZZMax", ext=HSERIES_EXTENSION)) +@guppy.hugr_op(quantum_op("ZZMax", ext=HSERIES_EXTENSION)) def zz_max(q1: qubit, q2: qubit) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Rz")) +@guppy.hugr_op(quantum_op("Rz")) def rz(q: qubit, angle: angle) -> None: ... -@guppy.hugr_op(quantum, quantum_op("Rx")) +@guppy.hugr_op(quantum_op("Rx")) def rx(q: qubit, angle: angle) -> None: ... -@guppy.hugr_op(quantum, quantum_op("QAlloc")) +@guppy.hugr_op(quantum_op("QAlloc")) def dirty_qubit() -> qubit: ... -@guppy.custom(quantum, MeasureReturnCompiler()) +@guppy.custom(MeasureReturnCompiler()) def measure_return(q: qubit) -> bool: ... -@guppy.hugr_op(quantum, quantum_op("QFree")) +@guppy.hugr_op(quantum_op("QFree")) def discard(q: qubit @ owned) -> None: ... -@guppy(quantum) +@guppy @no_type_check def measure(q: qubit @ owned) -> bool: res = measure_return(q) @@ -102,7 +98,7 @@ def measure(q: qubit @ owned) -> bool: return res -@guppy(quantum) +@guppy @no_type_check def phased_x(q: qubit, angle1: angle, angle2: angle) -> None: f1 = float(angle1) @@ -110,14 +106,14 @@ def phased_x(q: qubit, angle1: angle, angle2: angle) -> None: _phased_x(q, f1, f2) -@guppy(quantum) +@guppy @no_type_check def zz_phase(q1: qubit, q2: qubit, angle: angle) -> None: f = float(angle) _zz_phase(q1, q2, f) -@guppy.hugr_op(quantum, quantum_op("Reset")) +@guppy.hugr_op(quantum_op("Reset")) def reset(q: qubit) -> None: ... @@ -126,7 +122,7 @@ def reset(q: qubit) -> None: ... # ------------------------------------------------------ -@guppy.hugr_op(quantum, quantum_op("PhasedX", ext=HSERIES_EXTENSION)) +@guppy.hugr_op(quantum_op("PhasedX", ext=HSERIES_EXTENSION)) def _phased_x(q: qubit, angle1: float, angle2: float) -> None: """PhasedX operation from the hseries extension. @@ -135,7 +131,7 @@ def _phased_x(q: qubit, angle1: float, angle2: float) -> None: """ -@guppy.hugr_op(quantum, quantum_op("ZZPhase", ext=HSERIES_EXTENSION)) +@guppy.hugr_op(quantum_op("ZZPhase", ext=HSERIES_EXTENSION)) def _zz_phase(q1: qubit, q2: qubit, angle: float) -> None: """ZZPhase operation from the hseries extension. diff --git a/tests/error/inout_errors/already_used.py b/tests/error/inout_errors/already_used.py index 5f037367..08d24357 100644 --- a/tests/error/inout_errors/already_used.py +++ b/tests/error/inout_errors/already_used.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/conflict.py b/tests/error/inout_errors/conflict.py index 4abc27a6..eb8b9517 100644 --- a/tests/error/inout_errors/conflict.py +++ b/tests/error/inout_errors/conflict.py @@ -3,11 +3,11 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/drop_after_call.py b/tests/error/inout_errors/drop_after_call.py index 61e81f81..38ab7e08 100644 --- a/tests/error/inout_errors/drop_after_call.py +++ b/tests/error/inout_errors/drop_after_call.py @@ -1,9 +1,9 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/moved.py b/tests/error/inout_errors/moved.py index 83057117..ecbafaec 100644 --- a/tests/error/inout_errors/moved.py +++ b/tests/error/inout_errors/moved.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/moved_assign.py b/tests/error/inout_errors/moved_assign.py index 6088fc52..a26f2548 100644 --- a/tests/error/inout_errors/moved_assign.py +++ b/tests/error/inout_errors/moved_assign.py @@ -1,9 +1,9 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy(module) diff --git a/tests/error/inout_errors/moved_if.py b/tests/error/inout_errors/moved_if.py index 173d8a69..b4a284cd 100644 --- a/tests/error/inout_errors/moved_if.py +++ b/tests/error/inout_errors/moved_if.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/moved_out.py b/tests/error/inout_errors/moved_out.py index ae8938ad..eb3d9361 100644 --- a/tests/error/inout_errors/moved_out.py +++ b/tests/error/inout_errors/moved_out.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.struct(module) diff --git a/tests/error/inout_errors/moved_out_if.py b/tests/error/inout_errors/moved_out_if.py index 6e3e733a..951fc35a 100644 --- a/tests/error/inout_errors/moved_out_if.py +++ b/tests/error/inout_errors/moved_out_if.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.struct(module) diff --git a/tests/error/inout_errors/nested_call_right_to_left.py b/tests/error/inout_errors/nested_call_right_to_left.py index 8924ee3a..d82f787f 100644 --- a/tests/error/inout_errors/nested_call_right_to_left.py +++ b/tests/error/inout_errors/nested_call_right_to_left.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/override_after_call.py b/tests/error/inout_errors/override_after_call.py index fe43d8aa..18bdcf5c 100644 --- a/tests/error/inout_errors/override_after_call.py +++ b/tests/error/inout_errors/override_after_call.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/shadow.py b/tests/error/inout_errors/shadow.py index a82eb47c..caee9b1b 100644 --- a/tests/error/inout_errors/shadow.py +++ b/tests/error/inout_errors/shadow.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy(module) diff --git a/tests/error/inout_errors/shadow_if.py b/tests/error/inout_errors/shadow_if.py index 27100c52..b8be43b2 100644 --- a/tests/error/inout_errors/shadow_if.py +++ b/tests/error/inout_errors/shadow_if.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy(module) diff --git a/tests/error/inout_errors/struct_constructor.py b/tests/error/inout_errors/struct_constructor.py index 129134eb..dc8432a2 100644 --- a/tests/error/inout_errors/struct_constructor.py +++ b/tests/error/inout_errors/struct_constructor.py @@ -1,9 +1,9 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.struct(module) diff --git a/tests/error/inout_errors/subscript_not_setable.py b/tests/error/inout_errors/subscript_not_setable.py index da036584..7b630397 100644 --- a/tests/error/inout_errors/subscript_not_setable.py +++ b/tests/error/inout_errors/subscript_not_setable.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/inout_errors/unused_after_call.py b/tests/error/inout_errors/unused_after_call.py index 4c74509e..9989f16b 100644 --- a/tests/error/inout_errors/unused_after_call.py +++ b/tests/error/inout_errors/unused_after_call.py @@ -1,10 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/iter_errors/end_missing.py b/tests/error/iter_errors/end_missing.py index e21b5b6c..2e4a8b9e 100644 --- a/tests/error/iter_errors/end_missing.py +++ b/tests/error/iter_errors/end_missing.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator that is missing the `__end__` method.""" @@ -19,7 +19,7 @@ def __hasnext__(self: "MyIter") -> tuple[bool, "MyIter"]: ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 02c6248c..949df053 100644 --- a/tests/error/iter_errors/end_wrong_type.py +++ b/tests/error/iter_errors/end_wrong_type.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator where the `__end__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> "MyIter": ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 3b3f25e0..b9b44a6e 100644 --- a/tests/error/iter_errors/hasnext_missing.py +++ b/tests/error/iter_errors/hasnext_missing.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator that is missing the `__hasnext__` method.""" @@ -19,7 +19,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 0e96b983..e3ab045a 100644 --- a/tests/error/iter_errors/hasnext_wrong_type.py +++ b/tests/error/iter_errors/hasnext_wrong_type.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator where the `__hasnext__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 41e923c7..db546b8a 100644 --- a/tests/error/iter_errors/iter_missing.py +++ b/tests/error/iter_errors/iter_missing.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType()) +@guppy.type(NoneType(), module=module) 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 64f837f8..84467343 100644 --- a/tests/error/iter_errors/iter_wrong_type.py +++ b/tests/error/iter_errors/iter_wrong_type.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 ec0f3f2c..2e11c639 100644 --- a/tests/error/iter_errors/next_missing.py +++ b/tests/error/iter_errors/next_missing.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator that is missing the `__next__` method.""" @@ -19,7 +19,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) 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 c1f8f53e..812e696d 100644 --- a/tests/error/iter_errors/next_wrong_type.py +++ b/tests/error/iter_errors/next_wrong_type.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator where the `__next__` method has the wrong signature.""" @@ -23,7 +23,7 @@ def __end__(self: "MyIter") -> None: ... -@guppy.type(module, NoneType().to_hugr()) +@guppy.type(NoneType().to_hugr(), module=module) class MyType: """Type that produces the iterator above.""" diff --git a/tests/error/linear_errors/unused_expr.err b/tests/error/linear_errors/unused_expr.err index e96b1ee4..c43033b4 100644 --- a/tests/error/linear_errors/unused_expr.err +++ b/tests/error/linear_errors/unused_expr.err @@ -1,7 +1,7 @@ -Guppy compilation failed. Error in file $FILE:14 +Guppy compilation failed. Error in file $FILE:13 -12: @guppy(module) -13: def foo(q: qubit @owned) -> None: -14: h(q) +11: @guppy(module) +12: def foo(q: qubit @owned) -> None: +13: h(q) ^^^^ GuppyTypeError: Value with linear type `qubit` is not used diff --git a/tests/error/linear_errors/unused_expr.py b/tests/error/linear_errors/unused_expr.py index 65fb2625..6f90a930 100644 --- a/tests/error/linear_errors/unused_expr.py +++ b/tests/error/linear_errors/unused_expr.py @@ -1,12 +1,11 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit from guppylang.prelude.quantum_functional import h module = GuppyModule("test") -module.load_all(quantum) -module.load(h) +module.load(qubit, h) @guppy(module) diff --git a/tests/error/linear_errors/while_unused.err b/tests/error/linear_errors/while_unused.err index f6a5b2fa..9f02819b 100644 --- a/tests/error/linear_errors/while_unused.err +++ b/tests/error/linear_errors/while_unused.err @@ -1,7 +1,7 @@ -Guppy compilation failed. Error in file $FILE:13 +Guppy compilation failed. Error in file $FILE:12 -11: @guppy(module) -12: def test(n: int) -> None: -13: q = qubit() +10: @guppy(module) +11: def test(n: int) -> None: +12: q = qubit() ^ GuppyError: Variable `q` with linear type `qubit` is not used on all control-flow paths diff --git a/tests/error/linear_errors/while_unused.py b/tests/error/linear_errors/while_unused.py index cacb04ea..1fd83834 100644 --- a/tests/error/linear_errors/while_unused.py +++ b/tests/error/linear_errors/while_unused.py @@ -1,11 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit from guppylang.prelude.quantum_functional import h module = GuppyModule("test") -module.load_all(quantum) -module.load(h) +module.load(qubit, h) @guppy(module) diff --git a/tests/error/misc_errors/extern_bad_type.err b/tests/error/misc_errors/extern_bad_type.err index 382e00ea..1d4d85b7 100644 --- a/tests/error/misc_errors/extern_bad_type.err +++ b/tests/error/misc_errors/extern_bad_type.err @@ -2,6 +2,6 @@ Guppy compilation failed. Error in file $FILE:9 7: module = GuppyModule("test") 8: -9: guppy.extern(module, "x", ty="float[int]") - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +9: guppy.extern("x", ty="float[int]", module=module) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GuppyError: Type `float` is not parameterized diff --git a/tests/error/misc_errors/extern_bad_type.py b/tests/error/misc_errors/extern_bad_type.py index 4f8e044d..adf4e5c2 100644 --- a/tests/error/misc_errors/extern_bad_type.py +++ b/tests/error/misc_errors/extern_bad_type.py @@ -7,6 +7,6 @@ module = GuppyModule("test") -guppy.extern(module, "x", ty="float[int]") +guppy.extern("x", ty="float[int]", module=module) module.compile() diff --git a/tests/error/misc_errors/nested_arg_flag.py b/tests/error/misc_errors/nested_arg_flag.py index a66e6510..f2af08c3 100644 --- a/tests/error/misc_errors/nested_arg_flag.py +++ b/tests/error/misc_errors/nested_arg_flag.py @@ -1,11 +1,11 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/misc_errors/return_flag.py b/tests/error/misc_errors/return_flag.py index 2b9be101..78b576fe 100644 --- a/tests/error/misc_errors/return_flag.py +++ b/tests/error/misc_errors/return_flag.py @@ -1,11 +1,11 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/misc_errors/return_flag_callable.py b/tests/error/misc_errors/return_flag_callable.py index 97ea9e32..79061edb 100644 --- a/tests/error/misc_errors/return_flag_callable.py +++ b/tests/error/misc_errors/return_flag_callable.py @@ -3,11 +3,11 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import owned -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.declare(module) diff --git a/tests/error/poly_errors/arg_mismatch1.py b/tests/error/poly_errors/arg_mismatch1.py index 31e5cc87..de7b28be 100644 --- a/tests/error/poly_errors/arg_mismatch1.py +++ b/tests/error/poly_errors/arg_mismatch1.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/arg_mismatch2.py b/tests/error/poly_errors/arg_mismatch2.py index eb52c542..a373037d 100644 --- a/tests/error/poly_errors/arg_mismatch2.py +++ b/tests/error/poly_errors/arg_mismatch2.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/arg_mismatch3.py b/tests/error/poly_errors/arg_mismatch3.py index e7fc3d97..515bee0f 100644 --- a/tests/error/poly_errors/arg_mismatch3.py +++ b/tests/error/poly_errors/arg_mismatch3.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -n = guppy.nat_var(module, "n") +n = guppy.nat_var("n", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/define.py b/tests/error/poly_errors/define.py index 4cb064ad..72d1ae57 100644 --- a/tests/error/poly_errors/define.py +++ b/tests/error/poly_errors/define.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy(module) diff --git a/tests/error/poly_errors/free_return_var.py b/tests/error/poly_errors/free_return_var.py index d03e1e24..d7078783 100644 --- a/tests/error/poly_errors/free_return_var.py +++ b/tests/error/poly_errors/free_return_var.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/inst_return_mismatch.py b/tests/error/poly_errors/inst_return_mismatch.py index b74af0ad..4b5f3572 100644 --- a/tests/error/poly_errors/inst_return_mismatch.py +++ b/tests/error/poly_errors/inst_return_mismatch.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/inst_return_mismatch_nested.py b/tests/error/poly_errors/inst_return_mismatch_nested.py index fc146a86..36c44adc 100644 --- a/tests/error/poly_errors/inst_return_mismatch_nested.py +++ b/tests/error/poly_errors/inst_return_mismatch_nested.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/non_linear1.py b/tests/error/poly_errors/non_linear1.py index 857ef37e..2f298bfc 100644 --- a/tests/error/poly_errors/non_linear1.py +++ b/tests/error/poly_errors/non_linear1.py @@ -8,7 +8,7 @@ module.load_all(quantum) -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/non_linear2.py b/tests/error/poly_errors/non_linear2.py index 26360157..710b3279 100644 --- a/tests/error/poly_errors/non_linear2.py +++ b/tests/error/poly_errors/non_linear2.py @@ -10,7 +10,7 @@ module.load_all(quantum) module.load(h) -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/non_linear3.py b/tests/error/poly_errors/non_linear3.py index 7ace1e63..c732c2f4 100644 --- a/tests/error/poly_errors/non_linear3.py +++ b/tests/error/poly_errors/non_linear3.py @@ -3,13 +3,13 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/pass_poly_free.py b/tests/error/poly_errors/pass_poly_free.py index 1e8d9c97..c6701390 100644 --- a/tests/error/poly_errors/pass_poly_free.py +++ b/tests/error/poly_errors/pass_poly_free.py @@ -6,7 +6,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/return_mismatch.py b/tests/error/poly_errors/return_mismatch.py index 14aafd49..85fc5dfb 100644 --- a/tests/error/poly_errors/return_mismatch.py +++ b/tests/error/poly_errors/return_mismatch.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/poly_errors/right_to_left.py b/tests/error/poly_errors/right_to_left.py index baee3ef7..2d356608 100644 --- a/tests/error/poly_errors/right_to_left.py +++ b/tests/error/poly_errors/right_to_left.py @@ -4,7 +4,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) diff --git a/tests/error/py_errors/tket2_not_installed.py b/tests/error/py_errors/tket2_not_installed.py index 10481287..8b619b71 100644 --- a/tests/error/py_errors/tket2_not_installed.py +++ b/tests/error/py_errors/tket2_not_installed.py @@ -2,13 +2,13 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit circ = Circuit(1) circ.H(0) module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy(module) diff --git a/tests/error/struct_errors/constructor_arg_mismatch_poly.py b/tests/error/struct_errors/constructor_arg_mismatch_poly.py index 8e2a609c..9ce8b60c 100644 --- a/tests/error/struct_errors/constructor_arg_mismatch_poly.py +++ b/tests/error/struct_errors/constructor_arg_mismatch_poly.py @@ -5,7 +5,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.struct(module) diff --git a/tests/error/struct_errors/invalid_instantiate1.py b/tests/error/struct_errors/invalid_instantiate1.py index 7ef70786..29828c6b 100644 --- a/tests/error/struct_errors/invalid_instantiate1.py +++ b/tests/error/struct_errors/invalid_instantiate1.py @@ -5,7 +5,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.struct(module) diff --git a/tests/error/struct_errors/invalid_instantiate2.py b/tests/error/struct_errors/invalid_instantiate2.py index 326e0e20..ef2fe640 100644 --- a/tests/error/struct_errors/invalid_instantiate2.py +++ b/tests/error/struct_errors/invalid_instantiate2.py @@ -5,7 +5,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.struct(module) diff --git a/tests/error/struct_errors/mutate_classical.py b/tests/error/struct_errors/mutate_classical.py index 5a4088b7..6becfeaa 100644 --- a/tests/error/struct_errors/mutate_classical.py +++ b/tests/error/struct_errors/mutate_classical.py @@ -1,9 +1,9 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule -from guppylang.prelude.quantum import quantum, qubit +from guppylang.prelude.quantum import qubit module = GuppyModule("test") -module.load_all(quantum) +module.load(qubit) @guppy.struct(module) diff --git a/tests/error/tensor_errors/poly_tensor.py b/tests/error/tensor_errors/poly_tensor.py index 0931b137..d963f84f 100644 --- a/tests/error/tensor_errors/poly_tensor.py +++ b/tests/error/tensor_errors/poly_tensor.py @@ -3,7 +3,7 @@ module = GuppyModule("test") -T = guppy.type_var(module, "T") +T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: diff --git a/tests/error/test_misc_errors.py b/tests/error/test_misc_errors.py index 842cf686..aa24b26f 100644 --- a/tests/error/test_misc_errors.py +++ b/tests/error/test_misc_errors.py @@ -28,4 +28,4 @@ def test_extern_bad_type_syntax(): module = GuppyModule("test") with pytest.raises(GuppyError, match="Not a valid Guppy type: `foo bar`"): - guppy.extern(module, name="x", ty="foo bar") + guppy.extern(name="x", ty="foo bar", module=module) diff --git a/tests/error/util.py b/tests/error/util.py index a2662615..7b753b73 100644 --- a/tests/error/util.py +++ b/tests/error/util.py @@ -29,7 +29,7 @@ def run_error_test(file, capsys): @decorator.guppy.type( - util, tys.Opaque(extension="", id="", args=[], bound=TypeBound.Copyable) + tys.Opaque(extension="", id="", args=[], bound=TypeBound.Copyable), module=util ) class NonBool: pass diff --git a/tests/integration/modules/mod_a.py b/tests/integration/modules/mod_a.py index 3a2d2488..792ad130 100644 --- a/tests/integration/modules/mod_a.py +++ b/tests/integration/modules/mod_a.py @@ -16,7 +16,7 @@ def f(x: int) -> int: def g() -> int: ... -@guppy.type(mod_a, ht.Bool) +@guppy.type(ht.Bool, module=mod_a) class MyType: @guppy.declare(mod_a) def __neg__(self: "MyType") -> "MyType": ... diff --git a/tests/integration/modules/mod_b.py b/tests/integration/modules/mod_b.py index 223c88c1..2e8e114d 100644 --- a/tests/integration/modules/mod_b.py +++ b/tests/integration/modules/mod_b.py @@ -11,7 +11,7 @@ def f(x: bool) -> bool: return not x -@guppy.hugr_op(mod_b, unsupported_op("h")) +@guppy.hugr_op(unsupported_op("h"), module=mod_b) def h() -> int: ... diff --git a/tests/integration/modules/mod_c.py b/tests/integration/modules/mod_c.py index fc638e89..9817c5b8 100644 --- a/tests/integration/modules/mod_c.py +++ b/tests/integration/modules/mod_c.py @@ -16,7 +16,7 @@ def h(x: int) -> int: # Extend type defined in module A -@guppy.extend_type(mod_c, MyType) +@guppy.extend_type(MyType, module=mod_c) class _: @guppy(mod_c) def __int__(self: "MyType") -> int: diff --git a/tests/integration/test_comprehension.py b/tests/integration/test_comprehension.py index f4c34a35..2c4632e8 100644 --- a/tests/integration/test_comprehension.py +++ b/tests/integration/test_comprehension.py @@ -247,7 +247,7 @@ def test_linear_next_nonlinear_iter(validate): module.load_all(quantum) module.load(qubit) - @guppy.type(module, NoneType().to_hugr()) + @guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator that yields linear values but is not linear itself.""" @@ -260,7 +260,7 @@ def __next__(self: "MyIter") -> tuple[qubit, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter") -> None: ... - @guppy.type(module, NoneType().to_hugr()) + @guppy.type(NoneType().to_hugr(), module=module) class MyType: """Type that produces the iterator above.""" @@ -281,9 +281,9 @@ def test_nonlinear_next_linear_iter(validate): module.load(qubit) @guppy.type( - module, tys.Opaque(extension="prelude", id="qubit", args=[], bound=tys.TypeBound.Any), linear=True, + module=module, ) class MyIter: """A linear iterator that yields non-linear values.""" @@ -297,7 +297,7 @@ def __next__(self: "MyIter" @owned) -> tuple[int, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter" @owned) -> None: ... - @guppy.type(module, NoneType().to_hugr()) + @guppy.type(NoneType().to_hugr(), module=module) class MyType: """Type that produces the iterator above.""" diff --git a/tests/integration/test_extern.py b/tests/integration/test_extern.py index 0449ec9f..83379546 100644 --- a/tests/integration/test_extern.py +++ b/tests/integration/test_extern.py @@ -8,7 +8,7 @@ def test_extern_float(validate): module = GuppyModule("module") - guppy.extern(module, "ext", ty="float") + guppy.extern("ext", ty="float", module=module) @guppy(module) def main() -> float: @@ -29,7 +29,7 @@ def main() -> float: def test_extern_alt_symbol(validate): module = GuppyModule("module") - guppy.extern(module, "ext", ty="int", symbol="foo") + guppy.extern("ext", ty="int", symbol="foo", module=module) @guppy(module) def main() -> int: @@ -50,7 +50,7 @@ def main() -> int: def test_extern_tuple(validate): module = GuppyModule("module") - guppy.extern(module, "ext", ty="tuple[int, float]") + guppy.extern("ext", ty="tuple[int, float]", module=module) @guppy(module) def main() -> float: diff --git a/tests/integration/test_linear.py b/tests/integration/test_linear.py index 0f6737f6..fe65c4c3 100644 --- a/tests/integration/test_linear.py +++ b/tests/integration/test_linear.py @@ -431,7 +431,7 @@ def test_for_nonlinear_break(validate): module.load_all(quantum_functional) module.load(qubit) - @guppy.type(module, NoneType().to_hugr()) + @guppy.type(NoneType().to_hugr(), module=module) class MyIter: """An iterator that yields linear values but is not linear itself.""" @@ -444,7 +444,7 @@ def __next__(self: "MyIter") -> tuple[qubit, "MyIter"]: ... @guppy.declare(module) def __end__(self: "MyIter") -> None: ... - @guppy.type(module, NoneType().to_hugr()) + @guppy.type(NoneType().to_hugr(), module=module) class MyType: """Type that produces the iterator above.""" diff --git a/tests/integration/test_poly.py b/tests/integration/test_poly.py index 8f2820e9..812f8bb9 100644 --- a/tests/integration/test_poly.py +++ b/tests/integration/test_poly.py @@ -15,7 +15,7 @@ def test_id(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -29,7 +29,7 @@ def main(x: int) -> int: def test_id_nested(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -43,7 +43,7 @@ def main(x: int) -> int: def test_use_twice(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -58,7 +58,7 @@ def main(x: int, y: bool) -> None: def test_define_twice(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -77,7 +77,7 @@ def main(x: bool, y: float) -> None: def test_return_tuple_implicit(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -91,7 +91,7 @@ def main(x: int) -> tuple[int, int]: def test_same_args(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: T, y: T) -> None: ... @@ -105,8 +105,8 @@ def main(x: int) -> None: def test_different_args(validate): module = GuppyModule("test") - S = guppy.type_var(module, "S") - T = guppy.type_var(module, "T") + S = guppy.type_var("S", module=module) + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(x: S, y: T, z: tuple[S, T]) -> T: ... @@ -120,7 +120,7 @@ def main(x: int, y: float) -> float: def test_nat_args(validate): module = GuppyModule("test") - n = guppy.nat_var(module, "n") + n = guppy.nat_var("n", module=module) @guppy.declare(module) def foo(x: array[int, n]) -> array[int, n]: ... @@ -132,7 +132,7 @@ def main(x: array[int, 42]) -> array[int, 42]: def test_infer_basic(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo() -> T: ... @@ -146,7 +146,7 @@ def main() -> None: def test_infer_list(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo() -> T: ... @@ -161,7 +161,7 @@ def main() -> None: def test_infer_nested(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo() -> T: ... @@ -178,8 +178,8 @@ def main() -> None: def test_infer_left_to_right(validate): module = GuppyModule("test") - S = guppy.type_var(module, "S") - T = guppy.type_var(module, "T") + S = guppy.type_var("S", module=module) + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo() -> T: ... @@ -196,7 +196,7 @@ def main() -> None: def test_pass_poly_basic(validate): module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(f: Callable[[T], T]) -> None: ... @@ -213,8 +213,8 @@ def main() -> None: def test_pass_poly_cross(validate): module = GuppyModule("test") - S = guppy.type_var(module, "S") - T = guppy.type_var(module, "T") + S = guppy.type_var("S", module=module) + T = guppy.type_var("T", module=module) @guppy.declare(module) def foo(f: Callable[[S], int]) -> None: ... @@ -232,7 +232,7 @@ def main() -> None: def test_linear(validate): module = GuppyModule("test") module.load_all(quantum) - T = guppy.type_var(module, "T", linear=True) + T = guppy.type_var("T", linear=True, module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -247,7 +247,7 @@ def main(q: qubit) -> qubit: def test_pass_nonlinear(validate): module = GuppyModule("test") module.load_all(quantum) - T = guppy.type_var(module, "T", linear=True) + T = guppy.type_var("T", linear=True, module=module) @guppy.declare(module) def foo(x: T) -> T: ... @@ -262,7 +262,7 @@ def main(x: int) -> None: def test_pass_linear(validate): module = GuppyModule("test") module.load_all(quantum) - T = guppy.type_var(module, "T", linear=True) + T = guppy.type_var("T", linear=True, module=module) @guppy.declare(module) def foo(f: Callable[[T], T]) -> None: ... @@ -283,7 +283,7 @@ def compile(self, args: list[Wire]) -> list[Wire]: return args module = GuppyModule("test") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.custom(module, CustomCompiler()) def foo(x: T) -> T: ... diff --git a/tests/integration/test_py.py b/tests/integration/test_py.py index 63cc8b94..492c5c85 100644 --- a/tests/integration/test_py.py +++ b/tests/integration/test_py.py @@ -7,7 +7,8 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule from guppylang.prelude.builtins import py -from guppylang.prelude.quantum import qubit, quantum +from guppylang.prelude import quantum +from guppylang.prelude.quantum import qubit from tests.util import compile_guppy tket2_installed = find_spec("tket2") is not None diff --git a/tests/integration/test_struct.py b/tests/integration/test_struct.py index 9b206c4a..07860a8c 100644 --- a/tests/integration/test_struct.py +++ b/tests/integration/test_struct.py @@ -81,8 +81,8 @@ def main(a: StructA, b: StructB) -> None: def test_generic(validate): module = GuppyModule("module") - S = guppy.type_var(module, "S") - T = guppy.type_var(module, "T") + S = guppy.type_var("S", module=module) + T = guppy.type_var("T", module=module) @guppy.struct(module) class StructA(Generic[T]): @@ -139,7 +139,7 @@ def main(a: StructA, b: StructB) -> tuple[int, float]: def test_higher_order(validate): module = GuppyModule("module") - T = guppy.type_var(module, "T") + T = guppy.type_var("T", module=module) @guppy.struct(module) class Struct(Generic[T]): diff --git a/tests/integration/test_tket.py b/tests/integration/test_tket.py index ecb36ab1..baabdd11 100644 --- a/tests/integration/test_tket.py +++ b/tests/integration/test_tket.py @@ -19,7 +19,8 @@ from guppylang.module import GuppyModule from guppylang.prelude.angles import pi from guppylang.prelude.builtins import owned, py -from guppylang.prelude.quantum import measure, qubit, quantum +from guppylang.prelude import quantum +from guppylang.prelude.quantum import measure, qubit from guppylang.prelude.quantum_functional import phased_x, rz, zz_max from tests.util import guppy_to_circuit