Skip to content

Fix except* type inference for BaseException subclasses - #11571

Open
hsusul wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix-except-star-base-exception-subclasses
Open

Fix except* type inference for BaseException subclasses#11571
hsusul wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix-except-star-base-exception-subclasses

Conversation

@hsusul

@hsusul hsusul commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Infer BaseExceptionGroup[T] for except* targets that derive from BaseException but not from Exception.
  • Add regression coverage for built-in, tuple, and custom exception subclasses while preserving ExceptionGroup[T] for ordinary Exception subclasses.

Problem

For an except* KeyboardInterrupt as exc clause, Pyright currently reveals
ExceptionGroup[KeyboardInterrupt]. At runtime, ExceptionGroup can contain
only Exception subclasses, so a group containing KeyboardInterrupt is a
BaseExceptionGroup.

Root cause

The exception-group evaluator selected BaseExceptionGroup only when the
target was exactly the built-in BaseException class. It did not account for
subclasses such as KeyboardInterrupt, SystemExit, or user-defined
BaseException subclasses.

Solution

Use the existing standard-library MRO helper to select BaseExceptionGroup
when any except* target derives from BaseException without also deriving
from Exception. The existing ExceptionGroup behavior remains unchanged for
Exception subclasses.

Tests

  • PYLANCE_JEST_TRANSPILE_ONLY=1 node --max-old-space-size=8192 --expose-gc ./node_modules/jest/bin/jest src/tests/typeEvaluator7.test.ts --runInBand --forceExit -t exceptionGroup1 — passed.
  • PYLANCE_JEST_TRANSPILE_ONLY=1 node --max-old-space-size=8192 --expose-gc ./node_modules/jest/bin/jest src/tests/typeEvaluator7.test.ts --runInBand --forceExit — 165 tests passed.
  • node --max-old-space-size=8192 --expose-gc ./node_modules/jest/bin/jest --forceExit --testPathIgnorePatterns src/tests/benchmarks --runInBand — 62 suites and 2,549 tests passed.

Validation

  • npm run check — syncpack, ESLint, and Prettier passed.
  • npx lerna exec --stream --no-bail -- "tsc --noEmit" — TypeScript passed in all four packages.
  • npm run build:cli:dev — CLI bundle built successfully.
  • npm run build:extension:dev — VS Code extension bundle built successfully.
  • The rebuilt CLI reveals BaseExceptionGroup[KeyboardInterrupt] for the original reproduction and continues to reveal ExceptionGroup[ValueError] for the control case.
  • An initial parallel npm test run completed 61 of 62 suites and timed out in the unrelated language-server background-diagnostics test. All four variants of that test then passed in isolation, and the complete serial suite passed as reported above.

Compatibility and risk

This is an analyzer-only correction for Python 3.11+ except* target
inference. It does not change the public API, diagnostics, parsing, or runtime
behavior. The predicate reuses existing MRO metadata and retains the previous
result for all Exception subclasses.

Documentation

No documentation change is needed because this aligns inferred types with the
existing Python exception-group semantics.

Related issues and prior work

#9467 introduced the ExceptionGroup versus BaseExceptionGroup distinction
for #9466. This change covers the remaining subclass boundary in that logic.
No new issue was created for this focused correction.

@rchiodo

rchiodo commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

🔒 Automated review in progress — @rchiodo is auto-reviewing this PR.

@rchiodo rchiodo 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.

Approved via Review Center.

@rchiodo rchiodo added the review-auto:approved Automated review: no blocking findings (approval posted). label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants