astral-sh/ruff · error

Expected simple statement to be an assert

Error message

Expected simple statement to be an assert

What it means

Internal consistency error in the flake8_pytest_style assertion rewriting helpers. After the enclosing statement list is located (either the module body or an embedded function body), the code destructures it expecting exactly one simple statement, and then expects that statement's small statements to begin with an assert. When the pattern match on Statement::Simple/SmallStatement::Assert fails, this bail fires: the AST shape produced by the caller (composite_condition) does not match the assumed structure of a single assert statement, so no pytest-style assertion transformation can be applied. It signals a bug in the caller's statement extraction rather than a condition the end user can trigger.

Source

Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs:773

        &mut tree.body
    } else {
        let [Statement::Compound(CompoundStatement::FunctionDef(embedding))] = &mut *tree.body
        else {
            bail!("Expected statement to be embedded in a function definition")
        };

        let indented_block = match_indented_block(&mut embedding.body)?;
        indented_block.indent = Some(outer_indent);

        &mut indented_block.body
    };

    let [Statement::Simple(simple_statement_line)] = statements.as_slice() else {
        bail!("Expected one simple statement")
    };

    let [SmallStatement::Assert(assert_statement)] = simple_statement_line.body.as_slice() else {
        bail!("Expected simple statement to be an assert")
    };

    // Extract the individual conditions.
    let mut conditions: Vec<Expression> = Vec::with_capacity(2);
    match &assert_statement.test {
        Expression::UnaryOperation(op) => {
            if matches!(op.operator, libcst_native::UnaryOp::Not { .. }) {
                if let Expression::BooleanOperation(boolean_operation) = &*op.expression {
                    if matches!(boolean_operation.operator, BooleanOp::Or { .. }) {
                        conditions.push(negate(&parenthesize(
                            &boolean_operation.left,
                            &op.expression,
                        )));
                        conditions.push(negate(&parenthesize(
                            &boolean_operation.right,
                            &op.expression,
                        )));
                    } else {

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Check the statement kind before entering the rewrite path
  2. Skip the autofix when the small statement is not an assert
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs:773 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/ed7cc7ebe58eb052. Report an issue: GitHub.