mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-09-04 15:50:43 +02:00
docs: update AGENTS.md to clarify Qt module import rules and threading guidelines
This commit is contained in:
@@ -10,14 +10,16 @@ This file is an agent-oriented operating manual. User-facing documentation lives
|
||||
|
||||
## Core Rules
|
||||
|
||||
- Import Qt modules from `qtpy`, not `PySide6`.
|
||||
- Import Qt modules from `qtpy`, not `PySide6` — CI greps for `from PySide6.` and fails the build;
|
||||
only `PySide6.QtDesigner` and `PySide6.scripts` are exempt.
|
||||
- Do not hand-edit generated RPC or Designer files; regenerate them with `bw-generate-cli`.
|
||||
- If a widget exposes `USER_ACCESS` or is available in Qt Designer, treat its generated CLI and plugin
|
||||
stubs as part of the change.
|
||||
- Inherit `BECWidget` first, then the Qt base class.
|
||||
- Use `MessageEndpoints`, `BECDispatcher`, `SafeSlot`, and existing local widget patterns before
|
||||
introducing a new abstraction.
|
||||
- Do not block the Qt event loop with slow I/O, RPC, or heavy computation.
|
||||
- Do not block the Qt event loop with slow I/O, RPC, or heavy computation. Run slow work off the GUI
|
||||
thread and deliver results back through signals — never touch widgets from another thread.
|
||||
- Clean up dispatcher subscriptions, timers, and long-lived resources in `cleanup()`.
|
||||
- Beamline-specific widgets usually belong in a plugin repository, not core `bec_widgets`.
|
||||
- Keep diffs focused. Avoid unrelated refactors while fixing a specific issue.
|
||||
@@ -153,8 +155,10 @@ Run the smallest relevant test target first. For substantial UI plumbing changes
|
||||
changes, or work that affects many widgets, run the broader affected package suite before finishing.
|
||||
|
||||
Unit tests are the default. CI runs them with `--random-order`, so local validation should do the same
|
||||
when practical. Create widgets with `create_widget(...)` from `tests/unit_tests/conftest.py` so
|
||||
registration and teardown stay consistent. Before adding a new fixture, check for reusable fixtures in
|
||||
when practical. Create widgets with `create_widget(...)` from `tests/unit_tests/conftest.py`. It
|
||||
registers the widget with `qtbot` so it is closed at test end; the autouse conftest fixtures handle the
|
||||
rest of the teardown (dispatcher disconnect, singleton resets) and fail the test if any top-level
|
||||
widget is left open. Before adding a new fixture, check for reusable fixtures in
|
||||
`tests/unit_tests/conftest.py` and helpers in `bec_widgets/tests/utils.py`.
|
||||
|
||||
Mock BEC, Redis, and hardware in unit tests. Reuse existing helpers such as `FakeDevice`,
|
||||
|
||||
@@ -2,32 +2,5 @@
|
||||
|
||||
@AGENTS.md
|
||||
|
||||
The guidelines above are imported from [`AGENTS.md`](AGENTS.md) (single source of
|
||||
truth). The points that matter most in day-to-day work:
|
||||
|
||||
- **Check for `AGENTS_PERSONAL.md` first.** If it exists, it extends `AGENTS.md` with
|
||||
machine-specific environment setup and takes precedence over the generic venv/pip instructions there.
|
||||
It is untracked and personal — never commit it, and never assume it exists.
|
||||
- **Import from `qtpy`, never `PySide6.*`.** CI greps for `from PySide6.` and fails the build (only
|
||||
`PySide6.QtDesigner` and `PySide6.scripts` are exempt).
|
||||
- **`bec_widgets/cli/client.py` and the Designer plugin files are generated — never hand-edit them.**
|
||||
Regenerate with `bw-generate-cli --target bec_widgets` whenever a widget's RPC API changes
|
||||
(`USER_ACCESS` entries or an exposed signature) or a new widget with RPC access or a Qt Designer
|
||||
plugin is added; CI runs the same command and `git diff --exit-code`. For a beamline plugin repo,
|
||||
`--target` is that repository's importable package name (`bw-generate-cli --target my_plugin_repo`).
|
||||
- **Widget pattern**: inherit `BECWidget` first, then the Qt class; declare `USER_ACCESS`; subscribe via
|
||||
`BECDispatcher` + `MessageEndpoints`; decorate slots with `@SafeSlot`; reach BEC through
|
||||
`self.get_bec_shortcuts()`. Disconnect subscriptions and stop timers in `cleanup()`, and never block
|
||||
the Qt event loop.
|
||||
- **Tests**: `python -m pytest --random-order tests/unit_tests/`. Build widgets with
|
||||
`create_widget(qtbot, WidgetClass, ...)` from `tests/unit_tests/conftest.py` so `qtbot` owns teardown;
|
||||
reuse `FakeDevice`/`FakePositioner`/`DMMock` from `bec_widgets/tests/utils.py`. Headless runs need
|
||||
`QT_QPA_PLATFORM=offscreen`.
|
||||
- **Format before finishing**: `black --line-length=100 --skip-magic-trailing-comma .` and
|
||||
`isort --line-length=100 --profile=black --multi-line=3 --trailing-comma .`.
|
||||
- **Beamline-specific widgets belong in a plugin repo**, discovered via the `bec.widgets.user_widgets`
|
||||
entry-point group — not in this repository.
|
||||
- **Do not commit or push unless explicitly asked, and never open a pull request.** If you do commit,
|
||||
write a single Conventional Commits line — it is parsed into the published changelog. Opening the PR
|
||||
is the human's step; leave them the summary, test output, and a screenshot or GIF of any visible GUI
|
||||
change.
|
||||
All guidelines are imported from [`AGENTS.md`](AGENTS.md), the single source of truth — start with
|
||||
its Core Rules and honor the `AGENTS_PERSONAL.md` local overlay if present. Nothing here overrides it.
|
||||
|
||||
Reference in New Issue
Block a user