qupython.qubit
1from __future__ import annotations 2 3 4from contextvars import ContextVar 5from typing import Self 6 7import qiskit.circuit.library as clib 8from .err_msg import ERR_MSG 9 10__active_controls__ = ContextVar("qupython_active_controls", default=()) 11 12class Bit: 13 """ 14 Base class for `Qubit` and `BitPromise` objects; you shouldn't create an 15 instance of this class yourself. 16 """ 17 operations: list 18 """History of operations on the bit""" 19 20 def _get_linked_bits(self, already_found=None): 21 """ 22 Find all Bit objects that interact with this Bit through quantum 23 circuit operations. 24 """ 25 # TODO: unit test 26 searched_bits = set() 27 all_known_bits = { self } 28 while len(searched_bits) < len(all_known_bits): 29 for bit in (all_known_bits - searched_bits): 30 for op in bit.operations: 31 all_known_bits |= set(op.qubits + op.promises) 32 searched_bits.add(bit) 33 return all_known_bits 34 35 def as_control(self) -> _ControlBitContextManager: 36 """ 37 Return a context manager to condition quantum gates. Use this to 38 control quantum gates using the `with` statement. 39 40 ```python 41 with my_bit.as_control(): 42 qubit.x() # conditioned on my_bit 43 ``` 44 45 You can condition on both `Qubit` and `BitPromise` objects. 46 """ 47 return _ControlBitContextManager(self) 48 49class Qubit(Bit): 50 """ 51 This is the main quPython object you'll interact with and the only object 52 you should instantiate directly. Qubits start in state |0〉. 53 54 `Qubit` objects support the following single-qubit gate operations as 55 methods. 56 57 | Name | Qiskit object | 58 |-------|-----------------------------------------------------------------------------------------| 59 | `x` | [`XGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.XGate) | 60 | `y` | [`YGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.YGate) | 61 | `z` | [`ZGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.ZGate) | 62 | `h` | [`HGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.HGate) | 63 | `s` | [`SGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.SGate) | 64 | `sdg` | [`SdgGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.SdgGate) | 65 | `t` | [`TGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.TGate) | 66 | `tdg` | [`TdgGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.TdgGate) | 67 | `p` | [`PhaseGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.PhaseGate) | 68 | `rx` | [`RXGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RXGate) | 69 | `ry` | [`RYGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RYGate) | 70 | `rz` | [`RZGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RZGate) | 71 | `u` | [`UGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.UGate) | 72 73 These gate methods mutate the `Qubit` object and return it so you can stack them. 74 75 ```python 76 qubit = Qubit().x().h() # Qubit in state |-> 77 qubit.h() # mutate to state |1> 78 ``` 79 80 The `p`, `rx`, `ry`, `rz`, and `u` gates require angles. See their 81 corresponding Qiskit objects for a description of the gates and their 82 angles. 83 84 ```python 85 Qubit().rx(0.2) 86 ``` 87 88 For a controlled gate, use the `as_control` method and the `with` 89 statement. This will control all gates inside the context by that qubit. 90 91 ```python 92 qubit, another_qubit = Qubit(), Qubit() 93 with qubit.as_control(): 94 another_qubit.x() 95 ``` 96 97 You can also control gates by passing a list of `Qubit`, `BitPromise`, and 98 `bool` objects to the `conditions` argument. All conditions must be true to 99 for the gate to apply. 100 101 ```python 102 qubit.x(conditions=[another_qubit, measurement_result, True]) 103 ``` 104 105 Use the `measure` method to return a `BitPromise`. These promises can 106 control quantum gates too using the `as_control` method. 107 """ 108 def __init__(self): 109 self.operations = [] 110 self._create_1q_gate_methods() 111 112 def __bool__(self): 113 raise ValueError( 114 "Can't cast Qubit to bool; use `.measure()` to measure" 115 " the qubit instead." 116 ) 117 118 def _separate_conditions(self, conditions): 119 qubits = [c for c in conditions if isinstance(c, Qubit)] 120 promises = [c for c in conditions if isinstance(c, BitPromise)] 121 build_time_conditions = [c for c in conditions if not isinstance(c, (Qubit, BitPromise))] 122 return qubits, promises, build_time_conditions 123 124 def _create_1q_gate_methods(self): 125 """ 126 Generate methods such as self.h, self.p, etc. 127 This method runs on object initialization. 128 """ 129 130 # TODO: unit test 131 # TODO: neaten up 132 def _create_method(gate): 133 def add_gate(*args, **kwargs): 134 conditions = kwargs.pop("conditions", []) 135 conditions += __active_controls__.get() 136 qubits, promises, build_time_conditions = self._separate_conditions(conditions) 137 if not all(build_time_conditions): 138 return 139 qiskit_inst = gate(*args, **kwargs) 140 if qubits: 141 qiskit_inst = qiskit_inst.control(len(qubits)) 142 inst = _quPythonInstruction( 143 qiskit_instruction=qiskit_inst, 144 qubits=qubits + [self], 145 promises=promises 146 ) 147 for qubit in qubits + [self]: 148 qubit.operations.append(inst) 149 for promise in promises: 150 promise.operations.append(inst) 151 return self 152 153 return add_gate 154 155 for gate, name in [ 156 (clib.XGate, "x"), 157 (clib.YGate, "y"), 158 (clib.ZGate, "z"), 159 (clib.HGate, "h"), 160 (clib.SGate, "s"), 161 (clib.SdgGate, "sdg"), 162 (clib.TGate, "t"), 163 (clib.TdgGate, "tdg"), 164 (clib.PhaseGate, "p"), 165 (clib.RXGate, "rx"), 166 (clib.RYGate, "ry"), 167 (clib.RZGate, "rz"), 168 (clib.UGate, "u"), 169 ]: 170 setattr(self, name, _create_method(gate)) 171 attr = getattr(self, name) 172 attr.__doc__ = f"Apply '{name}' gate to qubit" 173 attr.__annotations__["return"] = Self 174 175 def measure(self, conditions=None) -> BitPromise: 176 """ 177 Add measure instruction to Qubit and return BitPromise 178 """ 179 conditions = conditions or [] 180 conditions += __active_controls__.get() 181 qubits, promises, build_time_conditions = self._separate_conditions(conditions) 182 if qubits or promises: 183 raise ConditionMeasurementAtRuntimeError(ERR_MSG["ConditionMeasurementAtRuntimeError"]) 184 if not all(build_time_conditions): 185 return 186 inst = _quPythonMeasurement(self) 187 self.operations.append(inst) 188 return inst.promises[0] 189 190class BitPromise(Bit): 191 """ 192 Placeholder for qubit measurement results. You should never instantiate 193 this class directly, it should only be output from `Qubit.measure`. 194 195 When you return a `BitPromise` from an `@quantum` function, quPython finds 196 the `Qubit` that created this `BitPromise` and compiles the quantum program 197 needed to calculate it. 198 199 Invert a `BitPromise` using the `~` operator. This returns a new 200 `BitPromise` with an inverted value. 201 202 ```python 203 with (~bit_promise).as_control(): 204 # Apply gates if `bit_promise` is `False` 205 ``` 206 207 <details> 208 <summary>Gotchas</summary> 209 210 After its value is determined, a `BitPromise` tries to behave as much like 211 a `bool` as possible. Unfortunately, there are some quirks because 212 `BitPromise` objects need to have unique hashes before circuit compilation, 213 but `bool`s all have the same hash (0 or 1) and you can't change an 214 object's hash without breaking basic Python functionality. The following 215 code snippet shows an example. 216 217 ```python 218 # Create fulfilled qubit promise 219 promise = BitPromise(None) 220 promise.value = True 221 222 # Show unexpected behavior 223 promise == True # True 224 promise in (True, False) # False 225 ``` 226 227 For best results, cast to `bool` as soon as possible after the function 228 completes or use the `value` attribute. 229 230 If you have better ideas on how to handle this, let me know in an 231 [issue](https://github.com/frankharkins/qupython/issues/new?title=[Suggestion]:%20BitPromise%20values). 232 </details> 233 """ 234 235 def __init__(self, measurement_instruction, inverse=False): 236 self.operations = [measurement_instruction] 237 self._inverse = inverse 238 self.value = None 239 """ 240 Value of the `BitPromise`. This is `None` until the promise is 241 resolved. 242 """ 243 244 def __bool__(self): 245 if self.value is None: 246 raise BitPromiseNotResolvedError(ERR_MSG["BitPromiseNotResolved"]) 247 if self._inverse: 248 return not self.value 249 return self.value 250 251 def __int__(self): 252 return int(bool(self)) 253 254 def __eq__(self, other): 255 if self.value is None: 256 return id(self) == id(other) 257 return bool(self) == other 258 259 def __hash__(self): 260 return id(self) 261 262 def __repr__(self): 263 if self.value is None: 264 return f"BitPromise({self.operations})" 265 return repr(bool(self)) 266 267 def __invert__(self) -> BitPromise: 268 # TODO: This is a bit inefficient as it adds a new measurement each 269 # time we invert the promise 270 measurement_instruction = self.operations[0] 271 new_promise = BitPromise( 272 measurement_instruction, 273 inverse= not self._inverse 274 ) 275 measurement_instruction.promises.append(new_promise) 276 return new_promise 277 278 279class _quPythonInstruction: 280 def __init__(self, qiskit_instruction, qubits, promises=[]): 281 self.qiskit_instruction = qiskit_instruction 282 self.qubits = qubits 283 self.promises = promises 284 285 def __repr__(self): 286 return f"_quPythonInstruction({self.qiskit_instruction.name}, {self.qubits})" 287 288 289class _quPythonMeasurement: 290 def __init__(self, qubit): 291 self.promises = [BitPromise(self)] 292 self.qubits = [qubit] 293 294 295class BitPromiseNotResolvedError(Exception): 296 """ 297 For if you try to cast to `bool` before the promise has been resolved. 298 """ 299 pass 300 301class ConditionMeasurementAtRuntimeError(Exception): 302 """ 303 We can't currently condition measurement operations on `Bit` objects so 304 raise an exception if someone tries it. 305 """ 306 pass 307 308class _ControlBitContextManager: 309 def __init__(self, control): 310 self.control = control 311 def __enter__(self): 312 existing_controls = __active_controls__.get() 313 self.reset_token = __active_controls__.set(existing_controls + (self.control,)) 314 def __exit__(self, _exc_type, _exc_value, _traceback): 315 __active_controls__.reset(self.reset_token)
13class Bit: 14 """ 15 Base class for `Qubit` and `BitPromise` objects; you shouldn't create an 16 instance of this class yourself. 17 """ 18 operations: list 19 """History of operations on the bit""" 20 21 def _get_linked_bits(self, already_found=None): 22 """ 23 Find all Bit objects that interact with this Bit through quantum 24 circuit operations. 25 """ 26 # TODO: unit test 27 searched_bits = set() 28 all_known_bits = { self } 29 while len(searched_bits) < len(all_known_bits): 30 for bit in (all_known_bits - searched_bits): 31 for op in bit.operations: 32 all_known_bits |= set(op.qubits + op.promises) 33 searched_bits.add(bit) 34 return all_known_bits 35 36 def as_control(self) -> _ControlBitContextManager: 37 """ 38 Return a context manager to condition quantum gates. Use this to 39 control quantum gates using the `with` statement. 40 41 ```python 42 with my_bit.as_control(): 43 qubit.x() # conditioned on my_bit 44 ``` 45 46 You can condition on both `Qubit` and `BitPromise` objects. 47 """ 48 return _ControlBitContextManager(self)
Base class for Qubit and BitPromise objects; you shouldn't create an
instance of this class yourself.
36 def as_control(self) -> _ControlBitContextManager: 37 """ 38 Return a context manager to condition quantum gates. Use this to 39 control quantum gates using the `with` statement. 40 41 ```python 42 with my_bit.as_control(): 43 qubit.x() # conditioned on my_bit 44 ``` 45 46 You can condition on both `Qubit` and `BitPromise` objects. 47 """ 48 return _ControlBitContextManager(self)
Return a context manager to condition quantum gates. Use this to
control quantum gates using the with statement.
with my_bit.as_control():
qubit.x() # conditioned on my_bit
You can condition on both Qubit and BitPromise objects.
50class Qubit(Bit): 51 """ 52 This is the main quPython object you'll interact with and the only object 53 you should instantiate directly. Qubits start in state |0〉. 54 55 `Qubit` objects support the following single-qubit gate operations as 56 methods. 57 58 | Name | Qiskit object | 59 |-------|-----------------------------------------------------------------------------------------| 60 | `x` | [`XGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.XGate) | 61 | `y` | [`YGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.YGate) | 62 | `z` | [`ZGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.ZGate) | 63 | `h` | [`HGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.HGate) | 64 | `s` | [`SGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.SGate) | 65 | `sdg` | [`SdgGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.SdgGate) | 66 | `t` | [`TGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.TGate) | 67 | `tdg` | [`TdgGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.TdgGate) | 68 | `p` | [`PhaseGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.PhaseGate) | 69 | `rx` | [`RXGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RXGate) | 70 | `ry` | [`RYGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RYGate) | 71 | `rz` | [`RZGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.RZGate) | 72 | `u` | [`UGate`](https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.UGate) | 73 74 These gate methods mutate the `Qubit` object and return it so you can stack them. 75 76 ```python 77 qubit = Qubit().x().h() # Qubit in state |-> 78 qubit.h() # mutate to state |1> 79 ``` 80 81 The `p`, `rx`, `ry`, `rz`, and `u` gates require angles. See their 82 corresponding Qiskit objects for a description of the gates and their 83 angles. 84 85 ```python 86 Qubit().rx(0.2) 87 ``` 88 89 For a controlled gate, use the `as_control` method and the `with` 90 statement. This will control all gates inside the context by that qubit. 91 92 ```python 93 qubit, another_qubit = Qubit(), Qubit() 94 with qubit.as_control(): 95 another_qubit.x() 96 ``` 97 98 You can also control gates by passing a list of `Qubit`, `BitPromise`, and 99 `bool` objects to the `conditions` argument. All conditions must be true to 100 for the gate to apply. 101 102 ```python 103 qubit.x(conditions=[another_qubit, measurement_result, True]) 104 ``` 105 106 Use the `measure` method to return a `BitPromise`. These promises can 107 control quantum gates too using the `as_control` method. 108 """ 109 def __init__(self): 110 self.operations = [] 111 self._create_1q_gate_methods() 112 113 def __bool__(self): 114 raise ValueError( 115 "Can't cast Qubit to bool; use `.measure()` to measure" 116 " the qubit instead." 117 ) 118 119 def _separate_conditions(self, conditions): 120 qubits = [c for c in conditions if isinstance(c, Qubit)] 121 promises = [c for c in conditions if isinstance(c, BitPromise)] 122 build_time_conditions = [c for c in conditions if not isinstance(c, (Qubit, BitPromise))] 123 return qubits, promises, build_time_conditions 124 125 def _create_1q_gate_methods(self): 126 """ 127 Generate methods such as self.h, self.p, etc. 128 This method runs on object initialization. 129 """ 130 131 # TODO: unit test 132 # TODO: neaten up 133 def _create_method(gate): 134 def add_gate(*args, **kwargs): 135 conditions = kwargs.pop("conditions", []) 136 conditions += __active_controls__.get() 137 qubits, promises, build_time_conditions = self._separate_conditions(conditions) 138 if not all(build_time_conditions): 139 return 140 qiskit_inst = gate(*args, **kwargs) 141 if qubits: 142 qiskit_inst = qiskit_inst.control(len(qubits)) 143 inst = _quPythonInstruction( 144 qiskit_instruction=qiskit_inst, 145 qubits=qubits + [self], 146 promises=promises 147 ) 148 for qubit in qubits + [self]: 149 qubit.operations.append(inst) 150 for promise in promises: 151 promise.operations.append(inst) 152 return self 153 154 return add_gate 155 156 for gate, name in [ 157 (clib.XGate, "x"), 158 (clib.YGate, "y"), 159 (clib.ZGate, "z"), 160 (clib.HGate, "h"), 161 (clib.SGate, "s"), 162 (clib.SdgGate, "sdg"), 163 (clib.TGate, "t"), 164 (clib.TdgGate, "tdg"), 165 (clib.PhaseGate, "p"), 166 (clib.RXGate, "rx"), 167 (clib.RYGate, "ry"), 168 (clib.RZGate, "rz"), 169 (clib.UGate, "u"), 170 ]: 171 setattr(self, name, _create_method(gate)) 172 attr = getattr(self, name) 173 attr.__doc__ = f"Apply '{name}' gate to qubit" 174 attr.__annotations__["return"] = Self 175 176 def measure(self, conditions=None) -> BitPromise: 177 """ 178 Add measure instruction to Qubit and return BitPromise 179 """ 180 conditions = conditions or [] 181 conditions += __active_controls__.get() 182 qubits, promises, build_time_conditions = self._separate_conditions(conditions) 183 if qubits or promises: 184 raise ConditionMeasurementAtRuntimeError(ERR_MSG["ConditionMeasurementAtRuntimeError"]) 185 if not all(build_time_conditions): 186 return 187 inst = _quPythonMeasurement(self) 188 self.operations.append(inst) 189 return inst.promises[0]
This is the main quPython object you'll interact with and the only object you should instantiate directly. Qubits start in state |0〉.
Qubit objects support the following single-qubit gate operations as
methods.
| Name | Qiskit object |
|---|---|
x |
XGate |
y |
YGate |
z |
ZGate |
h |
HGate |
s |
SGate |
sdg |
SdgGate |
t |
TGate |
tdg |
TdgGate |
p |
PhaseGate |
rx |
RXGate |
ry |
RYGate |
rz |
RZGate |
u |
UGate |
These gate methods mutate the Qubit object and return it so you can stack them.
qubit = Qubit().x().h() # Qubit in state |->
qubit.h() # mutate to state |1>
The p, rx, ry, rz, and u gates require angles. See their
corresponding Qiskit objects for a description of the gates and their
angles.
Qubit().rx(0.2)
For a controlled gate, use the as_control method and the with
statement. This will control all gates inside the context by that qubit.
qubit, another_qubit = Qubit(), Qubit()
with qubit.as_control():
another_qubit.x()
You can also control gates by passing a list of Qubit, BitPromise, and
bool objects to the conditions argument. All conditions must be true to
for the gate to apply.
qubit.x(conditions=[another_qubit, measurement_result, True])
Use the measure method to return a BitPromise. These promises can
control quantum gates too using the as_control method.
176 def measure(self, conditions=None) -> BitPromise: 177 """ 178 Add measure instruction to Qubit and return BitPromise 179 """ 180 conditions = conditions or [] 181 conditions += __active_controls__.get() 182 qubits, promises, build_time_conditions = self._separate_conditions(conditions) 183 if qubits or promises: 184 raise ConditionMeasurementAtRuntimeError(ERR_MSG["ConditionMeasurementAtRuntimeError"]) 185 if not all(build_time_conditions): 186 return 187 inst = _quPythonMeasurement(self) 188 self.operations.append(inst) 189 return inst.promises[0]
Add measure instruction to Qubit and return BitPromise
Inherited Members
191class BitPromise(Bit): 192 """ 193 Placeholder for qubit measurement results. You should never instantiate 194 this class directly, it should only be output from `Qubit.measure`. 195 196 When you return a `BitPromise` from an `@quantum` function, quPython finds 197 the `Qubit` that created this `BitPromise` and compiles the quantum program 198 needed to calculate it. 199 200 Invert a `BitPromise` using the `~` operator. This returns a new 201 `BitPromise` with an inverted value. 202 203 ```python 204 with (~bit_promise).as_control(): 205 # Apply gates if `bit_promise` is `False` 206 ``` 207 208 <details> 209 <summary>Gotchas</summary> 210 211 After its value is determined, a `BitPromise` tries to behave as much like 212 a `bool` as possible. Unfortunately, there are some quirks because 213 `BitPromise` objects need to have unique hashes before circuit compilation, 214 but `bool`s all have the same hash (0 or 1) and you can't change an 215 object's hash without breaking basic Python functionality. The following 216 code snippet shows an example. 217 218 ```python 219 # Create fulfilled qubit promise 220 promise = BitPromise(None) 221 promise.value = True 222 223 # Show unexpected behavior 224 promise == True # True 225 promise in (True, False) # False 226 ``` 227 228 For best results, cast to `bool` as soon as possible after the function 229 completes or use the `value` attribute. 230 231 If you have better ideas on how to handle this, let me know in an 232 [issue](https://github.com/frankharkins/qupython/issues/new?title=[Suggestion]:%20BitPromise%20values). 233 </details> 234 """ 235 236 def __init__(self, measurement_instruction, inverse=False): 237 self.operations = [measurement_instruction] 238 self._inverse = inverse 239 self.value = None 240 """ 241 Value of the `BitPromise`. This is `None` until the promise is 242 resolved. 243 """ 244 245 def __bool__(self): 246 if self.value is None: 247 raise BitPromiseNotResolvedError(ERR_MSG["BitPromiseNotResolved"]) 248 if self._inverse: 249 return not self.value 250 return self.value 251 252 def __int__(self): 253 return int(bool(self)) 254 255 def __eq__(self, other): 256 if self.value is None: 257 return id(self) == id(other) 258 return bool(self) == other 259 260 def __hash__(self): 261 return id(self) 262 263 def __repr__(self): 264 if self.value is None: 265 return f"BitPromise({self.operations})" 266 return repr(bool(self)) 267 268 def __invert__(self) -> BitPromise: 269 # TODO: This is a bit inefficient as it adds a new measurement each 270 # time we invert the promise 271 measurement_instruction = self.operations[0] 272 new_promise = BitPromise( 273 measurement_instruction, 274 inverse= not self._inverse 275 ) 276 measurement_instruction.promises.append(new_promise) 277 return new_promise
Placeholder for qubit measurement results. You should never instantiate
this class directly, it should only be output from Qubit.measure.
When you return a BitPromise from an @quantum function, quPython finds
the Qubit that created this BitPromise and compiles the quantum program
needed to calculate it.
Invert a BitPromise using the ~ operator. This returns a new
BitPromise with an inverted value.
with (~bit_promise).as_control():
# Apply gates if `bit_promise` is `False`
Gotchas
After its value is determined, a BitPromise tries to behave as much like
a bool as possible. Unfortunately, there are some quirks because
BitPromise objects need to have unique hashes before circuit compilation,
but bools all have the same hash (0 or 1) and you can't change an
object's hash without breaking basic Python functionality. The following
code snippet shows an example.
# Create fulfilled qubit promise
promise = BitPromise(None)
promise.value = True
# Show unexpected behavior
promise == True # True
promise in (True, False) # False
For best results, cast to bool as soon as possible after the function
completes or use the value attribute.
If you have better ideas on how to handle this, let me know in an
Inherited Members
296class BitPromiseNotResolvedError(Exception): 297 """ 298 For if you try to cast to `bool` before the promise has been resolved. 299 """ 300 pass
For if you try to cast to bool before the promise has been resolved.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- add_note
- args
302class ConditionMeasurementAtRuntimeError(Exception): 303 """ 304 We can't currently condition measurement operations on `Bit` objects so 305 raise an exception if someone tries it. 306 """ 307 pass
We can't currently condition measurement operations on Bit objects so
raise an exception if someone tries it.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- add_note
- args