Coverage for /home/runner/work/tket/tket/pytket/pytket/backends/resulthandle.py: 82%
39 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 11:30 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 11:30 +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]
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:`pytket.backends.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 :rtype: ResultHandle
50 """
51 try:
52 evaltuple = literal_eval(string) # will raise ValueError if failed
53 if (not isinstance(evaltuple, tuple)) or (
54 not all(
55 isinstance(arg, (int, float, complex, str, bool, bytes))
56 for arg in evaltuple
57 )
58 ):
59 raise ValueError # type check failed
60 return cls(*evaltuple)
61 except ValueError:
62 raise ValueError("ResultHandle string format invalid.")
64 def __hash__(self) -> int:
65 return hash(self._identifiers)
67 def __eq__(self, other: object) -> bool:
68 if not isinstance(other, ResultHandle): 68 ↛ 69line 68 didn't jump to line 69 because the condition on line 68 was never true
69 return NotImplemented
70 return bool(self._identifiers == other._identifiers)
72 def __str__(self) -> str:
73 return str(self._identifiers)
75 def __repr__(self) -> str:
76 return "ResultHandle" + repr(self._identifiers)
78 def __iter__(self) -> Iterator:
79 return iter(self._identifiers)
81 def __len__(self) -> int:
82 return len(self._identifiers)
84 @overload
85 def __getitem__(self, key: int) -> BasicHashType: ... 85 ↛ exitline 85 didn't return from function '__getitem__' because
87 @overload
88 def __getitem__(self, key: slice) -> tuple[BasicHashType, ...]: ... 88 ↛ exitline 88 didn't return from function '__getitem__' because
90 def __getitem__(
91 self, key: int | slice
92 ) -> BasicHashType | tuple[BasicHashType, ...]:
93 # weird logic required to make mypy happy, can't just
94 # return self._identifiers[key]
95 if isinstance(key, slice):
96 return self._identifiers[key]
97 return self._identifiers[key]