Skip to content

V4.0.0 - #5

Merged
LC-Linkous merged 19 commits into
mainfrom
v4.0.0
Oct 18, 2026
Merged

LC-Linkous merged 19 commits into
mainfrom
v4.0.0

Conversation

@LC-Linkous

Copy link
Copy Markdown
Owner

Summary

tsapython 4.0.0: the library identifies the connected tinySA and refuses what that model cannot do, reports device rejections as errors instead of returning the firmware's text, gates the RF output behind set_output_allowed(True), and adds a 120 s default read timeout. Nothing is renamed or removed; several calls return different values than 3.x (see README "Upgrading to 4.0.0").

Verified on a tinySA Ultra ZS405 running tinySA4_v1.4-252 (and v1.4-143 before the firmware update): probe script 0 differences from the firmware-source reading; pytest -m hardware 19 passed / 1 expected skip; pytest -m hardware_output 5 passed with the output on into a 50 Ω load. Basic and Ultra+ profiles are from the firmware source.

Closes #

Type of change

  • New command / feature
  • Bug fix
  • Docs / examples
  • Test / CI / tooling

Highlights

  • Device profiles (_profiles.py): BASIC, ZS405, ZS406, ZS407; identification at connect via version/info/help; commands, words and ranges the model lacks are refused before sending. select_existing_device() now works; DeviceProfile/PROFILES exported.
  • Reply classification (_identify.py): usage:, name?, usb disk mode active, Command timeout return the error value. get_last_status() reports how the last command ended, so the default b'' return is no longer ambiguous.
  • RF output setting and generator helpers setup_generator() / set_generator(), which pause the sweep around settings and check each step's status.
  • Output-mode firmware behaviour handled: a between-sweeps command sent within ~200 ms of output/modulation/caloutput/leveloffset is dropped by the firmware and answered Command timeout 20 s later. The library settles 0.4 s after those setters, treats Command timeout as end-of-reply, and resends idempotent setters once.
  • Reader hardening: echo required before a prompt is accepted (stale replies discarded); 47-byte command limit (firmware line length); short/timed-out scanraw frames fail instead of returning partial data; sd_read text replies no longer read as a length; connect()/disconnect() release the port.
  • Also: scan_raw_stream() (device-side continuous scan), serial read timeout, firmware floor v1.4-182, DeprecationWarning on the three deprecated aliases, numpy moved to the plotting extra (library depends on pyserial only), Python 3.14 in the matrix.
  • Tests: 669 passed, 98% coverage, ruff + mypy clean. FakePort now flushes on reset and delivers replies in chunks; boundary tests for every reader. hardware and hardware_output markers (the latter also needs TSAPYTHON_OUTPUT_OK=1).
  • CI: Dependabot, CodeQL, weekly run, uv sync --locked, twine check, wheel + sdist install smoke tests, examples compile check; build-release.yml attaches a tag's files to a draft release and release.yml publishes those same files to PyPI. Issue/PR templates updated for 4.0.0.

How it was tested

  • uv run pytest passes (669 passed, 15 skipped, 5 deselected)
  • uv run ruff check . passes
  • uv run mypy passes
  • Real device: uv run pytest -m hardware — 19 passed, 1 skipped (ZS405, tinySA4_v1.4-252-g2b4aa51)
  • TSAPYTHON_OUTPUT_OK=1 uv run pytest -m hardware_output — 5 passed, 50 Ω load on the RF port

Notes for reviewers

CHANGELOG [4.0.0], README "Upgrading to 4.0.0", "Device Profiles", "RF Output Setting", "Firmware Compatibility" and CONTRIBUTING describe the design. Not in this PR: measuring the generator output with a receiver (tests/bench_generator.py is the script for that session) and the web UI's 4.0.0 update, both of which follow the release.

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

d.ser = OneFrame()
frames = list(d.scan_raw_stream(1e8, 2e8, 4, count=1))
assert len(frames) == 1 and d.ser.sent[-1] == "pause"
del acq
Comment thread tsapython/tests/bench_generator.py Fixed
Comment thread tsapython/src/tsapython/core.py Fixed
Comment thread tsapython/src/tsapython/_host.py Outdated
def set_sweep_cw(self, val: "int | float | str") -> "bytearray | None": ...

def pause(self) -> "bytearray | None": ...

Comment thread tsapython/src/tsapython/_commands/output_signal.py Fixed
Comment thread tsapython/src/tsapython/_commands/output_signal.py Fixed
Comment thread tsapython/src/tsapython/_commands/output_signal.py Fixed
Comment thread tsapython/src/tsapython/_commands/output_signal.py Fixed
Comment thread tsapython/src/tsapython/_commands/acquisition.py Fixed
@LC-Linkous
LC-Linkous merged commit d86fe3b into main Oct 18, 2026
37 of 39 checks passed
@LC-Linkous
LC-Linkous deleted the v4.0.0 branch October 18, 2026 20:31
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.

2 participants