Repository navigation
feat!: Bump openjd-* Rust crates to the openjd-model 0.11.0 release - #375
Merged
leongdl merged 2 commits intoOct 5, 2026
Merged
Conversation
openjd-rs released openjd-expr 0.10.1, openjd-model 0.10.1 and openjd-sessions 0.7.2 on 2026-09-30 (OpenJobDescription/openjd-rs#416), then openjd-model 0.11.0 and openjd-sessions 0.7.3 on 2026-10-03 (#420). This package pinned 0.10.0 / 0.10.0 / 0.7.1. Cargo.lock moves only the three crates; no transitive dependency changed. openjd-sessions has no source change in either release. One public Rust API change breaks compilation: #419 makes template::SimpleAction::script a FormatString. The constructor and the getter of PySimpleAction were the two errors. Following OpenJobDescription#373's capability-name precedent, the Python-facing SimpleAction.script is now an openjd.expr.FormatString in both directions, like its args/timeout siblings and the EmbeddedFile.data it desugars to. The new Rust-side SimpleActionKind / simple_actions / simple_action helpers are not exposed: nothing here consumes them, and step.bash..node already cover introspection. resolve_syntax_sugar changed signature but the bindings never call it. Behaviour changes, each measured through this package's Python API against both pins, with expectations copied from upstream assertions: - #419: bash/python/cmd/powershell/node steps are validated at decode with errors at the authored path (steps[0] -> bash -> args[1]). On 0.10.0, 17 of 21 upstream rejection cases decoded; 9 failed later at create_job at the desugared path, 8 were never rejected. A malformed script now fails at parse (DecodeValidationError). Non-ASCII step names no longer raise PanicException (ASCII-only sanitizer, named in the squash body but not the changelog). - #419, also named only in the squash body: the comprehension-variable check now covers a step script's authored embeddedFiles[].data. A comprehension over a let-bound name in data decoded on 0.10.0 and is now rejected at steps[0] -> script -> embeddedFiles[0] -> data. The same check on command and args is unchanged. v0 agrees on outcome and path in 4/4 cases. - #421: LIST[PATH] defaults must be relative and stay inside the template directory, are joined to it and normalized, element by element; relative submitted PATH / LIST[PATH] values are joined and normalized; defaults are constraint-checked after the join, including environment-template parameters. Absolute submitted values are returned as written. create_job without a preceding preprocess is unchanged (measured, 7 cases identical on both pins). - #410: a job environment's let failure now reads like a step script's ("script let binding 'q': ..."); the missing-extension message lists extensions sorted. - #410/#417/#418: openjd.expr memory accounting; every upstream byte figure reproduces. Some expressions that fit now exceed the limit (coercion to the target type, string slices, attribute base lookups) and some that failed now fit. No existing Python test pinned a moved figure. Unreachable from Python: URI-allowed LIST[PATH] rows (the binding hard-codes allow_uri_path_values=false, create_job_fns.rs:158; upstream test_create_job.rs covers them). The Windows rows of #421 are added as win32-only tests and were not run locally. v0 divergence: v0 preprocess_job_parameters returns LIST[PATH] defaults unjoined and does not normalize submitted '..'. openjd-specifications#191 (Template Schemas 2.2, 2.12) makes v1's behaviour normative. Recorded as two strict xfails in test_known_gaps.py and in the model report; fixing v0 is a separate change. On the #419 decode cases v0 agrees with v1 on outcome in 22/24 and on field path in 16/24; the two outcome differences are v0 rejecting Task.File.<step>_script, which predates this bump. Verified: 6323 passed / 26 skipped / 5 xfailed, coverage 94.22%. The +2 skipped are the Windows-only tests, the +2 xfailed the v0 gaps; no strict xfail flipped. ruff, black, mypy, cargo fmt, build, clippy -D warnings, test and test --doc clean. THIRD-PARTY-LICENSES.txt regenerated (three version lines) and verify mode passes. Mutants, each rebuilt, bytecode cleared, restored by checksum: reverting the pins and the adaptation kills 62 of 79 new or edited cases (the 17 survivors are controls whose behaviour 0.10.0 shares); the getter returning str kills 4; the constructor accepting str kills 4. Not done: the three-auditor review of the new tests (regression-workflow section 3) was not dispatched; the mutation results above are the author's own. TestExtremeSliceSteps pins the #418 overflow fix only in a build with overflow checks; a hatch env install of 0.10.0 already returned the right answer. BREAKING CHANGE: SimpleAction.script is an openjd.expr.FormatString instead of str, and SimpleAction(script=...) requires one. LIST[PATH] defaults must be relative and are joined with the job template directory; relative submitted PATH values are normalized. Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com>
Rust 1.99.0 (stable since 2026-10-01) makes clippy flag clone_on_copy inside pyo3 0.29.2's #[pyclass(from_py_object)] expansion on Copy enums: 13 errors, which fail Rust Quality's clippy -D warnings step on every PR. pyo3 0.29.3 fixes the generated code (PyO3/pyo3#6309). Raise the floor in rust-bindings/Cargo.toml to 0.29.3 so a fresh resolve cannot pick the affected release. THIRD-PARTY-LICENSES.txt regenerated; only the four pyo3 version lines changed. Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com>
mwiebe
approved these changes
Oct 5, 2026
AlexTranAmz
approved these changes
Oct 5, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: n/a (dependency bump for OpenJobDescription/openjd-rs#416 and #420)
What was the problem/requirement? (What/Why)
openjd-rs released openjd-expr 0.10.1, openjd-model 0.10.1 and openjd-sessions 0.7.2 on 2026-09-30 (openjd-rs#416), then openjd-model 0.11.0 and openjd-sessions 0.7.3 on 2026-10-03 (openjd-rs#420). This package pinned 0.10.0 / 0.10.0 / 0.7.1. openjd-sessions has no source change in either release.
One public Rust API change breaks compilation: openjd-rs#419 makes
template::SimpleAction::scriptaFormatString. ThePySimpleActionconstructor and getter were the two errors.What was the solution? (How)
Bump the three pins and adapt the two call sites. Following #373's capability-name precedent, the Python-facing
SimpleAction.scriptis now anopenjd.expr.FormatStringin both directions, matching itsargs/timeoutsiblings and theEmbeddedFile.datait desugars to.The new Rust-side
SimpleActionKind/simple_actions/simple_actionhelpers are not exposed: nothing here consumes them, andstep.bash..step.nodealready cover introspection.resolve_syntax_sugarchanged signature, but the bindings never call it.Cargo.lockmoves only the three crates.THIRD-PARTY-LICENSES.txtwas regenerated withscripts/check_third_party_licenses.sh --updateand changed only the three version lines.pyo3 0.29.2 → 0.29.3 (second commit). Rust 1.99.0, stable since 2026-10-01, makes clippy flag
clone_on_copyinside pyo3 0.29.2's#[pyclass(from_py_object)]expansion on ourCopyenums. That produced 13 errors and failed Rust Quality'sclippy -D warningsstep on every PR, including unrelated dependabot runs. pyo3 0.29.3 fixes the generated code (PyO3/pyo3#6309). The floor inrust-bindings/Cargo.tomlis raised to0.29.3so a fresh resolve cannot pick the affected release. Only the four pyo3 lines inTHIRD-PARTY-LICENSES.txtchanged.What is the impact of this change?
Every behaviour change below was measured through this package's Python API on both the old and new pins, with expectations copied from the upstream tests' assertions rather than their prose.
bash/python/cmd/powershell/nodesteps are validated at decode, with errors at the authored path (steps[0] -> bash -> args[1]). A malformed script now fails at parse (DecodeValidationError). Non-ASCII step names no longer raisePanicException.create_jobat the desugared path, 8 were never rejected.letcheck now covers a step script's authoredembeddedFiles[].data.steps[0] -> script -> embeddedFiles[0] -> data. v0 agrees 4/4.create_jobwithout a preceding preprocess is unchanged (7 cases identical on both pins).letfailure reads like a step script's (script let binding 'q': ...). The missing-extension message lists extensions sorted.openjd.exprmemory accounting. Some expressions that fit now exceed the limit (coercion to the target type, string slices, attribute base lookups) and some that failed now fit.v0 divergence. v0
preprocess_job_parametersreturns LIST[PATH] defaults unjoined and does not normalize a submitted... openjd-specifications#191 (Template Schemas §2.2, §2.12) makes v1's behaviour normative, so v0 is the non-conformant side. Recorded as two strict xfails intest_known_gaps.pyand inreports/model-bindings-quality-evaluation-report.md; fixing v0 is a separate change. On the #419 decode cases v0 agrees with v1 on outcome in 22/24 and on field path in 16/24. The two outcome differences are v0 rejectingTask.File.<step>_script, which predates this bump.How was this change tested?
hatch run test: 6323 passed, 26 skipped, 5 xfailed, coverage 94.22%. The +2 skipped are the Windows-only #421 tests; the +2 xfailed are the v0 gaps above. No strict xfail flipped.hatch run lintandhatch run typingclean.cargo build --all-targets,cargo clippy --all-targets -- -D warnings,cargo testandcargo test --docagainstrust-bindings/clean. License verify mode passes.The pyo3 fix was checked against the toolchain CI uses:
rustup run 1.99.0 cargo clippy --manifest-path rust-bindings/Cargo.toml --all-targets -- -D warningsreports the same 13clone_on_copyerrors as CI with pyo3 0.29.2, and 0 with 0.29.3.New tests:
test/openjd/model_v1/test_parse.py:TestSimpleActionValidation(all 21 upstream rejection rows, 3 caller-limit rows, the brace-mismatch parse failure, controls) and the embedded-filedatacomprehension cases. Full-message assertions at the authored path.test/openjd/model_v1/test_create_job.py: SimpleAction caps, LIST[PATH] defaults, submitted-path normalization, post-join constraints, Windows rows,let-failure messages, sorted missing extensions.test/openjd/model_v1/test_template_types.py:scripttype,strrefusal, pickle.test/openjd/model_v1/test_known_gaps.py: two v0 strict xfails.test/openjd/expr/test_memory.py,test_slicing.py: memory-accounting figures, extreme slice step.Mutation check, each mutant rebuilt from source, bytecode cleared, restored by checksum:
scriptgetter returnsstrstrWhat could NOT be verified
allow_uri_path_values=falseatrust-bindings/src/model/create_job_fns.rs:158. Upstreamtest_create_job.rscovers them.TestExtremeSliceStepspins the openjd-rs#418 overflow fix only in a build with overflow checks.'hello'[1::9223372036854775807]panicked on 0.10.0 only in a dev build; a hatch editable install of 0.10.0 already returnede. Its docstring says so.src/openjd/_openjd_rs.pyiwas hand-edited, becausescripts/generate_stubs.shdoes not run on macOS (precedent ffd3f22). A stub regeneration on Linux should reproduce the edit, but nobody has checked.Was this change documented?
specs/python-model-interface.md:SimpleAction.scriptasFormatString, the SimpleAction decode-validation rules, and the PATH / LIST[PATH] preprocessing rules (including that walk-up also permits absolute defaults).src/openjd/_openjd_rs.pyi: thescripttype onSimpleAction.reports/model-bindings-quality-evaluation-report.md: the v0 PATH divergence.Is this a breaking change?
Yes.
SimpleAction.scriptisopenjd.expr.FormatStringinstead ofstr. A caller reading the template text uses.raw(); a caller constructing one wraps inFormatString(...).Templates that decoded before may now be rejected: SimpleAction steps that only failed at
create_job(or never), embedded-filedatawith a comprehension variable shadowing aletbinding, and LIST[PATH] defaults that are absolute or escape the template directory.Does this change impact security?
In the direction of enforcement. LIST[PATH] defaults can no longer be absolute or escape the template directory unless
allow_job_template_dir_walk_up=True, and defaults are constraint-checked after the join. SimpleAction scripts are validated at decode rather than at job creation.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.