Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ positive comes from upstream typing (a stub that omits the attribute, a
scalar union, a field added to an upstream dataclass), with a comment
saying which; keep the count under twenty repo-wide.

ruff's S110 rule flags a `try`/`except Exception: pass`. Either log the
failure, or say where the error goes on the except line:
`except Exception: # noqa: S110 - <reason>`. A bare marker without a
reason is not accepted in review. Tests are exempt.

## Things to know before you patch

- The serving stack is stock mlx-vlm with late-bound patches over its
Expand Down
8 changes: 4 additions & 4 deletions bench/serve-bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ def wait_ready(runtime, proc, timeout):
if r.status_code == 200:
data = (r.json() or {}).get("data") or []
return data[0]["id"] if data else "model"
except Exception:
except Exception: # noqa: S110 - not ready yet; the poll loop retries
pass
time.sleep(1.0)
raise TimeoutError(f"{runtime} server not ready within {timeout}s")
Expand Down Expand Up @@ -972,7 +972,7 @@ def die_temp():
parts = out.split() # "DIE 62.4 MAX 66.1 (n=42)"
if len(parts) >= 4 and parts[0] == "DIE":
return float(parts[1]), float(parts[3])
except Exception:
except Exception: # noqa: S110 - no die-temp probe -> None
pass
return None

Expand All @@ -991,7 +991,7 @@ def thermal_snapshot():
for line in out.splitlines():
if "CPU_Speed_Limit" in line:
return line.strip()
except Exception:
except Exception: # noqa: S110 - no thermal readout -> None
pass
return None

Expand Down Expand Up @@ -2055,7 +2055,7 @@ def main():
["git", "-C", os.path.dirname(args.ds4_bin), "rev-parse",
"--short", "HEAD"], capture_output=True, text=True,
timeout=5).stdout.strip() or None
except Exception:
except Exception: # noqa: S110 - unknown ds4 commit -> None
pass

def _meta(partial):
Expand Down
2 changes: 1 addition & 1 deletion gmlx/_exitfix.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def _guard() -> None:
try:
sys.stdout.flush()
sys.stderr.flush()
except Exception:
except Exception: # noqa: S110 - stdio may already be closed at exit
pass
os._exit(_code)

Expand Down
2 changes: 1 addition & 1 deletion gmlx/assistant/brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def turn(self, user_text: str) -> Iterator[BrainEvent]:
if self.memory is not None and completed:
try:
self.memory.remember(user_text, "".join(spoken))
except Exception: # noqa: BLE001 - best-effort
except Exception: # noqa: BLE001, S110 - best-effort
pass
if completed:
if timings:
Expand Down
6 changes: 5 additions & 1 deletion gmlx/assistant/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import importlib
import inspect
import json
import logging
import os
import sys
import threading
Expand All @@ -54,6 +55,8 @@
from .brain import AssistantBrain, ToolRegistry
from gmlx.talk.client import TalkClientError, stream_chat

_log = logging.getLogger(__name__)

_ASSISTANT_FLAG = "_kq_gguf_assistant_serve"
_MAX_CONCURRENT_TURNS = 4 # immediate 429 above this, per process
_DEFAULT_MAX_TOKENS = 4096
Expand Down Expand Up @@ -100,7 +103,8 @@ def close_memories(self) -> None:
try:
m.close()
except Exception:
pass
_log.warning("assistant memory store close failed; queued "
"facts may be lost", exc_info=True)

def try_acquire(self) -> bool:
with self._lock:
Expand Down
2 changes: 1 addition & 1 deletion gmlx/cache/apc_pooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def model_has_pools(model) -> bool:
break
try:
model._kq_has_pools = found
except Exception:
except Exception: # noqa: S110 - memo stamp; recomputed when the model forbids ad-hoc attrs
pass
return found

Expand Down
4 changes: 2 additions & 2 deletions gmlx/cache/kvarn_apc.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def stamp_model(model) -> None:
if obj is not None:
try:
setattr(obj, _MODE_STAMP, True)
except Exception:
except Exception: # noqa: S110 - stamp only; an unsettable object reads as unstamped
pass


Expand Down Expand Up @@ -93,7 +93,7 @@ def kvarn_model_converts(model) -> bool:
val = False
try:
setattr(model, _CONVERTS_ATTR, val)
except Exception:
except Exception: # noqa: S110 - memo stamp; recomputed when the model forbids ad-hoc attrs
pass
return val

Expand Down
12 changes: 6 additions & 6 deletions gmlx/cache/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,13 +1575,13 @@ def _once():
# release must not leak the other block set out of the manager.
try:
_ckpt_decline(manager, "exception")
except Exception:
pass # decline is telemetry only
except Exception: # noqa: S110 - decline is telemetry only
pass
for blks in (main_blocks, bounded_blocks):
try:
manager.release(blks)
except Exception:
pass # best-effort release on the failure path
except Exception: # noqa: S110 - best-effort release on the failure path
pass
_log.warning("APC ckpt store failed; continuing", exc_info=True)
return 0

Expand Down Expand Up @@ -2165,8 +2165,8 @@ def _ckpt_disk_lookup(manager, ids, *, extra_hash, min_prefix_tokens,
for blks in (blocks, wblocks):
try:
manager.release(blks)
except Exception:
pass # best-effort release on the failure path
except Exception: # noqa: S110 - best-effort release on the failure path
pass
_log.warning("APC ckpt disk lookup failed; continuing",
exc_info=True)
return None, 0
Expand Down
2 changes: 1 addition & 1 deletion gmlx/commands/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def cmd_complete(argv: list[str]) -> int:
try:
for line in _complete(list(argv)):
print(line)
except Exception: # noqa: BLE001 - never let completion fail loudly
except Exception: # noqa: BLE001, S110 - never let completion fail loudly
pass
return 0

Expand Down
34 changes: 16 additions & 18 deletions gmlx/commands/menubar.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ def ptt_modifier_from_config(run: dict | None) -> str:
"push_to_talk_modifier", "globe")
if mod in PUSH_TO_TALK_MODIFIERS:
return mod
except Exception:
pass # unreadable config -> default modifier
except Exception: # noqa: S110 - unreadable config -> default modifier
pass
return "globe"


Expand Down Expand Up @@ -160,8 +160,8 @@ def _existing_default_config() -> str | None:
for p in default_config_paths():
if p.exists():
return str(p)
except Exception:
pass # probe only; no readable default config -> no path
except Exception: # noqa: S110 - probe only; no readable default config -> no path
pass
return None


Expand Down Expand Up @@ -275,8 +275,8 @@ def _autostart_server_once() -> None:
lifecycle.launch_detached(argv, host=host, port=port,
config_abspath=auto.get("config_abspath"),
api_key_set=bool(auto.get("api_key_set")))
except Exception:
pass # best-effort autostart replay; the menu stays usable without it
except Exception: # noqa: S110 - best-effort autostart replay; the menu stays usable without it
pass


def build_menu_model(snapshot: dict, run: dict | None,
Expand Down Expand Up @@ -774,17 +774,17 @@ def work():
_post_json(_server_root(self.url) + "/unload",
{"model": model_id},
api_key=self._resolve_key(), timeout=8.0)
except Exception:
pass # fire-and-forget; the next poll shows the real state
except Exception: # noqa: S110 - fire-and-forget; the next poll shows the real state
pass
self._spawn(work)

def _reload(self) -> None:
def work():
try:
_post_json(_server_root(self.url) + "/v1/reload",
{}, api_key=self._resolve_key(), timeout=15.0)
except Exception:
pass # fire-and-forget; the next poll shows the real state
except Exception: # noqa: S110 - fire-and-forget; the next poll shows the real state
pass
self._spawn(work)

def _copy_url(self) -> None:
Expand Down Expand Up @@ -939,9 +939,8 @@ def _voice_notification(self, msg: str) -> None:
def post():
try:
self._rumps.notification("gmlx voice", None, msg)
except Exception:
pass # notification center unavailable (bare interpreter,
# no Info.plist) - the transcript line still has it
except Exception: # noqa: S110 - no notification center (bare interpreter); the transcript line still has it
pass
try:
from PyObjCTools import AppHelper
AppHelper.callAfter(post)
Expand Down Expand Up @@ -1086,8 +1085,8 @@ def _repreflight_hotkey(self) -> None:
if hotkey.preflight():
self._hotkey_error = None
self._arm_hotkey_async()
except Exception:
pass # advisory probe; the next tick retries
except Exception: # noqa: S110 - advisory probe; the next tick retries
pass

def _set_hotkey(self, choice: str) -> None:
"""Menu callback (main run-loop thread): switch the hotkey on or
Expand Down Expand Up @@ -1212,9 +1211,8 @@ def _post_down_notification(self, snap: dict,
msg = down_message(snap.get("url") or self.url, run, pid_dead)
try:
self._rumps.notification("gmlx", None, msg)
except Exception:
pass # notification center unavailable (bare interpreter, no
# Info.plist) - the glyph flip still shows the state
except Exception: # noqa: S110 - no notification center (bare interpreter); the glyph flip still shows the state
pass

def _make_unload(self, model_id: str):
return lambda _sender: self._unload(model_id)
Expand Down
6 changes: 3 additions & 3 deletions gmlx/eval_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ def _harvest() -> None:
register_stream(mx.default_stream(mx.Device(mx.cpu)))
try:
register_stream(mx.default_stream(mx.Device(mx.gpu)))
except Exception:
pass # no Metal device (CI)
except Exception: # noqa: S110 - no Metal device (CI)
pass
try:
from mlx_lm.generate import generation_stream
register_stream(generation_stream)
except Exception:
except Exception: # noqa: S110 - optional: mlx_lm's generation stream is harvested when present
pass


Expand Down
2 changes: 1 addition & 1 deletion gmlx/gen/media_spans.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def _absolute_offset(batch) -> int:
if callable(real):
try:
return int(real(0))
except Exception:
except Exception: # noqa: S110 - odd batch without the row helper; the column count is the offset
pass
return int(getattr(batch, "_processed_prompt_columns", 0))

Expand Down
4 changes: 2 additions & 2 deletions gmlx/gen/thinking_budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def think_tokenizer_for(processor):
wrapped = tok
try:
processor._gmlx_think_tokenizer = wrapped
except Exception: # noqa: BLE001 - unsettable processor: skip the cache
except Exception: # noqa: BLE001, S110 - unsettable processor: skip the cache
pass
return wrapped

Expand Down Expand Up @@ -754,7 +754,7 @@ def _quiet_kernel_status() -> None:
attrs = termios.tcgetattr(fd)
attrs[3] |= nokerninfo
termios.tcsetattr(fd, termios.TCSANOW, attrs)
except Exception: # noqa: BLE001 - cosmetic; never block generation
except Exception: # noqa: BLE001, S110 - cosmetic; never block generation
pass


Expand Down
4 changes: 2 additions & 2 deletions gmlx/load/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ def _save_header_cache(cache: dict) -> None:
with os.fdopen(fd, "w") as f:
json.dump(cache, f)
os.replace(tmp, p)
except Exception:
pass # best-effort cache write; discovery just re-scans next time
except Exception: # noqa: S110 - best-effort cache write; discovery re-scans next time
pass


# Model-card sampling embedded in the GGUF header (llama.cpp writes
Expand Down
4 changes: 2 additions & 2 deletions gmlx/load/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ def _auth_headers(url: str) -> dict:
try:
from huggingface_hub import get_token
token = get_token()
except Exception:
pass # no stored hub token -> anonymous request
except Exception: # noqa: S110 - no stored hub token -> anonymous request
pass
if token:
return {"Authorization": f"Bearer {token}"}
return {}
Expand Down
2 changes: 1 addition & 1 deletion gmlx/models/deepseek_v4/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ def fire(fn):
guard.eval(*(out if isinstance(out, (tuple, list)) else (out,)),
site="dsa-warm-probe", owner="scratch")
n += 1
except Exception: # noqa: BLE001 - warm only, probes stay live
except Exception: # noqa: BLE001, S110 - warm only, probes stay live
pass

B, H, L, D, P = 1, 64, 64, 128, 1024
Expand Down
12 changes: 6 additions & 6 deletions gmlx/serve/bridge_vlm.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ def _build_detokenizer(backend):
return _mlxvlm_tok.SPMStreamingDetokenizer(backend, trim_space=False)
if _mlxvlm_tok._is_bpe_decoder(decoder):
return _mlxvlm_tok.BPEStreamingDetokenizer(backend)
except Exception:
pass # unprobeable tokenizer json -> naive detokenizer
except Exception: # noqa: S110 - unprobeable tokenizer json -> naive detokenizer
pass
return naive(backend)


Expand Down Expand Up @@ -343,7 +343,7 @@ def _ensure_text_embedding_probe(model, raw_model) -> None:
try:
if lm._token_embedding() is not None:
return # stock probe already reaches it
except Exception: # noqa: BLE001 - exotic wrapper
except Exception: # noqa: BLE001, S110 - exotic wrapper
pass
emb = _find_token_embedding(raw_model)
if emb is None:
Expand Down Expand Up @@ -798,8 +798,8 @@ def _apply_draft_block_size_override(result) -> None:
cfg.runtime_block_size = n
else:
cfg.block_size = n
except Exception:
pass # frozen/odd config object -> keep the drafter's own default
except Exception: # noqa: S110 - frozen/odd config object -> keep the drafter's own default
pass


def _log_drafter_source(gguf_path: str, drafter, draft_gguf_path: str | None) -> None:
Expand Down Expand Up @@ -855,7 +855,7 @@ def _degrade_failed_mtp(model_path: str, error: str) -> None:
import mlx.core as mx

mx.clear_cache()
except Exception:
except Exception: # noqa: S110 - cache release is advisory after a failed load
pass


Expand Down
2 changes: 1 addition & 1 deletion gmlx/serve/decode_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ def decode_batch() -> int:
fw = frontier_width()
if fw:
return min(DEFAULT_DECODE_BATCH, fw)
except Exception:
except Exception: # noqa: S110 - capacity table unreadable -> default width
pass
return DEFAULT_DECODE_BATCH
Loading