diff --git a/guppylang/decorator.py b/guppylang/decorator.py index 72e65d3c..77538f9e 100644 --- a/guppylang/decorator.py +++ b/guppylang/decorator.py @@ -1,6 +1,9 @@ import functools +import inspect from collections.abc import Callable, Iterator, Sequence from dataclasses import dataclass +from pathlib import Path +from types import ModuleType from typing import Any, ClassVar, TypeVar from guppylang.ast_util import AstNode, has_empty_body @@ -12,55 +15,102 @@ DefaultCallCompiler, OpCompiler, ) -from guppylang.error import GuppyError, pretty_errors +from guppylang.error import GuppyError, MissingModuleError, pretty_errors from guppylang.gtypes import GuppyType, TypeTransformer from guppylang.hugr import ops, tys from guppylang.hugr.hugr import Hugr from guppylang.module import GuppyModule, PyFunc, parse_py_func -FuncDecorator = Callable[[PyFunc], PyFunc] +FuncDecorator = Callable[[PyFunc], PyFunc | Hugr] CustomFuncDecorator = Callable[[PyFunc], CustomFunction] ClassDecorator = Callable[[type], type] +@dataclass(frozen=True) +class ModuleIdentifier: + """Identifier for the Python file/module that called the decorator.""" + + filename: Path + module: ModuleType | None + + @property + def name(self) -> str: + """Returns a user-friendly name for the caller. + + If the called is not a function, uses the file name. + """ + if self.module is not None: + return str(self.module.__name__) + return self.filename.name + + class _Guppy: """Class for the `@guppy` decorator.""" - # The current module - _module: GuppyModule | None + # The currently-alive GuppyModules, associated with a Python file/module. + # + # Only contains **uncompiled** modules. + _modules: dict[ModuleIdentifier, GuppyModule] def __init__(self) -> None: - self._module = None - - def set_module(self, module: GuppyModule) -> None: - self._module = module + self._modules = {} @pretty_errors - def __call__(self, arg: PyFunc | GuppyModule) -> Hugr | None | FuncDecorator: + def __call__(self, arg: PyFunc | GuppyModule) -> FuncDecorator: """Decorator to annotate Python functions as Guppy code. - Optionally, the `GuppyModule` in which the function should be placed can be - passed to the decorator. + Optionally, the `GuppyModule` in which the function should be placed can + be passed to the decorator. """ - if isinstance(arg, GuppyModule): + def make_dummy(wraps: PyFunc) -> Callable[..., Any]: + @functools.wraps(wraps) + def dummy(*args: Any, **kwargs: Any) -> Any: + raise GuppyError( + "Guppy functions can only be called in a Guppy context" + ) + + return dummy + + if not isinstance(arg, GuppyModule): + # Decorator used without any arguments. + # We default to a module associated with the caller of the decorator. + f = arg + + caller = self._get_python_caller(f) + if caller not in self._modules: + self._modules[caller] = GuppyModule(caller.name) + module = self._modules[caller] + module.register_func_def(f) + return make_dummy(f) + + if isinstance(arg, GuppyModule): + # Module passed. def dec(f: Callable[..., Any]) -> Callable[..., Any]: - assert isinstance(arg, GuppyModule) arg.register_func_def(f) + return make_dummy(f) - @functools.wraps(f) - def dummy(*args: Any, **kwargs: Any) -> Any: - raise GuppyError( - "Guppy functions can only be called in a Guppy context" - ) + return dec - return dummy + raise ValueError(f"Invalid arguments to `@guppy` decorator: {arg}") - return dec + def _get_python_caller(self, fn: PyFunc | None = None) -> ModuleIdentifier: + """Returns an identifier for the Python file/module that called the decorator. + + :param fn: Optional. The function that was decorated. + """ + if fn is not None: + filename = inspect.getfile(fn) + module = inspect.getmodule(fn) else: - module = self._module or GuppyModule("module") - module.register_func_def(arg) - return module.compile() + for s in inspect.stack(): + if s.filename != __file__: + filename = s.filename + module = inspect.getmodule(s.frame) + break + else: + raise GuppyError("Could not find a caller for the `@guppy` decorator") + return ModuleIdentifier(Path(filename), module) @pretty_errors def extend_type(self, module: GuppyModule, ty: type[GuppyType]) -> ClassDecorator: @@ -208,5 +258,35 @@ def dummy(*args: Any, **kwargs: Any) -> Any: return dec + def take_module(self, id: ModuleIdentifier | None = None) -> GuppyModule: + """Returns the local GuppyModule, removing it from the local state.""" + orig_id = id + if id is None: + id = self._get_python_caller() + if id not in self._modules: + err = ( + f"Module {orig_id.name} not found." + if orig_id + else "No Guppy functions or types defined in this module." + ) + raise MissingModuleError(err) + return self._modules.pop(id) + + def compile_module(self, id: ModuleIdentifier | None = None) -> Hugr | None: + """Compiles the local module into a Hugr.""" + module = self.take_module(id) + if not module: + err = ( + f"Module {id.name} not found." + if id + else "No Guppy functions or types defined in this module." + ) + raise MissingModuleError(err) + return module.compile() + + def registered_modules(self) -> list[ModuleIdentifier]: + """Returns a list of all currently registered modules for local contexts.""" + return list(self._modules.keys()) + guppy = _Guppy() diff --git a/guppylang/error.py b/guppylang/error.py index 6677cb88..8e8ae4bc 100644 --- a/guppylang/error.py +++ b/guppylang/error.py @@ -76,6 +76,10 @@ class GuppyTypeInferenceError(GuppyError): """Special Guppy exception for type inference errors.""" +class MissingModuleError(GuppyError): + """Special Guppy exception for operations that require a guppy module.""" + + class InternalGuppyError(Exception): """Exception for internal problems during compilation.""" @@ -166,7 +170,7 @@ def pretty_errors(f: FuncT) -> FuncT: """Decorator to print custom error banners when a `GuppyError` occurs.""" @functools.wraps(f) - def wrapped(*args: Any, **kwargs: Any) -> Any: + def pretty_errors_wrapped(*args: Any, **kwargs: Any) -> Any: try: return f(*args, **kwargs) except GuppyError as err: @@ -188,4 +192,4 @@ def wrapped(*args: Any, **kwargs: Any) -> Any: sys.exit(1) return None - return cast(FuncT, wrapped) + return cast(FuncT, pretty_errors_wrapped) diff --git a/tests/error/comprehension_errors/illegal_short_circuit.err b/tests/error/comprehension_errors/illegal_short_circuit.err index 6c8bfb78..d05dc6a8 100644 --- a/tests/error/comprehension_errors/illegal_short_circuit.err +++ b/tests/error/comprehension_errors/illegal_short_circuit.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(xs: list[int]) -> None: 6: [x for x in xs if x < 5 and x != 6] ^^^^^^^^^^^^^^^^ diff --git a/tests/error/comprehension_errors/illegal_short_circuit.py b/tests/error/comprehension_errors/illegal_short_circuit.py index f54d5209..103d72f5 100644 --- a/tests/error/comprehension_errors/illegal_short_circuit.py +++ b/tests/error/comprehension_errors/illegal_short_circuit.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int]) -> None: [x for x in xs if x < 5 and x != 6] diff --git a/tests/error/comprehension_errors/illegal_ternary.err b/tests/error/comprehension_errors/illegal_ternary.err index b7e9e7a9..d99720ac 100644 --- a/tests/error/comprehension_errors/illegal_ternary.err +++ b/tests/error/comprehension_errors/illegal_ternary.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(xs: list[int], ys: list[int], b: bool) -> None: 6: [x for x in (xs if b else ys)] ^^^^^^^^^^^^^^^ diff --git a/tests/error/comprehension_errors/illegal_ternary.py b/tests/error/comprehension_errors/illegal_ternary.py index 7c1a7715..d3136514 100644 --- a/tests/error/comprehension_errors/illegal_ternary.py +++ b/tests/error/comprehension_errors/illegal_ternary.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int], ys: list[int], b: bool) -> None: [x for x in (xs if b else ys)] diff --git a/tests/error/comprehension_errors/illegal_walrus.err b/tests/error/comprehension_errors/illegal_walrus.err index 2fbb77d7..4b19d4ba 100644 --- a/tests/error/comprehension_errors/illegal_walrus.err +++ b/tests/error/comprehension_errors/illegal_walrus.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(xs: list[int]) -> None: 6: [y := x for x in xs] ^^^^^^ diff --git a/tests/error/comprehension_errors/illegal_walrus.py b/tests/error/comprehension_errors/illegal_walrus.py index cf252b96..ea168ab2 100644 --- a/tests/error/comprehension_errors/illegal_walrus.py +++ b/tests/error/comprehension_errors/illegal_walrus.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int]) -> None: [y := x for x in xs] diff --git a/tests/error/errors_on_usage/and_not_defined.py b/tests/error/errors_on_usage/and_not_defined.py index 85d451ae..ebe2a498 100644 --- a/tests/error/errors_on_usage/and_not_defined.py +++ b/tests/error/errors_on_usage/and_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool, y: int) -> int: if x and (z := y + 1): return z diff --git a/tests/error/errors_on_usage/else_expr_not_defined.py b/tests/error/errors_on_usage/else_expr_not_defined.py index b462848b..c348a85e 100644 --- a/tests/error/errors_on_usage/else_expr_not_defined.py +++ b/tests/error/errors_on_usage/else_expr_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: (y := 1) if x else (z := 2) return z diff --git a/tests/error/errors_on_usage/else_expr_type_change.py b/tests/error/errors_on_usage/else_expr_type_change.py index c0aecc04..0c93cae7 100644 --- a/tests/error/errors_on_usage/else_expr_type_change.py +++ b/tests/error/errors_on_usage/else_expr_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 3 (y := y + 1) if x else (y := True) diff --git a/tests/error/errors_on_usage/else_not_defined.py b/tests/error/errors_on_usage/else_not_defined.py index f54ebeae..0c48ba75 100644 --- a/tests/error/errors_on_usage/else_not_defined.py +++ b/tests/error/errors_on_usage/else_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: if x: y = 1 diff --git a/tests/error/errors_on_usage/else_not_defined_functional.py b/tests/error/errors_on_usage/else_not_defined_functional.py index c5a23fcf..e3aae879 100644 --- a/tests/error/errors_on_usage/else_not_defined_functional.py +++ b/tests/error/errors_on_usage/else_not_defined_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional if x: diff --git a/tests/error/errors_on_usage/else_type_change.py b/tests/error/errors_on_usage/else_type_change.py index 0f576a8b..e1623f32 100644 --- a/tests/error/errors_on_usage/else_type_change.py +++ b/tests/error/errors_on_usage/else_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 3 if x: diff --git a/tests/error/errors_on_usage/else_type_change_functional.py b/tests/error/errors_on_usage/else_type_change_functional.py index 932885de..5f96b5ca 100644 --- a/tests/error/errors_on_usage/else_type_change_functional.py +++ b/tests/error/errors_on_usage/else_type_change_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 3 _@functional diff --git a/tests/error/errors_on_usage/for_new_var.py b/tests/error/errors_on_usage/for_new_var.py index f3c29ab1..42d4d917 100644 --- a/tests/error/errors_on_usage/for_new_var.py +++ b/tests/error/errors_on_usage/for_new_var.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int]) -> int: for _ in xs: y = 5 diff --git a/tests/error/errors_on_usage/for_target.py b/tests/error/errors_on_usage/for_target.py index b2876dc2..cfca2ee1 100644 --- a/tests/error/errors_on_usage/for_target.py +++ b/tests/error/errors_on_usage/for_target.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int]) -> int: for x in xs: pass diff --git a/tests/error/errors_on_usage/for_target_type_change.py b/tests/error/errors_on_usage/for_target_type_change.py index 4f5f3b08..90af80d6 100644 --- a/tests/error/errors_on_usage/for_target_type_change.py +++ b/tests/error/errors_on_usage/for_target_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[bool]) -> int: x = 5 for x in xs: diff --git a/tests/error/errors_on_usage/for_type_change.py b/tests/error/errors_on_usage/for_type_change.py index e4be618d..c12a5d59 100644 --- a/tests/error/errors_on_usage/for_type_change.py +++ b/tests/error/errors_on_usage/for_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(xs: list[int]) -> int: y = 5 for x in xs: diff --git a/tests/error/errors_on_usage/if_different_types.py b/tests/error/errors_on_usage/if_different_types.py index 401d18f5..4723e9d0 100644 --- a/tests/error/errors_on_usage/if_different_types.py +++ b/tests/error/errors_on_usage/if_different_types.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: if x: y = 1 diff --git a/tests/error/errors_on_usage/if_different_types_functional.py b/tests/error/errors_on_usage/if_different_types_functional.py index dc89271c..0b364870 100644 --- a/tests/error/errors_on_usage/if_different_types_functional.py +++ b/tests/error/errors_on_usage/if_different_types_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional if x: diff --git a/tests/error/errors_on_usage/if_expr_cond_type_change.py b/tests/error/errors_on_usage/if_expr_cond_type_change.py index 24f818e8..809999a4 100644 --- a/tests/error/errors_on_usage/if_expr_cond_type_change.py +++ b/tests/error/errors_on_usage/if_expr_cond_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 4 0 if (y := x) else (y := 6) diff --git a/tests/error/errors_on_usage/if_expr_not_defined.py b/tests/error/errors_on_usage/if_expr_not_defined.py index b2565829..570ef5a7 100644 --- a/tests/error/errors_on_usage/if_expr_not_defined.py +++ b/tests/error/errors_on_usage/if_expr_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: (y := 1) if x else 0 return y diff --git a/tests/error/errors_on_usage/if_expr_type_change.py b/tests/error/errors_on_usage/if_expr_type_change.py index 3a62c51f..65b5132b 100644 --- a/tests/error/errors_on_usage/if_expr_type_change.py +++ b/tests/error/errors_on_usage/if_expr_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool, a: int) -> int: y = 3 (y := False) if x or a > 5 else 0 diff --git a/tests/error/errors_on_usage/if_expr_type_conflict.err b/tests/error/errors_on_usage/if_expr_type_conflict.err index 3a1efcbb..239b9059 100644 --- a/tests/error/errors_on_usage/if_expr_type_conflict.err +++ b/tests/error/errors_on_usage/if_expr_type_conflict.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: bool) -> None: 6: y = True if x else 42 ^^^^^^^^^^^^^^^^^ diff --git a/tests/error/errors_on_usage/if_expr_type_conflict.py b/tests/error/errors_on_usage/if_expr_type_conflict.py index 65cc1589..9dfec99a 100644 --- a/tests/error/errors_on_usage/if_expr_type_conflict.py +++ b/tests/error/errors_on_usage/if_expr_type_conflict.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> None: y = True if x else 42 diff --git a/tests/error/errors_on_usage/if_not_defined.py b/tests/error/errors_on_usage/if_not_defined.py index 8755c617..11dd7e99 100644 --- a/tests/error/errors_on_usage/if_not_defined.py +++ b/tests/error/errors_on_usage/if_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: if x: y = 1 diff --git a/tests/error/errors_on_usage/if_not_defined_functional.py b/tests/error/errors_on_usage/if_not_defined_functional.py index ffccaac1..a3ff1a46 100644 --- a/tests/error/errors_on_usage/if_not_defined_functional.py +++ b/tests/error/errors_on_usage/if_not_defined_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional if x: diff --git a/tests/error/errors_on_usage/if_type_change.py b/tests/error/errors_on_usage/if_type_change.py index 7139a97a..9a1c8928 100644 --- a/tests/error/errors_on_usage/if_type_change.py +++ b/tests/error/errors_on_usage/if_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 3 if x: diff --git a/tests/error/errors_on_usage/if_type_change_functional.py b/tests/error/errors_on_usage/if_type_change_functional.py index 791bfae7..9bb0a814 100644 --- a/tests/error/errors_on_usage/if_type_change_functional.py +++ b/tests/error/errors_on_usage/if_type_change_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 3 _@functional diff --git a/tests/error/errors_on_usage/or_not_defined.py b/tests/error/errors_on_usage/or_not_defined.py index 6e91c33c..4e6d4283 100644 --- a/tests/error/errors_on_usage/or_not_defined.py +++ b/tests/error/errors_on_usage/or_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool, y: int) -> int: if x or (z := y + 1): return z diff --git a/tests/error/errors_on_usage/while_new_var.py b/tests/error/errors_on_usage/while_new_var.py index afd32701..1d230852 100644 --- a/tests/error/errors_on_usage/while_new_var.py +++ b/tests/error/errors_on_usage/while_new_var.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: while x: y = 5 diff --git a/tests/error/errors_on_usage/while_new_var_functional.py b/tests/error/errors_on_usage/while_new_var_functional.py index 6328b450..33604b36 100644 --- a/tests/error/errors_on_usage/while_new_var_functional.py +++ b/tests/error/errors_on_usage/while_new_var_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional while x: diff --git a/tests/error/errors_on_usage/while_type_change.py b/tests/error/errors_on_usage/while_type_change.py index be89e06e..4086422c 100644 --- a/tests/error/errors_on_usage/while_type_change.py +++ b/tests/error/errors_on_usage/while_type_change.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 5 while x: diff --git a/tests/error/errors_on_usage/while_type_change_functional.py b/tests/error/errors_on_usage/while_type_change_functional.py index 7992abea..fcc3c302 100644 --- a/tests/error/errors_on_usage/while_type_change_functional.py +++ b/tests/error/errors_on_usage/while_type_change_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: y = 5 _@functional diff --git a/tests/error/misc_errors/arg_not_annotated.err b/tests/error/misc_errors/arg_not_annotated.err index a607dc9b..0e680b48 100644 --- a/tests/error/misc_errors/arg_not_annotated.err +++ b/tests/error/misc_errors/arg_not_annotated.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:5 -3: @guppy +3: @compile_guppy 4: def foo(x: bool, y) -> int: ^ GuppyError: Argument type must be annotated diff --git a/tests/error/misc_errors/arg_not_annotated.py b/tests/error/misc_errors/arg_not_annotated.py index 8360f569..608a1c01 100644 --- a/tests/error/misc_errors/arg_not_annotated.py +++ b/tests/error/misc_errors/arg_not_annotated.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool, y) -> int: return y diff --git a/tests/error/misc_errors/functional_break.py b/tests/error/misc_errors/functional_break.py index 901330a3..3dd1b6d5 100644 --- a/tests/error/misc_errors/functional_break.py +++ b/tests/error/misc_errors/functional_break.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional while x: diff --git a/tests/error/misc_errors/functional_continue.py b/tests/error/misc_errors/functional_continue.py index 8df29c36..8e5f04d4 100644 --- a/tests/error/misc_errors/functional_continue.py +++ b/tests/error/misc_errors/functional_continue.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional while x: diff --git a/tests/error/misc_errors/functional_return.py b/tests/error/misc_errors/functional_return.py index 7072e37b..835a3afe 100644 --- a/tests/error/misc_errors/functional_return.py +++ b/tests/error/misc_errors/functional_return.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional while x: diff --git a/tests/error/misc_errors/nested_functional.py b/tests/error/misc_errors/nested_functional.py index 95c194fb..0008dc0d 100644 --- a/tests/error/misc_errors/nested_functional.py +++ b/tests/error/misc_errors/nested_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo(x: bool) -> int: _@functional while x: diff --git a/tests/error/misc_errors/no_return.err b/tests/error/misc_errors/no_return.err index 21a5858e..676e2bf1 100644 --- a/tests/error/misc_errors/no_return.err +++ b/tests/error/misc_errors/no_return.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: pass ^^^^ diff --git a/tests/error/misc_errors/no_return.py b/tests/error/misc_errors/no_return.py index 705bf071..3c853d95 100644 --- a/tests/error/misc_errors/no_return.py +++ b/tests/error/misc_errors/no_return.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: pass diff --git a/tests/error/misc_errors/return_not_annotated.err b/tests/error/misc_errors/return_not_annotated.err index dcce68ed..e66c67e0 100644 --- a/tests/error/misc_errors/return_not_annotated.err +++ b/tests/error/misc_errors/return_not_annotated.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:5 -3: @guppy +3: @compile_guppy 4: def foo(x: bool): ^^^^^^^^^^^^^^^^^ GuppyError: Return type must be annotated diff --git a/tests/error/misc_errors/return_not_annotated.py b/tests/error/misc_errors/return_not_annotated.py index f275e3f0..fd0389f9 100644 --- a/tests/error/misc_errors/return_not_annotated.py +++ b/tests/error/misc_errors/return_not_annotated.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool): return x diff --git a/tests/error/misc_errors/return_not_annotated_none1.err b/tests/error/misc_errors/return_not_annotated_none1.err index 58d79a43..2798749f 100644 --- a/tests/error/misc_errors/return_not_annotated_none1.err +++ b/tests/error/misc_errors/return_not_annotated_none1.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:5 -3: @guppy +3: @compile_guppy 4: def foo(): ^^^^^^^^^^ GuppyError: Return type must be annotated. Try adding a `-> None` annotation. diff --git a/tests/error/misc_errors/return_not_annotated_none1.py b/tests/error/misc_errors/return_not_annotated_none1.py index 7346dfff..29f10063 100644 --- a/tests/error/misc_errors/return_not_annotated_none1.py +++ b/tests/error/misc_errors/return_not_annotated_none1.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(): return diff --git a/tests/error/misc_errors/return_not_annotated_none2.err b/tests/error/misc_errors/return_not_annotated_none2.err index 58d79a43..2798749f 100644 --- a/tests/error/misc_errors/return_not_annotated_none2.err +++ b/tests/error/misc_errors/return_not_annotated_none2.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:5 -3: @guppy +3: @compile_guppy 4: def foo(): ^^^^^^^^^^ GuppyError: Return type must be annotated. Try adding a `-> None` annotation. diff --git a/tests/error/misc_errors/return_not_annotated_none2.py b/tests/error/misc_errors/return_not_annotated_none2.py index 1d4d5d76..861342b8 100644 --- a/tests/error/misc_errors/return_not_annotated_none2.py +++ b/tests/error/misc_errors/return_not_annotated_none2.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(): def bar(x: int) -> int: return x diff --git a/tests/error/misc_errors/undefined_var.err b/tests/error/misc_errors/undefined_var.err index b405ba4a..d5cf6925 100644 --- a/tests/error/misc_errors/undefined_var.err +++ b/tests/error/misc_errors/undefined_var.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return x ^ diff --git a/tests/error/misc_errors/undefined_var.py b/tests/error/misc_errors/undefined_var.py index 4640a9c1..753bd4ed 100644 --- a/tests/error/misc_errors/undefined_var.py +++ b/tests/error/misc_errors/undefined_var.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return x diff --git a/tests/error/misc_errors/unreachable_1.py b/tests/error/misc_errors/unreachable_1.py index bdaf8534..2a2c264b 100644 --- a/tests/error/misc_errors/unreachable_1.py +++ b/tests/error/misc_errors/unreachable_1.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return 0 x = 42 diff --git a/tests/error/misc_errors/unreachable_2.py b/tests/error/misc_errors/unreachable_2.py index 15f50a03..6a4a2750 100644 --- a/tests/error/misc_errors/unreachable_2.py +++ b/tests/error/misc_errors/unreachable_2.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: if x: return 4 diff --git a/tests/error/misc_errors/unreachable_3.py b/tests/error/misc_errors/unreachable_3.py index 597511ec..f14290eb 100644 --- a/tests/error/misc_errors/unreachable_3.py +++ b/tests/error/misc_errors/unreachable_3.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: while x: break diff --git a/tests/error/misc_errors/unreachable_4.py b/tests/error/misc_errors/unreachable_4.py index 78dee1c1..10b9fac3 100644 --- a/tests/error/misc_errors/unreachable_4.py +++ b/tests/error/misc_errors/unreachable_4.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: while x: continue diff --git a/tests/error/misc_errors/unreachable_5.py b/tests/error/misc_errors/unreachable_5.py index dcd27199..7875e472 100644 --- a/tests/error/misc_errors/unreachable_5.py +++ b/tests/error/misc_errors/unreachable_5.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: bool) -> int: while x: return 42 diff --git a/tests/error/nested_errors/different_types_if.py b/tests/error/nested_errors/different_types_if.py index 7e2d5176..2dcd722e 100644 --- a/tests/error/nested_errors/different_types_if.py +++ b/tests/error/nested_errors/different_types_if.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(b: bool) -> int: if b: def bar() -> int: diff --git a/tests/error/nested_errors/not_defined_if.py b/tests/error/nested_errors/not_defined_if.py index 886db223..fe9f9a4f 100644 --- a/tests/error/nested_errors/not_defined_if.py +++ b/tests/error/nested_errors/not_defined_if.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(b: bool) -> int: if b: def bar() -> int: diff --git a/tests/error/nested_errors/reassign_capture_1.py b/tests/error/nested_errors/reassign_capture_1.py index 6a0ec791..78d60ec2 100644 --- a/tests/error/nested_errors/reassign_capture_1.py +++ b/tests/error/nested_errors/reassign_capture_1.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: y = x + 1 diff --git a/tests/error/nested_errors/reassign_capture_2.py b/tests/error/nested_errors/reassign_capture_2.py index fa1d6cdf..70f83748 100644 --- a/tests/error/nested_errors/reassign_capture_2.py +++ b/tests/error/nested_errors/reassign_capture_2.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: y = x + 1 diff --git a/tests/error/nested_errors/reassign_capture_3.py b/tests/error/nested_errors/reassign_capture_3.py index e0d3a947..0a597a42 100644 --- a/tests/error/nested_errors/reassign_capture_3.py +++ b/tests/error/nested_errors/reassign_capture_3.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: y = x + 1 diff --git a/tests/error/nested_errors/var_not_defined.py b/tests/error/nested_errors/var_not_defined.py index 226e3a85..0fb7e3fb 100644 --- a/tests/error/nested_errors/var_not_defined.py +++ b/tests/error/nested_errors/var_not_defined.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: def bar() -> int: return x diff --git a/tests/error/py_errors/guppy_name1.err b/tests/error/py_errors/guppy_name1.err index f870fe12..1b8d8b62 100644 --- a/tests/error/py_errors/guppy_name1.err +++ b/tests/error/py_errors/guppy_name1.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return py(x + 1) ^ diff --git a/tests/error/py_errors/guppy_name1.py b/tests/error/py_errors/guppy_name1.py index a9ccabf0..87994b92 100644 --- a/tests/error/py_errors/guppy_name1.py +++ b/tests/error/py_errors/guppy_name1.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return py(x + 1) diff --git a/tests/error/py_errors/guppy_name2.err b/tests/error/py_errors/guppy_name2.err index fb0c8437..73d2d298 100644 --- a/tests/error/py_errors/guppy_name2.err +++ b/tests/error/py_errors/guppy_name2.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:9 -7: @guppy +7: @compile_guppy 8: def foo(x: int) -> int: 9: return py(x + 1) ^ diff --git a/tests/error/py_errors/guppy_name2.py b/tests/error/py_errors/guppy_name2.py index c39d25eb..6558c20f 100644 --- a/tests/error/py_errors/guppy_name2.py +++ b/tests/error/py_errors/guppy_name2.py @@ -1,9 +1,9 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy x = 42 -@guppy +@compile_guppy def foo(x: int) -> int: return py(x + 1) diff --git a/tests/error/py_errors/no_args.err b/tests/error/py_errors/no_args.err index 5f8f43fb..7c30ee04 100644 --- a/tests/error/py_errors/no_args.err +++ b/tests/error/py_errors/no_args.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return py() ^^^^ diff --git a/tests/error/py_errors/no_args.py b/tests/error/py_errors/no_args.py index 9f281714..074479e8 100644 --- a/tests/error/py_errors/no_args.py +++ b/tests/error/py_errors/no_args.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return py() diff --git a/tests/error/py_errors/python_err.err b/tests/error/py_errors/python_err.err index 9d4c1e70..5d21c3e8 100644 --- a/tests/error/py_errors/python_err.err +++ b/tests/error/py_errors/python_err.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return py(1 / 0) ^^^^^^^^^ diff --git a/tests/error/py_errors/python_err.py b/tests/error/py_errors/python_err.py index 63914253..68b874d3 100644 --- a/tests/error/py_errors/python_err.py +++ b/tests/error/py_errors/python_err.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return py(1 / 0) diff --git a/tests/error/py_errors/unsupported.err b/tests/error/py_errors/unsupported.err index 22343611..4de7be8c 100644 --- a/tests/error/py_errors/unsupported.err +++ b/tests/error/py_errors/unsupported.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return py({1, 2, 3}) ^^^^^^^^^^^^^ diff --git a/tests/error/py_errors/unsupported.py b/tests/error/py_errors/unsupported.py index 40ba328c..08c0daeb 100644 --- a/tests/error/py_errors/unsupported.py +++ b/tests/error/py_errors/unsupported.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return py({1, 2, 3}) diff --git a/tests/error/type_errors/binary_not_arith_left.err b/tests/error/type_errors/binary_not_arith_left.err index 4a532750..36bb9a57 100644 --- a/tests/error/type_errors/binary_not_arith_left.err +++ b/tests/error/type_errors/binary_not_arith_left.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return (1, 1) * 4 ^^^^^^^^^^ diff --git a/tests/error/type_errors/binary_not_arith_left.py b/tests/error/type_errors/binary_not_arith_left.py index c3534b82..0fddfc17 100644 --- a/tests/error/type_errors/binary_not_arith_left.py +++ b/tests/error/type_errors/binary_not_arith_left.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return (1, 1) * 4 diff --git a/tests/error/type_errors/binary_not_arith_right.err b/tests/error/type_errors/binary_not_arith_right.err index 0d9447c0..7bd8ce2d 100644 --- a/tests/error/type_errors/binary_not_arith_right.err +++ b/tests/error/type_errors/binary_not_arith_right.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return x + True ^^^^^^^^ diff --git a/tests/error/type_errors/binary_not_arith_right.py b/tests/error/type_errors/binary_not_arith_right.py index 56b011ce..7222dba3 100644 --- a/tests/error/type_errors/binary_not_arith_right.py +++ b/tests/error/type_errors/binary_not_arith_right.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return x + True diff --git a/tests/error/type_errors/call_missing_arg.err b/tests/error/type_errors/call_missing_arg.err index 10ccaed5..9562fd5a 100644 --- a/tests/error/type_errors/call_missing_arg.err +++ b/tests/error/type_errors/call_missing_arg.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return foo() ^^^^^ diff --git a/tests/error/type_errors/call_missing_arg.py b/tests/error/type_errors/call_missing_arg.py index 6b203136..301afc4c 100644 --- a/tests/error/type_errors/call_missing_arg.py +++ b/tests/error/type_errors/call_missing_arg.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return foo() diff --git a/tests/error/type_errors/call_not_function.err b/tests/error/type_errors/call_not_function.err index a2e5befb..f04efe2b 100644 --- a/tests/error/type_errors/call_not_function.err +++ b/tests/error/type_errors/call_not_function.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return x(42) ^ diff --git a/tests/error/type_errors/call_not_function.py b/tests/error/type_errors/call_not_function.py index de79fad3..cb912bfe 100644 --- a/tests/error/type_errors/call_not_function.py +++ b/tests/error/type_errors/call_not_function.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return x(42) diff --git a/tests/error/type_errors/call_unexpected_arg.err b/tests/error/type_errors/call_unexpected_arg.err index c09395c5..8fe6436d 100644 --- a/tests/error/type_errors/call_unexpected_arg.err +++ b/tests/error/type_errors/call_unexpected_arg.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return foo(x, x) ^ diff --git a/tests/error/type_errors/call_unexpected_arg.py b/tests/error/type_errors/call_unexpected_arg.py index 25865fcf..99c901ff 100644 --- a/tests/error/type_errors/call_unexpected_arg.py +++ b/tests/error/type_errors/call_unexpected_arg.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return foo(x, x) diff --git a/tests/error/type_errors/call_wrong_arg.err b/tests/error/type_errors/call_wrong_arg.err index 94daf5dc..8642b137 100644 --- a/tests/error/type_errors/call_wrong_arg.err +++ b/tests/error/type_errors/call_wrong_arg.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo(x: int) -> int: 6: return foo(True) ^^^^ diff --git a/tests/error/type_errors/call_wrong_arg.py b/tests/error/type_errors/call_wrong_arg.py index 8f4d0692..ab9b98ee 100644 --- a/tests/error/type_errors/call_wrong_arg.py +++ b/tests/error/type_errors/call_wrong_arg.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: return foo(True) diff --git a/tests/error/type_errors/fun_ty_mismatch_1.py b/tests/error/type_errors/fun_ty_mismatch_1.py index 3d7f8d57..d7e956b8 100644 --- a/tests/error/type_errors/fun_ty_mismatch_1.py +++ b/tests/error/type_errors/fun_ty_mismatch_1.py @@ -1,9 +1,9 @@ from collections.abc import Callable -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> Callable[[int], int]: def bar(x: int) -> bool: return x > 0 diff --git a/tests/error/type_errors/fun_ty_mismatch_2.py b/tests/error/type_errors/fun_ty_mismatch_2.py index d95b1d24..fc3af13e 100644 --- a/tests/error/type_errors/fun_ty_mismatch_2.py +++ b/tests/error/type_errors/fun_ty_mismatch_2.py @@ -1,9 +1,9 @@ from collections.abc import Callable -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: def bar(f: Callable[[], int]) -> int: return f() diff --git a/tests/error/type_errors/fun_ty_mismatch_3.py b/tests/error/type_errors/fun_ty_mismatch_3.py index 4d5519ed..e9dc0b48 100644 --- a/tests/error/type_errors/fun_ty_mismatch_3.py +++ b/tests/error/type_errors/fun_ty_mismatch_3.py @@ -1,9 +1,9 @@ from collections.abc import Callable -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo(x: int) -> int: def bar(f: Callable[[int], bool]) -> bool: return f(42) diff --git a/tests/error/type_errors/if_not_bool_functional.py b/tests/error/type_errors/if_not_bool_functional.py index 2840dbc7..0b240fab 100644 --- a/tests/error/type_errors/if_not_bool_functional.py +++ b/tests/error/type_errors/if_not_bool_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo() -> int: _@functional if 42: diff --git a/tests/error/type_errors/invert_not_int.err b/tests/error/type_errors/invert_not_int.err index fa1d83a2..16524a1f 100644 --- a/tests/error/type_errors/invert_not_int.err +++ b/tests/error/type_errors/invert_not_int.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return ~True ^^^^ diff --git a/tests/error/type_errors/invert_not_int.py b/tests/error/type_errors/invert_not_int.py index b9a29e3d..39399e81 100644 --- a/tests/error/type_errors/invert_not_int.py +++ b/tests/error/type_errors/invert_not_int.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return ~True diff --git a/tests/error/type_errors/return_mismatch.err b/tests/error/type_errors/return_mismatch.err index a59582be..0d9a0605 100644 --- a/tests/error/type_errors/return_mismatch.err +++ b/tests/error/type_errors/return_mismatch.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> bool: 6: return 42 ^^ diff --git a/tests/error/type_errors/return_mismatch.py b/tests/error/type_errors/return_mismatch.py index 677cf566..9328972e 100644 --- a/tests/error/type_errors/return_mismatch.py +++ b/tests/error/type_errors/return_mismatch.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> bool: return 42 diff --git a/tests/error/type_errors/unary_not_arith.err b/tests/error/type_errors/unary_not_arith.err index 5baf6757..ae82206b 100644 --- a/tests/error/type_errors/unary_not_arith.err +++ b/tests/error/type_errors/unary_not_arith.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: return -True ^^^^ diff --git a/tests/error/type_errors/unary_not_arith.py b/tests/error/type_errors/unary_not_arith.py index 3fd29c7a..bf9ce2cb 100644 --- a/tests/error/type_errors/unary_not_arith.py +++ b/tests/error/type_errors/unary_not_arith.py @@ -1,6 +1,6 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: return -True diff --git a/tests/error/type_errors/unpack_not_enough.err b/tests/error/type_errors/unpack_not_enough.err index 9628fc53..d9523c30 100644 --- a/tests/error/type_errors/unpack_not_enough.err +++ b/tests/error/type_errors/unpack_not_enough.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: a, b, c = 1, True ^^^^^^^^^^^^^^^^^ diff --git a/tests/error/type_errors/unpack_not_enough.py b/tests/error/type_errors/unpack_not_enough.py index 57e3d2e6..389b9fd9 100644 --- a/tests/error/type_errors/unpack_not_enough.py +++ b/tests/error/type_errors/unpack_not_enough.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: a, b, c = 1, True return a diff --git a/tests/error/type_errors/unpack_too_many.err b/tests/error/type_errors/unpack_too_many.err index aee08762..44ffb60f 100644 --- a/tests/error/type_errors/unpack_too_many.err +++ b/tests/error/type_errors/unpack_too_many.err @@ -1,6 +1,6 @@ Guppy compilation failed. Error in file $FILE:6 -4: @guppy +4: @compile_guppy 5: def foo() -> int: 6: a, b = 1, True, 3.0 ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/error/type_errors/unpack_too_many.py b/tests/error/type_errors/unpack_too_many.py index e861c538..b252cf7d 100644 --- a/tests/error/type_errors/unpack_too_many.py +++ b/tests/error/type_errors/unpack_too_many.py @@ -1,7 +1,7 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy -@guppy +@compile_guppy def foo() -> int: a, b = 1, True, 3.0 return a diff --git a/tests/error/type_errors/while_not_bool_functional.py b/tests/error/type_errors/while_not_bool_functional.py index 1b55ce26..78c66c40 100644 --- a/tests/error/type_errors/while_not_bool_functional.py +++ b/tests/error/type_errors/while_not_bool_functional.py @@ -1,7 +1,7 @@ from guppylang.decorator import guppy -@guppy +@compile_guppy def foo() -> int: _@functional while 42: diff --git a/tests/integration/test_arithmetic.py b/tests/integration/test_arithmetic.py index deead8fa..a31db662 100644 --- a/tests/integration/test_arithmetic.py +++ b/tests/integration/test_arithmetic.py @@ -1,8 +1,8 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_arith_basic(validate): - @guppy + @compile_guppy def add(x: int, y: int) -> int: return x + y @@ -10,7 +10,7 @@ def add(x: int, y: int) -> int: def test_constant(validate): - @guppy + @compile_guppy def const() -> float: return 42.0 @@ -18,7 +18,7 @@ def const() -> float: def test_aug_assign(validate): - @guppy + @compile_guppy def add(x: int) -> int: x += 1 return x @@ -27,7 +27,7 @@ def add(x: int) -> int: def test_float_coercion(validate): - @guppy + @compile_guppy def coerce(x: int, y: float) -> float: return x * y @@ -35,7 +35,7 @@ def coerce(x: int, y: float) -> float: def test_arith_big(validate): - @guppy + @compile_guppy def arith(x: int, y: float, z: int) -> bool: a = x // y + 3 * z b = -8 >= a > 5 or (x * y == 0 and a % 3 < x) @@ -45,7 +45,7 @@ def arith(x: int, y: float, z: int) -> bool: def test_shortcircuit_assign1(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> bool: if (z := x) and y > 0: return z @@ -55,7 +55,7 @@ def foo(x: bool, y: int) -> bool: def test_shortcircuit_assign2(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> bool: if y > 0 and (z := x): return z @@ -65,7 +65,7 @@ def foo(x: bool, y: int) -> bool: def test_shortcircuit_assign3(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> bool: if (z := x) or y > 0: return z @@ -75,7 +75,7 @@ def foo(x: bool, y: int) -> bool: def test_shortcircuit_assign4(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> bool: if y > 0 or (z := x): return False diff --git a/tests/integration/test_basic.py b/tests/integration/test_basic.py index d082270f..bb57695e 100644 --- a/tests/integration/test_basic.py +++ b/tests/integration/test_basic.py @@ -1,10 +1,11 @@ from guppylang.decorator import guppy from guppylang.hugr import ops from guppylang.module import GuppyModule +from tests.util import compile_guppy def test_id(validate): - @guppy + @compile_guppy def identity(x: int) -> int: return x @@ -12,7 +13,7 @@ def identity(x: int) -> int: def test_void(validate): - @guppy + @compile_guppy def void() -> None: return @@ -20,7 +21,7 @@ def void() -> None: def test_copy(validate): - @guppy + @compile_guppy def copy(x: int) -> (int, int): return x, x @@ -28,7 +29,7 @@ def copy(x: int) -> (int, int): def test_discard(validate): - @guppy + @compile_guppy def discard(x: int) -> None: return @@ -36,7 +37,7 @@ def discard(x: int) -> None: def test_implicit_return(validate): - @guppy + @compile_guppy def ret() -> None: pass @@ -44,7 +45,7 @@ def ret() -> None: def test_assign(validate): - @guppy + @compile_guppy def foo(x: bool) -> bool: y = x return y @@ -53,7 +54,7 @@ def foo(x: bool) -> bool: def test_assign_expr(validate): - @guppy + @compile_guppy def foo(x: bool) -> bool: (y := x) return y @@ -62,7 +63,7 @@ def foo(x: bool) -> bool: def test_func_def_name(): - @guppy + @compile_guppy def func_name() -> None: return diff --git a/tests/integration/test_call.py b/tests/integration/test_call.py index 0e2f6791..01a520c9 100644 --- a/tests/integration/test_call.py +++ b/tests/integration/test_call.py @@ -1,5 +1,6 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule +from tests.util import compile_guppy def test_call(validate): @@ -31,7 +32,7 @@ def bar(x: int) -> int: def test_recursion(validate): - @guppy + @compile_guppy def main(x: int) -> int: return main(x) diff --git a/tests/integration/test_comprehension.py b/tests/integration/test_comprehension.py index 3b5c0774..76da7749 100644 --- a/tests/integration/test_comprehension.py +++ b/tests/integration/test_comprehension.py @@ -5,10 +5,11 @@ from guppylang.prelude.quantum import Qubit, h, cx import guppylang.prelude.quantum as quantum +from tests.util import compile_guppy def test_basic(validate): - @guppy + @compile_guppy def test(xs: list[float]) -> list[int]: return [int(x) for x in xs] @@ -27,7 +28,7 @@ def test(qs: linst[Qubit]) -> linst[Qubit]: def test_guarded(validate): - @guppy + @compile_guppy def test(xs: list[int]) -> list[int]: return [2 * x for x in xs if x > 0 if x < 20] @@ -35,7 +36,7 @@ def test(xs: list[int]) -> list[int]: def test_multiple(validate): - @guppy + @compile_guppy def test(xs: list[int], ys: list[int]) -> list[int]: return [x + y for x in xs for y in ys if x + y > 42] @@ -43,7 +44,7 @@ def test(xs: list[int], ys: list[int]) -> list[int]: def test_tuple_pat(validate): - @guppy + @compile_guppy def test(xs: list[tuple[int, int, float]]) -> list[float]: return [x + y * z for x, y, z in xs if x - y > z] @@ -62,7 +63,7 @@ def test(qs: linst[tuple[int, Qubit, Qubit]]) -> linst[tuple[Qubit, Qubit]]: def test_tuple_return(validate): - @guppy + @compile_guppy def test(xs: list[int], ys: list[float]) -> list[tuple[int, float]]: return [(x, y) for x in xs for y in ys] @@ -84,7 +85,7 @@ def test(xs: list[float]) -> list[float]: def test_capture(validate): - @guppy + @compile_guppy def test(xs: list[int], y: int) -> list[int]: return [x + y for x in xs if x > y] @@ -92,7 +93,7 @@ def test(xs: list[int], y: int) -> list[int]: def test_scope(validate): - @guppy + @compile_guppy def test(xs: list[None]) -> float: x = 42.0 [x for x in xs] @@ -102,7 +103,7 @@ def test(xs: list[None]) -> float: def test_nested_left(validate): - @guppy + @compile_guppy def test(xs: list[int], ys: list[float]) -> list[list[float]]: return [[x + y for y in ys] for x in xs] @@ -110,7 +111,7 @@ def test(xs: list[int], ys: list[float]) -> list[list[float]]: def test_nested_right(validate): - @guppy + @compile_guppy def test(xs: list[int]) -> list[int]: return [-x for x in [2 * x for x in xs]] diff --git a/tests/integration/test_decorator.py b/tests/integration/test_decorator.py new file mode 100644 index 00000000..f7383fea --- /dev/null +++ b/tests/integration/test_decorator.py @@ -0,0 +1,43 @@ +from guppylang.decorator import guppy +from guppylang.module import GuppyModule + + +def test_decorator(): + module = GuppyModule("test") + + @guppy + def a() -> None: + pass + + @guppy(module) + def b() -> None: + pass + + @guppy + def c() -> None: + pass + + default_module = guppy.take_module() + + assert not module.contains_function("a") + assert module.contains_function("b") + assert not module.contains_function("c") + + assert default_module.contains_function("a") + assert not default_module.contains_function("b") + assert default_module.contains_function("c") + + +def test_nested(): + def make_module() -> GuppyModule: + @guppy + def a() -> None: + pass + + return guppy.take_module() + + module_a = make_module() + module_b = make_module() + + assert module_a.contains_function("a") + assert module_b.contains_function("a") diff --git a/tests/integration/test_for.py b/tests/integration/test_for.py index 08a26e96..0d82c357 100644 --- a/tests/integration/test_for.py +++ b/tests/integration/test_for.py @@ -1,8 +1,8 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_basic(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: for x in xs: pass @@ -12,7 +12,7 @@ def foo(xs: list[int]) -> int: def test_counting_loop(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: s = 0 for x in xs: @@ -23,7 +23,7 @@ def foo(xs: list[int]) -> int: def test_multi_targets(validate): - @guppy + @compile_guppy def foo(xs: list[tuple[int, float]]) -> float: s = 0.0 for x, y in xs: @@ -34,7 +34,7 @@ def foo(xs: list[tuple[int, float]]) -> float: def test_multi_targets_same(validate): - @guppy + @compile_guppy def foo(xs: list[tuple[int, float]]) -> float: s = 1.0 for x, x in xs: @@ -45,7 +45,7 @@ def foo(xs: list[tuple[int, float]]) -> float: def test_reassign_iter(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: s = 1 for x in xs: @@ -57,7 +57,7 @@ def foo(xs: list[int]) -> int: def test_break(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: i = 1 for x in xs: @@ -70,7 +70,7 @@ def foo(xs: list[int]) -> int: def test_continue(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: i = len(xs) for x in xs: @@ -83,7 +83,7 @@ def foo(xs: list[int]) -> int: def test_return_in_loop(validate): - @guppy + @compile_guppy def foo(xs: list[int]) -> int: y = 42 for x in xs: @@ -96,7 +96,7 @@ def foo(xs: list[int]) -> int: def test_nested_loop(validate): - @guppy + @compile_guppy def foo(xs: list[int], ys: list[int]) -> int: p = 0 for x in xs: @@ -110,7 +110,7 @@ def foo(xs: list[int], ys: list[int]) -> int: def test_nested_loop_break_continue(validate): - @guppy + @compile_guppy def foo(xs: list[int], ys: list[int]) -> int: p = 0 for x in xs: diff --git a/tests/integration/test_functional.py b/tests/integration/test_functional.py index 761b5c0b..238a04b0 100644 --- a/tests/integration/test_functional.py +++ b/tests/integration/test_functional.py @@ -1,12 +1,12 @@ import pytest -from guppylang.decorator import guppy from tests.integration.util import functional, _ +from tests.util import compile_guppy @pytest.mark.skip() def test_if_no_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: _ @ functional if x: @@ -18,7 +18,7 @@ def foo(x: bool, y: int) -> int: @pytest.mark.skip() def test_if_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: _ @ functional if x: @@ -32,7 +32,7 @@ def foo(x: bool, y: int) -> int: @pytest.mark.skip() def test_if_elif(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: _ @ functional if x: @@ -46,7 +46,7 @@ def foo(x: bool, y: int) -> int: @pytest.mark.skip() def test_if_elif_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: _ @ functional if x: @@ -62,7 +62,7 @@ def foo(x: bool, y: int) -> int: @pytest.mark.skip() def test_infinite_loop(validate): - @guppy + @compile_guppy def foo() -> int: while True: pass @@ -73,7 +73,7 @@ def foo() -> int: @pytest.mark.skip() def test_counting_loop(validate): - @guppy + @compile_guppy def foo(i: int) -> int: while i > 0: i -= 1 @@ -84,7 +84,7 @@ def foo(i: int) -> int: @pytest.mark.skip() def test_nested_loop(validate): - @guppy + @compile_guppy def foo(x: int, y: int) -> int: p = 0 _ @ functional diff --git a/tests/integration/test_higher_order.py b/tests/integration/test_higher_order.py index e751e475..94de2b31 100644 --- a/tests/integration/test_higher_order.py +++ b/tests/integration/test_higher_order.py @@ -2,6 +2,7 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule +from tests.util import compile_guppy def test_basic(validate): @@ -55,7 +56,7 @@ def baz(y: int) -> None: def test_nested(validate): - @guppy + @compile_guppy def foo(x: int) -> Callable[[int], bool]: def bar(y: int) -> bool: return x > y diff --git a/tests/integration/test_if.py b/tests/integration/test_if.py index ea4a5bcd..67dfb7be 100644 --- a/tests/integration/test_if.py +++ b/tests/integration/test_if.py @@ -1,10 +1,10 @@ import pytest -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_if_no_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 1 @@ -14,7 +14,7 @@ def foo(x: bool, y: int) -> int: def test_if_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 1 @@ -26,7 +26,7 @@ def foo(x: bool, y: int) -> int: def test_if_elif(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 1 @@ -38,7 +38,7 @@ def foo(x: bool, y: int) -> int: def test_if_elif_else(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 1 @@ -52,7 +52,7 @@ def foo(x: bool, y: int) -> int: def test_if_expr(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: return y + 1 if x else 42 @@ -60,7 +60,7 @@ def foo(x: bool, y: int) -> int: def test_if_expr_nested(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: a = y + 1 if x else y * y if 0 < y <= 10 else 42 b = a if a < 5 or (not x and -7 >= a > 42) else -a @@ -70,7 +70,7 @@ def foo(x: bool, y: int) -> int: def test_if_expr_tuple(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> (int, int, int): t = (y + 1 if x else 42), 8, (y * 2 if x else 64) return t @@ -79,7 +79,7 @@ def foo(x: bool, y: int) -> (int, int, int): def test_if_expr_assign_both(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: (z := 5) if x else (z := 42) return z @@ -88,7 +88,7 @@ def foo(x: bool) -> int: def test_if_expr_assign_cond(validate): - @guppy + @compile_guppy def foo(x: bool) -> bool: return z if (z := x) else False @@ -96,7 +96,7 @@ def foo(x: bool) -> bool: def test_if_expr_reassign(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: y = 5 (y := 1) if x else 6 @@ -108,7 +108,7 @@ def foo(x: bool) -> int: def test_if_expr_reassign_cond(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: y = 5 return y if (y := 42) > 5 else 64 if x else y @@ -117,7 +117,7 @@ def foo(x: bool) -> int: def test_if_expr_double_type_change(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: y = 4 (y := 1) if (y := x) else (y := 6) @@ -127,7 +127,7 @@ def foo(x: bool) -> int: def test_if_return(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: return y @@ -138,7 +138,7 @@ def foo(x: bool, y: int) -> int: def test_else_return(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 3 @@ -151,7 +151,7 @@ def foo(x: bool, y: int) -> int: def test_both_return(validate): - @guppy + @compile_guppy def foo(x: bool, y: int) -> int: if x: y += 3 @@ -164,7 +164,7 @@ def foo(x: bool, y: int) -> int: def test_nested_return(validate): - @guppy + @compile_guppy def foo(x: int, y: int) -> int: if x > 5: if y == 4: @@ -177,7 +177,7 @@ def foo(x: int, y: int) -> int: def test_return_defined1(validate): - @guppy + @compile_guppy def foo(x: int, y: int) -> int: if x > 5: return y @@ -189,7 +189,7 @@ def foo(x: int, y: int) -> int: def test_return_defined2(validate): - @guppy + @compile_guppy def foo(x: int) -> int: if x > 5: z = 45 @@ -201,7 +201,7 @@ def foo(x: int) -> int: def test_break_different_types1(validate): - @guppy + @compile_guppy def foo(x: int) -> int: z = 0 while True: @@ -217,7 +217,7 @@ def foo(x: int) -> int: def test_break_different_types2(validate): - @guppy + @compile_guppy def foo(x: int) -> int: z = 0 while True: @@ -234,7 +234,7 @@ def foo(x: int) -> int: @pytest.mark.skip("Known bug") def test_continue_different_types1(validate): - @guppy + @compile_guppy def foo(x: int) -> int: z = 0 while True: @@ -251,7 +251,7 @@ def foo(x: int) -> int: @pytest.mark.skip("Known bug") def test_continue_different_types2(validate): - @guppy + @compile_guppy def foo(x: int) -> int: z = 0 while True: diff --git a/tests/integration/test_list.py b/tests/integration/test_list.py index 9bee4016..e90f1bfe 100644 --- a/tests/integration/test_list.py +++ b/tests/integration/test_list.py @@ -1,8 +1,8 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_types(validate): - @guppy + @compile_guppy def test( xs: list[int], ys: list[tuple[int, float]] ) -> tuple[list[int], list[tuple[int, float]]]: @@ -12,7 +12,7 @@ def test( def test_len(validate): - @guppy + @compile_guppy def test(xs: list[int]) -> int: return len(xs) @@ -20,7 +20,7 @@ def test(xs: list[int]) -> int: def test_literal(validate): - @guppy + @compile_guppy def test(x: float) -> list[float]: return [1.0, 2.0, 3.0, 4.0 + x] @@ -28,7 +28,7 @@ def test(x: float) -> list[float]: def test_arith(validate): - @guppy + @compile_guppy def test(xs: list[int]) -> list[int]: xs += xs + [42] xs = 3 * xs @@ -38,7 +38,7 @@ def test(xs: list[int]) -> list[int]: def test_subscript(validate): - @guppy + @compile_guppy def test(xs: list[float], i: int) -> float: return xs[2 * i] diff --git a/tests/integration/test_nested.py b/tests/integration/test_nested.py index 30dbc414..aac788ba 100644 --- a/tests/integration/test_nested.py +++ b/tests/integration/test_nested.py @@ -1,8 +1,8 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_basic(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int) -> int: return y @@ -13,7 +13,7 @@ def bar(y: int) -> int: def test_call_twice(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int) -> int: return y + 3 @@ -27,7 +27,7 @@ def bar(y: int) -> int: def test_redefine(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int) -> int: return y + 3 @@ -44,7 +44,7 @@ def bar(y: int) -> int: def test_define_twice(validate): - @guppy + @compile_guppy def foo(x: int) -> int: if x == 0: @@ -61,7 +61,7 @@ def bar(y: int) -> int: def test_nested_deep(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int) -> int: def baz(z: int) -> int: @@ -75,7 +75,7 @@ def baz(z: int) -> int: def test_recurse(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int) -> int: if y == 0: @@ -88,7 +88,7 @@ def bar(y: int) -> int: def test_capture_arg(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar() -> int: return 1 + x @@ -99,7 +99,7 @@ def bar() -> int: def test_capture_assigned(validate): - @guppy + @compile_guppy def foo(x: int) -> int: y = x + 1 @@ -112,7 +112,7 @@ def bar() -> int: def test_capture_multiple(validate): - @guppy + @compile_guppy def foo(x: int) -> int: if x > 5: y = 3 @@ -130,7 +130,7 @@ def bar() -> int: def test_capture_cfg(validate): - @guppy + @compile_guppy def foo(x: int) -> int: a = x + 4 if x > 5: @@ -146,7 +146,7 @@ def bar() -> int: def test_capture_deep(validate): - @guppy + @compile_guppy def foo(x: int) -> int: a = x * 2 @@ -165,7 +165,7 @@ def baz(y: int) -> int: def test_capture_recurse(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int, z: int) -> int: if y == 0: @@ -178,7 +178,7 @@ def bar(y: int, z: int) -> int: def test_capture_recurse_nested(validate): - @guppy + @compile_guppy def foo(x: int) -> int: def bar(y: int, z: int) -> int: if y == 0: @@ -197,7 +197,7 @@ def baz() -> int: def test_capture_while(validate): - @guppy + @compile_guppy def foo(x: int) -> int: a = 0 while x > 0: diff --git a/tests/integration/test_programs.py b/tests/integration/test_programs.py index 1fca9ec6..44c7968d 100644 --- a/tests/integration/test_programs.py +++ b/tests/integration/test_programs.py @@ -1,9 +1,10 @@ from guppylang.decorator import guppy from guppylang.module import GuppyModule +from tests.util import compile_guppy def test_factorial(validate): - @guppy + @compile_guppy def factorial1(x: int) -> int: acc = 1 while x > 0: @@ -11,13 +12,13 @@ def factorial1(x: int) -> int: x -= 1 return acc - @guppy + @compile_guppy def factorial2(x: int) -> int: if x == 0: return 1 return factorial2(x - 1) * x - @guppy + @compile_guppy def factorial3(x: int, acc: int) -> int: if x == 0: return acc diff --git a/tests/integration/test_py.py b/tests/integration/test_py.py index 85b0ec1f..be3353ac 100644 --- a/tests/integration/test_py.py +++ b/tests/integration/test_py.py @@ -1,11 +1,11 @@ -from guppylang.decorator import guppy from tests.integration.util import py +from tests.util import compile_guppy def test_basic(validate): x = 42 - @guppy + @compile_guppy def foo() -> int: return py(x + 1) @@ -13,7 +13,7 @@ def foo() -> int: def test_builtin(validate): - @guppy + @compile_guppy def foo() -> int: return py(len({"a": 1337, "b": None})) @@ -23,7 +23,7 @@ def foo() -> int: def test_if(validate): b = True - @guppy + @compile_guppy def foo() -> int: if py(b or 1 > 6): return 0 @@ -35,7 +35,7 @@ def foo() -> int: def test_redeclare_after(validate): x = 1 - @guppy + @compile_guppy def foo() -> int: return py(x) @@ -45,7 +45,7 @@ def foo() -> int: def test_tuple(validate): - @guppy + @compile_guppy def foo() -> int: x, y = py((1, False)) return x @@ -54,7 +54,7 @@ def foo() -> int: def test_tuple_implicit(validate): - @guppy + @compile_guppy def foo() -> int: x, y = py(1, False) return x diff --git a/tests/integration/test_unused.py b/tests/integration/test_unused.py index c2f81c27..f4b5b01f 100644 --- a/tests/integration/test_unused.py +++ b/tests/integration/test_unused.py @@ -1,10 +1,10 @@ """ All sorts of weird stuff is allowed when variables are not used. """ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_not_always_defined1(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: if x: z = 5 @@ -14,7 +14,7 @@ def foo(x: bool) -> int: def test_not_always_defined2(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: if x: pass @@ -26,7 +26,7 @@ def foo(x: bool) -> int: def test_not_always_defined3(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: if x: y = True @@ -38,7 +38,7 @@ def foo(x: bool) -> int: def test_different_types1(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: if x: z = True @@ -50,7 +50,7 @@ def foo(x: bool) -> int: def test_different_types2(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: z = False if x: @@ -63,7 +63,7 @@ def foo(x: bool) -> int: def test_different_types3(validate): - @guppy + @compile_guppy def foo(x: bool) -> int: z = False if x: @@ -76,7 +76,7 @@ def foo(x: bool) -> int: def test_while_change_type(validate): - @guppy + @compile_guppy def foo() -> None: x = 42 while True: @@ -86,7 +86,7 @@ def foo() -> None: def test_if_expr_different_types(validate): - @guppy + @compile_guppy def foo(x: bool) -> None: 5 if x else False diff --git a/tests/integration/test_while.py b/tests/integration/test_while.py index 286bf40a..c351481a 100644 --- a/tests/integration/test_while.py +++ b/tests/integration/test_while.py @@ -1,8 +1,8 @@ -from guppylang.decorator import guppy +from tests.util import compile_guppy def test_infinite_loop(validate): - @guppy + @compile_guppy def foo() -> int: while True: pass @@ -12,7 +12,7 @@ def foo() -> int: def test_counting_loop(validate): - @guppy + @compile_guppy def foo(i: int) -> int: while i > 0: i -= 1 @@ -22,7 +22,7 @@ def foo(i: int) -> int: def test_break(validate): - @guppy + @compile_guppy def foo(i: int) -> int: while True: if i == 0: @@ -34,7 +34,7 @@ def foo(i: int) -> int: def test_continue(validate): - @guppy + @compile_guppy def foo(i: int) -> int: x = 42 while True: @@ -47,7 +47,7 @@ def foo(i: int) -> int: def test_return_in_loop(validate): - @guppy + @compile_guppy def foo(i: int) -> int: x = 42 while i > 0: @@ -61,7 +61,7 @@ def foo(i: int) -> int: def test_nested_loop(validate): - @guppy + @compile_guppy def foo(x: int, y: int) -> int: p = 0 while x > 0: @@ -77,7 +77,7 @@ def foo(x: int, y: int) -> int: def test_nested_loop_break_continue(validate): - @guppy + @compile_guppy def foo(x: int, y: int) -> int: p = 0 while x > 0: diff --git a/tests/util.py b/tests/util.py new file mode 100644 index 00000000..3a45073e --- /dev/null +++ b/tests/util.py @@ -0,0 +1,18 @@ +import guppylang +from guppylang.hugr.hugr import Hugr +from guppylang.module import GuppyModule + + +def compile_guppy(fn) -> Hugr: + """A decorator that combines @guppy with HUGR compilation. + + Creates a temporary module that only contains the defined function. + """ + assert not isinstance( + fn, + GuppyModule, + ), "`@compile_guppy` does not support extra arguments." + + module = GuppyModule("module") + guppylang.decorator.guppy(module)(fn) + return module.compile()