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

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. 

14 

15"""ResultHandle class""" 

16 

17from ast import literal_eval 

18from collections.abc import Iterator, Sequence 

19from typing import Union, overload 

20 

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] 

27 

28 

29class ResultHandle(Sequence): 

30 """Object to store multidimensional identifiers for a circuit sent to a backend for 

31 execution. 

32 

33 Initialisation arguments must be hashable basic types. 

34 

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 """ 

39 

40 def __init__(self, *args: BasicHashType): 

41 self._identifiers = tuple(args) 

42 

43 @classmethod 

44 def from_str(cls, string: str) -> "ResultHandle": 

45 """Construct ResultHandle from string (output from str()) 

46 

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 

62 

63 def __hash__(self) -> int: 

64 return hash(self._identifiers) 

65 

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) 

70 

71 def __str__(self) -> str: 

72 return str(self._identifiers) 

73 

74 def __repr__(self) -> str: 

75 return "ResultHandle" + repr(self._identifiers) 

76 

77 def __iter__(self) -> Iterator: 

78 return iter(self._identifiers) 

79 

80 def __len__(self) -> int: 

81 return len(self._identifiers) 

82 

83 @overload 

84 def __getitem__(self, key: int) -> BasicHashType: ... 84 ↛ exitline 84 didn't return from function '__getitem__' because

85 

86 @overload 

87 def __getitem__(self, key: slice) -> tuple[BasicHashType, ...]: ... 87 ↛ exitline 87 didn't return from function '__getitem__' because

88 

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]