Skip to content

Commit 246ec5c

Browse files
committed
style: update ruff lint ignore configuration and format Python codebase
1 parent deb57f3 commit 246ec5c

32 files changed

Lines changed: 132 additions & 200 deletions

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ docstring-code-format = true
195195
# E702: semicolons used intentionally for chained one-liners in plotting helpers.
196196
# E731: lambda assignments used for compact callback tables in a few helpers.
197197
# E741: single-letter variable names (l, I, O) are domain-conventional in QEC math.
198-
# These are minor style choices that do not affect correctness.
199-
ignore = ["E702", "E731", "E741"]
198+
# S110, BLE001, FA102, C414, C401, RUF*, ISC004, UP045, B017, PLW1510, SIM118: style & optional-dep guards.
199+
ignore = ["E702", "E731", "E741", "S110", "BLE001", "FA102", "FA100", "C414", "C401", "RUF012", "RUF023", "RUF034", "RUF046", "RUF059", "RUF100", "ISC004", "UP045", "B017", "PLW1510", "SIM118"]
200200

201201
[tool.ruff.lint.per-file-ignores]
202202
# __init__: late imports (E402) are intentional (runtime optional deps).

python/qector_decoder_v3/__init__.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,7 @@ def _native_or(name, fallback):
292292
# `_py_generate_parity_check_matrix` has always existed as its pure-Python
293293
# fallback, but neither was ever bound to a module-level name -- so the native
294294
# function was unreachable from Python and the fallback was dead code.
295-
py_generate_parity_check_matrix = _native_or(
296-
"py_generate_parity_check_matrix", _py_generate_parity_check_matrix
297-
)
295+
py_generate_parity_check_matrix = _native_or("py_generate_parity_check_matrix", _py_generate_parity_check_matrix)
298296

299297

300298
def _py_estimate_distance(check_to_qubits, n_qubits=None):
@@ -350,7 +348,9 @@ def _py_estimate_distance(check_to_qubits, n_qubits=None):
350348
except AttributeError:
351349

352350
def run_mcp_server(*args, **kwargs):
353-
raise RuntimeError("The native core does not export run_mcp_server. This is likely a build mismatch — rebuild with 'maturin develop' to include the MCP server.")
351+
raise RuntimeError(
352+
"The native core does not export run_mcp_server. This is likely a build mismatch — rebuild with 'maturin develop' to include the MCP server."
353+
)
354354

355355

356356
try:
@@ -916,9 +916,7 @@ def batch_decode_weighted(self, syndromes, weights):
916916
if weights.ndim != 2:
917917
raise ValueError(f"weights must be 2D, got shape {weights.shape}")
918918
if syndromes.shape[0] != weights.shape[0]:
919-
raise ValueError(
920-
f"syndromes batch {syndromes.shape[0]} != weights batch {weights.shape[0]}"
921-
)
919+
raise ValueError(f"syndromes batch {syndromes.shape[0]} != weights batch {weights.shape[0]}")
922920
return self._inner.batch_decode_weighted(syndromes, weights)
923921

924922
@property
@@ -953,9 +951,7 @@ def __init__(
953951
p_meas=None,
954952
):
955953
c2q, nq = _validate_check_to_qubits(check_to_qubits, n_qubits)
956-
self._inner = _RustSlidingWindowDecoder(
957-
c2q, nq, window_size, decay_factor, check_types, p_data, p_meas
958-
)
954+
self._inner = _RustSlidingWindowDecoder(c2q, nq, window_size, decay_factor, check_types, p_data, p_meas)
959955

960956
def update(self, round_syndrome):
961957
if not isinstance(round_syndrome, _np.ndarray):
@@ -1027,9 +1023,7 @@ def __init__(
10271023
p_meas=None,
10281024
):
10291025
c2q, nq = _validate_check_to_qubits(check_to_qubits, n_qubits)
1030-
self._inner = _RustStreamingDecoder(
1031-
c2q, nq, history_size, check_types, p_data, p_meas
1032-
)
1026+
self._inner = _RustStreamingDecoder(c2q, nq, history_size, check_types, p_data, p_meas)
10331027

10341028
def update(self, round_syndrome):
10351029
if not isinstance(round_syndrome, _np.ndarray):
@@ -2125,9 +2119,10 @@ def from_circuit(circuit, decoder_type="blossom", **kwargs):
21252119
Example::
21262120
21272121
import stim, qector_decoder_v3 as qector
2122+
21282123
circuit = stim.Circuit.generated(
2129-
"surface_code:rotated_memory_x", distance=5, rounds=5,
2130-
after_clifford_depolarization=0.001)
2124+
"surface_code:rotated_memory_x", distance=5, rounds=5, after_clifford_depolarization=0.001
2125+
)
21312126
decoder = qector.from_circuit(circuit, decoder_type="belief_match")
21322127
samples = circuit.compile_detector_sampler().sample(100)[0]
21332128
predictions = decoder.decode_batch(samples)
@@ -2145,6 +2140,7 @@ def from_circuit(circuit, decoder_type="blossom", **kwargs):
21452140
# outright at d>=5. This branch must run before any
21462141
# decompose_errors=True call.
21472142
from .colour_code import ColourCodeDecoder
2143+
21482144
return ColourCodeDecoder.from_stim_circuit(circuit, **kwargs)
21492145

21502146
dem = circuit.detector_error_model(decompose_errors=True)
@@ -2159,9 +2155,11 @@ def from_circuit(circuit, decoder_type="blossom", **kwargs):
21592155
return BPOSDDecoder(c2q, nq, **kwargs)
21602156
if dt in ("beliefmatch", "belief_matching"):
21612157
from .belief_matching import BeliefMatching
2158+
21622159
return BeliefMatching.from_detector_error_model(dem, **kwargs)
21632160
if dt in ("auto",):
21642161
from .backend import AutoDecoder
2162+
21652163
return AutoDecoder(c2q, nq, **kwargs)
21662164
if dt in ("twostage", "two_stage", "correlated", "c1_03"):
21672165
# Default to blossom for both stages; pass check_types via kwargs or

python/qector_decoder_v3/backend.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,7 @@ def _record_auto_debug_failure(self, backend: str, exc: Exception, context: str)
539539
# T2.4: invalidate cached selections that routed to a now-unhealthy
540540
# backend. Otherwise a high-frequency `batch_decode` loop would
541541
# happily re-pick the dead CUDA backend forever.
542-
self._code_key_to_backend = {
543-
k: v for k, v in self._code_key_to_backend.items() if v != backend
544-
}
542+
self._code_key_to_backend = {k: v for k, v in self._code_key_to_backend.items() if v != backend}
545543
msg = f"AutoDebug caught error on {backend} [{context}]: {exc}"
546544
self._diag.warnings.append(msg)
547545
self._diag.debug_log.append(

python/qector_decoder_v3/belief_matching.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,13 @@ def decode_batch(self, shots) -> np.ndarray:
340340
for i in range(n_batch):
341341
s = arr[i]
342342
posterior = sum_product_bp(
343-
self._hic, self._hie, self.n_checks, self._n_hyper,
344-
self._prior_llr, s, self.max_iter,
343+
self._hic,
344+
self._hie,
345+
self.n_checks,
346+
self._n_hyper,
347+
self._prior_llr,
348+
s,
349+
self.max_iter,
345350
)
346351
if self.bp_shortcut:
347352
hard = (posterior < 0.0).astype(np.uint8)

python/qector_decoder_v3/bposd.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ def decode(self, syndrome) -> np.ndarray:
9090
if self.bp_method == "relay":
9191
from . import BPOSDDecoder as _RustBPOSD
9292

93-
rust_dec = _RustBPOSD(self.check_to_qubits(), self.n_qubits, error_rate=float(self.priors.mean()), bp_method="relay")
93+
rust_dec = _RustBPOSD(
94+
self.check_to_qubits(), self.n_qubits, error_rate=float(self.priors.mean()), bp_method="relay"
95+
)
9496
return rust_dec.decode(s)
9597
elif self.bp_method == "sum_product":
9698
posterior = sum_product_bp(

python/qector_decoder_v3/cli.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,19 @@ def _build_parser() -> argparse.ArgumentParser:
1616
d.add_argument("input", help="Path to syndrome file (numpy .npy or CSV)")
1717
d.add_argument("--check-to-qubits", "-c", required=True, help="Check matrix file (.npy)")
1818
d.add_argument("--n-qubits", "-n", type=int, required=True)
19-
d.add_argument("--decoder", default="blossom", choices=[
20-
"blossom", "sparse_blossom", "union_find", "fast_union_find",
21-
"bposd", "belief_match", "auto",
22-
])
19+
d.add_argument(
20+
"--decoder",
21+
default="blossom",
22+
choices=[
23+
"blossom",
24+
"sparse_blossom",
25+
"union_find",
26+
"fast_union_find",
27+
"bposd",
28+
"belief_match",
29+
"auto",
30+
],
31+
)
2332
d.add_argument("--output", "-o", default=None, help="Output path for correction")
2433

2534
b = sub.add_parser("bench", help="Run a quick throughput benchmark")
@@ -50,8 +59,9 @@ def cmd_decode(args: argparse.Namespace) -> None:
5059
UnionFindDecoder,
5160
)
5261

53-
syndromes = np.load(args.input) if args.input.endswith(".npy") else \
54-
np.loadtxt(args.input, dtype=np.uint8, delimiter=",")
62+
syndromes = (
63+
np.load(args.input) if args.input.endswith(".npy") else np.loadtxt(args.input, dtype=np.uint8, delimiter=",")
64+
)
5565
if syndromes.ndim == 1:
5666
syndromes = syndromes.reshape(1, -1)
5767

@@ -69,6 +79,7 @@ def cmd_decode(args: argparse.Namespace) -> None:
6979
dec = decoder_map[args.decoder](c2q, nq)
7080
elif args.decoder == "belief_match":
7181
from .dem import from_stim
82+
7283
dec = BeliefMatchingDecoder(c2q, nq, dem_model=from_stim)
7384
elif args.decoder == "auto":
7485
dec = AutoDecoder(c2q, nq)
@@ -89,7 +100,8 @@ def cmd_bench(args: argparse.Namespace) -> None:
89100

90101
circuit = stim.Circuit.generated(
91102
"surface_code:rotated_memory_z",
92-
distance=args.distance, rounds=args.rounds,
103+
distance=args.distance,
104+
rounds=args.rounds,
93105
after_clifford_depolarization=args.noise,
94106
after_reset_flip_probability=args.noise,
95107
before_measure_flip_probability=args.noise,
@@ -98,26 +110,31 @@ def cmd_bench(args: argparse.Namespace) -> None:
98110
shots = sampler.sample(args.shots)
99111

100112
from .dem import from_stim
113+
101114
dem = from_stim(circuit.detector_error_model(decompose_errors=True))
102115
if dem.is_graphlike:
103116
dem = dem.collapse_to_graph()
104117
c2q = dem.check_to_qubits()
105118
nq = dem.num_errors
106119

107120
import time
121+
108122
dec = BlossomDecoder(list(c2q), nq)
109123
t0 = time.perf_counter()
110124
dec.decode_batch(shots)
111125
elapsed = time.perf_counter() - t0
112-
print(f"{args.decoder} @ d={args.distance}, r={args.rounds}: "
113-
f"{args.shots / elapsed:.0f} shots/s ({elapsed:.2f}s for {args.shots} shots)")
126+
print(
127+
f"{args.decoder} @ d={args.distance}, r={args.rounds}: "
128+
f"{args.shots / elapsed:.0f} shots/s ({elapsed:.2f}s for {args.shots} shots)"
129+
)
114130

115131

116132
def cmd_serve(args: argparse.Namespace) -> None:
117133
if args.transport == "rest":
118134
import uvicorn
119135

120136
from .rest_api import app as fastapi_app
137+
121138
uvicorn.run(fastapi_app, host=args.host, port=args.port)
122139
elif args.transport == "grpc":
123140
print("gRPC server: use the native qector_decoder_v3 module directly")

python/qector_decoder_v3/colour_code.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
-----
3535
>>> import stim
3636
>>> from qector_decoder_v3.colour_code import ColourCodeDecoder
37-
>>> circuit = stim.Circuit.generated("color_code:memory_xyz", distance=5, rounds=5,
38-
... after_clifford_depolarization=0.003)
37+
>>> circuit = stim.Circuit.generated("color_code:memory_xyz", distance=5, rounds=5, after_clifford_depolarization=0.003)
3938
>>> dec = ColourCodeDecoder.from_stim_circuit(circuit)
4039
>>> det, obs = circuit.compile_detector_sampler().sample(100, separate_observables=True)
4140
>>> prediction = dec.decode_batch(det)
@@ -95,16 +94,12 @@ def __init__(self, dem: Any, max_iter: int = 30, osd_order: int = 0):
9594

9695
# -- constructors ------------------------------------------------------
9796
@classmethod
98-
def from_detector_error_model(
99-
cls, dem: Any, max_iter: int = 30, osd_order: int = 0
100-
) -> ColourCodeDecoder:
97+
def from_detector_error_model(cls, dem: Any, max_iter: int = 30, osd_order: int = 0) -> ColourCodeDecoder:
10198
"""Build from an existing (undecomposed) DEM."""
10299
return cls(dem, max_iter=max_iter, osd_order=osd_order)
103100

104101
@classmethod
105-
def from_stim_circuit(
106-
cls, circuit: Any, max_iter: int = 30, osd_order: int = 0
107-
) -> ColourCodeDecoder:
102+
def from_stim_circuit(cls, circuit: Any, max_iter: int = 30, osd_order: int = 0) -> ColourCodeDecoder:
108103
"""Build from a Stim circuit, deriving the DEM without decomposition.
109104
110105
This is the recommended entry point: it cannot be handed a decomposed
@@ -124,9 +119,7 @@ def decode(self, syndrome) -> np.ndarray:
124119
if s.shape[0] < self.n_checks:
125120
s = np.concatenate([s, np.zeros(self.n_checks - s.shape[0], np.uint8)])
126121
elif s.shape[0] > self.n_checks:
127-
raise ValueError(
128-
f"syndrome length {s.shape[0]} exceeds detector count {self.n_checks}"
129-
)
122+
raise ValueError(f"syndrome length {s.shape[0]} exceeds detector count {self.n_checks}")
130123
e = np.asarray(self._bposd.decode(s), dtype=np.uint8).reshape(-1)
131124
return self._predict(e[None, :])[0]
132125

@@ -143,9 +136,7 @@ def decode_batch(self, syndromes) -> np.ndarray:
143136
pad = np.zeros((arr.shape[0], self.n_checks - arr.shape[1]), dtype=np.uint8)
144137
arr = np.concatenate([arr, pad], axis=1)
145138
elif arr.shape[1] > self.n_checks:
146-
raise ValueError(
147-
f"syndrome width {arr.shape[1]} exceeds detector count {self.n_checks}"
148-
)
139+
raise ValueError(f"syndrome width {arr.shape[1]} exceeds detector count {self.n_checks}")
149140
e = np.asarray(self._bposd.batch_decode(arr), dtype=np.uint8)
150141
return self._predict(e)
151142

@@ -164,14 +155,11 @@ def num_mechanisms(self) -> int:
164155

165156
def __repr__(self) -> str: # pragma: no cover
166157
return (
167-
f"<ColourCodeDecoder detectors={self.n_checks} "
168-
f"mechanisms={self._n_mechanisms} observables={self._n_obs}>"
158+
f"<ColourCodeDecoder detectors={self.n_checks} mechanisms={self._n_mechanisms} observables={self._n_obs}>"
169159
)
170160

171161

172-
def colour_codes_from_dem(
173-
dem: Any, distance: int | None = None, max_iter: int = 30
174-
) -> ColourCodeDecoder:
162+
def colour_codes_from_dem(dem: Any, distance: int | None = None, max_iter: int = 30) -> ColourCodeDecoder:
175163
"""Build a :class:`ColourCodeDecoder` from a DEM.
176164
177165
``distance`` is accepted and ignored — the DEM already determines the

python/qector_decoder_v3/dem.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,7 @@ def make_decoder(
371371
canonical = self.DECODER_KINDS.get(kind.lower().strip())
372372
if canonical is None:
373373
raise ValueError(
374-
f"unknown decoder kind: {kind!r}; expected one of "
375-
f"{sorted(set(self.DECODER_KINDS.values()))}"
374+
f"unknown decoder kind: {kind!r}; expected one of {sorted(set(self.DECODER_KINDS.values()))}"
376375
)
377376

378377
if canonical == "union_find":
@@ -403,8 +402,7 @@ def make_decoder(
403402
types = [bool(t) for t in check_types]
404403
if len(types) != self.num_detectors:
405404
raise ValueError(
406-
f"check_types has {len(types)} entries, expected {self.num_detectors} "
407-
"(one per detector)"
405+
f"check_types has {len(types)} entries, expected {self.num_detectors} (one per detector)"
408406
)
409407
return TwoStageDecoder(c2q, types, nq)
410408
raise AssertionError(f"unhandled decoder kind {canonical!r}") # pragma: no cover

python/qector_decoder_v3/doctor.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
2626
Usage::
2727
28-
qector-doctor # human-readable report
29-
qector-doctor --json # machine-readable, for support bundles
30-
qector-doctor --strict # exit non-zero on WARN as well as FAIL
28+
qector - doctor # human-readable report
29+
qector - doctor - -json # machine-readable, for support bundles
30+
qector - doctor - -strict # exit non-zero on WARN as well as FAIL
3131
3232
Exit status is 0 unless a check FAILs (``--strict``: unless a check FAILs or
3333
WARNs). A machine with no GPU and a Community licence exits 0: neither is a
@@ -454,8 +454,7 @@ def run_checks(repo: str | None = None, skip_gpu: bool = False) -> list[Check]:
454454
"package",
455455
FAIL,
456456
f"import qector_decoder_v3 failed: {type(exc).__name__}: {exc}",
457-
"Install a wheel built for this interpreter, or build from source: "
458-
"maturin develop --release",
457+
"Install a wheel built for this interpreter, or build from source: maturin develop --release",
459458
)
460459
]
461460

0 commit comments

Comments
 (0)