From 0d34f4c9bd213415e9f5591778930cd8b5c3919c Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Tue, 11 Aug 2026 22:01:05 +0900 Subject: [PATCH] Release 1.0.5: pin wirelog to v0.54.0 to fix #180 Move the bundled and validated wirelog ref from v0.53.0 to v0.54.0 at peeled SHA 9f80877c82564cb92ea45bd6fffc2d681b0e13de and bump PyreWire to 1.0.5. v0.54.0 is the first release carrying wirelog#955, which fixes the optimize() head-binding corruption reported in #180: an SIP-inserted semijoin widened the reported output layout by the right relation's arity, shifting every column resolved above it until the out-of-range lookup fell back to column 0. Four body atoms is the threshold because with three there is nothing resolved above the semijoin. Nothing in PyreWire was wrong; optimize() is a faithful passthrough. Keep the runtime minimum at 0.52.0. The public C header change is additive - one appended wirelog_str_fn_t member and documentation - and the SONAME is unchanged, so no PyreWire code stops supporting 0.52.0. The three tests covering behavior only 0.54.0 provides are skipped on older runtimes rather than raising the floor. Two tests pinned engine behavior that v0.54.0 corrects, and both now assert the fixed behavior: - test_insert_arity_mismatch_raises: wirelog#1038 checks the insert width against the .decl on the first insert, so a row wider than the declaration is an error instead of a silent truncation. - test_crc32_checksum_example_partitions_frames_by_stored_checksum: crc32_ethernet() now agrees with the stored CRCs. Expectations are wirelog's own golden output for examples/05-crc32-checksum. --- .github/workflows/ci.yml | 4 +- CHANGELOG.md | 46 +++++++++++++++++++- docs/support.md | 4 +- docs/versioning.md | 1 + pyproject.toml | 10 ++--- src/pyrewire/__init__.py | 2 +- tests/docs/test_support_matrix.py | 4 +- tests/docs/test_versioning_contract.py | 15 ++++++- tests/integration/test_examples.py | 28 +++++++++---- tests/test_batch.py | 58 ++++++++++++++++++++++++++ tests/test_changelog_format.py | 4 +- tests/test_ci_workflow.py | 2 +- tests/test_easy_session.py | 30 ++++++++++--- tests/test_release_metadata.py | 6 +-- 14 files changed, 179 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7d8915..ec79997 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,10 +54,10 @@ jobs: python: ["3.11", "3.12", "3.13", "3.14"] env: # WIRELOG_VERSION here is the exact wirelog ref CI builds against. - # The default is pinned to the wirelog v0.53.0 release commit; + # The default is pinned to the wirelog v0.54.0 release commit; # override the repository variable to test another ref before # updating this fallback. - WIRELOG_VERSION: ${{ vars.WIRELOG_VERSION || '668f82ad69c2bbfc8e8111839302adf1360f55da' }} + WIRELOG_VERSION: ${{ vars.WIRELOG_VERSION || '9f80877c82564cb92ea45bd6fffc2d681b0e13de' }} # `runner.temp` is NOT available in job-level `env:` (only in # step-level contexts) — using it here caused the whole workflow # to fail at startup (#114). `github.workspace` IS resolvable at diff --git a/CHANGELOG.md b/CHANGELOG.md index 6868796..4f41b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,49 @@ wirelog floor and a validated wirelog ref (see ## [Unreleased] +## [1.0.5] - 2026-08-11 + +### Fixed +- `BatchProgram.optimize()` no longer corrupts head bindings for a rule + with four or more body atoms (#180). The engine's SIP-inserted semijoin + widened the reported output layout by the right relation's arity, which + shifted every column resolved above it; the out-of-range lookup fell + back to column 0, so the last head variable came back as `0` while the + row count and arity stayed correct. Fixed upstream in wirelog#955 and + delivered here by the engine bump below. There was nothing to fix in + PyreWire — `optimize()` is a faithful passthrough — so a source install + resolving an older system `libwirelog` is still affected. +- `crc32_ethernet()` now agrees with externally computed CRCs. Through + wirelog 0.53.0 it returned a checksum that matched no stored value, so + `examples/05_crc32_checksum` classified every frame as corrupt. + +### Changed +- The bundled and validated wirelog ref moves from `v0.53.0` to + `v0.54.0` at peeled SHA + `9f80877c82564cb92ea45bd6fffc2d681b0e13de`. +- The minimum compatible runtime wirelog version remains `0.52.0`. + wirelog 0.54.0's public C header change is additive — one appended + `wirelog_str_fn_t` member and documentation — and the library SONAME is + unchanged, so no PyreWire code stops supporting `0.52.0`. The PyreWire + public API is unchanged. Tests covering behavior that only wirelog + `0.54.0` provides are skipped on older runtimes. +- `EasySession.insert()` now raises when the row is wider or narrower + than the relation's `.decl`, on the first insert as well as later ones + (wirelog#1038). Previously a relation's width was whatever its first + producer supplied: too narrow fabricated a zero column, too wide + dropped the surplus, both silently. +- Programs that are heavy on joins may evaluate more slowly. wirelog#955 + removes an under-derivation that the previous speed depended on, so + correct answers cost more than the wrong ones did — upstream measured + DOOP W=1 at ~94 s before and ~1,414 s after. +- `wirelog_program_get_facts`, `wirelog_io_ctx_num_cols`, and + `wirelog_io_ctx_col_type` report the *physical* row stride rather than + the declared column count. The two differ only for a relation declaring + an `inline` compound column. PyreWire passes all three through + unchanged, so its own contract is unaffected; an embedder that + reconstructed the stride from a schema of its own should read wirelog's + release notes. + ## [1.0.4] - 2026-07-31 ### Changed @@ -184,7 +227,8 @@ runtime wirelog version remaining `0.44.0`. wirelog#852. They are available in the later [1.0.0] line, whose validated wirelog ref is v0.50.0. Tracked in wirelog#859. -[Unreleased]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.4...HEAD +[Unreleased]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.5...HEAD +[1.0.5]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.4...v1.0.5 [1.0.4]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.3...v1.0.4 [1.0.3]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.2...v1.0.3 [1.0.2]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.1...v1.0.2 diff --git a/docs/support.md b/docs/support.md index 21f8911..98f3e87 100644 --- a/docs/support.md +++ b/docs/support.md @@ -19,8 +19,8 @@ not need to install wirelog separately. | macOS | `arm64` | `macos-15` | Apple Silicon only for v1.0; no macOS Intel or universal2 wheel is produced. | | Windows | `win_amd64` / `AMD64` | `windows-2025-vs2026` | Built with MSVC and repaired with delvewheel. | -The bundled library is built from wirelog v0.53.0, using peeled SHA -`668f82ad69c2bbfc8e8111839302adf1360f55da`. +The bundled library is built from wirelog v0.54.0, using peeled SHA +`9f80877c82564cb92ea45bd6fffc2d681b0e13de`. ## Source Distributions diff --git a/docs/versioning.md b/docs/versioning.md index c288e62..541310c 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -59,6 +59,7 @@ release to publish; it is **not** tied to the wirelog change. | `1.0.2` | `0.44.0` | `0c6e0cdaee7db069be5d8d896bb59bdcb15673e9` | Validated against wirelog `v0.51.0` (peeled tag SHA); runtime minimum remains `0.44.0`. PyreWire-only maintenance release (CI action bumps, SPDX headers, docs); no engine change. | | `1.0.3` | `0.52.0` | `da82a14a7e1472e33aa6ed753b3bc3dfe28a68ba` | Validated against wirelog `v0.52.0` (peeled tag SHA); runtime minimum raised to `0.52.0`. Bundled engine bumped to v0.52.0 and the loader floor moved up to match. | | `1.0.4` | `0.52.0` | `668f82ad69c2bbfc8e8111839302adf1360f55da` | Validated against wirelog `v0.53.0` (peeled tag SHA); runtime minimum remains `0.52.0`. Bundled engine bumped to v0.53.0 with no public C header or SONAME change. | +| `1.0.5` | `0.52.0` | `9f80877c82564cb92ea45bd6fffc2d681b0e13de` | Validated against wirelog `v0.54.0` (peeled tag SHA); runtime minimum remains `0.52.0`. Bundled engine bumped to v0.54.0 to pick up the wirelog#955 semijoin layout fix (#180); the public C header change is additive and the SONAME is unchanged. | The table grows with every release; the source of truth is the [CHANGELOG](https://github.com/semantic-reasoning/PyreWire/blob/main/CHANGELOG.md). diff --git a/pyproject.toml b/pyproject.toml index 42ce70d..3b8194b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pyrewire" -version = "1.0.4" +version = "1.0.5" description = "Python wrapper for wirelog - declarative dataflow analysis" readme = "README.md" requires-python = ">=3.11" @@ -74,7 +74,7 @@ test-requires = ["pytest", "pytest-cov"] before-build = "python {project}/scripts/bundle_libwirelog.py" # Pin the wirelog source ref here too so the environment matches the # `WIRELOG_VERSION` used by the test-matrix workflow. -environment = { WIRELOG_VERSION = "668f82ad69c2bbfc8e8111839302adf1360f55da" } +environment = { WIRELOG_VERSION = "9f80877c82564cb92ea45bd6fffc2d681b0e13de" } [tool.cibuildwheel.linux] manylinux-x86_64-image = "manylinux_2_28" @@ -83,7 +83,7 @@ before-all = """ pip install meson && \ WIRELOG_PREFIX=/wirelog-install bash {project}/scripts/build_wirelog.sh """ -environment = { WIRELOG_VERSION = "668f82ad69c2bbfc8e8111839302adf1360f55da", WIRELOG_PREFIX = "/wirelog-install", WIRELOG_LIB = "/wirelog-install/lib/libwirelog.so.1", LD_LIBRARY_PATH = "/wirelog-install/lib" } +environment = { WIRELOG_VERSION = "9f80877c82564cb92ea45bd6fffc2d681b0e13de", WIRELOG_PREFIX = "/wirelog-install", WIRELOG_LIB = "/wirelog-install/lib/libwirelog.so.1", LD_LIBRARY_PATH = "/wirelog-install/lib" } # `auditwheel` bundles libwirelog.so.1 into the wheel and patches the # RPATH (#31). Without this every wheel would ship as a manylinux # wheel that immediately fails at import time on systems without the @@ -96,7 +96,7 @@ before-all = """ brew install ninja meson pkg-config && \ WIRELOG_PREFIX=$HOME/wirelog-install bash {project}/scripts/build_wirelog.sh """ -environment = { WIRELOG_VERSION = "668f82ad69c2bbfc8e8111839302adf1360f55da", WIRELOG_PREFIX = "$HOME/wirelog-install", WIRELOG_LIB = "$HOME/wirelog-install/lib/libwirelog.1.dylib", DYLD_LIBRARY_PATH = "$HOME/wirelog-install/lib" } +environment = { WIRELOG_VERSION = "9f80877c82564cb92ea45bd6fffc2d681b0e13de", WIRELOG_PREFIX = "$HOME/wirelog-install", WIRELOG_LIB = "$HOME/wirelog-install/lib/libwirelog.1.dylib", DYLD_LIBRARY_PATH = "$HOME/wirelog-install/lib" } # `delocate` is macOS's auditwheel equivalent — copies the dylib into # the wheel and rewrites install names so the bundled copy wins. repair-wheel-command = "DYLD_LIBRARY_PATH=$HOME/wirelog-install/lib delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}" @@ -104,7 +104,7 @@ repair-wheel-command = "DYLD_LIBRARY_PATH=$HOME/wirelog-install/lib delocate-whe [tool.cibuildwheel.windows] archs = ["AMD64"] before-all = "powershell {project}\\scripts\\build_wirelog.ps1" -environment = { WIRELOG_VERSION = "668f82ad69c2bbfc8e8111839302adf1360f55da", WIRELOG_PREFIX = "C:/wirelog-install", WIRELOG_LIB = "C:/wirelog-install/bin/wirelog-1.dll" } +environment = { WIRELOG_VERSION = "9f80877c82564cb92ea45bd6fffc2d681b0e13de", WIRELOG_PREFIX = "C:/wirelog-install", WIRELOG_LIB = "C:/wirelog-install/bin/wirelog-1.dll" } # `delvewheel` is the Windows analogue. The bundled DLL ends up in # `pyrewire/_lib/` and the loader (#2) finds it ahead of system paths. repair-wheel-command = "pip install delvewheel && delvewheel repair -w {dest_dir} --no-mangle-all --add-path C:/wirelog-install/bin {wheel}" diff --git a/src/pyrewire/__init__.py b/src/pyrewire/__init__.py index dcf6ee4..c12f544 100644 --- a/src/pyrewire/__init__.py +++ b/src/pyrewire/__init__.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later """PyreWire - Python wrapper for wirelog declarative dataflow analysis.""" -__version__ = "1.0.4" +__version__ = "1.0.5" __author__ = "PyreWire Contributors" __license__ = "Apache-2.0 OR GPL-3.0-or-later" diff --git a/tests/docs/test_support_matrix.py b/tests/docs/test_support_matrix.py index 3d97165..768741c 100644 --- a/tests/docs/test_support_matrix.py +++ b/tests/docs/test_support_matrix.py @@ -12,7 +12,7 @@ yaml = pytest.importorskip("yaml") -PINNED_WIRELOG_SHA = "668f82ad69c2bbfc8e8111839302adf1360f55da" +PINNED_WIRELOG_SHA = "9f80877c82564cb92ea45bd6fffc2d681b0e13de" SUPPORTED_PYTHONS = ["3.11", "3.12", "3.13", "3.14"] SUPPORTED_CP_TAGS = ["cp311", "cp312", "cp313", "cp314"] SUPPORTED_RUNNERS = ["ubuntu-24.04", "macos-15", "windows-2025-vs2026"] @@ -122,7 +122,7 @@ def test_support_wirelog_bundle_contract_matches_config_and_versioning(): assert cibw["macos"]["environment"]["WIRELOG_VERSION"] == PINNED_WIRELOG_SHA assert cibw["windows"]["environment"]["WIRELOG_VERSION"] == PINNED_WIRELOG_SHA - assert "wirelog v0.53.0" in support + assert "wirelog v0.54.0" in support assert PINNED_WIRELOG_SHA in support assert "peeled SHA" in support assert "Wheels bundle" in versioning diff --git a/tests/docs/test_versioning_contract.py b/tests/docs/test_versioning_contract.py index 2c2f467..5db12af 100644 --- a/tests/docs/test_versioning_contract.py +++ b/tests/docs/test_versioning_contract.py @@ -12,13 +12,14 @@ yaml = pytest.importorskip("yaml") # The wirelog ref the current release bundles and validates against. -PINNED_WIRELOG_SHA = "668f82ad69c2bbfc8e8111839302adf1360f55da" +PINNED_WIRELOG_SHA = "9f80877c82564cb92ea45bd6fffc2d681b0e13de" # Historical pins kept frozen in the compatibility table, one per release. WIRELOG_SHA_100 = "272edf3a24b25676f12c4b843d55510f5048dd2f" WIRELOG_SHA_101 = "0c6e0cdaee7db069be5d8d896bb59bdcb15673e9" WIRELOG_SHA_102 = WIRELOG_SHA_101 WIRELOG_SHA_103 = "da82a14a7e1472e33aa6ed753b3bc3dfe28a68ba" -WIRELOG_SHA_104 = PINNED_WIRELOG_SHA +WIRELOG_SHA_104 = "668f82ad69c2bbfc8e8111839302adf1360f55da" +WIRELOG_SHA_105 = PINNED_WIRELOG_SHA def _repo_root() -> Path: @@ -76,6 +77,16 @@ def test_versioning_documents_104_wirelog_pin_and_runtime_floor(): assert "peeled tag SHA" in notes +def test_versioning_documents_105_wirelog_pin_and_runtime_floor(): + minimum, validated_ref, notes = _versioning_row("1.0.5") + + assert minimum == "`0.52.0`" + assert validated_ref == f"`{WIRELOG_SHA_105}`" + assert "v0.54.0" in notes + assert "runtime minimum remains `0.52.0`" in notes + assert "peeled tag SHA" in notes + + def test_versioning_explains_sdist_and_wheel_wirelog_behavior(): text = _read("docs/versioning.md") diff --git a/tests/integration/test_examples.py b/tests/integration/test_examples.py index 7a69c39..372a147 100644 --- a/tests/integration/test_examples.py +++ b/tests/integration/test_examples.py @@ -81,17 +81,29 @@ def test_hash_functions_example_validates_stored_checksums() -> None: assert set(out["corrupted_record"]) == {(5, "dave", 1234567890123456789, -8213464378072455284)} -def test_crc32_checksum_example_reports_current_main_head_behavior() -> None: +def test_crc32_checksum_example_partitions_frames_by_stored_checksum() -> None: + """`crc32_ethernet()` agrees with the stored CRCs from wirelog 0.54.0 on. + + Through wirelog 0.53.0 the built-in computed a checksum that matched no + stored value, so every frame landed in `corrupt_frame` and this test + pinned that as "current main head behavior". The expectations below are + wirelog's own golden output for `examples/05-crc32-checksum`, which + became a checked example in 0.54.0. + """ + if _wirelog_ver() < (0, 54, 0): + pytest.skip("crc32_ethernet() matches its stored checksums from wirelog 0.54.0 on") + mod = _import_example("05_crc32_checksum") out = mod.run() - assert out["valid_frame"] == [] + assert set(out["valid_frame"]) == { + ("F001", "DEADBEEF0102030405060708", 3838819244), + ("F002", "CAFEBABE0A0B0C0D0E0F1011", 250819451), + ("F003", "AABBCCDD1213141516171819", 1661565857), + ("F005", "FFEEDDCCBBAA998877665544", 2259087609), + } assert set(out["corrupt_frame"]) == { - ("F001", 3838819244, 2844319735), - ("F002", 250819451, 3954038922), - ("F003", 1661565857, 767742221), - ("F004", 9999999999, 1877464688), - ("F005", 2259087609, 2054014018), - ("F006", 1234567890, 944292671), + ("F004", 9999999999, 2056678491), + ("F006", 1234567890, 1992588221), } diff --git a/tests/test_batch.py b/tests/test_batch.py index 251b4c8..3da0724 100644 --- a/tests/test_batch.py +++ b/tests/test_batch.py @@ -9,6 +9,8 @@ import pytest from pyrewire._core.errors import ExecError +from pyrewire._ffi._loader import _parse_version, _pep440_base +from pyrewire._ffi._util import wirelog_version from pyrewire.batch import BatchProgram, Result # ---------------------------------------------------------------------- @@ -61,6 +63,62 @@ def test_evaluate_without_optimize_is_allowed(): res.close() +# A rule with four or more body atoms lets SIP insert a semijoin with +# something resolved above it. Before wirelog#955 the semijoin widened the +# reported output layout by the right relation's arity, shifting every +# column resolved above it; the out-of-range lookup then fell back to +# column 0, so the last head variable silently came back as 0 (#180). +# +# The corruption is silent — `evaluate()` succeeds and returns the right +# row count and arity — so this compares the optimized result against the +# unoptimized one instead of just asserting evaluation worked. +_SEMIJOIN_LAYOUT_SRC = """ +.decl typ(s: int32, c: int32) +.decl mand(c: int32) +.decl ord(s: int32, o: int32) +.decl rsn(s: int32, r: int32) +.decl out(o: int32, s: int32, r: int32) + +out(O, S, R) :- mand(C), typ(S, C), ord(S, O), rsn(S, R). + +typ(1, 5). +mand(5). +ord(1, 10). +rsn(1, 7). +""" + + +def _semijoin_layout_rows(optimize: bool) -> list[tuple[int, ...]]: + with BatchProgram.from_string(_SEMIJOIN_LAYOUT_SRC) as bp: + if optimize: + bp.optimize() + bp.load_all_facts() + res = bp.evaluate() + try: + return sorted({tuple(int(v) for v in row) for row in res.relation("out")}) + finally: + res.close() + + +def _wirelog_older_than(minimum: tuple[int, int, int]) -> bool: + return _parse_version(_pep440_base(wirelog_version())) < minimum + + +@pytest.mark.skipif( + _wirelog_older_than((0, 54, 0)), + reason=( + "wirelog#955 (the #180 fix) first ships in wirelog 0.54.0; the " + "loader floor still admits 0.52.0, where this corrupts silently." + ), +) +def test_optimize_preserves_head_bindings_with_four_body_atoms(): + """`optimize()` must not change the answer (#180, wirelog#955).""" + optimized = _semijoin_layout_rows(optimize=True) + + assert optimized == _semijoin_layout_rows(optimize=False) + assert optimized == [(10, 1, 7)] + + # ---------------------------------------------------------------------- # Result (#18) # ---------------------------------------------------------------------- diff --git a/tests/test_changelog_format.py b/tests/test_changelog_format.py index 965dfcc..b604d5b 100644 --- a/tests/test_changelog_format.py +++ b/tests/test_changelog_format.py @@ -168,11 +168,11 @@ def test_release_compare_links_are_tag_to_tag(): changelog = (_repo_root() / "CHANGELOG.md").read_text(encoding="utf-8") assert ( - "[Unreleased]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.4...HEAD" + "[Unreleased]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.5...HEAD" in changelog ) assert ( - "[1.0.4]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.3...v1.0.4" + "[1.0.5]: https://github.com/semantic-reasoning/PyreWire/compare/v1.0.4...v1.0.5" in changelog ) assert ( diff --git a/tests/test_ci_workflow.py b/tests/test_ci_workflow.py index d7268bf..0fd25de 100644 --- a/tests/test_ci_workflow.py +++ b/tests/test_ci_workflow.py @@ -24,7 +24,7 @@ def _workflow() -> dict[str, Any]: def test_ci_default_wirelog_version_is_exact_sha(): env = _workflow()["jobs"]["test"]["env"] default = str(env["WIRELOG_VERSION"]) - assert "668f82ad69c2bbfc8e8111839302adf1360f55da" in default + assert "9f80877c82564cb92ea45bd6fffc2d681b0e13de" in default def test_ci_matrix_drops_python_310(): diff --git a/tests/test_easy_session.py b/tests/test_easy_session.py index bddafe9..8fbafbd 100644 --- a/tests/test_easy_session.py +++ b/tests/test_easy_session.py @@ -8,6 +8,9 @@ import pytest from pyrewire import EasySession, ParseError +from pyrewire._core.errors import WirelogError +from pyrewire._ffi._loader import _parse_version, _pep440_base +from pyrewire._ffi._util import wirelog_version _FRIENDSHIP = """ .decl friend(a: symbol, b: symbol) @@ -18,6 +21,10 @@ _EDGE_INT = ".decl edge(x: int32, y: int32)\n" +def _wirelog_older_than(minimum: tuple[int, int, int]) -> bool: + return _parse_version(_pep440_base(wirelog_version())) < minimum + + def test_open_and_close_via_context_manager(): with EasySession(_EDGE_INT) as s: assert s is not None @@ -69,13 +76,24 @@ def test_remove_after_insert(): s.remove("friend", ["alice", "bob"]) -def test_insert_arity_mismatch_does_not_immediately_error(): - """wirelog_easy_insert does not validate arity at insert time; the - error surfaces later (at step/snapshot). Just verify the call - completes without crashing — the strict validation is the - responsibility of higher-level helpers.""" +@pytest.mark.skipif( + _wirelog_older_than((0, 54, 0)), + reason=( + "wirelog#1038 checks the insert width against the `.decl` on the " + "first insert from 0.54.0 on; older builds silently dropped the " + "surplus value, and the loader floor still admits 0.52.0." + ), +) +def test_insert_arity_mismatch_raises(): + """A row wider than the `.decl` is rejected (wirelog#1038). + + Before wirelog 0.54.0 the relation's width was set lazily from + whatever the first producer supplied and nothing compared it against + the declaration, so this insert silently dropped the third value. + """ with EasySession(_EDGE_INT) as s: - s.insert("edge", [1, 2, 3]) # too many values; accepted at this layer + with pytest.raises(WirelogError): + s.insert("edge", [1, 2, 3]) # `edge` declares two columns def test_unsupported_row_value_type_raises(): diff --git a/tests/test_release_metadata.py b/tests/test_release_metadata.py index 571e1df..467141a 100644 --- a/tests/test_release_metadata.py +++ b/tests/test_release_metadata.py @@ -28,9 +28,9 @@ def _runtime_version_literal() -> str: return match.group(1) -def test_project_and_runtime_versions_are_104(): - assert _pyproject()["project"]["version"] == "1.0.4" - assert _runtime_version_literal() == "1.0.4" +def test_project_and_runtime_versions_are_105(): + assert _pyproject()["project"]["version"] == "1.0.5" + assert _runtime_version_literal() == "1.0.5" def test_project_classifiers_mark_stable_python_311_through_314():