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

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] 

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:`pytket.backends.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 :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.") 

63 

64 def __hash__(self) -> int: 

65 return hash(self._identifiers) 

66 

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) 

71 

72 def __str__(self) -> str: 

73 return str(self._identifiers) 

74 

75 def __repr__(self) -> str: 

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

77 

78 def __iter__(self) -> Iterator: 

79 return iter(self._identifiers) 

80 

81 def __len__(self) -> int: 

82 return len(self._identifiers) 

83 

84 @overload 

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

86 

87 @overload 

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

89 

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]