def _generate_qwc_paulis(
    input_pauli: cirq.PauliString, num_output: int, exclude_input_pauli: bool = False
) -> list[cirq.PauliString]:
    """Generates PauliStrings that are Qubit-Wise Commuting (QWC)
    with the input_pauli.

    All operations in input_pauli must not be pauli I.
    """
    allowed_paulis_per_qubit = []
    qubits = input_pauli.qubits

    for qubit in qubits:
        pauli_op = input_pauli.get(qubit, cirq.I)

        allowed_pauli_op = []
        if pauli_op == cirq.I:
            allowed_pauli_op = [cirq.I, cirq.X, cirq.Y, cirq.Z]  # pragma: no cover
        elif pauli_op == cirq.X:
            allowed_pauli_op = [cirq.I, cirq.X]
        elif pauli_op == cirq.Y:
            allowed_pauli_op = [cirq.I, cirq.Y]
        elif pauli_op == cirq.Z:
            allowed_pauli_op = [cirq.I, cirq.Z]

        allowed_paulis_per_qubit.append(allowed_pauli_op)

    qwc_paulis: list[cirq.PauliString] = []

    for pauli_combination in itertools.product(*allowed_paulis_per_qubit):
        pauli_dict = {}
        for i, qid in enumerate(qubits):
            pauli_dict[qid] = pauli_combination[i]

        qwc_pauli: cirq.PauliString = cirq.PauliString(pauli_dict)
        if exclude_input_pauli and qwc_pauli == input_pauli:
            continue  # pragma: no cover
        if all(q == cirq.I for q in qwc_pauli):
            continue
        qwc_paulis.append(qwc_pauli)

    return qwc_paulis if num_output > len(qwc_paulis) else random.sample(qwc_paulis, num_output)
Generates PauliStrings that are Qubit-Wise Commuting (QWC)
    with the input_pauli.

    All operations in input_pauli must not be pauli I.
    
cirq-core/cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py