This is an automated email from the ASF dual-hosted git repository.

guanmingchiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/mahout.git


The following commit(s) were added to refs/heads/main by this push:
     new 4390f792a Enable Ruff rules E and most of ANN (#1159)
4390f792a is described below

commit 4390f792a83b34dc126b428511ef9ee318dfea6d
Author: Tim Hsiung <[email protected]>
AuthorDate: Mon Mar 9 12:48:18 2026 +0800

    Enable Ruff rules E and most of ANN (#1159)
---
 .github/scripts/checks/general_review.py           |  2 +-
 .github/scripts/review_pr.py                       |  4 +--
 examples/qdp/simple.ipynb                          |  4 +--
 examples/qumat/Optimization_Example.ipynb          |  2 +-
 pyproject.toml                                     | 14 +++++++-
 qdp/qdp-python/benchmark/benchmark_e2e.py          | 10 +++---
 qdp/qdp-python/benchmark/benchmark_latency.py      |  2 +-
 .../benchmark/benchmark_latency_pytorch.py         |  2 +-
 qdp/qdp-python/benchmark/benchmark_numpy_io.py     |  2 +-
 qdp/qdp-python/benchmark/benchmark_throughput.py   |  2 +-
 .../pennylane_baseline/iris_amplitude.py           |  4 +--
 .../qdp_pipeline/iris_amplitude.py                 |  6 ++--
 qdp/qdp-python/benchmark/utils.py                  |  4 +--
 qdp/qdp-python/qumat_qdp/api.py                    |  2 +-
 qdp/qdp-python/tests/test_dlpack_validation.py     | 14 ++++----
 qdp/qdp-python/tests/test_quantum_data_loader.py   | 22 ++++++------
 qumat/amazon_braket_backend.py                     | 28 +++++++--------
 qumat/cirq_backend.py                              | 28 +++++++--------
 qumat/qdp.py                                       |  4 ++-
 qumat/qiskit_backend.py                            | 28 +++++++--------
 qumat/qumat.py                                     | 42 +++++++++++-----------
 testing/utils/qumat_helpers.py                     |  2 +-
 22 files changed, 121 insertions(+), 107 deletions(-)

diff --git a/.github/scripts/checks/general_review.py 
b/.github/scripts/checks/general_review.py
index 8ac0ec845..eb0f7176e 100644
--- a/.github/scripts/checks/general_review.py
+++ b/.github/scripts/checks/general_review.py
@@ -18,7 +18,7 @@ import ast
 
 
 class GeneralReviewCheck:
-    def __init__(self, client, model_name):
+    def __init__(self, client, model_name) -> None:
         self.client = client
         self.model_name = model_name
 
diff --git a/.github/scripts/review_pr.py b/.github/scripts/review_pr.py
index 1d2596b18..21aa76be3 100644
--- a/.github/scripts/review_pr.py
+++ b/.github/scripts/review_pr.py
@@ -22,7 +22,7 @@ from github import Github
 from gofannon.github.pr_review_tool import PRReviewTool
 
 
-def check_env_vars():
+def check_env_vars() -> None:
     required_vars = [
         "GITHUB_TOKEN",
         "OPENAI_API_KEY",
@@ -39,7 +39,7 @@ def check_env_vars():
 check_env_vars()
 
 
-def main():
+def main() -> None:
     pr_number = int(os.environ["PR_NUMBER"])
     repo_name = os.environ["REPO_NAME"]
     pr_review_tool = PRReviewTool()
diff --git a/examples/qdp/simple.ipynb b/examples/qdp/simple.ipynb
index fb8b98c52..ad70a66b3 100644
--- a/examples/qdp/simple.ipynb
+++ b/examples/qdp/simple.ipynb
@@ -90,7 +90,7 @@
     "# 4. QML Model on GPU — double precision\n",
     "# ─────────────────────────────────────────────\n",
     "class VariationalLayer(nn.Module):\n",
-    "    def __init__(self, dim):\n",
+    "    def __init__(self, dim) -> None:\n",
     "        super().__init__()\n",
     "        self.theta = nn.Parameter(torch.randn(dim, 
dtype=torch.float64))\n",
     "\n",
@@ -101,7 +101,7 @@
     "\n",
     "\n",
     "class QMLClassifier(nn.Module):\n",
-    "    def __init__(self, num_qubits):\n",
+    "    def __init__(self, num_qubits) -> None:\n",
     "        super().__init__()\n",
     "        dim = 2 * (2**num_qubits)  # real + imag\n",
     "        self.layer1 = VariationalLayer(dim)\n",
diff --git a/examples/qumat/Optimization_Example.ipynb 
b/examples/qumat/Optimization_Example.ipynb
index c573f50a9..3c10b1089 100644
--- a/examples/qumat/Optimization_Example.ipynb
+++ b/examples/qumat/Optimization_Example.ipynb
@@ -127,7 +127,7 @@
     "\n",
     "\n",
     "# Define a simple placeholder cost function\n",
-    "def your_cost_function():\n",
+    "def your_cost_function() -> int:\n",
     "    # Placeholder: replace with a real function in actual applications\n",
     "    return 0\n",
     "\n",
diff --git a/pyproject.toml b/pyproject.toml
index 6a8ccc0f9..a763ff001 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -102,6 +102,10 @@ target-version = "py310"
 
 [tool.ruff.lint]
 select = [
+    # flake8-annotations
+    "ANN",
+    # pycodestyle
+    "E",
     # Pyflakes
     "F",
     # pyupgrade
@@ -119,7 +123,15 @@ select = [
     "PT",
 ]
 
-ignore = ["PT011"]
+ignore = [
+    "E402",   # Module level import not at top of file
+    "E501",   # Line too long
+    # The following ignore rules are temporary and should be removed when the 
issues are fixed.
+    "PT011",  # TODO: `pytest.raises(ValueError)` is too broad
+    "ANN001", # TODO: fix (missing-type-function-argument)
+    "ANN201", # TODO: fix (missing-return-type-undocumented-public-function)
+    "ANN202", # TODO: fix (missing-return-type-private-function)
+]
 
 [tool.ruff.lint.pyflakes]
 allowed-unused-imports = ["_qdp"]
diff --git a/qdp/qdp-python/benchmark/benchmark_e2e.py 
b/qdp/qdp-python/benchmark/benchmark_e2e.py
index 7a6cd971a..eeb347966 100644
--- a/qdp/qdp-python/benchmark/benchmark_e2e.py
+++ b/qdp/qdp-python/benchmark/benchmark_e2e.py
@@ -66,7 +66,7 @@ HIDDEN_DIM = 16
 BATCH_SIZE = 64  # Small batch to stress loop overhead
 
 
-def clean_cache():
+def clean_cache() -> None:
     """Clear GPU cache and Python garbage collection."""
     gc.collect()
     if torch.cuda.is_available():
@@ -75,7 +75,7 @@ def clean_cache():
 
 
 class DummyQNN(nn.Module):
-    def __init__(self, n_qubits):
+    def __init__(self, n_qubits) -> None:
         super().__init__()
         self.fc = nn.Linear(1 << n_qubits, HIDDEN_DIM)
 
@@ -83,7 +83,7 @@ class DummyQNN(nn.Module):
         return self.fc(x)
 
 
-def generate_data(n_qubits, n_samples, encoding_method: str = "amplitude"):
+def generate_data(n_qubits, n_samples, encoding_method: str = "amplitude") -> 
None:
     for f in [DATA_FILE, ARROW_FILE]:
         if os.path.exists(f):
             os.remove(f)
@@ -400,7 +400,7 @@ def run_mahout_arrow(engine, n_qubits, n_samples, 
encoding_method: str = "amplit
     return total_time, gpu_batched
 
 
-def compare_states(name_a, states_a, name_b, states_b):
+def compare_states(name_a, states_a, name_b, states_b) -> None:
     print("\n" + "=" * 70)
     print(f"VERIFICATION ({name_a} vs {name_b})")
     print("=" * 70)
@@ -425,7 +425,7 @@ def compare_states(name_a, states_a, name_b, states_b):
         print(">> FAILURE: States do not match.")
 
 
-def verify_correctness(states_dict):
+def verify_correctness(states_dict) -> None:
     # Filter out None values
     valid_states = {
         name: states for name, states in states_dict.items() if states is not 
None
diff --git a/qdp/qdp-python/benchmark/benchmark_latency.py 
b/qdp/qdp-python/benchmark/benchmark_latency.py
index 38adf269c..5b53c56c8 100644
--- a/qdp/qdp-python/benchmark/benchmark_latency.py
+++ b/qdp/qdp-python/benchmark/benchmark_latency.py
@@ -208,7 +208,7 @@ def run_qiskit_statevector(
     return duration, latency_ms
 
 
-def main():
+def main() -> None:
     parser = argparse.ArgumentParser(
         description="Benchmark Data-to-State latency across frameworks."
     )
diff --git a/qdp/qdp-python/benchmark/benchmark_latency_pytorch.py 
b/qdp/qdp-python/benchmark/benchmark_latency_pytorch.py
index 5f92139b1..49b11460d 100755
--- a/qdp/qdp-python/benchmark/benchmark_latency_pytorch.py
+++ b/qdp/qdp-python/benchmark/benchmark_latency_pytorch.py
@@ -120,7 +120,7 @@ def run_mahout_numpy(
     return duration, latency_ms
 
 
-def main():
+def main() -> None:
     parser = argparse.ArgumentParser(
         description="Benchmark PyTorch Tensor encoding latency (zero-copy 
optimization test)."
     )
diff --git a/qdp/qdp-python/benchmark/benchmark_numpy_io.py 
b/qdp/qdp-python/benchmark/benchmark_numpy_io.py
index 4a563f00f..3bd4a6dff 100644
--- a/qdp/qdp-python/benchmark/benchmark_numpy_io.py
+++ b/qdp/qdp-python/benchmark/benchmark_numpy_io.py
@@ -165,7 +165,7 @@ def run_pennylane_numpy(num_qubits: int, num_samples: int, 
npy_path: str):
         return 0.0, 0.0, 0.0
 
 
-def main():
+def main() -> None:
     parser = argparse.ArgumentParser(
         description="Benchmark NumPy I/O + Encoding: Mahout vs PennyLane"
     )
diff --git a/qdp/qdp-python/benchmark/benchmark_throughput.py 
b/qdp/qdp-python/benchmark/benchmark_throughput.py
index 414ce06c5..8abbf7c79 100644
--- a/qdp/qdp-python/benchmark/benchmark_throughput.py
+++ b/qdp/qdp-python/benchmark/benchmark_throughput.py
@@ -179,7 +179,7 @@ def run_qiskit(num_qubits: int, total_batches: int, 
batch_size: int, prefetch: i
     return duration, throughput
 
 
-def main():
+def main() -> None:
     parser = argparse.ArgumentParser(
         description="Benchmark DataLoader throughput across frameworks."
     )
diff --git 
a/qdp/qdp-python/benchmark/encoding_benchmarks/pennylane_baseline/iris_amplitude.py
 
b/qdp/qdp-python/benchmark/encoding_benchmarks/pennylane_baseline/iris_amplitude.py
index 730e96799..66045f853 100644
--- 
a/qdp/qdp-python/benchmark/encoding_benchmarks/pennylane_baseline/iris_amplitude.py
+++ 
b/qdp/qdp-python/benchmark/encoding_benchmarks/pennylane_baseline/iris_amplitude.py
@@ -72,7 +72,7 @@ def get_angles(x: np.ndarray) -> np.ndarray:
 
 
 # --- Circuit: amplitude state prep (RY/CNOT) + variational layer (Rot + CNOT) 
---
-def state_preparation(a, wires=(0, 1)):
+def state_preparation(a, wires=(0, 1)) -> None:
     """Amplitude encoding via rotation angles (tutorial / Möttönen et al.)."""
     qml.RY(a[0], wires=wires[0])
     qml.CNOT(wires=[wires[0], wires[1]])
@@ -87,7 +87,7 @@ def state_preparation(a, wires=(0, 1)):
     qml.PauliX(wires=wires[0])
 
 
-def layer(layer_weights, wires=(0, 1)):
+def layer(layer_weights, wires=(0, 1)) -> None:
     """Rot on each wire + CNOT (tutorial Iris section)."""
     for i, w in enumerate(wires):
         qml.Rot(*layer_weights[i], wires=w)
diff --git 
a/qdp/qdp-python/benchmark/encoding_benchmarks/qdp_pipeline/iris_amplitude.py 
b/qdp/qdp-python/benchmark/encoding_benchmarks/qdp_pipeline/iris_amplitude.py
index a830da7a9..5ab902b74 100644
--- 
a/qdp/qdp-python/benchmark/encoding_benchmarks/qdp_pipeline/iris_amplitude.py
+++ 
b/qdp/qdp-python/benchmark/encoding_benchmarks/qdp_pipeline/iris_amplitude.py
@@ -65,7 +65,7 @@ STATE_DIM = 2**NUM_QUBITS  # 4
 
 
 # --- Circuit: variational layer (Rot + CNOT); state prep is 
StatePrep(encoded) in training ---
-def layer(layer_weights, wires=(0, 1)):
+def layer(layer_weights, wires=(0, 1)) -> None:
     """Rot on each wire + CNOT (tutorial Iris section)."""
     for i, w in enumerate(wires):
         qml.Rot(*layer_weights[i], wires=w)
@@ -216,7 +216,7 @@ def _run_training_cpu(
     Y_train: np.ndarray,
     Y_test: np.ndarray,
     *,
-    dev_qml: Any,
+    dev_qml: Any,  # noqa: ANN401
     num_layers: int,
     iterations: int,
     batch_size: int,
@@ -309,7 +309,7 @@ def _run_training_gpu(
     Y_train: np.ndarray,
     Y_test: np.ndarray,
     *,
-    dev_qml: Any,
+    dev_qml: Any,  # noqa: ANN401
     num_layers: int,
     iterations: int,
     batch_size: int,
diff --git a/qdp/qdp-python/benchmark/utils.py 
b/qdp/qdp-python/benchmark/utils.py
index 1dc59b6b6..ef55ac1b6 100644
--- a/qdp/qdp-python/benchmark/utils.py
+++ b/qdp/qdp-python/benchmark/utils.py
@@ -166,7 +166,7 @@ def prefetched_batches(
     """
     q: queue.Queue[np.ndarray | None] = queue.Queue(maxsize=prefetch)
 
-    def producer():
+    def producer() -> None:
         for batch_idx in range(total_batches):
             base = batch_idx * batch_size
             batch = [
@@ -209,7 +209,7 @@ def prefetched_batches_torch(
     """
     q: queue.Queue[torch.Tensor | None] = queue.Queue(maxsize=prefetch)
 
-    def producer():
+    def producer() -> None:
         for batch_idx in range(total_batches):
             base = batch_idx * batch_size
             batch = [
diff --git a/qdp/qdp-python/qumat_qdp/api.py b/qdp/qdp-python/qumat_qdp/api.py
index ae2e44c69..3661ede56 100644
--- a/qdp/qdp-python/qumat_qdp/api.py
+++ b/qdp/qdp-python/qumat_qdp/api.py
@@ -82,7 +82,7 @@ class QdpBenchmark:
     (Linux/CUDA build).
     """
 
-    def __init__(self, device_id: int = 0):
+    def __init__(self, device_id: int = 0) -> None:
         self._device_id = device_id
         self._num_qubits: int | None = None
         self._encoding_method: str = "amplitude"
diff --git a/qdp/qdp-python/tests/test_dlpack_validation.py 
b/qdp/qdp-python/tests/test_dlpack_validation.py
index 42c0a8a6e..414e44f7b 100644
--- a/qdp/qdp-python/tests/test_dlpack_validation.py
+++ b/qdp/qdp-python/tests/test_dlpack_validation.py
@@ -32,7 +32,7 @@ def _engine():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_cuda_float32_amplitude_supported():
+def test_cuda_float32_amplitude_supported() -> None:
     """1D float32 CUDA tensor should be supported for amplitude encoding via 
GPU pointer f32 path."""
     engine = _engine()
     # 1D float32 CUDA tensor (contiguous)
@@ -48,7 +48,7 @@ def test_cuda_float32_amplitude_supported():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_cuda_float32_amplitude_2d_supported():
+def test_cuda_float32_amplitude_2d_supported() -> None:
     """2D float32 CUDA tensor should use the batch GPU-pointer float32 
amplitude path."""
     engine = _engine()
     t = torch.tensor(
@@ -82,7 +82,7 @@ def test_cuda_float32_amplitude_2d_supported():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_cuda_float32_amplitude_2d_respects_engine_precision():
+def test_cuda_float32_amplitude_2d_respects_engine_precision() -> None:
     """2D float32 CUDA amplitude batch should still honor float64 engine 
output precision."""
     engine = QdpEngine(0, precision="float64")
     t = torch.tensor(
@@ -116,7 +116,7 @@ def 
test_cuda_float32_amplitude_2d_respects_engine_precision():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_stride_1d_non_contiguous_rejected():
+def test_stride_1d_non_contiguous_rejected() -> None:
     """Non-contiguous 1D CUDA tensor (stride != 1) should fail with contiguous 
requirement."""
     engine = _engine()
     # Slice so stride is 2: shape (2,), stride (2,)
@@ -131,7 +131,7 @@ def test_stride_1d_non_contiguous_rejected():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_stride_2d_non_contiguous_rejected():
+def test_stride_2d_non_contiguous_rejected() -> None:
     """Non-contiguous 2D CUDA tensor should fail with contiguous 
requirement."""
     engine = _engine()
     # (4, 2) with strides (3, 2) -> not C-contiguous; expected for (4,2) is 
(2, 1)
@@ -150,7 +150,7 @@ def test_stride_2d_non_contiguous_rejected():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_valid_cuda_float64_1d_succeeds():
+def test_valid_cuda_float64_1d_succeeds() -> None:
     """Valid 1D float64 contiguous CUDA tensor should encode successfully."""
     engine = _engine()
     t = torch.randn(4, dtype=torch.float64, device="cuda")
@@ -159,7 +159,7 @@ def test_valid_cuda_float64_1d_succeeds():
 
 
 @pytest.mark.skipif(not _cuda_available(), reason="CUDA not available")
-def test_valid_cuda_float64_2d_succeeds():
+def test_valid_cuda_float64_2d_succeeds() -> None:
     """Valid 2D float64 contiguous CUDA tensor should encode successfully."""
     engine = _engine()
     t = torch.randn(3, 4, dtype=torch.float64, device="cuda")
diff --git a/qdp/qdp-python/tests/test_quantum_data_loader.py 
b/qdp/qdp-python/tests/test_quantum_data_loader.py
index 9eb4fb30e..d9aa78472 100644
--- a/qdp/qdp-python/tests/test_quantum_data_loader.py
+++ b/qdp/qdp-python/tests/test_quantum_data_loader.py
@@ -29,7 +29,7 @@ def _loader_available():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_mutual_exclusion_both_sources_raises():
+def test_mutual_exclusion_both_sources_raises() -> None:
     """Calling both .source_synthetic() and .source_file() then __iter__ 
raises ValueError."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -47,7 +47,7 @@ def test_mutual_exclusion_both_sources_raises():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_mutual_exclusion_exact_message():
+def test_mutual_exclusion_exact_message() -> None:
     """ValueError when both sources set: message mentions source_synthetic and 
source_file."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -62,7 +62,7 @@ def test_mutual_exclusion_exact_message():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_source_file_empty_path_raises():
+def test_source_file_empty_path_raises() -> None:
     """source_file() with empty path raises ValueError."""
     loader = QuantumDataLoader(device_id=0).qubits(4).batches(10, size=4)
     with pytest.raises(ValueError) as exc_info:
@@ -71,7 +71,7 @@ def test_source_file_empty_path_raises():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_synthetic_loader_batch_count():
+def test_synthetic_loader_batch_count() -> None:
     """Synthetic loader yields exactly total_batches batches."""
     total = 5
     batch_size = 4
@@ -91,7 +91,7 @@ def test_synthetic_loader_batch_count():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_file_loader_unsupported_extension_raises():
+def test_file_loader_unsupported_extension_raises() -> None:
     """source_file with unsupported extension raises at __iter__."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -120,7 +120,7 @@ def test_file_loader_unsupported_extension_raises():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_streaming_requires_parquet():
+def test_streaming_requires_parquet() -> None:
     """source_file(path, streaming=True) with non-.parquet path raises 
ValueError."""
     with pytest.raises(ValueError) as exc_info:
         QuantumDataLoader(device_id=0).qubits(4).batches(10, 
size=4).source_file(
@@ -131,7 +131,7 @@ def test_streaming_requires_parquet():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_streaming_parquet_extension_ok():
+def test_streaming_parquet_extension_ok() -> None:
     """source_file(path, streaming=True) with .parquet path does not raise at 
builder."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -148,7 +148,7 @@ def test_streaming_parquet_extension_ok():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_null_handling_fill_zero():
+def test_null_handling_fill_zero() -> None:
     """null_handling('fill_zero') sets the field correctly."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -160,7 +160,7 @@ def test_null_handling_fill_zero():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_null_handling_reject():
+def test_null_handling_reject() -> None:
     """null_handling('reject') sets the field correctly."""
     loader = (
         QuantumDataLoader(device_id=0)
@@ -172,7 +172,7 @@ def test_null_handling_reject():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_null_handling_invalid_raises():
+def test_null_handling_invalid_raises() -> None:
     """null_handling with an invalid string raises ValueError."""
     with pytest.raises(ValueError) as exc_info:
         QuantumDataLoader(device_id=0).null_handling("invalid_policy")
@@ -181,7 +181,7 @@ def test_null_handling_invalid_raises():
 
 
 @pytest.mark.skipif(not _loader_available(), reason="QuantumDataLoader not 
available")
-def test_null_handling_default_is_none():
+def test_null_handling_default_is_none() -> None:
     """By default, _null_handling is None (Rust will use FillZero)."""
     loader = QuantumDataLoader(device_id=0)
     assert loader._null_handling is None
diff --git a/qumat/amazon_braket_backend.py b/qumat/amazon_braket_backend.py
index d568b7770..608a30263 100644
--- a/qumat/amazon_braket_backend.py
+++ b/qumat/amazon_braket_backend.py
@@ -56,47 +56,47 @@ def create_empty_circuit(num_qubits: int | None = None):
     return circuit
 
 
-def apply_not_gate(circuit, qubit_index):
+def apply_not_gate(circuit, qubit_index) -> None:
     circuit.x(qubit_index)
 
 
-def apply_hadamard_gate(circuit, qubit_index):
+def apply_hadamard_gate(circuit, qubit_index) -> None:
     circuit.h(qubit_index)
 
 
-def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index):
+def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index) -> None:
     circuit.cnot(control_qubit_index, target_qubit_index)
 
 
 def apply_toffoli_gate(
     circuit, control_qubit_index1, control_qubit_index2, target_qubit_index
-):
+) -> None:
     circuit.ccnot(control_qubit_index1, control_qubit_index2, 
target_qubit_index)
 
 
-def apply_swap_gate(circuit, qubit_index1, qubit_index2):
+def apply_swap_gate(circuit, qubit_index1, qubit_index2) -> None:
     circuit.swap(qubit_index1, qubit_index2)
 
 
 def apply_cswap_gate(
     circuit, control_qubit_index, target_qubit_index1, target_qubit_index2
-):
+) -> None:
     circuit.cswap(control_qubit_index, target_qubit_index1, 
target_qubit_index2)
 
 
-def apply_pauli_x_gate(circuit, qubit_index):
+def apply_pauli_x_gate(circuit, qubit_index) -> None:
     circuit.x(qubit_index)
 
 
-def apply_pauli_y_gate(circuit, qubit_index):
+def apply_pauli_y_gate(circuit, qubit_index) -> None:
     circuit.y(qubit_index)
 
 
-def apply_pauli_z_gate(circuit, qubit_index):
+def apply_pauli_z_gate(circuit, qubit_index) -> None:
     circuit.z(qubit_index)
 
 
-def apply_t_gate(circuit, qubit_index):
+def apply_t_gate(circuit, qubit_index) -> None:
     circuit.t(qubit_index)
 
 
@@ -143,7 +143,7 @@ def draw_circuit(circuit):
     return str(circuit)
 
 
-def apply_rx_gate(circuit, qubit_index, angle):
+def apply_rx_gate(circuit, qubit_index, angle) -> None:
     if isinstance(angle, (int, float)):
         circuit.rx(qubit_index, angle)
     else:
@@ -151,7 +151,7 @@ def apply_rx_gate(circuit, qubit_index, angle):
         circuit.rx(qubit_index, param)
 
 
-def apply_ry_gate(circuit, qubit_index, angle):
+def apply_ry_gate(circuit, qubit_index, angle) -> None:
     if isinstance(angle, (int, float)):
         circuit.ry(qubit_index, angle)
     else:
@@ -159,7 +159,7 @@ def apply_ry_gate(circuit, qubit_index, angle):
         circuit.ry(qubit_index, param)
 
 
-def apply_rz_gate(circuit, qubit_index, angle):
+def apply_rz_gate(circuit, qubit_index, angle) -> None:
     if isinstance(angle, (int, float)):
         circuit.rz(qubit_index, angle)
     else:
@@ -167,7 +167,7 @@ def apply_rz_gate(circuit, qubit_index, angle):
         circuit.rz(qubit_index, param)
 
 
-def apply_u_gate(circuit, qubit_index, theta, phi, lambd):
+def apply_u_gate(circuit, qubit_index, theta, phi, lambd) -> None:
     # U(θ, φ, λ) = Rz(φ) · Ry(θ) · Rz(λ)
     circuit.rz(qubit_index, lambd)
     circuit.ry(qubit_index, theta)
diff --git a/qumat/cirq_backend.py b/qumat/cirq_backend.py
index 36c37d5cb..46915a8e0 100644
--- a/qumat/cirq_backend.py
+++ b/qumat/cirq_backend.py
@@ -42,17 +42,17 @@ def create_empty_circuit(num_qubits: int | None = None):
     return circuit
 
 
-def apply_not_gate(circuit, qubit_index):
+def apply_not_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.X(qubit))
 
 
-def apply_hadamard_gate(circuit, qubit_index):
+def apply_hadamard_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.H(qubit))
 
 
-def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index):
+def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index) -> None:
     control_qubit = cirq.LineQubit(control_qubit_index)
     target_qubit = cirq.LineQubit(target_qubit_index)
     circuit.append(cirq.CNOT(control_qubit, target_qubit))
@@ -60,14 +60,14 @@ def apply_cnot_gate(circuit, control_qubit_index, 
target_qubit_index):
 
 def apply_toffoli_gate(
     circuit, control_qubit_index1, control_qubit_index2, target_qubit_index
-):
+) -> None:
     control_qubit1 = cirq.LineQubit(control_qubit_index1)
     control_qubit2 = cirq.LineQubit(control_qubit_index2)
     target_qubit = cirq.LineQubit(target_qubit_index)
     circuit.append(cirq.CCX(control_qubit1, control_qubit2, target_qubit))
 
 
-def apply_swap_gate(circuit, qubit_index1, qubit_index2):
+def apply_swap_gate(circuit, qubit_index1, qubit_index2) -> None:
     qubit1 = cirq.LineQubit(qubit_index1)
     qubit2 = cirq.LineQubit(qubit_index2)
     circuit.append(cirq.SWAP(qubit1, qubit2))
@@ -75,29 +75,29 @@ def apply_swap_gate(circuit, qubit_index1, qubit_index2):
 
 def apply_cswap_gate(
     circuit, control_qubit_index, target_qubit_index1, target_qubit_index2
-):
+) -> None:
     control_qubit = cirq.LineQubit(control_qubit_index)
     target_qubit1 = cirq.LineQubit(target_qubit_index1)
     target_qubit2 = cirq.LineQubit(target_qubit_index2)
     circuit.append(cirq.CSWAP(control_qubit, target_qubit1, target_qubit2))
 
 
-def apply_pauli_x_gate(circuit, qubit_index):
+def apply_pauli_x_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.X(qubit))
 
 
-def apply_pauli_y_gate(circuit, qubit_index):
+def apply_pauli_y_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.Y(qubit))
 
 
-def apply_pauli_z_gate(circuit, qubit_index):
+def apply_pauli_z_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.Z(qubit))
 
 
-def apply_t_gate(circuit, qubit_index):
+def apply_t_gate(circuit, qubit_index) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.T(qubit))
 
@@ -140,25 +140,25 @@ def draw_circuit(circuit):
     return str(circuit)
 
 
-def apply_rx_gate(circuit, qubit_index, angle):
+def apply_rx_gate(circuit, qubit_index, angle) -> None:
     param = sympy.Symbol(angle) if isinstance(angle, str) else angle
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.rx(param).on(qubit))
 
 
-def apply_ry_gate(circuit, qubit_index, angle):
+def apply_ry_gate(circuit, qubit_index, angle) -> None:
     param = sympy.Symbol(angle) if isinstance(angle, str) else angle
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.ry(param).on(qubit))
 
 
-def apply_rz_gate(circuit, qubit_index, angle):
+def apply_rz_gate(circuit, qubit_index, angle) -> None:
     param = sympy.Symbol(angle) if isinstance(angle, str) else angle
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.rz(param).on(qubit))
 
 
-def apply_u_gate(circuit, qubit_index, theta, phi, lambd):
+def apply_u_gate(circuit, qubit_index, theta, phi, lambd) -> None:
     qubit = cirq.LineQubit(qubit_index)
     circuit.append(cirq.rz(lambd).on(qubit))
     circuit.append(cirq.ry(theta).on(qubit))
diff --git a/qumat/qdp.py b/qumat/qdp.py
index d62a0946f..3027a499e 100644
--- a/qumat/qdp.py
+++ b/qumat/qdp.py
@@ -29,6 +29,8 @@ Example:
     >>> torch_tensor = torch.from_dlpack(qtensor)
 """
 
+from typing import NoReturn
+
 _INSTALL_MSG = (
     "QDP requires the qumat-qdp native extension. "
     "Build and install it with: cd qdp/qdp-python && maturin develop --release"
@@ -38,7 +40,7 @@ _INSTALL_MSG = (
 def _make_stub(name: str) -> type:
     """Create a stub class that raises ImportError on instantiation."""
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, *args: object, **kwargs: object) -> NoReturn:
         raise ImportError(_INSTALL_MSG)
 
     return type(name, (), {"__init__": __init__, "__doc__": f"Stub class - 
{name}"})
diff --git a/qumat/qiskit_backend.py b/qumat/qiskit_backend.py
index db61d1977..652df888e 100644
--- a/qumat/qiskit_backend.py
+++ b/qumat/qiskit_backend.py
@@ -47,17 +47,17 @@ def create_empty_circuit(num_qubits: int | None = None):
         return qiskit.QuantumCircuit()
 
 
-def apply_not_gate(circuit, qubit_index):
+def apply_not_gate(circuit, qubit_index) -> None:
     # Apply a NOT gate (X gate) on the specified qubit
     circuit.x(qubit_index)
 
 
-def apply_hadamard_gate(circuit, qubit_index):
+def apply_hadamard_gate(circuit, qubit_index) -> None:
     # Apply a Hadamard gate on the specified qubit
     circuit.h(qubit_index)
 
 
-def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index):
+def apply_cnot_gate(circuit, control_qubit_index, target_qubit_index) -> None:
     # Apply a CNOT gate (controlled-X gate) with the specified control and
     # target qubits
     circuit.cx(control_qubit_index, target_qubit_index)
@@ -65,40 +65,40 @@ def apply_cnot_gate(circuit, control_qubit_index, 
target_qubit_index):
 
 def apply_toffoli_gate(
     circuit, control_qubit_index1, control_qubit_index2, target_qubit_index
-):
+) -> None:
     # Apply a Toffoli gate (controlled-controlled-X gate) with the
     # specified control and target qubits
     circuit.ccx(control_qubit_index1, control_qubit_index2, target_qubit_index)
 
 
-def apply_swap_gate(circuit, qubit_index1, qubit_index2):
+def apply_swap_gate(circuit, qubit_index1, qubit_index2) -> None:
     # Apply a SWAP gate to exchange the states of two qubits
     circuit.swap(qubit_index1, qubit_index2)
 
 
 def apply_cswap_gate(
     circuit, control_qubit_index, target_qubit_index1, target_qubit_index2
-):
+) -> None:
     # Apply a controlled-SWAP (Fredkin) gate with the specified control and 
target qubits
     circuit.cswap(control_qubit_index, target_qubit_index1, 
target_qubit_index2)
 
 
-def apply_pauli_x_gate(circuit, qubit_index):
+def apply_pauli_x_gate(circuit, qubit_index) -> None:
     # Apply a Pauli X gate on the specified qubit
     circuit.x(qubit_index)
 
 
-def apply_pauli_y_gate(circuit, qubit_index):
+def apply_pauli_y_gate(circuit, qubit_index) -> None:
     # Apply a Pauli Y gate on the specified qubit
     circuit.y(qubit_index)
 
 
-def apply_pauli_z_gate(circuit, qubit_index):
+def apply_pauli_z_gate(circuit, qubit_index) -> None:
     # Apply a Pauli Z gate on the specified qubit
     circuit.z(qubit_index)
 
 
-def apply_t_gate(circuit, qubit_index):
+def apply_t_gate(circuit, qubit_index) -> None:
     # Apply a T gate (π/8 gate) on the specified qubit
     circuit.t(qubit_index)
 
@@ -168,22 +168,22 @@ def draw_circuit(circuit):
     return circuit.draw()
 
 
-def apply_rx_gate(circuit, qubit_index, angle):
+def apply_rx_gate(circuit, qubit_index, angle) -> None:
     param = qiskit.circuit.Parameter(angle) if isinstance(angle, str) else 
angle
     circuit.rx(param, qubit_index)
 
 
-def apply_ry_gate(circuit, qubit_index, angle):
+def apply_ry_gate(circuit, qubit_index, angle) -> None:
     param = qiskit.circuit.Parameter(angle) if isinstance(angle, str) else 
angle
     circuit.ry(param, qubit_index)
 
 
-def apply_rz_gate(circuit, qubit_index, angle):
+def apply_rz_gate(circuit, qubit_index, angle) -> None:
     param = qiskit.circuit.Parameter(angle) if isinstance(angle, str) else 
angle
     circuit.rz(param, qubit_index)
 
 
-def apply_u_gate(circuit, qubit_index, theta, phi, lambd):
+def apply_u_gate(circuit, qubit_index, theta, phi, lambd) -> None:
     # Apply the U gate directly with specified parameters
     circuit.u(theta, phi, lambd, qubit_index)
 
diff --git a/qumat/qumat.py b/qumat/qumat.py
index 449938666..47607f60c 100644
--- a/qumat/qumat.py
+++ b/qumat/qumat.py
@@ -31,7 +31,7 @@ class QuMat:
     :type backend_config: dict
     """
 
-    def __init__(self, backend_config):
+    def __init__(self, backend_config) -> None:
         """Create a QuMat instance with the specified backend configuration.
 
         :param backend_config: Configuration dictionary containing backend name
@@ -70,7 +70,7 @@ class QuMat:
         self.num_qubits = None
         self.parameters = {}
 
-    def create_empty_circuit(self, num_qubits: int | None = None):
+    def create_empty_circuit(self, num_qubits: int | None = None) -> None:
         """Create an empty quantum circuit with the specified number of qubits.
 
         Must be called before applying any gates or executing operations.
@@ -82,7 +82,7 @@ class QuMat:
         self.num_qubits = num_qubits
         self.circuit = self.backend_module.create_empty_circuit(num_qubits)
 
-    def _ensure_circuit_initialized(self):
+    def _ensure_circuit_initialized(self) -> None:
         """Ensure the circuit has been created before operations.
 
         Checks if the circuit has been initialized via 
``create_empty_circuit()``.
@@ -96,7 +96,7 @@ class QuMat:
                 "before applying gates or executing operations."
             )
 
-    def _validate_qubit_index(self, qubit_index, param_name="qubit_index"):
+    def _validate_qubit_index(self, qubit_index, param_name="qubit_index") -> 
None:
         """validate qubit index is within circuit bounds.
 
         :param qubit_index: the qubit index to validate.
@@ -118,7 +118,7 @@ class QuMat:
                 f"{self.num_qubits} qubits (valid range: 0-{self.num_qubits - 
1})"
             )
 
-    def apply_not_gate(self, qubit_index):
+    def apply_not_gate(self, qubit_index) -> None:
         """Apply a NOT gate (Pauli-X gate) to the specified qubit.
 
         Flips the qubit state from |0⟩ to |1⟩ or |1⟩ to |0⟩.
@@ -132,7 +132,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_not_gate(self.circuit, qubit_index)
 
-    def apply_hadamard_gate(self, qubit_index):
+    def apply_hadamard_gate(self, qubit_index) -> None:
         """Apply a Hadamard gate to the specified qubit.
 
         Creates a superposition state, transforming |0⟩ to (|0⟩ + |1⟩)/√2
@@ -146,7 +146,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_hadamard_gate(self.circuit, qubit_index)
 
-    def apply_cnot_gate(self, control_qubit_index, target_qubit_index):
+    def apply_cnot_gate(self, control_qubit_index, target_qubit_index) -> None:
         """Apply a Controlled-NOT (CNOT) gate between two qubits.
 
         Fundamental for entangling qubits. Flips the target qubit if and only
@@ -167,7 +167,7 @@ class QuMat:
 
     def apply_toffoli_gate(
         self, control_qubit_index1, control_qubit_index2, target_qubit_index
-    ):
+    ) -> None:
         """Apply a Toffoli gate (CCX gate) to three qubits.
 
         Acts as a quantum AND gate. Flips the target qubit if and only if
@@ -189,7 +189,7 @@ class QuMat:
             self.circuit, control_qubit_index1, control_qubit_index2, 
target_qubit_index
         )
 
-    def apply_swap_gate(self, qubit_index1, qubit_index2):
+    def apply_swap_gate(self, qubit_index1, qubit_index2) -> None:
         """Swap the states of two qubits.
 
         :param qubit_index1: Index of the first qubit.
@@ -205,7 +205,7 @@ class QuMat:
 
     def apply_cswap_gate(
         self, control_qubit_index, target_qubit_index1, target_qubit_index2
-    ):
+    ) -> None:
         """Apply a controlled-SWAP (Fredkin) gate.
 
         Swaps the states of two target qubits if and only if the control
@@ -227,7 +227,7 @@ class QuMat:
             self.circuit, control_qubit_index, target_qubit_index1, 
target_qubit_index2
         )
 
-    def apply_pauli_x_gate(self, qubit_index):
+    def apply_pauli_x_gate(self, qubit_index) -> None:
         """Apply a Pauli-X gate to the specified qubit.
 
         Equivalent to the NOT gate. Flips the qubit state from |0⟩ to |1⟩
@@ -241,7 +241,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_pauli_x_gate(self.circuit, qubit_index)
 
-    def apply_pauli_y_gate(self, qubit_index):
+    def apply_pauli_y_gate(self, qubit_index) -> None:
         """Apply a Pauli-Y gate to the specified qubit.
 
         Rotates the qubit around the Y-axis of the Bloch sphere, affecting
@@ -255,7 +255,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_pauli_y_gate(self.circuit, qubit_index)
 
-    def apply_pauli_z_gate(self, qubit_index):
+    def apply_pauli_z_gate(self, qubit_index) -> None:
         """Apply a Pauli-Z gate to the specified qubit.
 
         Rotates the qubit around the Z-axis of the Bloch sphere, altering
@@ -269,7 +269,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_pauli_z_gate(self.circuit, qubit_index)
 
-    def apply_t_gate(self, qubit_index):
+    def apply_t_gate(self, qubit_index) -> None:
         """Apply a T-gate (π/8 gate) to the specified qubit.
 
         Applies a relative pi/4 phase (multiplies the |1> state by e^{i*pi/4}).
@@ -332,7 +332,7 @@ class QuMat:
             self.circuit, self.backend, self.backend_config
         )
 
-    def bind_parameters(self, parameter_values):
+    def bind_parameters(self, parameter_values) -> None:
         """Bind numerical values to circuit parameters.
 
         Assigns numerical values to symbolic parameters defined in 
parameterized
@@ -413,7 +413,7 @@ class QuMat:
         """
         return self.draw_circuit()
 
-    def apply_rx_gate(self, qubit_index, angle):
+    def apply_rx_gate(self, qubit_index, angle) -> None:
         """Apply a rotation around the X-axis to the specified qubit.
 
         Rotates the qubit by the given angle around the X-axis of the Bloch
@@ -432,7 +432,7 @@ class QuMat:
         self._handle_parameter(angle)
         self.backend_module.apply_rx_gate(self.circuit, qubit_index, angle)
 
-    def apply_ry_gate(self, qubit_index, angle):
+    def apply_ry_gate(self, qubit_index, angle) -> None:
         """Apply a rotation around the Y-axis to the specified qubit.
 
         Rotates the qubit by the given angle around the Y-axis of the Bloch
@@ -451,7 +451,7 @@ class QuMat:
         self._handle_parameter(angle)
         self.backend_module.apply_ry_gate(self.circuit, qubit_index, angle)
 
-    def apply_rz_gate(self, qubit_index, angle):
+    def apply_rz_gate(self, qubit_index, angle) -> None:
         """Apply a rotation around the Z-axis to the specified qubit.
 
         Rotates the qubit by the given angle around the Z-axis of the Bloch
@@ -470,7 +470,7 @@ class QuMat:
         self._handle_parameter(angle)
         self.backend_module.apply_rz_gate(self.circuit, qubit_index, angle)
 
-    def _handle_parameter(self, param_name):
+    def _handle_parameter(self, param_name) -> None:
         """Register parameter names when parameterized gates are applied.
 
         Automatically adds string parameter names to the parameters dictionary
@@ -483,7 +483,7 @@ class QuMat:
         if isinstance(param_name, str) and param_name not in self.parameters:
             self.parameters[param_name] = None
 
-    def apply_u_gate(self, qubit_index, theta, phi, lambd):
+    def apply_u_gate(self, qubit_index, theta, phi, lambd) -> None:
         """Apply a U gate (universal single-qubit gate) to the specified qubit.
 
         A universal single-qubit gate parameterized by three angles (theta,
@@ -503,7 +503,7 @@ class QuMat:
         self._validate_qubit_index(qubit_index)
         self.backend_module.apply_u_gate(self.circuit, qubit_index, theta, 
phi, lambd)
 
-    def swap_test(self, ancilla_qubit, qubit1, qubit2):
+    def swap_test(self, ancilla_qubit, qubit1, qubit2) -> None:
         """Implement the swap test circuit for measuring overlap between two 
quantum states.
 
         Measures the inner product between the states on ``qubit1`` and 
``qubit2``.
diff --git a/testing/utils/qumat_helpers.py b/testing/utils/qumat_helpers.py
index 2e024857e..dfb9c6b53 100644
--- a/testing/utils/qumat_helpers.py
+++ b/testing/utils/qumat_helpers.py
@@ -51,7 +51,7 @@ def get_backend_config(backend_name: str) -> dict | None:
 
 
 class BinaryString(str):
-    def __new__(cls, value):
+    def __new__(cls, value):  # noqa: ANN204
         if not all(char in ["0", "1"] for char in value):
             raise ValueError("String contains characters other than '0' and 
'1'")
         return str.__new__(cls, value)


Reply via email to