From 552e6128c4241bd8fe97e1df5a929f6291173cec Mon Sep 17 00:00:00 2001 From: John Children <32305209+johnchildren@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:11:00 +0100 Subject: [PATCH] fix: Add copy implementations for Unit IDs (#1550) --- pytket/binders/unitid.cpp | 12 ++++++++ pytket/pytket/_tket/unit_id.pyi | 12 ++++++++ pytket/tests/unit_id/copy_test.py | 49 +++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 pytket/tests/unit_id/copy_test.py diff --git a/pytket/binders/unitid.cpp b/pytket/binders/unitid.cpp index 3d9d344807..2f3cecc8a6 100644 --- a/pytket/binders/unitid.cpp +++ b/pytket/binders/unitid.cpp @@ -119,6 +119,10 @@ PYBIND11_MODULE(unit_id, m) { "``UnitType.bit``"); py::class_(m, "Qubit", "A handle to a qubit") + .def("__copy__", [](const Qubit &id) { return Qubit(id); }) + .def( + "__deepcopy__", + [](const Qubit &id, const py::dict &) { return Qubit(id); }) .def( py::init(), "Constructs an id for some index in the default qubit " @@ -172,6 +176,10 @@ PYBIND11_MODULE(unit_id, m) { "list representation of the Qubit."); py::class_(m, "Bit", "A handle to a bit") + .def("__copy__", [](const Bit &id) { return Bit(id); }) + .def( + "__deepcopy__", + [](const Bit &id, const py::dict &) { return Bit(id); }) .def( py::init(), "Constructs an id for some index in the default classical " @@ -226,6 +234,10 @@ PYBIND11_MODULE(unit_id, m) { "list representation of the Bit."); py::class_(m, "Node", "A handle to a device node") + .def("__copy__", [](const Node &id) { return Node(id); }) + .def( + "__deepcopy__", + [](const Node &id, const py::dict &) { return Node(id); }) .def( py::init(), "Constructs an id for some index in the default physical " diff --git a/pytket/pytket/_tket/unit_id.pyi b/pytket/pytket/_tket/unit_id.pyi index 249e18c544..31c0b96862 100644 --- a/pytket/pytket/_tket/unit_id.pyi +++ b/pytket/pytket/_tket/unit_id.pyi @@ -13,6 +13,10 @@ class Bit(UnitID): """ def __and__(self: typing.Union[pytket.circuit.logic_exp.LogicExp, pytket._tket.unit_id.Bit, int], other: typing.Union[pytket.circuit.logic_exp.LogicExp, pytket._tket.unit_id.Bit, int]) -> pytket.circuit.logic_exp.BitLogicExp: ... + def __copy__(self) -> Bit: + ... + def __deepcopy__(self, arg0: dict) -> Bit: + ... def __eq__(self, arg0: typing.Any) -> bool: ... def __getstate__(self) -> tuple: @@ -172,6 +176,10 @@ class Node(Qubit): """ Construct Node instance from JSON serializable list representation of the Node. """ + def __copy__(self) -> Node: + ... + def __deepcopy__(self, arg0: dict) -> Node: + ... @typing.overload def __init__(self, index: int) -> None: """ @@ -227,6 +235,10 @@ class Qubit(UnitID): """ Construct Qubit instance from JSON serializable list representation of the Qubit. """ + def __copy__(self) -> Qubit: + ... + def __deepcopy__(self, arg0: dict) -> Qubit: + ... def __getstate__(self) -> tuple: ... @typing.overload diff --git a/pytket/tests/unit_id/copy_test.py b/pytket/tests/unit_id/copy_test.py new file mode 100644 index 0000000000..fa44a96411 --- /dev/null +++ b/pytket/tests/unit_id/copy_test.py @@ -0,0 +1,49 @@ +# Copyright 2019-2024 Cambridge Quantum Computing +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from copy import copy, deepcopy + +from pytket.unit_id import Bit, Qubit, Node + + +def test_copying_qubits() -> None: + q = Qubit(0) + + q1 = copy(q) + q2 = deepcopy(q) + + assert type(q) is Qubit + assert type(q1) is Qubit + assert type(q2) is Qubit + + +def test_copying_bits() -> None: + b = Bit(0) + + b1 = copy(b) + b2 = deepcopy(b) + + assert type(b) is Bit + assert type(b1) is Bit + assert type(b2) is Bit + + +def test_copying_nodes() -> None: + n = Node(0) + + n1 = copy(n) + n2 = deepcopy(n) + + assert type(n) is Node + assert type(n1) is Node + assert type(n2) is Node