Skip to content

step-narration ​

step-narration reports an own-line numbered-step comment (# 1. ..., # Step 2: ...), because such a comment inside a function body usually stands in for the helper name that step never got, and it leaves the extract-to-helper decision to whoever reads the finding.

Two forms are recognized, the bare numeric-dot form # N. text and the Step-prefixed forms # Step N: text and # Step N. text (with the keyword written Step or step). An inline comment at the end of a code line stays quiet, because it annotates the line rather than narrating a procedure. A pragma comment (# type: ignore, # noqa) stays quiet too, since it carries a different meaning, and a decimal version such as # 1.2 ... matches neither form. The lint fires at every scope (module level, function body, class body, nested block) and never rewrites.

Configuration ​

KeyTypeDefaultMeaning
enabledbooltrueTurns the rule on or off.

The Canonical Case ​

# 1. normalize input and # 2. emit the result sit at module scope above process, outside any function or class body. step-narration reports each one, because the numbered-step form triggers the lint in every scope.

# 1. normalize input
# 2. emit the result


def process(payload):
    return payload.strip()
python

More Examples ​

# 1. normalize whitespace sits on its own line inside process, a digit followed by . and a space. step-narration reports it with a message to extract the step into a named function, and the source is left as written, because the rule is lint-only.

# 1. normalize input sits on its own line inside the body of Processor, ahead of run. step-narration reports it, exactly as it reports a numbered-step comment inside a function, because the match reads the comment's own text and ignores the scope around it.

process narrates its statements with # 1., # 2., and # Step 3: comments on their own lines. step-narration reports one diagnostic per comment rather than one for the run, each diagnostic's range covering its own comment, because the numeric-dot form and the step-word form match independently.

No Change

# 1. normalize input sits between # fmt: off and # fmt: on inside process. step-narration reports nothing on it, because a # fmt: off block suppresses a lint diagnostic the same way it suppresses a rewrite.

No Change

# 1. trim whitespace sits at the end of the cleaned = payload.strip() line rather than on a line of its own. step-narration reports nothing, because the rule reads only a comment that occupies its own line, even though this one's text matches the numbered-step form exactly.

No Change

# noqa: F401, # type: ignore, and # pyright: ignore[reportMissingImports] sit on their own lines at the top of the module. step-narration reports nothing, because a pragma comment is a tool directive and the rule skips it, and the module is left byte for byte as written.

No Change

process carries no comments at all, so step-narration reports nothing and the source is left byte for byte as written, because the rule is lint-only and there is no numbered-step comment to report.

For per-line opt-outs, the Suppression chapter covers the # prose: ignore[step-narration] directive.