Coverage for /home/runner/work/tket/tket/pytket/pytket/backends/resulthandle.py: 82%
39 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-02 12:44 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-02 12:44 +0000
1# Copyright Quantinuum
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""ResultHandle class"""
17from ast import literal_eval
18from collections.abc import Iterator, Sequence
19from typing import Union, overload
21# mypy doesn't think you can pass the tuple to Union
22BasicHashType = Union[int, float, complex, str, bool, bytes] # noqa: UP007
23_ResultIdTuple = tuple[
24 type[int] | type[float] | type[complex] | type[str] | type[bool] | type[bytes],
25 ...,
26]
29class ResultHandle(Sequence):
30 """Object to store multidimensional identifiers for a circuit sent to a backend for
31 execution.
33 Initialisation arguments must be hashable basic types.
35 Note that a `ResultHandle` may be either persistent or transient, depending on the
36 backend: consult the :py:attr:`~.Backend.persistent_handles` property
37 to determine this.
38 """
40 def __init__(self, *args: BasicHashType):
41 self._identifiers = tuple(args)
43 @classmethod
44 def from_str(cls, string: str) -> "ResultHandle":
45 """Construct ResultHandle from string (output from str())
47 :raises ValueError: If string format is invalid
48 :return: Instance of ResultHandle
49 """
50 try:
51 evaltuple = literal_eval(string) # will raise ValueError if failed
52 if (not isinstance(evaltuple, tuple)) or (
53 not all(
54 isinstance(arg, int | float | complex | str | bool | bytes)
55 for arg in evaltuple
56 )
57 ):
58 raise ValueError # type check failed
59 return cls(*evaltuple)
60 except ValueError:
61 raise ValueError("ResultHandle string format invalid.") # noqa: B904
63 def __hash__(self) -> int:
64 return hash(self._identifiers)
66 def __eq__(self, other: object) -> bool:
67 if not isinstance(other, ResultHandle): 67 ↛ 68line 67 didn't jump to line 68 because the condition on line 67 was never true
68 return NotImplemented
69 return bool(self._identifiers == other._identifiers)
71 def __str__(self) -> str:
72 return str(self._identifiers)
74 def __repr__(self) -> str:
75 return "ResultHandle" + repr(self._identifiers)
77 def __iter__(self) -> Iterator:
78 return iter(self._identifiers)
80 def __len__(self) -> int:
81 return len(self._identifiers)
83 @overload
84 def __getitem__(self, key: int) -> BasicHashType: ... 84 ↛ exitline 84 didn't return from function '__getitem__' because
86 @overload
87 def __getitem__(self, key: slice) -> tuple[BasicHashType, ...]: ... 87 ↛ exitline 87 didn't return from function '__getitem__' because
89 def __getitem__(
90 self, key: int | slice
91 ) -> BasicHashType | tuple[BasicHashType, ...]:
92 # weird logic required to make mypy happy, can't just
93 # return self._identifiers[key]
94 if isinstance(key, slice):
95 return self._identifiers[key]
96 return self._identifiers[key]