Skip to content

Re-enable stub-determinism CI check (issue #2203) - #2246

Merged
cqc-alec merged 3 commits into
Quantinuum:mainfrom
AnitaGeorge404:fix/stubgen-nondeterminism
Sep 25, 2026
Merged

cqc-alec merged 3 commits into
Quantinuum:mainfrom
AnitaGeorge404:fix/stubgen-nondeterminism

Conversation

@AnitaGeorge404

Copy link
Copy Markdown
Contributor

Description

The stub-generation CI check (Check type stubs are up-to-date and run mypy
in .github/workflows/build_and_test.yml) used to fail the build if
regenerating the pytket .pyi stubs produced a diff. When nanobind was
bumped from 2.12.0 to 2.13.0, stub output became non-deterministic, so the
fail-on-diff behaviour was disabled (commented out) and replaced with a
no-op, to keep CI green.

I investigated whether this is still an issue now that the repo is on
nanobind 3.1.0. Using the official pytket==2.18.4 wheel (built from this
exact commit) together with nanobind==3.1.0, I ran
stub_generation/regenerate_stubs repeatedly — 10+ runs, across different
PYTHONHASHSEED values and both Python 3.10 and 3.11 — and the generated
stubs were byte-identical every time. The non-determinism no longer
reproduces.

Since it's no longer reproducible, this PR restores the original
fail-on-diff check and adds a second regeneration pass that diffs against
the first, so CI explicitly re-verifies determinism (not just "matches the
committed stubs") on every run — guarding against a regression of the
original bug.

No source or stub files were changed; this is a CI-workflow-only fix.

Related issues

Fixes #2203

Checklist

  • I have performed a self-review of my code.
  • I have commented hard-to-understand parts of my code.
  • I have made corresponding changes to the public API documentation.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have updated the changelog with any user-facing changes.

The stub-generation CI check was neutered when nanobind 2.13.0
introduced non-deterministic stub output, turning the failure into a
no-op with a comment referencing the issue.

Investigation shows the non-determinism no longer occurs now that the
repo is on nanobind 3.1.0: running ./stub_generation/regenerate_stubs
repeatedly against the built extension produces byte-identical stubs
every time, across multiple runs and PYTHONHASHSEED values.

Restore the original fail-on-diff behaviour, and add a second
regeneration pass that diffs against the first, so CI explicitly
guards against a regression of the reported non-determinism.
The stub-generation CI check was disabled since issue Quantinuum#2203, so the
committed stubs were never re-verified against the nanobind versions
adopted afterwards (2.14.0, 2.15.0, 3.0.0, 3.0.1, 3.1.0). Regenerating
against the currently pinned nanobind 3.1.0 shows circuit.pyi was
stale: the args_wasm parameter of add_wasm/add_wasm_to_reg is rendered
via a types.UnionType[...] expression that needs `import types`,
which nanobind 2.13.0 (when the stub was last regenerated) did not
require.

This brings circuit.pyi back in sync with `./stub_generation/regenerate_stubs`
so the restored CI check in the previous commit actually passes.
Comment thread pytket/pytket/_tket/circuit.pyi
@cqc-alec
cqc-alec merged commit 10a895b into Quantinuum:main Sep 25, 2026
32 checks passed
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.

Non-determinism in stubgen

2 participants