Bump pylint version to unify across elements (#3635)

* Bump pylint version to unify across elements

This commit bumps the pinned versions of pylint and astroid to the
lastest versions of both. We are unifying the version of both used in CI
across all the elements to these versions to have a consistent
experience with the linters when working across the elements.

This adjusts the terra code to make the newer versions pass. This
involves disabling one rule globally because it doesn't apply to how
terra is structured, adding per file (and 1 per line) disable for usage
of numpy that pylint can't track because of the c extensions, and a
number of code changes to fix failing rules which are marked by the new
version.

Fixes #3629

* Fix tests

* Rename kron() args to avoid ordering confusion

* Fix lint failures introduced in recent patches

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Matthew Treinish 2020-01-07 12:21:32 -05:00 committed by Kevin Krsulich
parent 7718e3576d
commit 2fe5055411
38 changed files with 79 additions and 80 deletions

View File

@ -73,6 +73,7 @@ disable=no-self-use, # disabled as it is too verbose
unnecessary-pass, # allow for methods with just "pass", for clarity
no-else-return, # relax "elif" after a clause with a return
docstring-first-line-empty, # relax docstring style
import-outside-toplevel

View File

@ -1,4 +1,4 @@
astroid==2.2.5
pylint==2.3.1
astroid==2.3.3
pylint==2.4.4
matplotlib==3.2.0rc1;python_version=='3.8'
nbformat==4.4.0

View File

@ -89,7 +89,7 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
# delay instructions are ignored as timing is explicit within qobj
continue
elif isinstance(instruction, PulseInstruction):
if isinstance(instruction, PulseInstruction):
name = instruction.command.name
if name in user_pulselib and instruction.command != user_pulselib[name]:
name = "{0}-{1:x}".format(name, hash(instruction.command.samples.tostring()))

View File

@ -159,7 +159,7 @@ class AstInterpreter:
# A qubit or qreg or creg
if not self.bit_stack[-1]:
# Global scope
return [bit for bit in reg]
return list(reg)
else:
# local scope
if node.name in self.bit_stack[-1]:

View File

@ -210,7 +210,7 @@ class DAGCircuit:
Returns:
list[Clbit]: list of classical bits
"""
return [] if cond is None else [cbit for cbit in cond[0]]
return [] if cond is None else list(cond[0])
def _add_op_node(self, op, qargs, cargs, condition=None):
"""Add a new operation node to the graph and assign properties.
@ -569,7 +569,7 @@ class DAGCircuit:
"""
for wire in self.wires:
nodes = self.nodes_on_wire(wire, only_ops=False)
if len([i for i in nodes]) == 2:
if len(list(nodes)) == 2:
yield wire
def size(self):
@ -791,11 +791,7 @@ class DAGCircuit:
condition_bit_list = self._bits_in_condition(node.condition)
wire_map = {k: v for k, v in zip(wires,
[i for s in [node.qargs,
node.cargs,
condition_bit_list]
for i in s])}
wire_map = dict(zip(wires, list(node.qargs) + list(node.cargs) + list(condition_bit_list)))
self._check_wiremap_validity(wire_map, wires, self.input_map)
pred_map, succ_map = self._make_pred_succ_maps(node)
full_pred_map, full_succ_map = self._full_pred_succ_maps(pred_map, succ_map,
@ -1187,7 +1183,7 @@ class DAGCircuit:
def multigraph_layers(self):
"""Yield layers of the multigraph."""
predecessor_count = dict() # Dict[node, predecessors not visited]
cur_layer = [node for node in self.input_map.values()]
cur_layer = self.input_map.values()
yield cur_layer
next_layer = []
while cur_layer:

View File

@ -16,6 +16,7 @@
# pylint: disable=unused-variable
# pylint: disable=missing-param-doc
# pylint: disable=missing-type-doc
# pylint: disable=no-member
"""
Generic isometries from m to n qubits.
@ -416,7 +417,7 @@ def _get_qubits_by_label(labels, qubits, num_qubits):
def _reverse_qubit_oder(qubits):
return [q for q in reversed(qubits)]
return list(reversed(qubits))
# Convert list of binary digits to integer

View File

@ -57,7 +57,7 @@ def barrier(self, *qargs):
elif isinstance(qarg, list):
qubits.extend(qarg)
elif isinstance(qarg, range):
qubits.extend([i for i in qarg])
qubits.extend(list(qarg))
elif isinstance(qarg, slice):
qubits.extend(self.qubits[qarg])
else:

View File

@ -94,7 +94,7 @@ def mcrx(self, theta, q_controls, q_target, use_basis_gates=False):
# check controls
if isinstance(q_controls, QuantumRegister):
control_qubits = [qb for qb in q_controls]
control_qubits = list(q_controls)
elif isinstance(q_controls, list):
control_qubits = q_controls
else:
@ -142,7 +142,7 @@ def mcry(self, theta, q_controls, q_target, q_ancillae, mode='basic',
# check controls
if isinstance(q_controls, QuantumRegister):
control_qubits = [qb for qb in q_controls]
control_qubits = list(q_controls)
elif isinstance(q_controls, list):
control_qubits = q_controls
else:
@ -159,7 +159,7 @@ def mcry(self, theta, q_controls, q_target, q_ancillae, mode='basic',
if q_ancillae is None:
ancillary_qubits = []
elif isinstance(q_ancillae, QuantumRegister):
ancillary_qubits = [qb for qb in q_ancillae]
ancillary_qubits = list(q_ancillae)
elif isinstance(q_ancillae, list):
ancillary_qubits = q_ancillae
else:
@ -206,7 +206,7 @@ def mcrz(self, lam, q_controls, q_target, use_basis_gates=False):
# check controls
if isinstance(q_controls, QuantumRegister):
control_qubits = [qb for qb in q_controls]
control_qubits = list(q_controls)
elif isinstance(q_controls, list):
control_qubits = q_controls
else:

View File

@ -274,7 +274,7 @@ def mct(self, q_controls, q_target, q_ancilla, mode='basic'):
else:
# check controls
if isinstance(q_controls, QuantumRegister):
control_qubits = [qb for qb in q_controls]
control_qubits = list(q_controls)
elif isinstance(q_controls, list):
control_qubits = q_controls
else:
@ -290,7 +290,7 @@ def mct(self, q_controls, q_target, q_ancilla, mode='basic'):
if q_ancilla is None:
ancillary_qubits = []
elif isinstance(q_ancilla, QuantumRegister):
ancillary_qubits = [qb for qb in q_ancilla]
ancillary_qubits = list(q_ancilla)
elif isinstance(q_ancilla, list):
ancillary_qubits = q_ancilla
else:

View File

@ -280,7 +280,7 @@ class TimeslotCollection:
if interval.start >= ch_interval.stop:
break
elif interval.has_overlap(ch_interval):
if interval.has_overlap(ch_interval):
overlap_start = interval.start if interval.start > ch_interval.start \
else ch_interval.start
overlap_end = ch_interval.stop if interval.stop > ch_interval.stop \

View File

@ -12,6 +12,8 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=unpacking-non-sequence
"""
Chi-matrix representation of a Quantum Channel.

View File

@ -12,6 +12,8 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=unpacking-non-sequence
"""
Choi-matrix representation of a Quantum Channel.

View File

@ -406,7 +406,7 @@ class Kraus(QuantumChannel):
if reverse:
input_dims = self.input_dims() + other.input_dims()
output_dims = self.output_dims() + other.output_dims()
kab_l = [np.kron(b, a) for a in ka_l for b in kb_l]
kab_l = [np.kron(b_in, a_in) for a_in in ka_l for b_in in kb_l]
else:
input_dims = other.input_dims() + self.input_dims()
output_dims = other.output_dims() + self.output_dims()
@ -419,7 +419,7 @@ class Kraus(QuantumChannel):
if kb_r is None:
kb_r = kb_l
if reverse:
kab_r = [np.kron(b, a) for a in ka_r for b in kb_r]
kab_r = [np.kron(b_in, a_in) for a_in in ka_r for b_in in kb_r]
else:
kab_r = [np.kron(a, b) for a in ka_r for b in kb_r]
data = (kab_l, kab_r)

View File

@ -12,6 +12,8 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=unpacking-non-sequence
"""
Pauli Transfer Matrix (PTM) representation of a Quantum Channel.

View File

@ -11,6 +11,9 @@
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=unpacking-non-sequence
"""
Superoperator representation of a Quantum Channel.

View File

@ -12,7 +12,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=too-many-return-statements,len-as-condition
# pylint: disable=too-many-return-statements,len-as-condition,unpacking-non-sequence
"""

View File

@ -155,8 +155,8 @@ class Pauli:
def __repr__(self):
"""Return the representation of self."""
z = [p for p in self._z]
x = [p for p in self._x]
z = list(self._z)
x = list(self._x)
ret = self.__class__.__name__ + "(z={}, x={})".format(z, x)
return ret

View File

@ -12,7 +12,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=len-as-condition
# pylint: disable=len-as-condition,unsubscriptable-object
"""
Predicates for operators.

View File

@ -96,7 +96,8 @@ class OneQubitEulerDecomposer:
raise QiskitError("OneQubitEulerDecomposer: invalid basis")
def _circuit(self, unitary_mat, simplify=True, atol=DEFAULT_ATOL):
theta, phi, lam, phase = self._angles(unitary_mat)
# NOTE: The 4th variable is phase to be used later
theta, phi, lam, _ = self._angles(unitary_mat)
if self._basis == 'U3':
return self._circuit_u3(theta, phi, lam)
if self._basis == 'U1X':

View File

@ -76,14 +76,9 @@ def slow_test(func):
return _wrapper
def _get_credentials(test_object, test_options):
def _get_credentials():
"""Finds the credentials for a specific test and options.
Args:
test_object (QiskitTestCase): The test object asking for credentials
test_options (dict): Options after QISKIT_TESTS was parsed by
get_test_options.
Returns:
Credentials: set of credentials
@ -128,7 +123,7 @@ def requires_qe_access(func):
if TEST_OPTIONS['skip_online']:
raise unittest.SkipTest('Skipping online tests')
credentials = _get_credentials(self, TEST_OPTIONS)
credentials = _get_credentials()
self.using_ibmq_credentials = credentials.is_ibmq()
kwargs.update({'qe_token': credentials.token,
'qe_url': credentials.url})
@ -173,7 +168,7 @@ def online_test(func):
if not HAS_NET_CONNECTION:
raise unittest.SkipTest("Test requires internet connection.")
credentials = _get_credentials(self, TEST_OPTIONS)
credentials = _get_credentials()
self.using_ibmq_credentials = credentials.is_ibmq()
kwargs.update({'qe_token': credentials.token,
'qe_url': credentials.url})

View File

@ -54,17 +54,16 @@ def _html_checker(job_var, interval, status, header,
job_status_msg = job_status.value
if job_status_name == 'ERROR':
break
if job_status_name == 'QUEUED':
job_status_msg += ' (%s)' % job_var.queue_position()
if job_var.queue_position() is None:
interval = 2
elif not _interval_set:
interval = max(job_var.queue_position(), 2)
else:
if job_status_name == 'QUEUED':
job_status_msg += ' (%s)' % job_var.queue_position()
if job_var.queue_position() is None:
interval = 2
elif not _interval_set:
interval = max(job_var.queue_position(), 2)
else:
if not _interval_set:
interval = 2
status.value = header % (job_status_msg)
if not _interval_set:
interval = 2
status.value = header % (job_status_msg)
status.value = header % (job_status_msg)

View File

@ -12,7 +12,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=invalid-name
# pylint: disable=invalid-name,unsupported-assignment-operation
"""
A collection of useful quantum information functions.

View File

@ -69,7 +69,7 @@ class CouplingMap:
Returns:
Tuple(int,int): Each edge is a pair of physical qubits.
"""
return [edge for edge in self.graph.edges()]
return list(self.graph.edges())
def add_physical_qubit(self, physical_qubit):
"""Add a physical qubit to the coupling graph as a node.
@ -119,7 +119,7 @@ class CouplingMap:
def physical_qubits(self):
"""Returns a sorted list of physical_qubits"""
if self._qubit_list is None:
self._qubit_list = sorted([pqubit for pqubit in self.graph.nodes])
self._qubit_list = sorted(self.graph.nodes)
return self._qubit_list
def is_connected(self):

View File

@ -298,7 +298,7 @@ class Layout():
for physical, virtual in enumerate(qubit_list):
if virtual is None:
continue
elif isinstance(virtual, Qubit):
if isinstance(virtual, Qubit):
if virtual in out._v2p:
raise LayoutError('Duplicate values not permitted; Layout is bijective.')
out[virtual] = physical

View File

@ -588,7 +588,7 @@ class CrosstalkAdaptiveSchedule(TransformationPass):
"""
Find the appropriate layer for a gate
"""
candidates = [i for i in range(len(layers))]
candidates = list(range(len(layers)))
for i, layer in enumerate(layers):
candidates = self.filter_candidates(candidates, layer, i, triplet)
if not candidates:

View File

@ -88,8 +88,7 @@ class NoiseAdaptiveLayout(AnalysisPass):
if item.name == 'gate_error':
g_reliab = 1.0 - item.value
break
else:
g_reliab = 1.0
g_reliab = 1.0
swap_reliab = pow(g_reliab, 3)
# convert swap reliability to edge weight
# for the Floyd-Warshall shortest weighted paths algorithm

View File

@ -73,21 +73,20 @@ class Unroller(TransformationPass):
if rule[0][0].name in self.basis:
dag.substitute_node(node, rule[0][0], inplace=True)
break
else:
try:
rule = rule[0][0].definition
except TypeError as err:
raise QiskitError('Error decomposing node {}: {}'.format(node.name, err))
try:
rule = rule[0][0].definition
except TypeError as err:
raise QiskitError('Error decomposing node {}: {}'.format(node.name, err))
else:
if not rule:
if rule == []: # empty node
dag.remove_op_node(node)
continue
else: # opaque node
raise QiskitError("Cannot unroll the circuit to the given basis, %s. "
"No rule to expand instruction %s." %
(str(self.basis), node.op.name))
# opaque node
raise QiskitError("Cannot unroll the circuit to the given basis, %s. "
"No rule to expand instruction %s." %
(str(self.basis), node.op.name))
# hacky way to build a dag on the same register as the rule is defined
# TODO: need anonymous rules to address wires by index

View File

@ -266,8 +266,7 @@ class PassManager:
for pass_set in self._pass_sets:
item = {'passes': pass_set['passes']}
if pass_set['flow_controllers']:
item['flow_controllers'] = {controller_name for controller_name in
pass_set['flow_controllers'].keys()}
item['flow_controllers'] = set(pass_set['flow_controllers'].keys())
else:
item['flow_controllers'] = {}
ret.append(item)

View File

@ -120,7 +120,7 @@ def graysynth(cnots, angles, section_size=2):
[cnots, ilist, qubit] = sta.pop()
if cnots == []:
continue
elif 0 <= qubit < n_qubits:
if 0 <= qubit < n_qubits:
condition = True
while condition:
condition = False

View File

@ -46,6 +46,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###############################################################################
# pylint: disable=unsubscriptable-object
"""Bloch sphere"""

View File

@ -522,17 +522,16 @@ def _latex_circuit_drawer(circuit,
try:
base = os.path.join(tmpdirname, tmpfilename)
subprocess.run(["pdftocairo", "-singlefile", "-png", "-q",
base + '.pdf', base])
base + '.pdf', base], check=True)
image = Image.open(base + '.png')
image = utils._trim(image)
os.remove(base + '.png')
if filename:
image.save(filename, 'PNG')
except OSError as ex:
if ex.errno == errno.ENOENT:
logger.warning('WARNING: Unable to convert pdf to image. '
'Is `poppler` installed? '
'Skipping circuit drawing...')
except (OSError, subprocess.CalledProcessError) as ex:
logger.warning('WARNING: Unable to convert pdf to image. '
'Is `poppler` installed? '
'Skipping circuit drawing...')
raise
return image

View File

@ -13,7 +13,7 @@
# that they have been altered from the originals.
# pylint: disable=invalid-name,ungrouped-imports,import-error
# pylint: disable=inconsistent-return-statements
# pylint: disable=inconsistent-return-statements,unsubscriptable-object
"""
Visualization functions for quantum states.

View File

@ -574,7 +574,7 @@ class TextDrawing():
lines = []
for layer_group in layer_groups:
wires = [i for i in zip(*layer_group)]
wires = list(zip(*layer_group))
lines += self.draw_wires(wires)
return lines
@ -763,7 +763,7 @@ class TextDrawing():
Args:
layer (list): A list of elements.
"""
instructions = [instruction for instruction in filter(lambda x: x is not None, layer)]
instructions = list(filter(lambda x: x is not None, layer))
longest = max([instruction.length for instruction in instructions])
for instruction in instructions:
instruction.layer_width = longest

View File

@ -356,7 +356,7 @@ class TestParameters(QiskitTestCase):
for i in range(num_processes)]
results = parallel_map(_construct_circuit,
[(param) for param in parameters],
parameters,
task_args=(qr,),
num_processes=num_processes)

View File

@ -582,8 +582,8 @@ class TestPulseAssemblerMissingKwargs(QiskitTestCase):
self.backend = FakeOpenPulse2Q()
self.config = self.backend.configuration()
self.defaults = self.backend.defaults()
self.qubit_lo_freq = [freq for freq in self.defaults.qubit_freq_est]
self.meas_lo_freq = [freq for freq in self.defaults.meas_freq_est]
self.qubit_lo_freq = list(self.defaults.qubit_freq_est)
self.meas_lo_freq = list(self.defaults.meas_freq_est)
self.qubit_lo_range = self.config.qubit_lo_range
self.meas_lo_range = self.config.meas_lo_range
self.schedule_los = {pulse.DriveChannel(0): self.qubit_lo_freq[0],

View File

@ -385,7 +385,7 @@ class TestPauli(QiskitTestCase):
self.assertEqual(sgn, 1j)
self.log.info("sign product reverse:")
p3, sgn = Pauli.sgn_prod(p2, p1)
p3, sgn = Pauli.sgn_prod(p2, p1) # pylint: disable=arguments-out-of-order
self.log.info("p2: %s", p2.to_label())
self.log.info("p1: %s", p1.to_label())
self.log.info("p3: %s", p3.to_label())

View File

@ -551,7 +551,7 @@ class TestDagOperations(QiskitTestCase):
self.dag.apply_operation_back(CnotGate(), [self.qubit0, self.qubit2])
self.dag.apply_operation_back(HGate(), [self.qubit2])
op_nodes = [node for node in self.dag.topological_op_nodes()]
op_nodes = list(self.dag.topological_op_nodes())
self.dag.remove_op_node(op_nodes[0])
expected = [('h', [self.qubit0]),

View File

@ -49,7 +49,7 @@ class TestCollect2qBlocks(QiskitTestCase):
qc.cx(qr[0], qr[1])
dag = circuit_to_dag(qc)
topo_ops = [i for i in dag.topological_op_nodes()]
topo_ops = list(dag.topological_op_nodes())
block_1 = [topo_ops[1], topo_ops[2]]
block_2 = [topo_ops[0], topo_ops[3]]