Skip to content

Resolve user-stub star re-exports through the active typeshed; fix lost preview-discard intent; path-restrict the Dependabot sweep#350

Merged
abdushakoor12 merged 8 commits into
mainfrom
bug-fixes-101
Jul 24, 2026
Merged

Resolve user-stub star re-exports through the active typeshed; fix lost preview-discard intent; path-restrict the Dependabot sweep#350
abdushakoor12 merged 8 commits into
mainfrom
bug-fixes-101

Conversation

@abdushakoor12

Copy link
Copy Markdown
Collaborator

TLDR

Fixes false imports_module_attribute errors when a user stub star-re-exports from a module owned by the active Typeshed source (the MicroPython uio.pyifrom io import * case, GitHub #312 follow-up), fixes a lost-cancelPreview race in the configuration editor's impact dialog, and makes the Dependabot sweep path-restricted so security-bump sweeps can no longer fail on workflow-file pushes (the failure that stranded #340).

What Was Added?

  • parse_snapshot_stub (crates/basilisk-checker/src/exports.rs): the single producer of a snapshot-backed StubModule, extracted from the cross-module loader closure so the re-export fallback gets the same target-filtered parse.
  • reexported_member_names_with_fallback (crates/basilisk-stubs/src/reexports.rs): like reexported_member_names, but consults a fallback loader for star targets that don't resolve inside the stub's own source root. Local resolution always wins; the fallback never overrides a sibling stub.
  • discardPreview() in the configuration editor webview runtime: every user-initiated dialog dismissal (Cancel button, Escape) posts cancelPreview synchronously with the action.
  • A workflow-file guard in the Dependabot sweep: a bump that itself edits .github/workflows/* is left open with an explanatory comment (the Actions token cannot push workflow files by construction) instead of failing the job.
  • .vscode-test.mjs honours BSK_TEST_GREP so one webview test can be run in isolation.
  • Five integration tests in import_apply_tests.rs and one end-to-end CLI test (see below).
  • linkify-it 5.0.1 → 5.0.2 (transitive dev dependency of @vscode/vsce) in the vscode-extension and website lockfiles.

What Was Changed or Deleted?

  • build_stub_api (crates/basilisk-checker/src/imports/apply.rs) now takes the import search paths and falls back to the active step-3 Typeshed snapshot when a user stub's star target doesn't resolve beside the stub — so uio.pyi containing only from io import * picks up io's members from the custom typeshed's stdlib/ tree instead of producing "Module uio has no attribute StringIO" on every re-exported name.
  • Configuration editor discard reporting: the webview previously told the host a preview was discarded only from the <dialog> close event, which Chromium dispatches on a queued element task — an occluded webview's throttled task queue can drop it, silently losing the discard and leaving the host holding a pending preview. The Cancel/Escape paths now post synchronously; the close listener remains as a guarded, double-post-proof fallback re-armed per preview state.
  • .github/workflows/dependabot-automerge.yml: the sweep no longer git merges the whole bump branch into dependabot-upgrades. It copies exactly the PR's own changed paths (merge-base diff, deletions included) onto the live staging tip. A full merge of a security bump (based on current main) into a drifted staging branch dragged main's workflow-file edits along, and the push was rejected — the workflows scope cannot be granted to GITHUB_TOKEN. Path-copying makes the sweep immune to staging-branch drift while keeping clobber semantics (latest bump of a file wins) and the retry-on-race loop.
  • make_custom_typeshed test helper now emits one VERSIONS line per top-level module, so package stubs (asyncio/__init__.pyi + asyncio/tasks.pyi) can be modelled.

How Do The Automated Tests Prove It Works?

  • user_stub_star_reexport_from_stdlib_stub_is_captured — mirrors micropython-esp32-stubs' uio.pyi verbatim; asserts StringIO/BytesIO land in the captured member API via the snapshot fallback.
  • user_stub_star_reexport_follows_stdlib_package_reexports — the chained uasyncio.pyifrom asyncio import * case; proves the walk keeps resolving the stdlib package's own relative re-exports (from .tasks import *) inside the snapshot.
  • user_stub_star_reexport_honours_stdlib_dunder_all — a stdlib stub's __all__ stays authoritative across the boundary (BytesIO excluded when absent from __all__).
  • user_stub_alias_reexport_from_stdlib_stub_is_captured — the from io import StringIO as StringIO redundant-alias convention crosses the boundary too.
  • user_stub_star_reexport_prefers_sibling_stub_over_snapshot — guard: a sibling machine.pyi in the same stub dir shadows a same-named snapshot module; the snapshot is a fallback, never an override.
  • cli_accepts_user_stub_reexports_from_the_custom_typeshed_stdlib (e2e, real CLI) — the reporter's exact configuration (stub-paths and typeshed-path both at typings/) checks uio.StringIO()/uio.BytesIO() with exit code 0 and no imports_module_attribute.
  • "a dismissed rule preview discards the change and restores the control" (VSIX real-webview DOM test) — previously flaked under full-suite load because the queued close event never fired (instrumentation showed dialog.open flipping with zero close events delivered and no cancelPreview intent reaching the host). The driver now dismisses through the Cancel button exactly as a user would and the test passes deterministically — 793ms vs 5–6s before, since nothing waits on the throttled task queue.
  • The workflow change has no automated test (no harness for Actions runs); the sweep script's path-copy, deletion handling, drift immunity, and workflow-file guard were exercised in a scratch-repo simulation of both a security bump and a github-actions bump.

Spec / Doc Changes

docs/specs/CHECKER-STUB-RESOLUTION-SPEC.md ([STUBRES-PYI-REEXPORTS]): documents local-first star-target resolution with fallback to the active step-3 Typeshed source, recursive resolution within whichever source resolved each target, and sibling-shadowing semantics. The dependabot-automerge workflow's header comments were rewritten to describe the path-restricted sweep and the workflow-file constraint.

Breaking Changes

  • None

dependabot Bot and others added 8 commits July 21, 2026 22:09
…update

Bumps the npm_and_yarn group with 1 update in the /vscode-extension directory: [linkify-it](https://github.com/markdown-it/linkify-it).
Bumps the npm_and_yarn group with 1 update in the /website directory: [linkify-it](https://github.com/markdown-it/linkify-it).


Updates `linkify-it` from 5.0.1 to 5.0.2
- [Changelog](https://github.com/markdown-it/linkify-it/blob/master/CHANGELOG.md)
- [Commits](markdown-it/linkify-it@5.0.1...5.0.2)

Updates `linkify-it` from 5.0.1 to 5.0.2
- [Changelog](https://github.com/markdown-it/linkify-it/blob/master/CHANGELOG.md)
- [Commits](markdown-it/linkify-it@5.0.1...5.0.2)

---
updated-dependencies:
- dependency-name: linkify-it
  dependency-version: 5.0.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: linkify-it
  dependency-version: 5.0.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
A user stub re-exporting from a stdlib stub (MicroPython's uio.pyi is just
`from io import *`, with io in the custom typeshed's stdlib/ tree) produced
false imports_module_attribute errors: the re-export walk only searched the
stub's own source root, so the star target silently resolved to nothing
(GitHub #312 follow-up).

- basilisk-stubs: add reexported_member_names_with_fallback — star targets
  resolve in the stub's own root first, then through a caller-supplied
  fallback; a sibling stub always shadows a same-named fallback module.
- basilisk-checker: hoist the snapshot read+parse inline in
  load_snapshot_stub_module into a shared parse_snapshot_stub, and make
  build_stub_api fall back to the active step-3 typeshed snapshot.
- Tests: flat-module star (uio→io), stdlib-package recursion
  (uasyncio→asyncio→.tasks), stdlib __all__ authority, redundant-alias form,
  sibling-stub precedence, and a CLI e2e mirroring the reporter's exact
  pyproject (stub-paths and typeshed-path both at typings/).
- Spec [STUBRES-PYI-REEXPORTS]: document local-first + snapshot-fallback.

Verified against the reporter's real micropython stub corpus: 24 files,
0 diagnostics — parity with pyright/mypy.
…9dce415db' of github.com:Nimblesite/Basilisk into bug-fixes-101
A full-branch merge of a security bump (based on current main) into a
drifted staging branch dragged main's workflow-file edits along, and the
Actions token can never push .github/workflows/* changes (no workflows
scope, not grantable). PR #340's sweep failed exactly this way and the
PR was left sitting on main.

The sweep now copies only the PR's own changed paths (merge-base diff)
onto the live staging tip, so main's drift never rides along. Bumps that
themselves edit workflow files are left open with a comment for human
review instead of failing.
…log's queued close event

The configuration editor told the host a preview was discarded only from
the <dialog> 'close' event listener. Chromium dispatches that event on a
queued element task, and an occluded webview's throttled task queue may
never run it — the dialog's open flag flips but the discard intent is
silently lost, leaving the host holding a pending preview forever. The
full VSIX suite reproduced this on macOS: the dismissed-rule-preview DOM
test failed whenever earlier suites left the panel occluded.

Every user-initiated discard (Cancel button, Escape) now posts
cancelPreview synchronously through discardPreview(); the close-event
listener stays as a guarded fallback for any other close, re-armed on
each preview state so a fresh preview can always report its own discard.
The DOM test drives the Cancel button exactly as a user would instead of
calling dialog.close() programmatically, and .vscode-test.mjs accepts
BSK_TEST_GREP to run a single webview test in isolation.
CI's Lint job runs stable cargo fmt --check; the new re-export tests
were formatted under nightly rustfmt, whose layout for these two
call expressions differs. Whitespace-only.
cargo-mutants runs with --copy-target true, so each parallel job holds a
full copy of the debug target; on the standard runner's ~14 GB root disk
the shards exhausted space mid-run. The linker died with 'No space left
on device' or SIGBUS, and cargo-mutants recorded those aborted builds as
UNVIABLE — deflating caught (137 -> 121 -> 111 across two runs) and
failing the ratchet gate on mutants that were never actually tested.
Purge the ~25 GB of preinstalled toolchains the job never touches, the
same reclaim the coverage job already does.
# Conflicts:
#	.github/workflows/ci.yml
@abdushakoor12
abdushakoor12 enabled auto-merge (squash) July 24, 2026 17:16
@abdushakoor12
abdushakoor12 merged commit 727cf95 into main Jul 24, 2026
24 checks passed
@abdushakoor12
abdushakoor12 deleted the bug-fixes-101 branch July 24, 2026 17:27
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.

1 participant