matchers
matchers ¶
Composable AST matchers for style rules — import this module as M.
Every factory (kind, calls, under, ...) and preset (imports,
control_flow, ...) is a module-level Matcher
builder or constant; author a rule by combining them with &, |, and ~.
Example
from captain_hook.style import matchers as M M.imports & M.child_of(M.control_flow) & ~M.under(M.type_checking)
Matcher
dataclass
¶
A composable, immutable AST matcher: a node predicate that is also a tree selector.
A Matcher wraps a single (node, parents) -> bool test. Node-local matchers
(e.g. calls) ignore parents; structural
matchers (e.g. under) consult it. Compose with
the boolean algebra & (intersection), | (union), and ~ (negation), refine with
where, and finish with a terminal —
over,
violations, or
exists.
The module-level vocabulary (M.imports, M.control_flow, ...) and factories
(M.kind, M.calls, ...) are the whole surface — author a new rule by combining
them, not by reaching for a framework helper.
Example
M.imports & M.child_of(M.control_flow) & ~M.under(M.type_checking)
where ¶
Refine with a node-local one-off predicate — the escape hatch for bespoke conditions.
diff ¶
diff(
pre: AST,
post: AST,
key: Callable[[AST], Hashable] = ast.unparse,
label: str | Callable[[AST], str] | None = None,
) -> Iterator[Violation]
Yield violations for matches in post whose key was absent from pre.
matches ¶
Test a single node (node-local matchers only; raises for structural matchers).
kind ¶
Match any of the given AST node types — the primitive for a category not shipped.
calls ¶
Match a call to the bare-name function name (e.g. calls("zip")).
kwarg ¶
Match a call that passes the keyword argument name (combine with calls).
named ¶
Match a class/function/assignment/parameter whose bound name matches pattern (re.search).
annotated ¶
Match an annotation owner (annotated variable, parameter, or function return).
Excludes *args/**kwargs. When inner is given, the owner's annotation
expression must also match it (e.g. annotated(ref("Any"))).
under ¶
Match a node with any ancestor matching other (negate with ~ for "not inside").
following ¶
Match a body statement that follows the first sibling matching boundary.