def assert_conjugation(
    input_ps: cirq.PauliString,
    op: cirq.Operation,
    expected: cirq.PauliString | None = None,
    force_checking_unitary=True,
):
    """Verifies that conjugating `input_ps` by `op` results in `expected`.

    Also ensures that the unitary representation of the Pauli string is
    preserved under the conjugation.
    """

    def _ps_on_qubits(ps: cirq.PauliString, qubits: tuple[cirq.Qid, ...]):
        """Extracts a sub-PauliString from a given PauliString, restricted to
        a specified subset of qubits.
        """
        pauli_map = {}
        for q, pauli in ps.items():
            if q in qubits:
                pauli_map[q] = pauli
        return cirq.PauliString(qubit_pauli_map=pauli_map, coefficient=ps.coefficient)

    conjugation = input_ps.conjugated_by(op)
    if expected is None or force_checking_unitary:
        # Compares the unitary of the conjugation result and the expected unitary.
        clifford = cirq.CliffordGate.from_op_list([op], op.qubits)
        actual_unitary = cirq.unitary(_ps_on_qubits(conjugation, op.qubits).dense(op.qubits))
        c = cirq.unitary(clifford)
        expected_unitary = (
            np.conj(c.T) @ cirq.unitary(_ps_on_qubits(input_ps, op.qubits).dense(op.qubits)) @ c
        )
        assert np.allclose(actual_unitary, expected_unitary, atol=1e-8)
    if expected is not None:
        assert conjugation == expected
Verifies that conjugating `input_ps` by `op` results in `expected`.

    Also ensures that the unitary representation of the Pauli string is
    preserved under the conjugation.
    
cirq-core/cirq/ops/pauli_string_test.py