Skip to content

feat: warn on known trigger-source coercion via capability flags - #176

Merged
little-did-I-know merged 3 commits into
mainfrom
worktree-trigger-quirk-capability-flags
Sep 3, 2026
Merged

little-did-I-know merged 3 commits into
mainfrom
worktree-trigger-quirk-capability-flags

Conversation

@little-did-I-know

Copy link
Copy Markdown
Owner

Description

Pilot for moving known SCPI hardware quirks from comment-only documentation into typed, driver-consumed ModelCapability flags. This PR migrates exactly one quirk: the SDS824X HD's silent trigger-source coercion (EX/EX5 never take, and a disabled channel is coerced to LINE), already measured and documented in trigger.py/scpi_commands.py comments but never acted on by the driver.

Related Issues

Fixes #

Type of Change

  • New feature (non-breaking change adding functionality)

Changes Made

  • Add unreliable_trigger_sources: FrozenSet[str] and warns_on_disabled_trigger_channel: bool to ModelCapability (scpi_control/models.py), populated only for "SDS824X HD" — every other registry entry keeps safe defaults until measured.
  • Wire both flags into Trigger.source's setter (scpi_control/trigger.py): it now logs a logger.warning(...) before writing a trigger source the connected model is known to silently coerce, without changing what gets written to the instrument.
  • Guard the consumer with isinstance(cap, ModelCapability) (not a bare is None/truthy check) so it's a safe no-op against the plain unittest.mock.Mock() scopes used throughout the existing trigger test suite.
  • Wrap the disabled-channel check's live instrument query in a try/except so a query failure degrades to "can't check" rather than blocking the write — this mechanism is advisory only, per the design spec.
  • Update the Trigger.source docstring and docs/user-guide/trigger-control.md to describe the new warning while preserving "read it back" guidance for unmeasured models.
  • CHANGELOG entry (mirrored to docs/about/changelog.md).

Design spec: docs/superpowers/specs/2026-09-02-trigger-quirk-capability-flags-design.md (local, not committed — this repo's docs/superpowers/ convention is untracked working notes).

Testing

  • Tests pass locally (pytest tests/)
  • Added tests for new functionality
  • Tested with real hardware (if applicable)
  • All CI checks pass (black, flake8 on new files, full fast suite)

Test Details

Test environment:

  • OS: Windows 11
  • Python version: 3.9+ (repo floor)
  • Oscilloscope model: N/A (unit tests against mocks; hardware facts encoded here were previously measured on a real SDS824X HD, cited in the code)

Test results:

3011 passed, 61 skipped (pytest -m "not slow" -n 8), up from a 3000-passed baseline (+11 new tests)
black --check --line-length 200 scpi_control/ examples/  ->  clean
flake8 --select=F401 on new test file -> clean

New tests: tests/test_models.py (capability flag defaults/values), tests/test_trigger_coercion_warnings.py (warning fires for EX/EX5/disabled-channel, does not fire for LINE/enabled channel/unflagged models/plain-Mock test doubles), plus a mutation check (verified during development, not committed) proving the new tests fail when the flags are cleared.

Code Quality

  • Code follows the project style guidelines (make lint passes)
  • Code is formatted with Black (make format)
  • Self-reviewed the code
  • Commented complex code sections
  • Updated docstrings for modified functions/classes
  • No new linting warnings introduced

Documentation

  • Updated README.md (if needed)
  • Updated CHANGELOG.md with changes
  • Added/updated docstrings
  • Added/updated examples (if applicable)
  • Updated type hints

Checklist

  • I have read the CONTRIBUTING.md guide
  • My code follows the project's code style
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have made corresponding changes to the documentation

Additional Notes

This is a pilot. If it holds up in review, the same pattern (measured facts on ModelCapability, isinstance-guarded consumer) is intended to extend to three other known quirks that are explicitly out of scope here: code_per_div sharing, the :WAVeform:POINt trap, and the SPD1000X OVP fall-through. A final whole-branch review flagged that those three are behavior-affecting rather than advisory, so the field-naming convention (warns_on_disabled_trigger_channel names the driver's reaction, not the hardware fact) should be revisited before that follow-up work, and ModelCapability's flat field list is worth nesting into a quirks sub-dataclass once a second quirk lands.

https://claude.ai/code/session_01JADNk6BTZoHFRgtSQSfpXe

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
scpi_control/trigger.py 88.23% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@little-did-I-know
little-did-I-know merged commit 1733ea8 into main Sep 3, 2026
30 checks passed
@little-did-I-know
little-did-I-know deleted the worktree-trigger-quirk-capability-flags branch September 3, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant