Take the .qp and .wfl format version from the library version - #42
Conversation
Both headers carried a literal 1.0. They now read the installed version, cut to major.minor, so this release writes `#!QProgram 0.2` and `#!WaveformLibrary 0.2`, and the library moves to 0.2.0. The one derivation lives in `qprogram/_version.py`, stdlib-only, which keeps `serialization/_format.py` a leaf the writer and the parser can both import and keeps `waveform_library.py` clear of the serialization package it otherwise imports only inside its methods. The compatibility check is untouched: any minor within the running major loads, a different major does not, so a file from 0.1.x is refused on its major. The suite builds its headers from the running version through `tests/_header.py` rather than pinning one.
AI AnalysisPurpose of the changes:The changes update the test files to use a new header format for QProgram, ensuring consistency across the tests and reflecting updates in the expected program format version.
|
The fallback for a source tree with no installed metadata was excluded from coverage by a trailing pragma. It is tested now, along with the truncation itself, so the pragma goes.
AI Analysis
Purpose of the changes:Add tests for library version handling and improve error handling in version retrieval.
|
|
A file written against an earlier version now loads instead of being refused. A release that changes a syntax registers one rewrite under its own version with `qp.register_migration`, and reading applies every rewrite between the version in the file's header and the running one, oldest first, to the lines in memory; the file on disk is untouched. A release that breaks nothing registers nothing, so an older file with no rewrite behind it loads as it is. A rewrite works line for line and may not add or drop one, which is what keeps a `ParseError`'s line number and every `source_map` entry naming a line of the file its author opened. `.wfl` reads the same way, from its own table, since a program body and a library entry are not the same text. The `require <vendor>` line follows the rule too, against the extension's version instead of the library's, so an extension that renames an operation registers a rewrite with `qp.register_vendor_migration` and the files its users already have keep loading. Both readers now take a version to be exactly `major.minor` and refuse anything above the running one. A newer file used to load when its major matched; nothing runs backwards, so it is refused. A patch or a bare major in a header is refused as well, since a patch release changes code and never the format — the grammar's header terminal already said so, and the hand-written parser now agrees with it. Sits on top of #42.
`towncrier build` renders the fifteen fragments under `changelog/` into a `## 0.2.0` section and deletes them. The version needed no change: #42 already moved it to 0.2.0 mid-cycle, since the format version is derived from it. The rendered entries are then ordered by what a reader needs first rather than by pull request number, so within each heading the changes to how the library is used come before the documentation ones. A paragraph opens the section with the one thing an 0.1.0 user has to know: a file written by that release no longer loads, and files written from here on are carried up by a migration instead.
`towncrier build` renders the fifteen fragments under `changelog/` into a `## 0.2.0` section and deletes them. The version needed no change: #42 already moved it to 0.2.0 mid-cycle, since the format version is derived from it. The rendered entries are then ordered by what a reader needs first rather than by pull request number, so within each heading the changes to how the library is used come before the documentation ones. A paragraph opens the section with the one thing an 0.1.0 user has to know: a file written by that release no longer loads, and files written from here on are carried up by a migration instead.
…the browser wrap the docs (#45) Raises the numpy floor from `>=2.1` to `>=2.3.2`, the oldest release with wheels for every Python the test matrix covers. 2.1 has no 3.14 wheels, and it had aged past the two years of releases the floor is meant to span. xarray stays where it is: 2026.4.0 is the first release that does not trip `filterwarnings = ["error"]` when paired with numpy 2.5. `urls` becomes a `[project.urls]` table with one entry per line and gains a `Changelog` link, and the docs stop restating dependency versions that pyproject.toml already carries. Then the lock file is refreshed. Fifteen packages move, all tooling apart from a numpy patch, the largest being towncrier 25.8.0 to 26.9.0 and ruff 0.16.4 to 0.16.6. The new ruff adds `pytest-fixture-autouse`, which lands on the two fixtures that close a test's figures and empty the registry between tests; both need to run for every test in their file, so the rule joins the `tests/**` ignores. Every paragraph across the site, the README and the changelog becomes one line, since a newline inside a paragraph was never a line break the reader saw and the wrap column had to be held by hand on every edit. Fenced code, headings, tables, list structure, mkdocstrings directives with their YAML options blocks, and the HTML comments the documentation checker reads all keep their own line breaks, and the site renders to the same HTML as before once the whitespace outside a `<pre>` is collapsed. Separately, the Releasing section gains the step that was missing at the end: what happens to the version on `main` after a release, and why the patch moves rather than the minor, the minor being the format version both file headers carry. Finally, `towncrier build` renders the fifteen fragments under `changelog/` into a `## 0.2.0` section and deletes them. The version needed no change, since #42 already moved it to 0.2.0 mid-cycle for the format version to be derived from it. The rendered entries are then ordered by what a reader needs first rather than by pull request number, so within each heading the changes to how the library is used come before the documentation ones, and a paragraph opens the section with the one thing an 0.1.0 user has to know: a file written by that release no longer loads, and files written from here on are carried up by a migration instead.



Both file headers carried a literal
1.0. They now take the installed library version cut tomajor.minor, so this release writes#!QProgram 0.2and#!WaveformLibrary 0.2, and the library itself moves to 0.2.0. The derivation sits in the new stdlib-onlyqprogram/_version.py, which keepsserialization/_format.pya leaf both the writer and the parser can import and keepswaveform_library.pyclear of the serialization package it otherwise touches only inside its methods. The major-only compatibility check is unchanged, so a file written by 0.1.x is now refused on its major. The suite builds its headers from the running version rather than pinning one.