diff --git a/docs/conf.py b/docs/conf.py index 96a39bc..0f665a9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -140,6 +140,7 @@ def determine_github_branch() -> str: def linkcode_resolve(domain, info): + """Add links to GitHub source code.""" if domain != "py": return None diff --git a/pyproject.toml b/pyproject.toml index fb91924..db48c3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,11 +59,9 @@ style = [ ] lint = [ "qiskit-addon-obp[style]", - "pydocstyle==6.3.0", "mypy==1.11.2", "pylint==3.2.7", "reno>=4.1", - "toml>=0.9.6", ] notebook-dependencies = [ "qiskit-addon-obp", @@ -138,6 +136,7 @@ select = [ "I", # isort "E", # pycodestyle "W", # pycodestyle + "D", # pydocstyle "F", # pyflakes "RUF", # ruff "UP", # pyupgrade @@ -153,8 +152,12 @@ ignore = [ max-args = 6 [tool.ruff.lint.extend-per-file-ignores] +"test/**.py" = [ + "D", # pydocstyle +] "docs/**/*" = [ "E402", # module level import not at top of file + "D100", # missing docstring in public module ] [tool.ruff.lint.flake8-copyright] @@ -172,6 +175,9 @@ notice-rgx = """ # that they have been altered from the originals\\. """ +[tool.ruff.lint.pydocstyle] +convention = "google" + [tool.typos.default.extend-words] IY = "IY" aer = "aer" diff --git a/qiskit_addon_obp/backpropagation.py b/qiskit_addon_obp/backpropagation.py index 2841aee..b79e97c 100644 --- a/qiskit_addon_obp/backpropagation.py +++ b/qiskit_addon_obp/backpropagation.py @@ -52,8 +52,7 @@ def backpropagate( operator_budget: OperatorBudget | None = None, max_seconds: int | None = None, ) -> tuple[list[SparsePauliOp], Sequence[QuantumCircuit], OBPMetadata]: - """ - Backpropagate slices of quantum circuit operations onto the provided observables. + """Backpropagate slices of quantum circuit operations onto the provided observables. This function takes a (list of) observable(s) and backpropagates the provided quantum circuit slices **in reverse order** onto the observable(s) until one of the stopping criteria is reached. @@ -100,6 +99,7 @@ def backpropagate( ValueError: All observables and slices must act on equivalent numbers of qubits. ValueError: An input observable is larger than the constraints specified by ``operator_budget``. ValueError: ``operator_budget.max_paulis`` or ``operator_budget.max_qwc_groups`` is less than 1. + """ operator_budget = operator_budget or OperatorBudget() truncation_error_budget = truncation_error_budget or TruncationErrorBudget() diff --git a/qiskit_addon_obp/utils/__init__.py b/qiskit_addon_obp/utils/__init__.py index 8641141..13c8dc9 100644 --- a/qiskit_addon_obp/utils/__init__.py +++ b/qiskit_addon_obp/utils/__init__.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Utility functionality for conducting operator backpropagation. +"""Utility functionality for conducting operator backpropagation. .. currentmodule:: qiskit_addon_obp.utils diff --git a/qiskit_addon_obp/utils/metadata.py b/qiskit_addon_obp/utils/metadata.py index 842143a..f5eb4a0 100644 --- a/qiskit_addon_obp/utils/metadata.py +++ b/qiskit_addon_obp/utils/metadata.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Container classes for holding backpropagation metadata. +"""Container classes for holding backpropagation metadata. .. currentmodule:: qiskit_addon_obp.utils.metadata @@ -157,6 +156,7 @@ def accumulated_error(self, observable_idx: int, slice_idx: int | None = None) - Returns: The accumulated error computed per the explanations above. + """ if slice_idx is None: slice_idx = self.num_backpropagated_slices # pragma: no cover @@ -198,6 +198,7 @@ def left_over_error_budget(self, observable_idx: int, slice_idx: int | None = No Returns: The left-over error budget computed per the explanations above. + """ if slice_idx is None: slice_idx = self.num_backpropagated_slices # pragma: no cover @@ -238,6 +239,7 @@ def from_json(cls, json_file: str) -> OBPMetadata: Returns: The loaded metadata. + """ with open(json_file) as file: data = json.load(file) @@ -260,6 +262,7 @@ def to_json(self, json_file: str, **kwargs) -> None: Args: json_file: the path to the file into which to dump the metadata. kwargs: keyword arguments to be passed on towards :meth:`.json.dump`. + """ with open(json_file, "w") as file: json.dump(asdict(self), file, **kwargs) diff --git a/qiskit_addon_obp/utils/operations.py b/qiskit_addon_obp/utils/operations.py index 7329a12..770daf4 100644 --- a/qiskit_addon_obp/utils/operations.py +++ b/qiskit_addon_obp/utils/operations.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Utility functions for operator backpropagation. +"""Utility functions for operator backpropagation. .. currentmodule:: qiskit_addon_obp.utils.operations @@ -71,6 +70,7 @@ def apply_op_to( Raises: ValueError: The number of unique operator qargs must match the number of qubits in the corresponding operator. + """ _validate_qargs(op1, op1_qargs) _validate_qargs(op2, op2_qargs) @@ -113,6 +113,7 @@ def to_global_op(op: SparsePauliOp, qargs: list[int], n_qubits: int) -> SparsePa Raises: ValueError: Qubit ID out of range + """ min_qargs = min(qargs) max_qargs = max(qargs) @@ -135,8 +136,7 @@ def _validate_qargs(op: SparsePauliOp, qargs: list[int]) -> None: def reduce_op(global_op: SparsePauliOp) -> tuple[SparsePauliOp, list[int]]: - """ - Create a lean representation of a global Pauli operator. + """Create a lean representation of a global Pauli operator. This function returns a lean representation of the input operator such that all of the qubits associated solely with Pauli-I terms have been removed. A list @@ -161,6 +161,7 @@ def reduce_op(global_op: SparsePauliOp) -> tuple[SparsePauliOp, list[int]]: Raises: ValueError: Input operator may not be the identity operator. + """ pauli_strings = [p.to_label() for p in global_op.paulis] reduced_qargs = [ @@ -186,8 +187,7 @@ def apply_reset_to( qubit_id: int, inplace: bool = False, ) -> SparsePauliOp: - """ - Apply a reset operation to a Pauli operator. + """Apply a reset operation to a Pauli operator. This function applies a reset operation to ``op`` in the following way: @@ -204,6 +204,7 @@ def apply_reset_to( Returns: The transformed operator + """ if not inplace: op = op.copy() diff --git a/qiskit_addon_obp/utils/simplify.py b/qiskit_addon_obp/utils/simplify.py index f9c24ba..bfb96de 100644 --- a/qiskit_addon_obp/utils/simplify.py +++ b/qiskit_addon_obp/utils/simplify.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Functions for simplifying Pauli operators. +"""Functions for simplifying Pauli operators. .. currentmodule:: qiskit_addon_obp.utils.simplify @@ -100,6 +99,7 @@ def simplify( Returns: The simplified Pauli operator. + """ # Get default atol and rtol if atol is None: diff --git a/qiskit_addon_obp/utils/truncating.py b/qiskit_addon_obp/utils/truncating.py index baf6d36..282ec5c 100644 --- a/qiskit_addon_obp/utils/truncating.py +++ b/qiskit_addon_obp/utils/truncating.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Functions for truncating Pauli operators within given error budgets. +"""Functions for truncating Pauli operators within given error budgets. .. currentmodule:: qiskit_addon_obp.utils.truncating @@ -115,6 +114,7 @@ def setup_budget( Raises: ValueError: if ``max_error_per_slice`` and ``max_error_total`` are both ``None``. + """ if max_error_per_slice is None and max_error_total is None: raise ValueError("max_error_per_slice and max_error_total may not both be None") @@ -168,6 +168,7 @@ def truncate_binary_search( .. note:: The incurred truncation error bound, :math:`E`, is calculated as the ``p-norm`` of the truncated terms' coefficient magnitudes, :math:`c`, such that :math:`E = \|c\|_p`. + """ abscs = np.abs(observable.coeffs) ** p_norm diff --git a/qiskit_addon_obp/utils/visualization.py b/qiskit_addon_obp/utils/visualization.py index 745891f..a148a70 100644 --- a/qiskit_addon_obp/utils/visualization.py +++ b/qiskit_addon_obp/utils/visualization.py @@ -10,8 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Various visualization utilities. +"""Various visualization utilities. .. currentmodule:: qiskit_addon_obp.utils.visualization @@ -72,6 +71,7 @@ def plot_accumulated_error(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ if not np.isinf(metadata.truncation_error_budget.max_error_total): axes.axhline( @@ -127,6 +127,7 @@ def plot_left_over_error_budget(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ for obs_idx in range(len(metadata.backpropagation_history[0].slice_errors)): axes.plot( @@ -176,6 +177,7 @@ def plot_slice_errors(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ num_observables = len(metadata.backpropagation_history[0].slice_errors) width = 0.8 / num_observables @@ -229,6 +231,7 @@ def plot_num_paulis(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ for obs_idx in range(len(metadata.backpropagation_history[0].slice_errors)): axes.plot( @@ -275,6 +278,7 @@ def plot_num_truncated_paulis(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ num_observables = len(metadata.backpropagation_history[0].slice_errors) width = 0.8 / num_observables @@ -329,6 +333,7 @@ def plot_sum_paulis(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ if metadata.operator_budget.max_paulis is not None: axes.axhline( @@ -380,6 +385,7 @@ def plot_num_qwc_groups(metadata: OBPMetadata, axes: Axes) -> None: Args: metadata: the metadata to be visualized. axes: the matplotlib axes in which to plot. + """ if metadata.operator_budget.max_qwc_groups is not None: axes.axhline( diff --git a/test/test_backpropagation.py b/test/test_backpropagation.py index e09c86d..17c5341 100644 --- a/test/test_backpropagation.py +++ b/test/test_backpropagation.py @@ -597,7 +597,6 @@ def test_backpropagate(self): def test_backpropagate_multi(self): """Tests back-propagation into multiple observables.""" - with self.subTest("Single slice"): theta = np.pi / 6 qc_mat = np.array( diff --git a/tox.ini b/tox.ini index 54f24b4..059fab8 100644 --- a/tox.ini +++ b/tox.ini @@ -29,7 +29,6 @@ commands = ruff check qiskit_addon_obp/ docs/ test/ ruff check --preview --select CPY001 --exclude "*.ipynb" qiskit_addon_obp/ test/ nbqa ruff docs/ - pydocstyle qiskit_addon_obp/ mypy qiskit_addon_obp/ pylint -rn qiskit_addon_obp/ test/ nbqa pylint -rn docs/