Skip to content

[red-knot] Add a diagnostic for raise statements used with non-exceptions #15038

@AlexWaygood

Description

@AlexWaygood

Red-knot currently doesn't emit a diagnostic on this snippet:

raise 42

But we should, since 42 is not a valid object to be used in a raise statement:

>>> raise 42
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    raise 42
TypeError: exceptions must derive from BaseException

The rule is that the object used in a raise statement must have a type that is assignable to the type BaseException | type[BaseException], since both of the following work:

>>> raise ValueError
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    raise ValueError
ValueError
>>> raise ValueError()
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    raise ValueError()
ValueError

We need to add some extra logic to this branch here:

fn infer_raise_statement(&mut self, raise: &ast::StmtRaise) {
let ast::StmtRaise {
range: _,
exc,
cause,
} = raise;
self.infer_optional_expression(exc.as_deref());
self.infer_optional_expression(cause.as_deref());
}

I think this will probably need to be a new rule added to https://github.com/astral-sh/ruff/blob/main/crates/red_knot_python_semantic/src/types/diagnostic.rs ? I don't think it fits neatly into any other rule. The alternative might be to make the existing INVALID_EXCEPTION_CAUGHT rule broader (and rename it).

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedContributions especially welcometyMulti-file analysis & type inference

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions