Skip to content

Annotate raise_qasm3_error as NoReturn - #416

Open
TheGupta2012 wants to merge 1 commit into
mainfrom
refactor-raise-qasm3-error-noreturn
Open

Annotate raise_qasm3_error as NoReturn#416
TheGupta2012 wants to merge 1 commit into
mainfrom
refactor-raise-qasm3-error-noreturn

Conversation

@TheGupta2012

@TheGupta2012 TheGupta2012 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Problem

raise_qasm3_error always raises — every path through it ends in a raise. But it was annotated -> None, so to mypy and pylint every caller looked like it could fall through and return nothing. Eight suppressions existed only to silence that:

  • # type: ignore[return] on evaluate_expression, _visit_switch_statement, extract_qasm_version, map_qasm_op_to_callable
  • inconsistent-return-statements disables in validator.py, analyzer.py, maps/gates.py, maps/expressions.py

Blanket suppressions do not distinguish a function that provably raises from one that genuinely falls through, so real gaps were sitting behind them.

Change

raise_qasm3_error is annotated NoReturn, and all eight suppressions are removed. mypy and pylint then found the three functions the annotation does not cover.

A valid switch crashed. _visit_switch_statement fell off its last branch when no case matched and no default was declared, returning None into result.extend(...):

int i = 5;
switch (i) {
  case 1 { x q; }
  case 2 { z q; }
}
// TypeError: 'NoneType' object is not iterable

The spec does not require a default, so this is valid and must simply contribute no statements. The redundant not case_fulfilled guard is gone too — the loop returns as soon as a case matches, so reaching that line already means none did.

qasm_variable_type_cast fell off its branch chain rather than reporting an unsupported target type. It now raises a ValidationError naming the type and variable.

validate_return_statement fell off its void branch implicitly. It now returns None explicitly, which also lets the else arm flatten out one level of nesting.

Tests

test_switch_no_match_without_default covers the crash. 803 passed, 3 skipped.

Verified against CI's exact linters (pylint==4.0.7, astroid==4.0.4): pylint exits 0 with no messages, isort and black exit 0, mypy reports only the pre-existing tabulate stub error.

@argus-eye

argus-eye Bot commented Aug 25, 2026

Copy link
Copy Markdown

Argus review

Auto-review is off for this repo. Tick the box below to run a review on this PR.

  • Trigger Argus review

Estimated cost

  • Files changed: 9
  • Diff lines (±): 64
  • Historical avg: ~243.6k tokens · ~$0.95 · across last 10 review(s)

Tip: you can also comment @argus-eye review at any time.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: db187a3c-b282-42f0-bee3-824af2e423f5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

codecov-commenter commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.44444% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pyqasm/maps/expressions.py 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Every path through raise_qasm3_error ends in a raise, but its `-> None`
annotation made each caller look like it could fall through. Eight
`# type: ignore[return]` comments and `inconsistent-return-statements`
suppressions existed only to silence that, and they hid real gaps:

  - `_visit_switch_statement` returned `None` when no case matched and no
    `default` was declared, so a valid switch crashed the caller with
    `TypeError: 'NoneType' object is not iterable`.
  - `qasm_variable_type_cast` fell off its branch chain instead of
    reporting an unsupported target type.
  - `validate_return_statement` fell off its void branch implicitly; it
    now returns None explicitly, which also flattens the else arm.

Both crashes are fixed, and mypy and pylint now check those functions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@TheGupta2012
TheGupta2012 force-pushed the refactor-raise-qasm3-error-noreturn branch from 573de7e to 46743da Compare August 25, 2026 08:31
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.

2 participants