From 599683566ea80ffec4293cf33711e808e522d339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Thu, 18 Jun 2026 17:07:25 +0100 Subject: [PATCH 1/6] Remove quantum_functional --- .../src/guppylang/std/quantum_functional.py | 50 +------------------ tests/test_removed.py | 11 ++++ 2 files changed, 13 insertions(+), 48 deletions(-) create mode 100644 tests/test_removed.py diff --git a/guppylang/src/guppylang/std/quantum_functional.py b/guppylang/src/guppylang/std/quantum_functional.py index 5d88ce1bf..2fbc49bd1 100644 --- a/guppylang/src/guppylang/std/quantum_functional.py +++ b/guppylang/src/guppylang/std/quantum_functional.py @@ -1,49 +1,3 @@ -"""Deprecated: Use `guppylang.std.quantum.functional` instead.""" - -from guppylang.std.quantum.functional import ( - ch, - crz, - cx, - cy, - cz, - h, - project_z, - reset, - rx, - ry, - rz, - s, - sdg, - t, - tdg, - toffoli, - v, - vdg, - x, - y, - z, -) - -__all__ = ( - "ch", - "crz", - "cx", - "cy", - "cz", - "h", - "project_z", - "reset", - "rx", - "ry", - "rz", - "s", - "sdg", - "t", - "tdg", - "toffoli", - "v", - "vdg", - "x", - "y", - "z", +raise ImportError( + "`guppylang.std.quantum_functional` has been removed. Import from `guppylang.std.quantum_functional` instead." # noqa: E501 ) diff --git a/tests/test_removed.py b/tests/test_removed.py new file mode 100644 index 000000000..e1e3648fb --- /dev/null +++ b/tests/test_removed.py @@ -0,0 +1,11 @@ +import pytest + + +def test_removed_quantum_functional(): + """Asserts that the module breaker works as intended to break tket imports.""" + + with pytest.raises( + ImportError, + match="`guppylang.std.quantum_functional` has been removed. Import from `guppylang.std.quantum_functional` instead.", # noqa: E501, RUF043 + ): + import guppylang.std.quantum_functional # noqa: F401 From 9b9018af16db7ba2319c3d840e7ca968a75171b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Thu, 18 Jun 2026 17:26:43 +0100 Subject: [PATCH 2/6] Move functions --- .../std/_internal/moved.py | 17 +++++++ guppylang/src/guppylang/std/builtins.py | 18 +++++--- tests/test_removed.py | 44 +++++++++++++++++-- 3 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 guppylang-internals/src/guppylang_internals/std/_internal/moved.py diff --git a/guppylang-internals/src/guppylang_internals/std/_internal/moved.py b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py new file mode 100644 index 000000000..4f8d9cc4b --- /dev/null +++ b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py @@ -0,0 +1,17 @@ +from collections.abc import Callable +from typing import ParamSpec, TypeVar + +P = ParamSpec("P") +Out = TypeVar("Out") + + +def produce_moved_function( + module: str, old_name: str, new_location: str +) -> Callable[P, Out]: + def moved_function(*_args: P.args, **_kwargs: P.kwargs) -> Out: + raise ImportError( + f"The function `{old_name}` has been moved to `{new_location}`, and " + f"can no longer be imported from `{module}`." + ) + + return moved_function diff --git a/guppylang/src/guppylang/std/builtins.py b/guppylang/src/guppylang/std/builtins.py index 312db7cfd..7cdc67389 100644 --- a/guppylang/src/guppylang/std/builtins.py +++ b/guppylang/src/guppylang/std/builtins.py @@ -1,5 +1,7 @@ """Reexports core types and functions that are available without an explicit import.""" +from guppylang_internals.std._internal.moved import produce_moved_function + from guppylang.std.array import ArrayIter, FrozenarrayIter, array, frozenarray from guppylang.std.bool import bool from guppylang.std.iter import Range, SizedIter, range @@ -15,11 +17,8 @@ py, ) from guppylang.std.list import list -from guppylang.std.mem import mem_swap from guppylang.std.num import ( abs, - bytecast_float_to_nat, - bytecast_nat_to_float, divmod, float, int, @@ -29,7 +28,7 @@ round, ) from guppylang.std.option import Option, nothing, some -from guppylang.std.platform import barrier, exit, output, panic, result +from guppylang.std.platform import exit, output, panic, result from guppylang.std.quantum import qubit from guppylang.std.reflection import callable from guppylang.std.string import str @@ -93,6 +92,15 @@ zip, ) +mem_swap = produce_moved_function(__name__, "mem_swap", "guppylang.std.mem") # type: ignore[var-annotated] +bytecast_float_to_nat = produce_moved_function( # type: ignore[var-annotated] + __name__, "bytecast_float_to_nat", "guppylang.std.num" +) +bytecast_nat_to_float = produce_moved_function( # type: ignore[var-annotated] + __name__, "bytecast_nat_to_float", "guppylang.std.num" +) +barrier = produce_moved_function(__name__, "barrier", "guppylang.std.platform") # type: ignore[var-annotated] + __all__ = ( # noqa: RUF022 "__import__", "abs", @@ -170,7 +178,6 @@ "round", "set", "setattr", - "SizedIter", "slice", "some", "sorted", @@ -186,6 +193,7 @@ "Daggerable", # TODO: Remove the following from prelude "ArrayIter", # Deprecated reexport + "SizedIter", # Deprecated reexport "barrier", # Deprecated reexport "bytecast_float_to_nat", # Deprecated reexport "bytecast_nat_to_float", # Deprecated reexport diff --git a/tests/test_removed.py b/tests/test_removed.py index e1e3648fb..5bff5fe0a 100644 --- a/tests/test_removed.py +++ b/tests/test_removed.py @@ -2,10 +2,48 @@ def test_removed_quantum_functional(): - """Asserts that the module breaker works as intended to break tket imports.""" - with pytest.raises( ImportError, - match="`guppylang.std.quantum_functional` has been removed. Import from `guppylang.std.quantum_functional` instead.", # noqa: E501, RUF043 + match=r"`guppylang.std.quantum_functional` has been removed. Import from `guppylang.std.quantum_functional` instead.", # noqa: E501 ): import guppylang.std.quantum_functional # noqa: F401 + + +def test_removed_mem_swap(): + from guppylang.std.builtins import mem_swap + + with pytest.raises( + ImportError, + match=r"The function `mem_swap` has been moved to `guppylang.std.mem`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + mem_swap(1, 2) + + +def test_removed_bytecast_float_to_nat(): + from guppylang.std.builtins import bytecast_float_to_nat + + with pytest.raises( + ImportError, + match=r"The function `bytecast_float_to_nat` has been moved to `guppylang.std.num`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + bytecast_float_to_nat(1.0) + + +def test_removed_bytecast_nat_to_float(): + from guppylang.std.builtins import bytecast_nat_to_float + + with pytest.raises( + ImportError, + match=r"The function `bytecast_nat_to_float` has been moved to `guppylang.std.num`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + bytecast_nat_to_float(1) + + +def test_removed_barrier(): + from guppylang.std.builtins import barrier + + with pytest.raises( + ImportError, + match=r"The function `barrier` has been moved to `guppylang.std.platform`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + barrier() From 82dc65e4f0a16e62bb2e111cc2572e492390674a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Thu, 18 Jun 2026 17:35:44 +0100 Subject: [PATCH 3/6] Move classes and improve docstrings --- .../std/_internal/moved.py | 21 ++++++++++ guppylang/src/guppylang/std/builtins.py | 18 +++++++-- tests/test_removed.py | 40 +++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/guppylang-internals/src/guppylang_internals/std/_internal/moved.py b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py index 4f8d9cc4b..ddaa14acf 100644 --- a/guppylang-internals/src/guppylang_internals/std/_internal/moved.py +++ b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py @@ -1,6 +1,8 @@ from collections.abc import Callable from typing import ParamSpec, TypeVar +from typing_extensions import Self + P = ParamSpec("P") Out = TypeVar("Out") @@ -8,6 +10,10 @@ def produce_moved_function( module: str, old_name: str, new_location: str ) -> Callable[P, Out]: + """Produces a function that raises an import error when used, stating that it + cannot be used any more from the current location. This is a temporary migration + mechanism, and should be considered for removal several months after the move.""" + def moved_function(*_args: P.args, **_kwargs: P.kwargs) -> Out: raise ImportError( f"The function `{old_name}` has been moved to `{new_location}`, and " @@ -15,3 +21,18 @@ def moved_function(*_args: P.args, **_kwargs: P.kwargs) -> Out: ) return moved_function + + +def produce_moved_class(module: str, old_name: str, new_location: str) -> type: + """Produces a class that raises an import error when instantiated, stating that it + cannot be used any more from the current location. This is a temporary migration + mechanism, and should be considered for removal several months after the move.""" + + class MovedClass: + def __new__(cls, *_args: P.args, **_kwargs: P.kwargs) -> Self: # type: ignore[valid-type] + raise ImportError( + f"The class `{old_name}` has been moved to `{new_location}`, and " + f"can no longer be imported from `{module}`." + ) + + return MovedClass diff --git a/guppylang/src/guppylang/std/builtins.py b/guppylang/src/guppylang/std/builtins.py index 7cdc67389..f7d862c55 100644 --- a/guppylang/src/guppylang/std/builtins.py +++ b/guppylang/src/guppylang/std/builtins.py @@ -1,10 +1,13 @@ """Reexports core types and functions that are available without an explicit import.""" -from guppylang_internals.std._internal.moved import produce_moved_function +from guppylang_internals.std._internal.moved import ( + produce_moved_class, + produce_moved_function, +) -from guppylang.std.array import ArrayIter, FrozenarrayIter, array, frozenarray +from guppylang.std.array import array, frozenarray from guppylang.std.bool import bool -from guppylang.std.iter import Range, SizedIter, range +from guppylang.std.iter import range from guppylang.std.lang import ( Controllable, Daggerable, @@ -100,6 +103,12 @@ __name__, "bytecast_nat_to_float", "guppylang.std.num" ) barrier = produce_moved_function(__name__, "barrier", "guppylang.std.platform") # type: ignore[var-annotated] +Range = produce_moved_class(__name__, "Range", "guppylang.std.iter") +SizedIter = produce_moved_class(__name__, "SizedIter", "guppylang.std.iter") +ArrayIter = produce_moved_class(__name__, "ArrayIter", "guppylang.std.array") +FrozenarrayIter = produce_moved_class( + __name__, "FrozenarrayIter", "guppylang.std.array" +) __all__ = ( # noqa: RUF022 "__import__", @@ -191,7 +200,8 @@ "Unitary", "Controllable", "Daggerable", - # TODO: Remove the following from prelude + # TODO: Remove the following from prelude once + # https://github.com/Quantinuum/guppylang/issues/1019 has been resolved for a while "ArrayIter", # Deprecated reexport "SizedIter", # Deprecated reexport "barrier", # Deprecated reexport diff --git a/tests/test_removed.py b/tests/test_removed.py index 5bff5fe0a..a4325c492 100644 --- a/tests/test_removed.py +++ b/tests/test_removed.py @@ -47,3 +47,43 @@ def test_removed_barrier(): match=r"The function `barrier` has been moved to `guppylang.std.platform`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 ): barrier() + + +def test_removed_Range(): + from guppylang.std.builtins import Range + + with pytest.raises( + ImportError, + match=r"The class `Range` has been moved to `guppylang.std.iter`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + Range() + + +def test_removed_SizedIter(): + from guppylang.std.builtins import SizedIter + + with pytest.raises( + ImportError, + match=r"The class `SizedIter` has been moved to `guppylang.std.iter`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + SizedIter() + + +def test_removed_ArrayIter(): + from guppylang.std.builtins import ArrayIter + + with pytest.raises( + ImportError, + match=r"The class `ArrayIter` has been moved to `guppylang.std.array`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + ArrayIter() + + +def test_removed_FrozenArrayIter(): + from guppylang.std.builtins import FrozenarrayIter + + with pytest.raises( + ImportError, + match=r"The class `FrozenarrayIter` has been moved to `guppylang.std.array`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 + ): + FrozenarrayIter() From 2c1c7d6605c63e0433d54b78d443e3c9d1921594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Thu, 18 Jun 2026 17:58:20 +0100 Subject: [PATCH 4/6] Subscripts --- .../src/guppylang_internals/std/_internal/moved.py | 10 +++++++++- tests/integration/test_range.py | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/guppylang-internals/src/guppylang_internals/std/_internal/moved.py b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py index ddaa14acf..6be1ba2fd 100644 --- a/guppylang-internals/src/guppylang_internals/std/_internal/moved.py +++ b/guppylang-internals/src/guppylang_internals/std/_internal/moved.py @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import ParamSpec, TypeVar +from typing import Any, ParamSpec, TypeVar from typing_extensions import Self @@ -35,4 +35,12 @@ def __new__(cls, *_args: P.args, **_kwargs: P.kwargs) -> Self: # type: ignore[v f"can no longer be imported from `{module}`." ) + def __class_getitem__(cls, item: Any) -> type: + # Gracefully handles subscripting of the type in positions that are + # evaluated by the Python interpreter + raise ImportError( + f"The class `{old_name}` has been moved to `{new_location}`, and " + f"can no longer be imported from `{module}`." + ) + return MovedClass diff --git a/tests/integration/test_range.py b/tests/integration/test_range.py index 0adf2ebb5..c9ea9ec22 100644 --- a/tests/integration/test_range.py +++ b/tests/integration/test_range.py @@ -1,8 +1,8 @@ import builtins from guppylang.decorator import guppy -from guppylang.std.builtins import range, SizedIter, py -from guppylang.std.iter import Range +from guppylang.std.builtins import range, py +from guppylang.std.iter import Range, SizedIter def test_range(run_int_fn): From 10de07e2037574ea7362f677fbf767127d72b075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Fri, 19 Jun 2026 09:35:07 +0100 Subject: [PATCH 5/6] Remove from __all__ --- guppylang/src/guppylang/std/builtins.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/guppylang/src/guppylang/std/builtins.py b/guppylang/src/guppylang/std/builtins.py index f7d862c55..91687d6bd 100644 --- a/guppylang/src/guppylang/std/builtins.py +++ b/guppylang/src/guppylang/std/builtins.py @@ -200,14 +200,4 @@ "Unitary", "Controllable", "Daggerable", - # TODO: Remove the following from prelude once - # https://github.com/Quantinuum/guppylang/issues/1019 has been resolved for a while - "ArrayIter", # Deprecated reexport - "SizedIter", # Deprecated reexport - "barrier", # Deprecated reexport - "bytecast_float_to_nat", # Deprecated reexport - "bytecast_nat_to_float", # Deprecated reexport - "FrozenarrayIter", # Deprecated reexport - "mem_swap", # Deprecated reexport - "Range", # Deprecated reexport ) From 14c472ed6267b3a8450aa7684ed8d141c4690609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= Date: Fri, 19 Jun 2026 09:42:12 +0100 Subject: [PATCH 6/6] Priority queue and cleanup --- guppylang/src/guppylang/std/builtins.py | 2 ++ .../src/guppylang/std/collections/stack.py | 19 ++++++++++++++---- .../src/guppylang/std/quantum_functional.py | 2 ++ tests/test_removed.py | 20 +++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/guppylang/src/guppylang/std/builtins.py b/guppylang/src/guppylang/std/builtins.py index 91687d6bd..92d11ca86 100644 --- a/guppylang/src/guppylang/std/builtins.py +++ b/guppylang/src/guppylang/std/builtins.py @@ -95,6 +95,8 @@ zip, ) +# TODO remove once https://github.com/Quantinuum/guppylang/issues/1019 has been resolved +# for a while mem_swap = produce_moved_function(__name__, "mem_swap", "guppylang.std.mem") # type: ignore[var-annotated] bytecast_float_to_nat = produce_moved_function( # type: ignore[var-annotated] __name__, "bytecast_float_to_nat", "guppylang.std.num" diff --git a/guppylang/src/guppylang/std/collections/stack.py b/guppylang/src/guppylang/std/collections/stack.py index ec5aef252..c6e8bc77c 100644 --- a/guppylang/src/guppylang/std/collections/stack.py +++ b/guppylang/src/guppylang/std/collections/stack.py @@ -2,6 +2,10 @@ from typing import TYPE_CHECKING, Generic, no_type_check +from guppylang_internals.std._internal.moved import ( + produce_moved_class, + produce_moved_function, +) from typing_extensions import Self from guppylang.decorator import guppy @@ -119,8 +123,15 @@ def empty_stack() -> Stack[T, MAX_SIZE]: return Stack(buf, 0) -# Deprecated reexport -from guppylang.std.collections.priority_queue import ( # noqa: F401 E402 - PriorityQueue, - empty_priority_queue, +# TODO remove once https://github.com/Quantinuum/guppylang/issues/1019 has been resolved +# for a while +PriorityQueue = produce_moved_class( + "guppylang.std.collections.stack", + "PriorityQueue", + "guppylang.std.collections.priority_queue", +) +empty_priority_queue = produce_moved_function( # type: ignore[var-annotated] + "guppylang.std.collections.stack", + "empty_priority_queue", + "guppylang.std.collections.priority_queue", ) diff --git a/guppylang/src/guppylang/std/quantum_functional.py b/guppylang/src/guppylang/std/quantum_functional.py index 2fbc49bd1..2c1457a48 100644 --- a/guppylang/src/guppylang/std/quantum_functional.py +++ b/guppylang/src/guppylang/std/quantum_functional.py @@ -1,3 +1,5 @@ +# TODO remove once https://github.com/Quantinuum/guppylang/issues/1019 has been resolved +# for a while raise ImportError( "`guppylang.std.quantum_functional` has been removed. Import from `guppylang.std.quantum_functional` instead." # noqa: E501 ) diff --git a/tests/test_removed.py b/tests/test_removed.py index a4325c492..e06941287 100644 --- a/tests/test_removed.py +++ b/tests/test_removed.py @@ -87,3 +87,23 @@ def test_removed_FrozenArrayIter(): match=r"The class `FrozenarrayIter` has been moved to `guppylang.std.array`, and can no longer be imported from `guppylang.std.builtins`.", # noqa: E501 ): FrozenarrayIter() + + +def test_removed_PriorityQueue(): + from guppylang.std.collections.stack import PriorityQueue + + with pytest.raises( + ImportError, + match=r"The class `PriorityQueue` has been moved to `guppylang.std.collections.priority_queue`, and can no longer be imported from `guppylang.std.collections.stack`.", # noqa: E501 + ): + PriorityQueue() + + +def test_removed_empty_priority_queue(): + from guppylang.std.collections.stack import empty_priority_queue + + with pytest.raises( + ImportError, + match=r"The function `empty_priority_queue` has been moved to `guppylang.std.collections.priority_queue`, and can no longer be imported from `guppylang.std.collections.stack`.", # noqa: E501 + ): + empty_priority_queue()