Skip to content

Take the .qp and .wfl format version from the library version - #42

Merged
fedonman merged 2 commits into
mainfrom
format-version-from-library
Sep 8, 2026
Merged

Take the .qp and .wfl format version from the library version#42
fedonman merged 2 commits into
mainfrom
format-version-from-library

Conversation

@fedonman

@fedonman fedonman commented Sep 7, 2026

Copy link
Copy Markdown
Member

Both file headers carried a literal 1.0. They now take the installed library version cut to major.minor, so this release writes #!QProgram 0.2 and #!WaveformLibrary 0.2, and the library itself moves to 0.2.0. The derivation sits in the new stdlib-only qprogram/_version.py, which keeps serialization/_format.py a leaf both the writer and the parser can import and keeps waveform_library.py clear 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.

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.
@pullpo-for-slack

Copy link
Copy Markdown

🔗Pullpo.io Slack PR-Channel

@pullpo-for-slack

pullpo-for-slack Bot commented Sep 7, 2026

Copy link
Copy Markdown

AI Analysis

Purpose 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.

Detailed file changes

(dropdown):
  • In file tests/test_parser.py:

    • Replaced hardcoded version strings in test cases with the HEADER constant for consistency.
    • Updated tests to ensure they work with the new QProgram header format.
  • In file tests/test_coverage_gaps.py:

    • Modified test cases to use the HEADER constant instead of hardcoded version strings.
    • Ensured that all instances of the QProgram version are consistent with the new format.
  • In file tests/test_fragments_serialization.py:

    • Updated test cases to use the HEADER constant for the QProgram version.
    • Ensured that fragment tests reflect the new header format.
  • In file docs/reference/qp-format.md:

    • Updated documentation to reflect the new QProgram version format.
    • Replaced all instances of version strings with the new format version to maintain accuracy.

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.
@pullpo-for-slack

Copy link
Copy Markdown

AI Analysis

of the newly committed changes

Purpose of the changes:

Add tests for library version handling and improve error handling in version retrieval.

Improvements and suggestions

(dropdown):
  • In file src/qprogram/_version.py / library_major_minor

Issue:
The exception handling for PackageNotFoundError is not clear as it lacks context for the user.

Suggested solution:
Consider adding a comment or logging to indicate why the exception is handled, improving clarity for future maintainers.

Detailed file changes

(dropdown):
  • In file tests/test_coverage_gaps.py:

    • Added parameterized test for library_major_minor to verify correct truncation of version strings.
    • Created a test to handle cases where the package is not installed, ensuring library_major_minor returns '0.0' in such scenarios.
  • In file src/qprogram/_version.py:

    • Updated exception handling for PackageNotFoundError to simply return '0.0' when the package is not found.

@sonarqubecloud

sonarqubecloud Bot commented Sep 7, 2026

Copy link
Copy Markdown

@flavie-lebars flavie-lebars left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@fedonman
fedonman merged commit 8f740db into main Sep 8, 2026
9 checks passed
@fedonman
fedonman deleted the format-version-from-library branch September 8, 2026 09:15
fedonman added a commit that referenced this pull request Sep 8, 2026
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.
fedonman added a commit that referenced this pull request Sep 8, 2026
`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.
fedonman added a commit that referenced this pull request Sep 8, 2026
`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.
fedonman added a commit that referenced this pull request Sep 8, 2026
…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.
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