Skip to content

Commit

Permalink
Merge branch 'main' into move-target
Browse files Browse the repository at this point in the history
  • Loading branch information
raynelfss committed May 12, 2024
2 parents 2d46d87 + f20dad0 commit 97d9341
Show file tree
Hide file tree
Showing 28 changed files with 102 additions and 64 deletions.
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ We provide more detail on [the release and support schedule of Qiskit in our doc
## Reporting a Vulnerability

To report vulnerabilities, you can privately report a potential security issue
via the Github security vulnerabilities feature. This can be done here:
via the GitHub security vulnerabilities feature. This can be done here:

https://github.com/Qiskit/qiskit/security/advisories

Please do **not** open a public issue about a potential security vulnerability.

You can find more details on the security vulnerability feature in the Github
You can find more details on the security vulnerability feature in the GitHub
documentation here:

https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,6 @@ disable = [
# remove from here and fix the issues. Else, move it above this section and add a comment
# with the rationale
"arguments-renamed",
"broad-exception-raised",
"consider-using-dict-items",
"consider-using-enumerate",
"consider-using-f-string",
"no-member",
Expand All @@ -228,7 +226,6 @@ disable = [
"unnecessary-dunder-call",
"unnecessary-lambda-assignment",
"unspecified-encoding",
"unsupported-assignment-operation",
]

enable = [
Expand Down
4 changes: 2 additions & 2 deletions qiskit/dagcircuit/collect_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ def run(self, block):
self.group[self.find_leader(first)].append(node)

blocks = []
for index in self.leader:
if self.leader[index] == index:
for index, item in self.leader.items():
if index == item:
blocks.append(self.group[index])

return blocks
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/basic_provider/basic_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,13 @@ def run(
from qiskit.compiler import assemble

out_options = {}
for key in backend_options:
for key, value in backend_options.items():
if not hasattr(self.options, key):
warnings.warn(
"Option %s is not used by this backend" % key, UserWarning, stacklevel=2
)
else:
out_options[key] = backend_options[key]
out_options[key] = value
qobj = assemble(run_input, self, **out_options)
qobj_options = qobj.config
self._set_options(qobj_config=qobj_options, backend_options=backend_options)
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/models/backendconfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,9 @@ def get_qubit_channels(self, qubit: Union[int, Iterable[int]]) -> List[Channel]:
channels = set()
try:
if isinstance(qubit, int):
for key in self._qubit_channel_map.keys():
for key, value in self._qubit_channel_map.items():
if qubit in key:
channels.update(self._qubit_channel_map[key])
channels.update(value)
if len(channels) == 0:
raise KeyError
elif isinstance(qubit, list):
Expand Down
18 changes: 9 additions & 9 deletions qiskit/providers/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,28 +229,28 @@ def set_validator(self, field, validator_value):
f"{type(validator_value)} is not a valid validator type, it "
"must be a tuple, list, or class/type"
)
self.validator[field] = validator_value
self.validator[field] = validator_value # pylint: disable=unsupported-assignment-operation

def update_options(self, **fields):
"""Update options with kwargs"""
for field in fields:
field_validator = self.validator.get(field, None)
for field_name, field in fields.items():
field_validator = self.validator.get(field_name, None)
if isinstance(field_validator, tuple):
if fields[field] > field_validator[1] or fields[field] < field_validator[0]:
if field > field_validator[1] or field < field_validator[0]:
raise ValueError(
f"Specified value for '{field}' is not a valid value, "
f"Specified value for '{field_name}' is not a valid value, "
f"must be >={field_validator[0]} or <={field_validator[1]}"
)
elif isinstance(field_validator, list):
if fields[field] not in field_validator:
if field not in field_validator:
raise ValueError(
f"Specified value for {field} is not a valid choice, "
f"Specified value for {field_name} is not a valid choice, "
f"must be one of {field_validator}"
)
elif isinstance(field_validator, type):
if not isinstance(fields[field], field_validator):
if not isinstance(field, field_validator):
raise TypeError(
f"Specified value for {field} is not of required type {field_validator}"
f"Specified value for {field_name} is not of required type {field_validator}"
)

self._fields.update(fields)
Expand Down
4 changes: 2 additions & 2 deletions qiskit/pulse/library/symbolic_pulses.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,8 @@ def __eq__(self, other: object) -> bool:
if not np.isclose(complex_amp1, complex_amp2):
return False

for key in self.parameters:
if key not in ["amp", "angle"] and self.parameters[key] != other.parameters[key]:
for key, value in self.parameters.items():
if key not in ["amp", "angle"] and value != other.parameters[key]:
return False

return True
Expand Down
7 changes: 5 additions & 2 deletions qiskit/quantum_info/operators/symplectic/pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,11 @@ def apply_layout(
n_qubits = num_qubits
if layout is None:
layout = list(range(self.num_qubits))
elif any(x >= n_qubits for x in layout):
raise QiskitError("Provided layout contains indices outside the number of qubits.")
else:
if any(x < 0 or x >= n_qubits for x in layout):
raise QiskitError("Provided layout contains indices outside the number of qubits.")
if len(set(layout)) != len(layout):
raise QiskitError("Provided layout contains duplicate indices.")
new_op = type(self)("I" * n_qubits)
return new_op.compose(self, qargs=layout)

Expand Down
8 changes: 5 additions & 3 deletions qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,6 @@ def apply_layout(
specified will be applied without any expansion. If layout is
None, the operator will be expanded to the given number of qubits.
Returns:
A new :class:`.SparsePauliOp` with the provided layout applied
"""
Expand All @@ -1159,10 +1158,13 @@ def apply_layout(
f"applied to a {n_qubits} qubit operator"
)
n_qubits = num_qubits
if layout is not None and any(x >= n_qubits for x in layout):
raise QiskitError("Provided layout contains indices outside the number of qubits.")
if layout is None:
layout = list(range(self.num_qubits))
else:
if any(x < 0 or x >= n_qubits for x in layout):
raise QiskitError("Provided layout contains indices outside the number of qubits.")
if len(set(layout)) != len(layout):
raise QiskitError("Provided layout contains duplicate indices.")
new_op = type(self)("I" * n_qubits)
return new_op.compose(self, qargs=layout)

Expand Down
2 changes: 1 addition & 1 deletion qiskit/quantum_info/quaternion.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __mul__(self, r):
out_data[3] = r(0) * q(3) - r(1) * q(2) + r(2) * q(1) + r(3) * q(0)
return Quaternion(out_data)
else:
raise Exception("Multiplication by other not supported.")
return NotImplemented

def norm(self):
"""Norm of quaternion."""
Expand Down
8 changes: 4 additions & 4 deletions qiskit/result/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ def __repr__(self):
out += ", seed=%s" % self.seed
if hasattr(self, "meas_return"):
out += ", meas_return=%s" % self.meas_return
for key in self._metadata:
if isinstance(self._metadata[key], str):
value_str = "'%s'" % self._metadata[key]
for key, value in self._metadata.items():
if isinstance(value, str):
value_str = "'%s'" % value
else:
value_str = repr(self._metadata[key])
value_str = repr(value)
out += f", {key}={value_str}"
out += ")"
return out
Expand Down
8 changes: 4 additions & 4 deletions qiskit/result/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ def __repr__(self):
)
)
out += f", date={self.date}, status={self.status}, header={self.header}"
for key in self._metadata:
if isinstance(self._metadata[key], str):
value_str = "'%s'" % self._metadata[key]
for key, value in self._metadata.items():
if isinstance(value, str):
value_str = "'%s'" % value
else:
value_str = repr(self._metadata[key])
value_str = repr(value)
out += f", {key}={value_str}"
out += ")"
return out
Expand Down
2 changes: 1 addition & 1 deletion qiskit/synthesis/clifford/clifford_decompose_bm.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def _cx_cost(clifford):
return _cx_cost2(clifford)
if clifford.num_qubits == 3:
return _cx_cost3(clifford)
raise Exception("No Clifford CX cost function for num_qubits > 3.")
raise RuntimeError("No Clifford CX cost function for num_qubits > 3.")


def _rank2(a, b, c, d):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ def collect_key(x):
prev = bit
self.gate_groups[self.find_set(prev)].append(nd)
# need to turn all groups that still exist into their own blocks
for index in self.parent:
if self.parent[index] == index and len(self.gate_groups[index]) != 0:
for index, item in self.parent.items():
if item == index and len(self.gate_groups[index]) != 0:
block_list.append(self.gate_groups[index][:])

self.property_set["block_list"] = block_list
Expand Down
4 changes: 2 additions & 2 deletions qiskit/visualization/bloch.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def set_label_convention(self, convention):
self.zlabel = ["$\\circlearrowleft$", "$\\circlearrowright$"]
self.xlabel = ["$\\leftrightarrow$", "$\\updownarrow$"]
else:
raise Exception("No such convention.")
raise ValueError("No such convention.")

def __str__(self):
string = ""
Expand Down Expand Up @@ -396,7 +396,7 @@ def add_annotation(self, state_or_vector, text, **kwargs):
if isinstance(state_or_vector, (list, np.ndarray, tuple)) and len(state_or_vector) == 3:
vec = state_or_vector
else:
raise Exception("Position needs to be specified by a qubit " + "state or a 3D vector.")
raise TypeError("Position needs to be specified by a qubit state or a 3D vector.")
self.annotations.append({"position": vec, "text": text, "opts": kwargs})

def make_sphere(self):
Expand Down
23 changes: 14 additions & 9 deletions qiskit/visualization/circuit/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,22 @@ def _initialize_latex_array(self):
self._latex.append([" "] * (self._img_depth + 1))

# display the bit/register labels
for wire in self._wire_map:
for wire, index in self._wire_map.items():
if isinstance(wire, ClassicalRegister):
register = wire
index = self._wire_map[wire]
wire_label = get_wire_label(
"latex", register, index, layout=self._layout, cregbundle=self._cregbundle
)
else:
register, bit_index, reg_index = get_bit_reg_index(self._circuit, wire)
index = bit_index if register is None else reg_index
wire_label = get_wire_label(
"latex",
register,
bit_index if register is None else reg_index,
layout=self._layout,
cregbundle=self._cregbundle,
)

wire_label = get_wire_label(
"latex", register, index, layout=self._layout, cregbundle=self._cregbundle
)
wire_label += " : "
if self._initial_state:
wire_label += "\\ket{{0}}" if isinstance(wire, Qubit) else "0"
Expand All @@ -234,7 +239,7 @@ def _initialize_latex_array(self):
self._latex[pos][1] = "\\lstick{/_{_{" + str(register.size) + "}}} \\cw"
wire_label = f"\\mathrm{{{wire_label}}}"
else:
pos = self._wire_map[wire]
pos = index
self._latex[pos][0] = "\\nghost{" + wire_label + " & " + "\\lstick{" + wire_label

def _get_image_depth(self):
Expand Down Expand Up @@ -620,11 +625,11 @@ def _add_condition(self, op, wire_list, col):
# First sort the val_bits in the order of the register bits in the circuit
cond_wires = []
cond_bits = []
for wire in self._wire_map:
for wire, index in self._wire_map.items():
reg, _, reg_index = get_bit_reg_index(self._circuit, wire)
if reg == cond_reg:
cond_bits.append(reg_index)
cond_wires.append(self._wire_map[wire])
cond_wires.append(index)

gap = cond_wires[0] - max(wire_list)
prev_wire = cond_wires[0]
Expand Down
3 changes: 1 addition & 2 deletions qiskit/visualization/circuit/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,10 +894,9 @@ def wire_names(self, with_initial_state=False):

self._wire_map = get_wire_map(self._circuit, (self.qubits + self.clbits), self.cregbundle)
wire_labels = []
for wire in self._wire_map:
for wire, index in self._wire_map.items():
if isinstance(wire, ClassicalRegister):
register = wire
index = self._wire_map[wire]
else:
register, bit_index, reg_index = get_bit_reg_index(self._circuit, wire)
index = bit_index if register is None else reg_index
Expand Down
4 changes: 2 additions & 2 deletions qiskit/visualization/transition_visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ def __mul__(self, b):
return self._multiply_with_quaternion(b)
elif isinstance(b, (list, tuple, np.ndarray)):
if len(b) != 3:
raise Exception(f"Input vector has invalid length {len(b)}")
raise ValueError(f"Input vector has invalid length {len(b)}")
return self._multiply_with_vector(b)
else:
raise Exception(f"Multiplication with unknown type {type(b)}")
return NotImplemented

def _multiply_with_quaternion(self, q_2):
"""Multiplication of quaternion with quaternion"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Fixed :meth:`.SparsePauliOp.apply_layout` and :meth:`.Pauli.apply_layout`
to raise :exc:`.QiskitError` if duplicate indices or negative indices are provided
as part of a layout.
2 changes: 1 addition & 1 deletion test/benchmarks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def random_circuit(
Exception: when invalid options given
"""
if max_operands < 1 or max_operands > 3:
raise Exception("max_operands must be between 1 and 3")
raise ValueError("max_operands must be between 1 and 3")

one_q_ops = [
IGate,
Expand Down
4 changes: 2 additions & 2 deletions test/python/primitives/test_backend_sampler_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,9 @@ def test_circuit_with_aliased_cregs(self, backend):
self.assertEqual(len(result), 1)
data = result[0].data
self.assertEqual(len(data), 3)
for creg_name in target:
for creg_name, creg in target.items():
self.assertTrue(hasattr(data, creg_name))
self._assert_allclose(getattr(data, creg_name), np.array(target[creg_name]))
self._assert_allclose(getattr(data, creg_name), np.array(creg))

@combine(backend=BACKENDS)
def test_no_cregs(self, backend):
Expand Down
4 changes: 2 additions & 2 deletions test/python/primitives/test_statevector_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,9 +606,9 @@ def test_circuit_with_aliased_cregs(self):
self.assertEqual(len(result), 1)
data = result[0].data
self.assertEqual(len(data), 3)
for creg_name in target:
for creg_name, creg in target.items():
self.assertTrue(hasattr(data, creg_name))
self._assert_allclose(getattr(data, creg_name), np.array(target[creg_name]))
self._assert_allclose(getattr(data, creg_name), np.array(creg))

def test_no_cregs(self):
"""Test that the sampler works when there are no classical register in the circuit."""
Expand Down
12 changes: 12 additions & 0 deletions test/python/quantum_info/operators/symplectic/test_pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,18 @@ def test_apply_layout_null_layout_invalid_num_qubits(self):
with self.assertRaises(QiskitError):
op.apply_layout(layout=None, num_qubits=1)

def test_apply_layout_negative_indices(self):
"""Test apply_layout with negative indices"""
op = Pauli("IZ")
with self.assertRaises(QiskitError):
op.apply_layout(layout=[-1, 0], num_qubits=3)

def test_apply_layout_duplicate_indices(self):
"""Test apply_layout with duplicate indices"""
op = Pauli("IZ")
with self.assertRaises(QiskitError):
op.apply_layout(layout=[0, 0], num_qubits=3)


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,18 @@ def test_apply_layout_null_layout_invalid_num_qubits(self):
with self.assertRaises(QiskitError):
op.apply_layout(layout=None, num_qubits=1)

def test_apply_layout_negative_indices(self):
"""Test apply_layout with negative indices"""
op = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
with self.assertRaises(QiskitError):
op.apply_layout(layout=[-1, 0], num_qubits=3)

def test_apply_layout_duplicate_indices(self):
"""Test apply_layout with duplicate indices"""
op = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
with self.assertRaises(QiskitError):
op.apply_layout(layout=[0, 0], num_qubits=3)


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit 97d9341

Please sign in to comment.