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)