Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix coverage exclusion syntax #6241

Merged
merged 7 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 17 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# How to Contribute

We'd love to accept your patches and contributions to this project.
We do have some guidelines to follow, covered in this document, but don't
We do have some guidelines to follow, covered in this document, but don't
worry about (or expect to) get everything right the first time!
Create a pull request and we'll nudge you in the right direction. Please also
Create a pull request and we'll nudge you in the right direction. Please also
note that we have a [code of conduct](CODE_OF_CONDUCT.md) to make Cirq an
open and welcoming environment.

Expand Down Expand Up @@ -83,7 +83,7 @@ on setting up your local development environment.

## Code Testing Standards

When a pull request is created or updated, various automatic checks will
When a pull request is created or updated, various automatic checks will
run to ensure that the change won't break Cirq and meets our coding standards.

Cirq contains a continuous integration tool to verify testing. See our
Expand All @@ -94,36 +94,36 @@ Please be aware of the following code standards that will be applied to any
new changes.

- **Tests**.
Existing tests must continue to pass (or be updated) when new changes are
introduced. We use [pytest](https://docs.pytest.org/en/latest/) to run our
Existing tests must continue to pass (or be updated) when new changes are
introduced. We use [pytest](https://docs.pytest.org/en/latest/) to run our
tests.
- **Coverage**.
Code should be covered by tests.
We use [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) to compute
We use [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) to compute
coverage, and custom tooling to filter down the output to only include new or
changed code. We don't require 100% coverage, but any uncovered code must
be annotated with `# coverage: ignore`. To ignore coverage of a single line,
place `# coverage: ignore` at the end of the line. To ignore coverage for
an entire block, start the block with a `# coverage: ignore` comment on its
changed code. We don't require 100% coverage, but any uncovered code must
be annotated with `# pragma: no cover`. To ignore coverage of a single line,
place `# pragma: no cover` at the end of the line. To ignore coverage for
an entire block, start the block with a `# pragma: no cover` comment on its
own line.
- **Lint**.
Code should meet common style standards for python and be free of error-prone
Code should meet common style standards for python and be free of error-prone
constructs. We use [pylint](https://www.pylint.org/) to check for lint.
To see which lint checks we enforce, see the
To see which lint checks we enforce, see the
[dev_tools/conf/.pylintrc](dev_tools/conf/.pylintrc) file. When pylint produces
a false positive, it can be squashed with annotations like
a false positive, it can be squashed with annotations like
`# pylint: disable=unused-import`.
- **Types**.
Code should have [type annotations](https://www.python.org/dev/peps/pep-0484/).
We use [mypy](http://mypy-lang.org/) to check that type annotations are correct.
When type checking produces a false positive, it can be ignored with
When type checking produces a false positive, it can be ignored with
annotations like `# type: ignore`.

## Request For Comment Process for New Major Features

For larger contributions that will benefit from design reviews, please use the
For larger contributions that will benefit from design reviews, please use the
[Request for Comment](docs/dev/rfc_process.md) process.

## Developing notebooks
## Developing notebooks

Please refer to our [notebooks guide](docs/dev/notebooks.md) on how to develop iPython notebooks for documentation.
Please refer to our [notebooks guide](docs/dev/notebooks.md) on how to develop iPython notebooks for documentation.
3 changes: 1 addition & 2 deletions cirq-core/cirq/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@

import sys

if sys.version_info < (3, 9, 0):
# coverage: ignore
if sys.version_info < (3, 9, 0): # pragma: no cover
raise SystemError(
"You installed the latest version of cirq but aren't on python 3.9+.\n"
'To fix this error, you need to either:\n'
Expand Down
4 changes: 2 additions & 2 deletions cirq-core/cirq/circuits/circuit_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ def _full_join_string_lists(
list1: Optional[Sequence[str]], list2: Optional[Sequence[str]]
) -> Optional[Sequence[str]]:
if list1 is None and list2 is None:
return None # coverage: ignore
return None # pragma: no cover
if list1 is None:
return list2 # coverage: ignore
return list2 # pragma: no cover
if list2 is None:
return list1
return [f'{first}{REPETITION_ID_SEPARATOR}{second}' for first in list1 for second in list2]
Expand Down
2 changes: 1 addition & 1 deletion cirq-core/cirq/circuits/qasm_output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def _qasm_(self, args: cirq.QasmArgs) -> str:

def _decompose_(self):
# Only used by test_output_unitary_same_as_qiskit
return () # coverage: ignore
return () # pragma: no cover

class DummyCompositeOperation(cirq.Operation):
qubits = (q0,)
Expand Down
3 changes: 1 addition & 2 deletions cirq-core/cirq/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def pytest_configure(config):

def pytest_pyfunc_call(pyfuncitem):
if inspect.iscoroutinefunction(pyfuncitem._obj):
# coverage: ignore
raise ValueError(
raise ValueError( # pragma: no cover
f'{pyfuncitem._obj.__name__} is a bare async function. '
f'It should be decorated with "@duet.sync".'
)
Expand Down
2 changes: 1 addition & 1 deletion cirq-core/cirq/contrib/acquaintance/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class _UnconstrainedAcquaintanceDevice(AcquaintanceDevice):
"""An acquaintance device with no constraints other than of the gate types."""

def __repr__(self) -> str:
return 'UnconstrainedAcquaintanceDevice' # coverage: ignore
return 'UnconstrainedAcquaintanceDevice' # pragma: no cover


UnconstrainedAcquaintanceDevice = _UnconstrainedAcquaintanceDevice()
2 changes: 1 addition & 1 deletion cirq-core/cirq/contrib/hacks/disable_validation_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_disable_op_validation():
with pytest.raises(ValueError, match='mysterious and terrible'):
with disable_op_validation():
# This does not run - the with condition errors out first.
_ = cirq.H(q0, q1) # coverage: ignore
_ = cirq.H(q0, q1) # pragma: no cover

# Passes, skipping validation.
with disable_op_validation(accept_debug_responsibility=True):
Expand Down
3 changes: 1 addition & 2 deletions cirq-core/cirq/contrib/noise_models/noise_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def __init__(self, depol_prob: float, prepend: bool = False):
self._prepend = prepend

def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
if validate_all_measurements(moment) or self.is_virtual_moment(moment):
# coverage: ignore
if validate_all_measurements(moment) or self.is_virtual_moment(moment): # pragma: no cover
return moment

output = [
Expand Down
2 changes: 1 addition & 1 deletion cirq-core/cirq/contrib/paulistring/clifford_optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def try_merge_cz(cz_op: ops.GateOperation, start_i: int) -> int:
else:
# Two CZ gates that share one qubit
# Pass through and keep looking
continue # coverage: ignore
continue # pragma: no cover
# The above line is covered by test_remove_staggered_czs but the
# coverage checker disagrees.
return 0
Expand Down
2 changes: 1 addition & 1 deletion cirq-core/cirq/contrib/qcircuit/qcircuit_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# coverage: ignore
# pragma: no cover

import errno
import os
Expand Down
5 changes: 2 additions & 3 deletions cirq-core/cirq/contrib/quimb/density_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ def circuit_to_density_matrix_tensors(
ValueError: If an op is encountered that cannot be converted.
"""
if qubits is None:
# coverage: ignore
qubits = sorted(circuit.all_qubits())
qubits = sorted(circuit.all_qubits()) # pragma: no cover
qubits = tuple(qubits)

qubit_frontier: Dict[cirq.Qid, int] = {q: 0 for q in qubits}
Expand Down Expand Up @@ -190,7 +189,7 @@ def _positions(_mi, _these_qubits):
)
kraus_frontier += 1
else:
raise ValueError(repr(op)) # coverage: ignore
raise ValueError(repr(op)) # pragma: no cover

_positions(mi + 1, op.qubits)
return tensors, qubit_frontier, positions
Expand Down
6 changes: 3 additions & 3 deletions cirq-core/cirq/contrib/quimb/grid_circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ def _interaction(
for col in range(col_start + col_start_offset, col_end + col_end_offset, col_step):
node1 = (row, col)
if node1 not in problem_graph.nodes:
continue # coverage: ignore
continue # pragma: no cover
node2 = get_neighbor(row, col)
if node2 not in problem_graph.nodes:
continue # coverage: ignore
continue # pragma: no cover
if (node1, node2) not in problem_graph.edges:
continue # coverage: ignore
continue # pragma: no cover

weight = problem_graph.edges[node1, node2].get('weight', 1)
yield two_qubit_gate(exponent=weight, global_shift=-0.5).on(
Expand Down
8 changes: 3 additions & 5 deletions cirq-core/cirq/contrib/quimb/state_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import cirq


# coverage: ignore
def _get_quimb_version():
"""Returns the quimb version and parsed (major,minor) numbers if possible.
Returns:
Expand All @@ -18,7 +17,7 @@ def _get_quimb_version():
version = quimb.__version__
try:
return tuple(int(x) for x in version.split('.')), version
except:
except: # pragma: no cover
return (0, 0), version


Expand Down Expand Up @@ -59,7 +58,7 @@ def circuit_to_tensors(
corresponding to the |0> state.
"""
if qubits is None:
qubits = sorted(circuit.all_qubits()) # coverage: ignore
qubits = sorted(circuit.all_qubits()) # pragma: no cover

qubit_frontier = {q: 0 for q in qubits}
positions = None
Expand Down Expand Up @@ -163,8 +162,7 @@ def tensor_expectation_value(
]
tn = qtn.TensorNetwork(tensors + end_bras)
if QUIMB_VERSION[0] < (1, 3):
# coverage: ignore
warnings.warn(
warnings.warn( # pragma: no cover
f'quimb version {QUIMB_VERSION[1]} detected. Please use '
f'quimb>=1.3 for optimal performance in '
'`tensor_expectation_value`. '
Expand Down
3 changes: 1 addition & 2 deletions cirq-core/cirq/contrib/routing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ def get_circuit_connectivity(circuit: 'cirq.Circuit') -> nx.Graph:
for op in circuit.all_operations():
n_qubits = len(op.qubits)
if n_qubits > 2:
# coverage: ignore
raise ValueError(
raise ValueError( # pragma: no cover
f"Cannot build a graph out of a circuit that "
f"contains {n_qubits}-qubit operations"
)
Expand Down
6 changes: 1 addition & 5 deletions cirq-core/cirq/contrib/svg/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,11 @@ def _fit_vertical(
return row_starts, row_heights, yi_map


def _debug_spacing(col_starts, row_starts):
def _debug_spacing(col_starts, row_starts): # pragma: no cover
"""Return a string suitable for inserting inside an <svg> tag that
draws green lines where columns and rows start. This is very useful
if you're developing this code and are debugging spacing issues.
"""
# coverage: ignore
t = ''
for i, cs in enumerate(col_starts):
t += (
Expand Down Expand Up @@ -198,7 +197,6 @@ def tdd_to_svg(
# qubits start at far left and their wires shall be blue
stroke = QBLUE
else:
# coverage: ignore
stroke = 'black'
t += f'<line x1="{x1}" x2="{x2}" y1="{y}" y2="{y}" stroke="{stroke}" stroke-width="1" />'

Expand Down Expand Up @@ -261,11 +259,9 @@ class SVGCircuit:
"""

def __init__(self, circuit: 'cirq.Circuit'):
# coverage: ignore
self.circuit = circuit

def _repr_svg_(self) -> str:
# coverage: ignore
return circuit_to_svg(self.circuit)


Expand Down
20 changes: 7 additions & 13 deletions cirq-core/cirq/devices/named_topologies.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def draw_gridlike(
to NetworkX plotting functionality.
"""
if ax is None:
ax = plt.gca() # coverage: ignore
ax = plt.gca() # pragma: no cover

if tilted:
pos = {node: (y, -x) for node, (x, y) in _node_and_coordinates(graph.nodes)}
Expand Down Expand Up @@ -295,8 +295,7 @@ def get_placements(
for big_to_small_map in matcher.subgraph_monomorphisms_iter():
dedupe[frozenset(big_to_small_map.keys())] = big_to_small_map
if len(dedupe) > max_placements:
# coverage: ignore
raise ValueError(
raise ValueError( # pragma: no cover
f"We found more than {max_placements} placements. Please use a "
f"more constraining `big_graph` or a more constrained `small_graph`."
)
Expand Down Expand Up @@ -367,27 +366,23 @@ def draw_placements(
this callback is called. The callback should accept `ax` and `i` keyword arguments
for the current axis and mapping index, respectively.
"""
if len(small_to_big_mappings) > max_plots:
# coverage: ignore
if len(small_to_big_mappings) > max_plots: # pragma: no cover
warnings.warn(f"You've provided a lot of mappings. Only plotting the first {max_plots}")
small_to_big_mappings = small_to_big_mappings[:max_plots]

call_show = False
if axes is None:
# coverage: ignore
call_show = True
call_show = True # pragma: no cover

for i, small_to_big_map in enumerate(small_to_big_mappings):
if axes is not None:
ax = axes[i]
else:
# coverage: ignore
else: # pragma: no cover
ax = plt.gca()

small_mapped = nx.relabel_nodes(small_graph, small_to_big_map)
if bad_placement_callback is not None:
# coverage: ignore
if not _is_valid_placement_helper(
if not _is_valid_placement_helper( # pragma: no cover
big_graph=big_graph,
small_mapped=small_mapped,
small_to_big_mapping=small_to_big_map,
Expand All @@ -406,7 +401,6 @@ def draw_placements(
)
ax.axis('equal')
if call_show:
# coverage: ignore
# poor man's multi-axis figure: call plt.show() after each plot
# and jupyter will put the plots one after another.
plt.show()
plt.show() # pragma: no cover
2 changes: 1 addition & 1 deletion cirq-core/cirq/devices/noise_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def noisy_moments(
# only ops with PHYSICAL_GATE_TAG will receive noise.
if virtual_ops:
# Only subclasses will trigger this case.
new_moments.append(circuits.Moment(virtual_ops)) # coverage: ignore
new_moments.append(circuits.Moment(virtual_ops)) # pragma: no cover
if physical_ops:
new_moments.append(circuits.Moment(physical_ops))

Expand Down
12 changes: 6 additions & 6 deletions cirq-core/cirq/experiments/readout_confusion_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def apply(
raise ValueError(f"method: {method} should be 'pseudo_inverse' or 'least_squares'.")

if method == 'pseudo_inverse':
return result @ self.correction_matrix(qubits) # coverage: ignore
return result @ self.correction_matrix(qubits) # pragma: no cover

# Least squares minimization.
cm = self.confusion_matrix(qubits)
Expand All @@ -291,11 +291,11 @@ def func(x):
res = scipy.optimize.minimize(
func, result, method='SLSQP', constraints=constraints, bounds=bounds
)
if res.success is False: # coverage: ignore
raise ValueError( # coverage: ignore
f"SLSQP optimization for constrained minimization " # coverage: ignore
f"did not converge. Result:\n{res}" # coverage: ignore
) # coverage: ignore
if res.success is False: # pragma: no cover
raise ValueError( # pragma: no cover
f"SLSQP optimization for constrained minimization " # pragma: no cover
f"did not converge. Result:\n{res}" # pragma: no cover
) # pragma: no cover
return res.x

def __repr__(self) -> str:
Expand Down
8 changes: 3 additions & 5 deletions cirq-core/cirq/experiments/xeb_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,11 @@ def per_cycle_depth(df):
def _try_keep(k):
"""If all the values for a key `k` are the same in this group, we can keep it."""
if k not in df.columns:
return # coverage: ignore
return # pragma: no cover
vals = df[k].unique()
if len(vals) == 1:
ret[k] = vals[0]
else:
# coverage: ignore
else: # pragma: no cover
raise AssertionError(
f"When computing per-cycle-depth fidelity, multiple "
f"values for {k} were grouped together: {vals}"
Expand Down Expand Up @@ -574,8 +573,7 @@ def _fit_exponential_decay(
p0=(a_0, layer_fid_0),
bounds=((0, 0), (1, 1)),
)
except ValueError: # coverage: ignore
# coverage: ignore
except ValueError: # pragma: no cover
return 0, 0, np.inf, np.inf

a_std, layer_fid_std = np.sqrt(np.diag(pcov))
Expand Down