Sixteen `>=` floors become exact pins across the two Python packages, taking five majors with them: mypy 1.13 -> 2.3.1, pylint 3.3 -> 4.0.7, pytest 8 -> 9, pytest-cov 5 -> 7, bandit 1.7 -> 1.9.4, plus ruff 0.15 -> 0.16.5 and requests/types-requests. A `>=` floor is satisfied by everything newer, so it told a checker nothing about whether these repos were actually current. Verified in a clean venv per repo, which is what both CI workflows do (`pip install -r requirements.txt`): gatelock 389 tests at 100% coverage under xvfb, crdt-sync 432 tests at 100%. No test change was needed for any of the five majors. **Open, and deliberately not in this commit:** `.pre-commit-config.yaml` pins these same tools AGAIN via `rev:` (ruff v0.15.2, mypy v1.13.0, pylint v3.3.2), independently of requirements.txt, and the gate does not read `rev:` pins at all -- so the linters CI actually runs are still on the old majors. Bumping them is a separate and much larger job: ruff 0.16 raises 71 findings here (CPY001 alone accounts for many, since this repo selects ALL) and mypy 2.x raises 60, mostly stricter implicit-re-export rules. One major per commit, and that is several. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRykabMwPgDzFHcARoqpaK |
||
|---|---|---|
| .. | ||
| docs | ||
| gatelock | ||
| prompts | ||
| .pre-commit-config.yaml | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
gatelock
Shared fullscreen lock-window + HMAC log-integrity backend, extracted from three personal automation tools that each independently implemented "lock the screen with a blocking overlay until a condition is met": diet_guard, wake_alarm, and screen-locker.
Why
All three reimplemented the same tkinter fullscreen mechanics (overrideredirect,
input grab, VT-switch disable) at different levels of maturity, and the
HMAC-signed-state module had already been hand-copied between two of them
because they live in separate repos. gatelock is the one place that logic
now lives.
Install
pip install "gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.1#subdirectory=gatelock"
Usage
import tkinter as tk
from gatelock import GateRoot, LockConfig, LockWindow
class MyGate:
def __init__(self, *, demo_mode: bool) -> None:
self.root = GateRoot()
self.root.on_callback_error = self._handle_callback_error
config = LockConfig(mode="soft" if demo_mode else "hard")
self._lock = LockWindow(self.root, config, hooks=self)
self._lock.setup()
# ... build your widgets ...
self._lock.grab_input()
def on_focus_ready(self) -> None:
self.my_entry.focus_force()
def on_callback_error(self) -> None:
self.close()
def on_close(self) -> None:
... # release any hardware/state held while locked
def close(self) -> None:
self._lock.close()
def run(self) -> None:
self._lock.run()
LockConfig's mode preset bundles the common combination ("soft" = topmost
only, typeable, WM-escapable; "hard" = overrideredirect + global grab +
VT-disable). Each axis (overrideredirect, grab, disable_vt,
grab_retry_ms) can be set explicitly to reproduce a consumer's exact prior
behavior where it diverges from the preset.
gatelock.log_integrity ports the HMAC-signed state module used by all three
projects; DEFAULT_HMAC_KEY_FILE (/etc/workout-locker/hmac.key) is
unchanged so existing signed history keeps verifying.
Development
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest
pre-commit install && pre-commit install --hook-type pre-push