diff --git a/dev_tools/.pylintrc b/dev_tools/.pylintrc index 3e375048..a5224ff9 100644 --- a/dev_tools/.pylintrc +++ b/dev_tools/.pylintrc @@ -7,16 +7,16 @@ output-format=colorized score=no reports=no enable= - # anomalous-backslash-in-string, # TODO: #210 - enable and fix + anomalous-backslash-in-string, assert-on-tuple, bad-indentation, bad-option-value, bad-reversed-sequence, bad-super-call, consider-merging-isinstance, - # consider-using-f-string, # TODO: #210 - enable and fix + consider-using-f-string, continue-in-finally, - # dangerous-default-value, # TODO: #210 - enable and fix + dangerous-default-value, docstyle, duplicate-argument-name, # expression-not-assigned, # TODO: #210 - enable and fix @@ -34,7 +34,7 @@ enable= nonexistent-operator, not-in-loop, # pointless-statement, # TODO: #210 - enable and fix - # redefined-builtin, # TODO: #210 - enable and fix + redefined-builtin, return-arg-in-generator, return-in-init, return-outside-function, @@ -46,14 +46,14 @@ enable= undefined-variable, # unexpected-keyword-arg, # TODO: #210 - enable and fix unhashable-dict-key, - # unnecessary-pass, # TODO: #210 - enable and fix + unnecessary-pass, unreachable, unrecognized-inline-option, unused-import, unnecessary-semicolon, - # unused-variable, # TODO: #210 - enable and fix - # unused-wildcard-import, # TODO: #210 - enable and fix - # wildcard-import, # TODO: #210 - enable and fix + unused-variable, + unused-wildcard-import, + wildcard-import, wrong-or-nonexistent-copyright-notice, wrong-import-order, wrong-import-position, diff --git a/examples/fox_in_a_hole/fox_in_a_hole.py b/examples/fox_in_a_hole/fox_in_a_hole.py index eed1fd53..409df8fc 100644 --- a/examples/fox_in_a_hole/fox_in_a_hole.py +++ b/examples/fox_in_a_hole/fox_in_a_hole.py @@ -123,7 +123,7 @@ def take_random_move(self) -> str: def history_append_state(self): """Append the current state into the history.""" - self.history.append("State: {}".format(self.state_to_string())) + self.history.append(f"State: {self.state_to_string()}") def history_append_move(self, move_str): """Append the given move into the history.""" @@ -131,7 +131,7 @@ def history_append_move(self, move_str): def history_append_guess(self, guess): """Append the given guess into the history.""" - self.history.append("Guess: {}".format(guess)) + self.history.append(f"Guess: {guess}") def run(self): """Handles the main game-loop of the Fox-in-a-hole game.""" @@ -162,7 +162,7 @@ def run(self): self.history_append_state() if result: - print("\nCongratulations! You won in {} step(s).\n".format(step_nr + 1)) + print(f"\nCongratulations! You won in {step_nr + 1} step(s).\n") self.print_history() return @@ -249,7 +249,13 @@ class QuantumGame(Game): (QuantumWorld, [QuantumObject]) -> quantum world, list of holes """ - def __init__(self, number_of_holes: int = 5, iswap: bool = False, qprob:float = 0.5, seed: Optional[int] = None): + def __init__( + self, + number_of_holes: int = 5, + iswap: bool = False, + qprob: float = 0.5, + seed: Optional[int] = None, + ): if iswap: self.move_operation = PhasedMove() self.split_operation = PhasedSplit() diff --git a/examples/quantum_chinese_chess/board.py b/examples/quantum_chinese_chess/board.py index 9fea49d6..ddba548e 100644 --- a/examples/quantum_chinese_chess/board.py +++ b/examples/quantum_chinese_chess/board.py @@ -76,7 +76,7 @@ def from_fen(cls, fen: str = _INITIAL_FEN) -> "Board": for char in row: # Add empty board pieces. if "1" <= char <= "9": - for i in range(int(char)): + for _ in range(int(char)): name = f"{chr(col)}{row_index}" chess_board[name] = Piece( name, SquareState.EMPTY, Type.EMPTY, Color.NA @@ -185,7 +185,7 @@ def add_piece_symbol( for i in range(row * 9, (row + 1) * 9): # We only print non-zero probabilities if probabilities[i] >= 1e-3: - board_string.append("{:.1f} ".format(probabilities[i])) + board_string.append(f"{probabilities[i]:.1f} ") else: board_string.append(" ") board_string += "\b" + _RESET + " \n" @@ -231,14 +231,14 @@ def add_piece_symbol( # space + _FULL_SPACE works for mac terminal and gLinux terminal. if probabilities[i] >= 1e-3: board_string.append( - "{:.1f} ".format(probabilities[i]) + _FULL_SPACE + f"{probabilities[i]:.1f} " + _FULL_SPACE ) else: board_string.append(" " + _FULL_SPACE) else: if probabilities[i] >= 1e-3: # space + space works for sublime terminus. - board_string.append("{:.1f} ".format(probabilities[i])) + board_string.append(f"{probabilities[i]:.1f} ") else: board_string.append(" ") board_string += "\b" + _RESET + _FULL_SPACE + "\n" diff --git a/examples/quantum_chinese_chess/board_test.py b/examples/quantum_chinese_chess/board_test.py index 317c719e..ad700f28 100644 --- a/examples/quantum_chinese_chess/board_test.py +++ b/examples/quantum_chinese_chess/board_test.py @@ -37,7 +37,7 @@ def test_init_with_default_fen(): # test English print assert ( - re.sub("\\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( + re.sub(r"\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( "\b", "" ) == """ @@ -59,7 +59,7 @@ def test_init_with_default_fen(): # test Chinese print board.set_language(Language.ZH) assert ( - re.sub("\\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( + re.sub(r"\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( "\b", "" ) == """ @@ -87,7 +87,7 @@ def test_init_with_specified_fen(): # test English print assert ( - re.sub("\\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( + re.sub(r"\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( "\b", "" ) == """ @@ -109,7 +109,7 @@ def test_init_with_specified_fen(): # test Chinese print board.set_language(Language.ZH) assert ( - re.sub("\\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( + re.sub(r"\033\[\d{1,2}m", "", board.to_str(TerminalType.MAC_OR_LINUX)).replace( "\b", "" ) == """ diff --git a/examples/quantum_chinese_chess/chess.py b/examples/quantum_chinese_chess/chess.py index 3544379c..3c4c5de7 100644 --- a/examples/quantum_chinese_chess/chess.py +++ b/examples/quantum_chinese_chess/chess.py @@ -463,9 +463,7 @@ def next_move(self) -> Tuple[bool, str]: all_boards = self.board.board.get_correlated_histogram() sorted_boards = sorted(all_boards.items(), key=lambda x: x[1], reverse=True) for board, count in sorted_boards: - print( - "\n ====== With probability ~ {:.1f} ======".format(count / 100.0) - ) + print(f"\n ====== With probability ~ {(count / 100.0):.1f} ======") print(self.board.to_str(self.terminal, None, list(board))) elif input_str.lower() == "undo": if self.undo(): diff --git a/examples/quantum_chinese_chess/move.py b/examples/quantum_chinese_chess/move.py index 7ce2b8e8..65639a93 100644 --- a/examples/quantum_chinese_chess/move.py +++ b/examples/quantum_chinese_chess/move.py @@ -592,7 +592,7 @@ def effect(self, *objects) -> Iterator[cirq.Operation]: # We loop over all quantum path pieces and check if it could be the only # occupied piece. The fire could be made if it does, otherwise not. # TODO(): think a more efficient way of implementing this case. - for index, expect_occupied_path_piece in enumerate(quantum_path_pieces_0): + for _, expect_occupied_path_piece in enumerate(quantum_path_pieces_0): # TODO(): consider specific cases to save the ancilla. # Add a new ancilla to indicate whether the fire could be made (value = 1 means it could). capture_ancilla = world._add_ancilla(expect_occupied_path_piece.name) diff --git a/examples/quantum_chinese_chess/move_test.py b/examples/quantum_chinese_chess/move_test.py index af5c882b..d0660d0f 100644 --- a/examples/quantum_chinese_chess/move_test.py +++ b/examples/quantum_chinese_chess/move_test.py @@ -14,9 +14,17 @@ from unitary import alpha -from .move import * +from .move import ( + CannonFire, + Jump, + MergeJump, + MergeSlide, + Move, + Slide, + SplitJump, + SplitSlide, +) from .board import Board -from .piece import Piece from .enums import ( MoveType, MoveVariant, diff --git a/examples/quantum_rpg/bb84_test.py b/examples/quantum_rpg/bb84_test.py index 43ca3360..a4a60e60 100644 --- a/examples/quantum_rpg/bb84_test.py +++ b/examples/quantum_rpg/bb84_test.py @@ -157,7 +157,7 @@ def test_alice_bob(): """.strip() ) # Reset input and get the keys - state.file = file = io.StringIO() + state.file = io.StringIO() key = bb84.solve_bb84(state.state_dict["alice"], state.state_dict["bob"]) state.get_user_input = input_helpers.get_user_input_function( [f"type {key}", "north", "south", "Quit"] diff --git a/examples/quantum_rpg/final_state_preparation/final_state_world_test.py b/examples/quantum_rpg/final_state_preparation/final_state_world_test.py index e1d72eb9..3daddccc 100644 --- a/examples/quantum_rpg/final_state_preparation/final_state_world_test.py +++ b/examples/quantum_rpg/final_state_preparation/final_state_world_test.py @@ -52,7 +52,7 @@ def go_directions(path: str) -> World: cur_room = example_world.current_location.label direction = Direction.parse(cmd) assert direction is not None - result = example_world.move(direction) + _result = example_world.move(direction) assert cmd is not None, f"Moving {cmd} in room {cur_room} not valid" return example_world @@ -67,7 +67,7 @@ def test_consistent_exits(): assert nearby_room is not None, f"Missing room {room_name}" try: return_exit = nearby_room.exits[OPPOSITE_DIR[direction]] - except KeyError as e: + except KeyError as _e: raise KeyError( f"{room_name} does not have a return exit in {direction} to {location.label}" ) diff --git a/examples/quantum_rpg/main_loop.py b/examples/quantum_rpg/main_loop.py index 63b87aef..d527dbde 100644 --- a/examples/quantum_rpg/main_loop.py +++ b/examples/quantum_rpg/main_loop.py @@ -30,12 +30,10 @@ class Error(Exception): """Base class for locally defined exceptions.""" - pass class AmbiguousCommandError(Error): """Raised when entered command is ambiguous.""" - pass class Command(enum.Enum): @@ -165,9 +163,11 @@ def loop(self, user_input: Optional[Sequence[str]] = None) -> None: try: input_cmd = Command.parse(current_input) except AmbiguousCommandError: - print(f"Ambiguous command '{current_input}'.", - Command.help(), - file=self.file) + print( + f"Ambiguous command '{current_input}'.", + Command.help(), + file=self.file, + ) print_room_description = False continue if input_cmd == Command.QUIT: @@ -184,7 +184,8 @@ def loop(self, user_input: Optional[Sequence[str]] = None) -> None: print(npc_class.__name__, file=self.file) print( textwrap.indent(npc_class.quantopedia_entry(), " "), - file=self.file) + file=self.file, + ) print(file=self.file) print_room_description = False elif input_cmd == Command.LOAD: diff --git a/examples/quantum_rpg/main_loop_test.py b/examples/quantum_rpg/main_loop_test.py index 493b5c06..770b51b1 100644 --- a/examples/quantum_rpg/main_loop_test.py +++ b/examples/quantum_rpg/main_loop_test.py @@ -551,14 +551,14 @@ def test_item_function(): def test_main_quit(): state = game_state.GameState(party=[], user_input=["4"], file=io.StringIO()) - loop = main_loop.main(state) + _loop = main_loop.main(state) assert state.file.getvalue() == _TITLE def test_main_help(): state = game_state.GameState(party=[], user_input=["3", "4"], file=io.StringIO()) - loop = main_loop.main(state) + _loop = main_loop.main(state) assert ( state.file.getvalue() @@ -570,7 +570,7 @@ def test_main_begin(): state = game_state.GameState( party=[], user_input=["1", "nova", "n", "Quit"], file=io.StringIO() ) - loop = main_loop.main(state) + _loop = main_loop.main(state) assert ( state.file.getvalue() @@ -611,7 +611,7 @@ def test_main_load(): user_input=["2", "classical3;1;Doug#Analyst#1", "Quit"], file=io.StringIO(), ) - loop = main_loop.main(state) + _loop = main_loop.main(state) assert ( state.file.getvalue() @@ -636,7 +636,7 @@ def test_main_bad_save_file(): user_input=["2", "", "2", "classical3;1;Doug#Analyst#1", "Quit"], file=io.StringIO(), ) - loop = main_loop.main(state) + _loop = main_loop.main(state) assert ( state.file.getvalue() diff --git a/examples/quantum_rpg/qaracter.py b/examples/quantum_rpg/qaracter.py index bed2a5c0..2cd31ac6 100644 --- a/examples/quantum_rpg/qaracter.py +++ b/examples/quantum_rpg/qaracter.py @@ -14,7 +14,6 @@ from typing import cast, Dict, List, Optional, Union import inspect -import sys import cirq from unitary import alpha @@ -221,9 +220,7 @@ def from_save_file( # Avoid circular import from . import classes - class_tuples = inspect.getmembers( - sys.modules["quantum_rpg.classes"], inspect.isclass - ) + class_tuples = inspect.getmembers(classes, inspect.isclass) new_cls = cls for cls_name, cls_type in class_tuples: if cls_name == class_name: diff --git a/unitary/alpha/quantum_world.py b/unitary/alpha/quantum_world.py index 8053dfbd..6ebd5f88 100644 --- a/unitary/alpha/quantum_world.py +++ b/unitary/alpha/quantum_world.py @@ -141,7 +141,7 @@ def add_object(self, obj: QuantumObject): self.compiled_qubits[obj.qubit] = [obj.qubit] else: self.compiled_qubits[obj.qubit] = [] - for qubit_num in range(num_bits(qudit_dim)): + for _ in range(num_bits(qudit_dim)): new_obj = self._add_ancilla(obj.qubit.name) self.compiled_qubits[obj.qubit].append(new_obj.qubit) obj.initial_effect() @@ -385,21 +385,21 @@ def _interpret_result(self, result: Union[int, Iterable[int]]) -> int: return result_list[0] return result - def unhook(self, object: QuantumObject) -> None: - """Replace all usages of the given `object` in the circuit with a new ancilla, + def unhook(self, obj: QuantumObject) -> None: + """Replace all usages of the given object in the circuit with a new ancilla, so that - - all former operations on `object` will be applied on the new ancilla; - - future operations on `object` start with its new reset value. + - all former operations on `obj` will be applied on the new ancilla; + - future operations on `obj` start with its new reset value. Note that we don't do force measurement on it, since we don't care about its current value but just want to reset it. """ # Create a new ancilla. - new_ancilla = self._add_ancilla(object.name) - # Replace operations of the given `object` with the new ancilla. + new_ancilla = self._add_ancilla(obj.name) + # Replace operations of the given `obj` with the new ancilla. qubit_remapping_dict = { - object.qubit: new_ancilla.qubit, - new_ancilla.qubit: object.qubit, + obj.qubit: new_ancilla.qubit, + new_ancilla.qubit: obj.qubit, } self.qubit_remapping_dict.append(qubit_remapping_dict) self.circuit = self.circuit.transform_qubits( @@ -716,12 +716,12 @@ def __getitem__(self, name: str) -> QuantumObject: raise KeyError(f"{name} did not exist in this world.") return quantum_object - def __to_state_vector__(self, input: tuple) -> np.ndarray: + def __to_state_vector__(self, input_bits: tuple) -> np.ndarray: """Converts the given tuple (of length N) to the corresponding state vector (of length 2**N). e.g. (0, 1) -> [0, 1, 0, 0] """ - num = len(input) - index = int("".join([str(i) for i in input]), 2) + num = len(input_bits) + index = int("".join([str(i) for i in input_bits]), 2) state_vector = np.array([0.0] * (2**num)) state_vector[index] = 1.0 return state_vector diff --git a/unitary/alpha/quantum_world_test.py b/unitary/alpha/quantum_world_test.py index bab88672..48d8c071 100644 --- a/unitary/alpha/quantum_world_test.py +++ b/unitary/alpha/quantum_world_test.py @@ -946,8 +946,6 @@ def test_density_matrix(simulator, compile_to_qubits): ], ) def test_measure_entanglement(simulator, compile_to_qubits): - rho_green = np.reshape([0, 0, 0, 1], (2, 2)) - rho_red = np.reshape([1, 0, 0, 0], (2, 2)) light1 = alpha.QuantumObject("red1", Light.RED) light2 = alpha.QuantumObject("green", Light.GREEN) light3 = alpha.QuantumObject("red2", Light.RED) diff --git a/unitary/alpha/qudit_gates_test.py b/unitary/alpha/qudit_gates_test.py index 843b376b..58f43a5a 100644 --- a/unitary/alpha/qudit_gates_test.py +++ b/unitary/alpha/qudit_gates_test.py @@ -42,7 +42,7 @@ def test_qutrit_x(state: int): def test_qutrit_plus_one(num_gates: int): qutrit = cirq.NamedQid("a", dimension=3) c = cirq.Circuit() - for i in range(num_gates): + for _ in range(num_gates): c.append(qudit_gates.QuditPlusGate(3)(qutrit)) c.append(cirq.measure(qutrit, key="m")) sim = cirq.Simulator() diff --git a/unitary/alpha/quokka_sampler.py b/unitary/alpha/quokka_sampler.py index c5c9cfc2..d5f9bff5 100644 --- a/unitary/alpha/quokka_sampler.py +++ b/unitary/alpha/quokka_sampler.py @@ -91,7 +91,6 @@ def run_sweep( Result list for this run; one for each possible parameter resolver. """ rtn_results = [] - qubits = sorted(program.all_qubits()) measure_keys = {} register_names = {} meas_i = 0 diff --git a/unitary/engine_utils.py b/unitary/engine_utils.py index 290a2df6..9caf49cd 100644 --- a/unitary/engine_utils.py +++ b/unitary/engine_utils.py @@ -96,7 +96,7 @@ def __init__(self, processor_id: Optional[str], gateset: Optional[str]): elif gateset == "sqrt-iswap": self.gate_set = cg.SQRT_ISWAP_GATESET else: - raise ValueError("Unknown gateset {}".format(gateset)) + raise ValueError(f"Unknown gateset {gateset}") def run( self, @@ -189,7 +189,7 @@ def run_sweep( ] else: assert len(meas) == 1 - i, op, gate = meas[0] + _, op, gate = meas[0] n_qubits = len(op.qubits) k = gate.key results = [ @@ -372,7 +372,7 @@ async def worker(): worker_jobs = [asyncio.create_task(worker()) for _ in range(num_workers)] for task in tasks: await queue.put(task) - print("Added everything to the queue. Current queue size: {}".format(queue.qsize())) + print(f"Added everything to the queue. Current queue size: {queue.qsize()}") await queue.join() for wjob in worker_jobs: wjob.cancel() diff --git a/unitary/engine_utils_test.py b/unitary/engine_utils_test.py index 67c12838..10499664 100644 --- a/unitary/engine_utils_test.py +++ b/unitary/engine_utils_test.py @@ -36,7 +36,7 @@ def test_get_program_id_2(): prog_id = _get_program_id(circuit) assert isinstance(prog_id, str) with pytest.raises(ValueError): - val = uuid.UUID(prog_id, version=4) + _ = uuid.UUID(prog_id, version=4) assert prog_id.startswith("my_fancy_var_1_my_fancy_var_2_x-3") @@ -50,7 +50,7 @@ def test_get_program_id_3(): prog_id = _get_program_id(circuit) assert isinstance(prog_id, str) with pytest.raises(ValueError): - val = uuid.UUID(prog_id, version=4) + _ = uuid.UUID(prog_id, version=4) assert prog_id.startswith("my_far_1_my_far_2_my_far_3_my_far_4_my_far_5_my_far_6_") @@ -61,7 +61,7 @@ def test_get_program_id_4(): prog_id = _get_program_id(circuit) assert isinstance(prog_id, str) # too many parts, it defaults back to uuid - val = uuid.UUID(prog_id, version=4) + _ = uuid.UUID(prog_id, version=4) def test_zeros_sampler_one_big_measure(): @@ -83,7 +83,7 @@ def test_zeros_sampler_many_measure(): sampler = unitary.ZerosSampler() result = sampler.run(circuit, repetitions=155) assert len(result.measurements) == 6 - for k, v in result.measurements.items(): + for v in result.measurements.values(): assert v.shape == (155, 1) diff --git a/unitary/quantum_chess/mcpe_utils.py b/unitary/quantum_chess/mcpe_utils.py index 882cd412..7c12ef81 100644 --- a/unitary/quantum_chess/mcpe_utils.py +++ b/unitary/quantum_chess/mcpe_utils.py @@ -22,7 +22,7 @@ """ from collections import defaultdict, deque -from typing import Callable, Dict, Iterable, Set, Tuple +from typing import Callable, Dict, Iterable, Optional, Set, Tuple import cirq @@ -67,8 +67,10 @@ class QubitMapping: initial_mapping: initial logical-to-physical qubit map. """ - def __init__(self, initial_mapping: Dict[cirq.Qid, cirq.GridQubit] = {}): - self.logical_to_physical = initial_mapping + def __init__( + self, initial_mapping: Optional[Dict[cirq.Qid, cirq.GridQubit]] = None + ): + self.logical_to_physical = initial_mapping or {} self.physical_to_logical = {v: k for k, v in initial_mapping.items()} def swap_physical(self, q1: cirq.GridQubit, q2: cirq.GridQubit) -> None: diff --git a/unitary/quantum_chess/mcpe_utils_test.py b/unitary/quantum_chess/mcpe_utils_test.py index 7da12cbe..35f5b971 100644 --- a/unitary/quantum_chess/mcpe_utils_test.py +++ b/unitary/quantum_chess/mcpe_utils_test.py @@ -57,7 +57,7 @@ def test_effect_of_swap(): def test_distance_fn(): - a1, a2, a3, b1, b2, b3 = cirq.GridQubit.rect(2, 3) + a1, a2, a3, _, b2, _ = cirq.GridQubit.rect(2, 3) # A gate operating on (a1, a3) will be improved by swapping a1 and a2, but # by how much depends on the distance function used. diff --git a/unitary/quantum_chess/quantum_board.py b/unitary/quantum_chess/quantum_board.py index 6434abc6..06937da3 100644 --- a/unitary/quantum_chess/quantum_board.py +++ b/unitary/quantum_chess/quantum_board.py @@ -706,7 +706,7 @@ def _do_noncontrolled_castle( self, variant, measurement, sbit, tbit, rook_sbit, rook_tbit ): """Kingside castle, or queenside castle with empty b-file.""" - squbit = bit_to_qubit(sbit) + _squbit = bit_to_qubit(sbit) tqubit = bit_to_qubit(tbit) rook_squbit = bit_to_qubit(rook_sbit) rook_tqubit = bit_to_qubit(rook_tbit) diff --git a/unitary/quantum_chess/quantum_board_test.py b/unitary/quantum_chess/quantum_board_test.py index e5e0eb3c..e9bc1c54 100644 --- a/unitary/quantum_chess/quantum_board_test.py +++ b/unitary/quantum_chess/quantum_board_test.py @@ -196,7 +196,7 @@ def test_split_move(move_type, board): "c1", "d1", move_type=enums.MoveType.JUMP, move_variant=enums.MoveVariant.BASIC ) assert b.do_move(m) - samples = b.sample(100) + _samples = b.sample(100) assert_samples_in(b, [u.squares_to_bitboard(["a3"]), u.squares_to_bitboard(["d1"])]) probs = b.get_probability_distribution(5000) assert_fifty_fifty(probs, u.square_to_bit("a3")) diff --git a/unitary/quantum_chess/swap_updater.py b/unitary/quantum_chess/swap_updater.py index a836f0b8..4ad272fc 100644 --- a/unitary/quantum_chess/swap_updater.py +++ b/unitary/quantum_chess/swap_updater.py @@ -161,14 +161,14 @@ def __init__( self, circuit: cirq.Circuit, device_qubits: Optional[Iterable[cirq.GridQubit]], - initial_mapping: Dict[cirq.Qid, cirq.GridQubit] = {}, + initial_mapping: Optional[Dict[cirq.Qid, cirq.GridQubit]] = None, swap_factory: Callable[ [cirq.Qid, cirq.Qid], Iterable[cirq.Operation] ] = generate_decomposed_swap, ): self.device_qubits = device_qubits or [] self.dlists = mcpe.DependencyLists(circuit) - self.mapping = mcpe.QubitMapping(initial_mapping) + self.mapping = mcpe.QubitMapping(initial_mapping or {}) self.swap_factory = swap_factory self.adjacent = {q: q.neighbors(device_qubits) for q in self.device_qubits} self.pairwise_distances = _pairwise_shortest_distances(self.adjacent) diff --git a/unitary/quantum_chess/swap_updater_test.py b/unitary/quantum_chess/swap_updater_test.py index f5d854fb..fe6e3281 100644 --- a/unitary/quantum_chess/swap_updater_test.py +++ b/unitary/quantum_chess/swap_updater_test.py @@ -110,7 +110,7 @@ def test_pentagonal_split_and_merge(): cirq.NamedQubit(f"{x}{i}") for x in ("a", "b") for i in range(3) ) initial_mapping = dict(zip(logical_qubits, grid_2x3)) - a1, a2, a3, b1, b2, b3 = logical_qubits + a1, a2, a3, b1, _, b3 = logical_qubits logical_circuit = cirq.Circuit( qm.normal_move(a1, b1), qm.normal_move(a2, a3), qm.merge_move(a3, b1, b3) ) @@ -182,7 +182,7 @@ def test_holes_in_device_graph(): cirq.NamedQubit(f"{x}{i}") for x in ("a", "b") for i in range(3) ) initial_mapping = dict(zip(logical_qubits, grid_2x3)) - a1, a2, a3, b1, b2, b3 = logical_qubits + _, _, _, b1, b2, b3 = logical_qubits # Circuit has a gate that operate on (b1, b3) qubits. # The best way to add swaps would be between (b1, b2) and (b2, b3), but # we aren't allowed to use b2, so we're forced to route swaps around it. @@ -203,7 +203,7 @@ def test_bad_initial_mapping(): cirq.NamedQubit(f"{x}{i}") for x in ("a", "b") for i in range(3) ) initial_mapping = dict(zip(logical_qubits, grid_2x3)) - a1, a2, a3, b1, b2, b3 = logical_qubits + a1, _, a3, _, _, _ = logical_qubits # Initial mapping puts a1 on a qubit that we're not allowed to use, but the # circuit uses a1. # That should cause the swap updater to throw. @@ -223,7 +223,7 @@ def test_disconnected_components(): cirq.NamedQubit(f"{x}{i}") for x in ("a", "b") for i in range(3) ) initial_mapping = dict(zip(logical_qubits, grid_2x3)) - a1, a2, a3, b1, b2, b3 = logical_qubits + a1, a2, a3, _, b2, _ = logical_qubits # a2 and b2 are disallowed. That splits the device graph into 2 disconnected # components and makes a3 unreachable from a1. circuit = cirq.Circuit(cirq.ISWAP(a1, a3))