Skip to content

Commit

Permalink
Improve ruff config (#315)
Browse files Browse the repository at this point in the history
I added more ruff checks using
https://github.com/cda-tum/mqt-qcec/blob/main/pyproject.toml as a
template.

---------

Signed-off-by: burgholzer <[email protected]>
Co-authored-by: burgholzer <[email protected]>
  • Loading branch information
nquetschlich and burgholzer authored Apr 10, 2024
1 parent b430673 commit 6c2d381
Show file tree
Hide file tree
Showing 58 changed files with 441 additions and 505 deletions.
26 changes: 25 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ repos:
- id: fix-ligatures
- id: fix-smartquotes

# Check for common mistakes
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal

# Clean jupyter notebooks
- repo: https://github.com/srstevenson/nb-clean
rev: "3.2.0"
Expand Down Expand Up @@ -75,7 +83,7 @@ repos:
rev: v1.9.0
hooks:
- id: mypy
files: ^(src|tests|setup.py)
files: ^(src|tests)
args: []
additional_dependencies:
- pytket_qiskit
Expand All @@ -88,3 +96,19 @@ repos:
- types-requests
- types-tqdm
- types-flask

# Catch common capitalization mistakes
- repo: local
hooks:
- id: disallow-caps
name: Disallow improper capitalization
language: pygrep
entry: PyBind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum
exclude: .pre-commit-config.yaml

# Check best practices for scientific Python code
- repo: https://github.com/scientific-python/cookie
rev: 2024.03.10
hooks:
- id: sp-repo-review
additional_dependencies: ["repo-review[cli]"]
8 changes: 4 additions & 4 deletions docs/Abstraction_levels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ shown above.

Different quantum computer realizations support
different native gate-sets. In our example, we consider the
`ibmq_manila` device as the target device which natively supports I, X, √X, Rz and CX gates.
``ibmq_manila`` device as the target device which natively supports I, X, √X, Rz and CX gates.
Consequently, the Ry gates in the previous figure have to be converted using only these native gates. In this case,
they are substituted by a sequence of X and Rz gates (denoted as • with a phase of −π).

Expand All @@ -63,10 +63,10 @@ they are substituted by a sequence of X and Rz gates (denoted as • with a phas

.. image:: /_static/arch.png
:width: 15%
:alt: Illustration of the `ibmq_manila` device
:alt: Illustration of the ``ibmq_manila`` device
:align: center

The architecture of the `ibmq_manila` device is shown above on the right and it defines between which qubits a two-qubit operation may be performed.
The architecture of the ``ibmq_manila`` device is shown above on the right and it defines between which qubits a two-qubit operation may be performed.
Since the circuit shown in the previous figure contains CX gates operating between all combination of qubits,
there is no mapping directly matching the target architecture's layout. As a consequence,
a non-trivial mapping followed by a round of optimization leads to the resulting circuit
Expand All @@ -80,4 +80,4 @@ shown below.
This is also the reason for the different sequence of CX gates compared
to the previous example.

This circuit is now executable on the `ibmq_manila` device, since all hardware induced requirements are fulfilled.
This circuit is now executable on the ``ibmq_manila`` device, since all hardware induced requirements are fulfilled.
2 changes: 1 addition & 1 deletion docs/Parameter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The ``mqt.bench.get_benchmark`` method has the following signature:
* ``circuit_size``\ : for most of the cases this is equal to number of qubits
(all scalable benchmarks except ``"qwalk-v-chain"`` and ``"grover-v-chain"``\ ) while for all other the qubit number is higher
* ``compiler``\ : ``"qiskit"`` or ``"tket"``
* `compiler_settings`: Optimization level for `"qiskit"` (`0`-`3`), placement for `"tket"` (`lineplacement` or `graphplacement`), exemplary shown:
* ``compiler_settings``: Optimization level for ``"qiskit"`` (``0``-``3``), placement for ``"tket"`` (``lineplacement`` or ``graphplacement``), exemplary shown:

.. code-block:: python
Expand Down
63 changes: 63 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Nox sessions."""

from __future__ import annotations

import argparse
import os

import nox

nox.needs_version = ">=2024.3.2"
nox.options.default_venv_backend = "uv|virtualenv"

PYTHON_ALL_VERSIONS = ["3.10", "3.11", "3.12"]

BUILD_REQUIREMENTS = [
"setuptools>=61",
"setuptools_scm>=7",
]

if os.environ.get("CI", None):
nox.options.error_on_missing_interpreters = True


@nox.session(reuse_venv=True)
def lint(session: nox.Session) -> None:
"""Lint the Python part of the codebase using pre-commit.
Simply execute `nox -rs lint` to run all configured hooks.
"""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", *session.posargs)


@nox.session(reuse_venv=True)
def docs(session: nox.Session) -> None:
"""Build the docs. Use "--non-interactive" to avoid serving. Pass "-b linkcheck" to check links."""
parser = argparse.ArgumentParser()
parser.add_argument("-b", dest="builder", default="html", help="Build target (default: html)")
args, posargs = parser.parse_known_args(session.posargs)

serve = args.builder == "html" and session.interactive
extra_installs = ["sphinx-autobuild"] if serve else []
session.install(*BUILD_REQUIREMENTS, *extra_installs)
session.install("--no-build-isolation", "-ve.[docs]")
session.chdir("docs")

if args.builder == "linkcheck":
session.run("sphinx-build", "-b", "linkcheck", ".", "_build/linkcheck", *posargs)
return

shared_args = (
"-n", # nitpicky mode
"-T", # full tracebacks
f"-b={args.builder}",
".",
f"_build/{args.builder}",
*posargs,
)

if serve:
session.run("sphinx-autobuild", *shared_args)
else:
session.run("sphinx-build", "--keep-going", *shared_args)
32 changes: 23 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ testpaths = ["tests"]
addopts = ["-ra", "--strict-markers", "--strict-config", "--showlocals"]
log_cli_level = "INFO"
xfail_strict = true
filterwarnings = [
"error",
"ignore:.*pkg_resources.*:DeprecationWarning:",
"ignore:.*sre_.*:DeprecationWarning:",
"ignore:.*Rigetti.*:UserWarning:",
"ignore:.*Values in x.*:RuntimeWarning:",
]

[tool.coverage]
run.source = ["mqt.bench", "mqt.benchviewer"]
Expand All @@ -108,7 +115,6 @@ mypy_path = "$MYPY_CONFIG_FILE_DIR/src"
files = ["src", "tests", "setup.py"]
python_version = "3.10"
strict = true
show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
explicit_package_bases = true
Expand All @@ -126,12 +132,13 @@ ignore_missing_imports = true
line-length = 120
extend-include = ["*.ipynb"]
src = ["src"]
preview = true
unsafe-fixes = true

[tool.ruff.lint]
extend-select = [
"A", # flake8-builtins
# "ANN", # flake8-annotations
"ANN", # flake8-annotations
"ARG", # flake8-unused-arguments
"ASYNC", # flake8-async
"B", "B904", # flake8-bugbear
Expand All @@ -141,11 +148,13 @@ extend-select = [
"EXE", # flake8-executable
"FA", # flake8-future-annotations
"FLY", # flynt
"FURB", # refurb
"I", # isort
"ICN", # flake8-import-conventions
"ISC", # flake8-implicit-str-concat
# "N", # flake8-naming
# "NPY", # numpy
"LOG", # flake8-logging-format
"N", # flake8-naming
"NPY", # numpy
"PERF", # perflint
"PGH", # pygrep-hooks
"PIE", # flake8-pie
Expand All @@ -166,19 +175,24 @@ extend-select = [
"UP", # pyupgrade
"YTT", # flake8-2020
]
extend-ignore = [
"PLR", # Design related pylint codes
"ISC001", # Added because of ruff-format warning
ignore = [
"ANN101", # Missing type annotation for self in method
"ANN102", # Missing type annotation for cls in classmethod
"ISC001", # Conflicts with formatter
"E501", # Line too long (Black is enough)
"PLR", # Design related pylint codes
"S101", # Use of assert detected
]
flake8-unused-arguments.ignore-variadic-names = true
isort.required-imports = ["from __future__ import annotations"]

[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"*.pyi" = ["D"] # pydocstyle
"*.ipynb" = [
"D", # pydocstyle
"E402", # Allow imports to appear anywhere in Jupyter notebooks
"I002", # Allow missing `from __future__ import annotations` import
]

[tool.ruff.pydocstyle]
[tool.ruff.lint.pydocstyle]
convention = "google"
10 changes: 5 additions & 5 deletions src/mqt/bench/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
)

__all__ = [
"BenchmarkGenerator",
"CompilerSettings",
"QiskitSettings",
"TKETSettings",
"generate",
"get_benchmark",
"BenchmarkGenerator",
"timeout_watcher",
"qiskit_helper",
"timeout_watcher",
"tket_helper",
"utils",
"CompilerSettings",
"QiskitSettings",
"TKETSettings",
]
9 changes: 4 additions & 5 deletions src/mqt/bench/benchmark_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ def get_benchmark(
Returns:
Quantum Circuit Object representing the benchmark with the selected options, either as Qiskit::QuantumCircuit or Pytket::Circuit object (depending on the chosen compiler---while the algorithm level is always provided using Qiskit)
"""

if "gate_set_name" in kwargs:
msg = "gate_set_name is deprecated and will be removed in a future release. Use provider_name instead."
warn(msg, DeprecationWarning, stacklevel=2)
Expand Down Expand Up @@ -466,18 +465,18 @@ def timeout_watcher(
timeout: int,
args: list[Any] | int | tuple[int, str] | str,
) -> bool | QuantumCircuit | Circuit:
class TimeoutException(Exception): # Custom exception class
class TimeoutExceptionError(Exception): # Custom exception class
pass

def timeout_handler(_signum: Any, _frame: Any) -> None: # Custom signal handler
raise TimeoutException
def timeout_handler(_signum: int, _frame: Any) -> None: # noqa: ANN401
raise TimeoutExceptionError

# Change the behavior of SIGALRM
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
try:
res = func(*args) if isinstance(args, tuple | list) else func(args)
except TimeoutException:
except TimeoutExceptionError:
print(
"Calculation/Generation exceeded timeout limit for ",
func.__name__,
Expand Down
8 changes: 4 additions & 4 deletions src/mqt/bench/benchmarks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
from mqt.bench.benchmarks.qiskit_application_optimization import routing, tsp

__all__ = [
"pricingput",
"pricingcall",
"groundstate",
"portfolioqaoa",
"portfoliovqe",
"groundstate",
"pricingcall",
"pricingput",
"qnn",
"routing",
"tsp",
"qnn",
]
7 changes: 4 additions & 3 deletions src/mqt/bench/benchmarks/ae.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
def create_circuit(num_qubits: int) -> QuantumCircuit:
"""Returns a quantum circuit implementing Quantum Amplitude Estimation.
Keyword arguments:
Keyword Arguments:
num_qubits -- number of qubits of the returned quantum circuit
"""

ae = AmplitudeEstimation(
num_eval_qubits=num_qubits - 1, # -1 because of the to be estimated qubit
)
Expand All @@ -38,6 +37,9 @@ def __init__(self, probability: float) -> None:
def __eq__(self, other: object) -> bool:
return isinstance(other, BernoulliQ) and self._theta_p == other._theta_p

def __hash__(self) -> int:
return hash(self._theta_p)

def power(self, power: float, _matrix_power: bool = True) -> QuantumCircuit:
# implement the efficient power of Q
q_k = QuantumCircuit(1)
Expand All @@ -47,7 +49,6 @@ def power(self, power: float, _matrix_power: bool = True) -> QuantumCircuit:

def get_estimation_problem() -> EstimationProblem:
"""Returns a estimation problem instance for a fixed p value."""

p = 0.2

"""A circuit representing the Bernoulli A operator."""
Expand Down
9 changes: 4 additions & 5 deletions src/mqt/bench/benchmarks/dj.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
def dj_oracle(case: str, n: int) -> QuantumCircuit:
# plus one output qubit
oracle_qc = QuantumCircuit(n + 1)
rng = np.random.default_rng(10)

if case == "balanced":
np.random.seed(10)
b_str = ""
for _ in range(n):
b = np.random.randint(0, 2)
b = rng.integers(0, 2)
b_str = b_str + str(b)

for qubit in range(len(b_str)):
Expand All @@ -29,7 +29,7 @@ def dj_oracle(case: str, n: int) -> QuantumCircuit:
oracle_qc.x(qubit)

if case == "constant":
output = np.random.randint(2)
output = rng.integers(2)
if output == 1:
oracle_qc.x(n)

Expand Down Expand Up @@ -62,11 +62,10 @@ def dj_algorithm(oracle: QuantumCircuit, n: int) -> QuantumCircuit:
def create_circuit(n: int, balanced: bool = True) -> QuantumCircuit:
"""Returns a quantum circuit implementing the Deutsch-Josza algorithm.
Keyword arguments:
Keyword Arguments:
num_qubits -- number of qubits of the returned quantum circuit
balanced -- True for a balanced and False for a constant oracle
"""

oracle_mode = "balanced" if balanced else "constant"
n = n - 1 # because of ancilla qubit
oracle_gate = dj_oracle(oracle_mode, n)
Expand Down
3 changes: 1 addition & 2 deletions src/mqt/bench/benchmarks/ghz.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
def create_circuit(num_qubits: int) -> QuantumCircuit:
"""Returns a quantum circuit implementing the GHZ state.
Keyword arguments:
Keyword Arguments:
num_qubits -- number of qubits of the returned quantum circuit
"""

q = QuantumRegister(num_qubits, "q")
qc = QuantumCircuit(q, name="ghz")
qc.h(q[-1])
Expand Down
3 changes: 1 addition & 2 deletions src/mqt/bench/benchmarks/graphstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
def create_circuit(num_qubits: int, degree: int = 2) -> QuantumCircuit:
"""Returns a quantum circuit implementing a graph state.
Keyword arguments:
Keyword Arguments:
num_qubits -- number of qubits of the returned quantum circuit
degree -- number of edges per node
"""

q = QuantumRegister(num_qubits, "q")
qc = QuantumCircuit(q, name="graphstate")

Expand Down
Loading

0 comments on commit 6c2d381

Please sign in to comment.