Module

linting.context

LintContext — the single immutable argument passed to every lint rule.

ALintContext carries BOTH the parsed Document AND the raw source string, plus two derived values computed eagerly at construction: the source split into lines and the full document-order sequence of AST nodes. AST-oriented rules readctx.headings()/ ctx.nodes_of_type(...); line-oriented rules read ctx.lines.

Thread Safety:

``LintContext`` is a frozen, slotted dataclass. Its derived state
(``_lines`` and ``_nodes``) is computed once in ``__post_init__`` via
``object.__setattr__`` BEFORE the context is ever shared, so the instance
is fully immutable and race-free thereafter. Safe to share across threads
within a run.

Classes

_NodeCollector 2
Collect every node in document order via a single AST walk. Instantiated fresh per `LintContext` c…
Bases: BaseVisitor[None]

Collect every node in document order via a single AST walk.

Instantiated fresh per LintContext construction (never shared), honoring the BaseVisitor per-call contract. Because BaseVisitor.visit dispatches then walks children, visit_defaultis invoked for every node in document order.

Methods

visit_default 1
Append every visited node (catch-all for all node types).
def visit_default(self, node: Node) -> None
Parameters
Name Type Description
node
Internal Methods 1
__init__ 0
Initialize with an empty accumulator.
def __init__(self) -> None
LintContext 9
Immutable context handed to each rule's ``check`` method.

Immutable context handed to each rule'scheckmethod.

Attributes

Name Type Description
document Document

The parsed AST root.

source str

The raw Markdown source (empty string if unavailable).

source_file str | None

Optional source file path, propagated into diagnostics.

_lines tuple[str, ...]
_nodes tuple[Node, ...]

Methods

lines 0 tuple[str, ...]
Source split on ``"\n"`` (1-indexed line N is ``lines[N - 1]``).
property
def lines(self) -> tuple[str, ...]
Returns
tuple[str, ...]
nodes_of_type 1 tuple[N, ...]
Return all nodes of ``node_type`` in document order. Filters the prebuilt docu…
def nodes_of_type(self, node_type: type[N]) -> tuple[N, ...]

Return all nodes ofnode_typein document order.

Filters the prebuilt document-order node sequence, so rules never spin up their own AST walk.

Parameters
Name Type Description
node_type

The node class to filter for (e.g.Link).

Returns
tuple[N, ...] A tuple of matching nodes in document order.
headings 0 tuple[Heading, ...]
Return all `Heading` nodes in document order. Sugar for ``nodes_of_type(Headin…
def headings(self) -> tuple[Heading, ...]

Return all Heading nodes in document order.

Sugar fornodes_of_type(Heading).

Returns
tuple[Heading, ...] A tuple of headings in document order.
Internal Methods 1
__post_init__ 0
Eagerly compute derived line and node sequences. Uses ``object.__setattr__`` (…
def __post_init__(self) -> None

Eagerly compute derived line and node sequences.

Usesobject.__setattr__(the sanctioned escape hatch for frozen dataclasses) to populate the private slots. Splitting on"\n"— NOTstr.splitlines()— keeps synthesized line numbers in lockstep with the parser, which also counts"\n" boundaries (splitlines over-splits on form-feed/vertical-tab/Unicode separators).