Core API¶
The core API provides the building blocks for writing rules and using the linter.
Rules¶
The Rule and LineRule base
classes are the foundation for all lint rules. See the Writing custom rules
guide for usage examples.
Base Rule class for Rude linter.
Simple API for rule authors with support for node filtering, configuration, and metadata dependencies.
- class rude.core.rule.LineRule[source]¶
Bases:
RuleBase,ABCBase class for line-based rules.
More efficient than AST rules for pattern matching on raw text. The linter iterates lines once and calls all LineRules, avoiding redundant iteration.
Example:
class NoTodoComments(LineRule): code = "TODO001" message = "TODO comment found" def check_line(self, line: str, lineno: int, ctx: FileContext) -> Iterator[Diagnostic]: if "TODO" in line: col = line.index("TODO") yield self.diagnostic_at(lineno, col)
- uses_line_infos: ClassVar[bool] = False¶
If True, check_line_info is used when pre-computed line metadata is available (from Rust), avoiding per-line decode and regex.
- abstractmethod check_line(line, lineno, ctx, *, comment_pos=-1)[source]¶
Check a single line and yield diagnostics.
- Parameters:
line (
str) – The line content (decoded string, no trailing newline)lineno (
int) – Line number (1-based)ctx (
FileContext) – File context for accessing file-level infocomment_pos (
int) – Position of ‘#’ comment start (-1 if none). Pre-computed by linter, ignores ‘#’ inside strings. Use line[:comment_pos] to get code portion.
- Yields:
Diagnostic objects for any issues found
- Return type:
Iterator[Diagnostic]
- check_line_info(lineno, info, ctx)[source]¶
Fast path using pre-computed line metadata from Rust.
Override this when
uses_line_infos = True. Theinfoargument is aLineInfostruct (frozen pyclass) with named fields:info.leading_spaces (int) info.indent_len (int) info.line_len (int) info.trailing_ws (int) info.comment_start (int, -1 if no comment) info.indent_has_tab (bool) info.indent_has_space (bool) info.is_blank (bool) info.is_in_string (bool) info.spaces_before_comment (int, -1 for block comment) info.char_after_hash (int, ASCII byte or 0) info.leading_hashes (int) info.style_flags (int, bitfield)
style_flags is a u8 bitfield with optimization hints:
bit 0 (0x01): DOUBLE_SPACE_AROUND_OP -- 2+ spaces near operator bit 1 (0x02): TAB_AROUND_OP -- tab near operator bit 2 (0x04): DOUBLE_SPACE_AFTER_COMMA -- 2+ spaces after , or ; bit 3 (0x08): TAB_AFTER_COMMA -- tab after , or ; bit 4 (0x10): DOUBLE_SPACE_AROUND_KW -- 2+ spaces near keyword bit 5 (0x20): TAB_AROUND_KW -- tab near keyword
Flags are hints: false positives OK, false negatives not allowed.
- Parameters:
lineno (
int)info (
LineInfo)ctx (
FileContext)
- Return type:
- class rude.core.rule.Rule[source]¶
Bases:
RuleBase,ABCBase class for linting rules.
Example:
class NoEval(Rule): code = "S001" message = "eval() is a security risk" node_types = {NodeType.CALL} def check(self, node: Node) -> Iterator[Diagnostic]: if node.function_name == "eval": yield self.diagnostic(node)
- node_types: ClassVar[set[NodeType] | None] = None¶
Tree-sitter node types to match. None = all nodes (discouraged).
Types¶
Core data types used throughout the API, including
Diagnostic, FileContext,
and Fix.
Core types for Rude linter.
Defines fundamental data structures: locations, edits, fixes, diagnostics, and file context with metadata provider support.
- class rude.core.types.Diagnostic[source]¶
Bases:
objectA linting diagnostic (error, warning, etc.).
- class rude.core.types.FileContext[source]¶
Bases:
objectContext for linting a single file.
Provides access to source, parsed tree, and metadata providers.
- Parameters:
- classmethod from_analysis(path, source, tree, *, string_lines=None, noqa_map=None, line_infos=None)[source]¶
Create a FileContext with pre-computed analysis results.
- get_metadata(provider_cls)[source]¶
Get metadata from a provider (lazy computed and cached).
- Parameters:
provider_cls (
type[TypeVar(MetadataProviderT, bound=MetadataProvider)])- Return type:
TypeVar(MetadataProviderT, bound=MetadataProvider)
- set_metadata(provider_cls, value)[source]¶
Inject a pre-computed metadata provider into the cache.
- Parameters:
provider_cls (
type[TypeVar(MetadataProviderT, bound=MetadataProvider)])value (
TypeVar(MetadataProviderT, bound=MetadataProvider))
- Return type:
- __init__(path, source, tree, _lines=None, _text=None, _text_lines=None, _string_lines=None, _noqa_map=None, _line_infos=None, _metadata_cache=<factory>)¶
- Parameters:
- Return type:
None
- class rude.core.types.Fix[source]¶
Bases:
objectAutofix for a diagnostic.
Fixes are declarative - rules describe WHAT should change, the linter handles HOW (including import insertion).
- Parameters:
- classmethod replace(node, new_text, *, description=None, imports=None, imports_from=None)[source]¶
Replace a node with new text.
- classmethod insert_before(node, text, *, description=None, imports=None)[source]¶
Insert text before a node.
- classmethod insert_after(node, text, *, description=None, imports=None)[source]¶
Insert text after a node.
- class rude.core.types.FixResult[source]¶
Bases:
objectResult of applying fixes to source.
- Parameters:
source (
str)applied (
tuple[Diagnostic,...])dropped (
tuple[Diagnostic,...])
- __init__(source, applied, dropped)¶
- Parameters:
source (
str)applied (
tuple[Diagnostic,...])dropped (
tuple[Diagnostic,...])
- Return type:
None
- class rude.core.types.Location[source]¶
Bases:
objectSource code location (LSP compatible: line 1-indexed, column 0-indexed).
Node¶
The Node wrapper around tree-sitter nodes, providing
a Pythonic API for AST navigation and inspection. See the
Writing custom rules guide for a quick reference table of all
Node properties and methods.
Ergonomic wrapper around tree-sitter nodes.
Provides a Pythonic API for rule authors with cached properties and semantic helpers for Python constructs.
- class rude.core.node.Node[source]¶
Bases:
_NodeTypeMixinErgonomic wrapper around tree-sitter nodes.
Example:
if node.is_call and node.function_name == "eval": yield self.diagnostic(node)
- Parameters:
node (
TSNode)ctx (
FileContext)
- __init__(node, ctx)[source]¶
- Parameters:
node (
TSNode)ctx (
FileContext)
- Return type:
None
- walk()[source]¶
Depth-first traversal of all descendants using TreeCursor.
Uses tree-sitter’s TreeCursor for efficient navigation without allocating Node wrappers for unvisited children. This reduces memory allocations significantly for large ASTs.
- get_metadata(provider_cls)[source]¶
Shortcut for ctx.get_metadata().
- Parameters:
provider_cls (
type[TypeVar(MetadataProviderT, bound=MetadataProvider)])- Return type:
TypeVar(MetadataProviderT, bound=MetadataProvider)
- property raw: TSNode¶
Underlying tree-sitter node.
- class rude.core.node.NodeLike[source]¶
Bases:
ProtocolProtocol documenting the shared Node/NodeProxy interface.
Both
Node(full tree-sitter wrapper) andNodeProxy(lightweight batch proxy) satisfy this protocol. Rule authors can type-hintNodeLikewhen they need to accept either transparently.- __init__(*args, **kwargs)¶
- class rude.core.node.NodeProxy[source]¶
Bases:
_NodeTypeMixinLightweight proxy that duck-types Node for batch dispatch.
Wraps a frozen
NodeEntrystruct from Rust (3 slots vs 14), exposing fields as properties. Heavy properties (children, parent, etc.) inflate to a full Node on first access – O(log depth).- Parameters:
node_type (
str)entry (
NodeEntry)ctx (
FileContext)
- __init__(node_type, entry, ctx)[source]¶
- Parameters:
node_type (
str)entry (
NodeEntry)ctx (
FileContext)
- Return type:
None
Node Types¶
Named constants for tree-sitter node types, used in rule node_types sets
for IDE autocomplete and typo prevention.
- rude.core.node_types.VALID_NODE_TYPES: frozenset[NodeType] = frozenset({NodeType.ALIASED_IMPORT, NodeType.ARGUMENT_LIST, NodeType.AS_PATTERN, NodeType.AS_PATTERN_TARGET, NodeType.ASSERT_STATEMENT, NodeType.ASSIGNMENT, NodeType.ATTRIBUTE, NodeType.AUGMENTED_ASSIGNMENT, NodeType.AWAIT, NodeType.BINARY_OPERATOR, NodeType.BLOCK, NodeType.BOOLEAN_OPERATOR, NodeType.BREAK_STATEMENT, NodeType.CALL, NodeType.CASE_CLAUSE, NodeType.CASE_PATTERN, NodeType.CHEVRON, NodeType.CLASS_DEFINITION, NodeType.CLASS_PATTERN, NodeType.COMMENT, NodeType.COMPARISON_OPERATOR, NodeType.COMPLEX_PATTERN, NodeType.CONCATENATED_STRING, NodeType.CONDITIONAL_EXPRESSION, NodeType.CONSTRAINED_TYPE, NodeType.CONTINUE_STATEMENT, NodeType.DECORATED_DEFINITION, NodeType.DECORATOR, NodeType.DEFAULT_PARAMETER, NodeType.DELETE_STATEMENT, NodeType.DICT_PATTERN, NodeType.DICTIONARY, NodeType.DICTIONARY_COMPREHENSION, NodeType.DICTIONARY_SPLAT, NodeType.DICTIONARY_SPLAT_PATTERN, NodeType.DOTTED_NAME, NodeType.ELIF_CLAUSE, NodeType.ELLIPSIS, NodeType.ELSE_CLAUSE, NodeType.ESCAPE_INTERPOLATION, NodeType.ESCAPE_SEQUENCE, NodeType.EXCEPT_CLAUSE, NodeType.EXEC_STATEMENT, NodeType.EXPRESSION_LIST, NodeType.EXPRESSION_STATEMENT, NodeType.FALSE, NodeType.FINALLY_CLAUSE, NodeType.FLOAT, NodeType.FOR_IN_CLAUSE, NodeType.FOR_STATEMENT, NodeType.FORMAT_EXPRESSION, NodeType.FORMAT_SPECIFIER, NodeType.FUNCTION_DEFINITION, NodeType.FUTURE_IMPORT_STATEMENT, NodeType.GENERATOR_EXPRESSION, NodeType.GENERIC_TYPE, NodeType.GLOBAL_STATEMENT, NodeType.IDENTIFIER, NodeType.IF_CLAUSE, NodeType.IF_STATEMENT, NodeType.IMPORT_FROM_STATEMENT, NodeType.IMPORT_PREFIX, NodeType.IMPORT_STATEMENT, NodeType.INTEGER, NodeType.INTERPOLATION, NodeType.KEYWORD_ARGUMENT, NodeType.KEYWORD_PATTERN, NodeType.KEYWORD_SEPARATOR, NodeType.LAMBDA, NodeType.LAMBDA_PARAMETERS, NodeType.LINE_CONTINUATION, NodeType.LIST, NodeType.LIST_COMPREHENSION, NodeType.LIST_PATTERN, NodeType.LIST_SPLAT, NodeType.LIST_SPLAT_PATTERN, NodeType.MATCH_STATEMENT, NodeType.MEMBER_TYPE, NodeType.MODULE, NodeType.NAMED_EXPRESSION, NodeType.NONE, NodeType.NONLOCAL_STATEMENT, NodeType.NOT_OPERATOR, NodeType.PAIR, NodeType.PARAMETERS, NodeType.PARENTHESIZED_EXPRESSION, NodeType.PARENTHESIZED_LIST_SPLAT, NodeType.PASS_STATEMENT, NodeType.PATTERN_LIST, NodeType.POSITIONAL_SEPARATOR, NodeType.PRINT_STATEMENT, NodeType.RAISE_STATEMENT, NodeType.RELATIVE_IMPORT, NodeType.RETURN_STATEMENT, NodeType.SET, NodeType.SET_COMPREHENSION, NodeType.SLICE, NodeType.SPLAT_PATTERN, NodeType.SPLAT_TYPE, NodeType.STRING, NodeType.STRING_CONTENT, NodeType.STRING_END, NodeType.STRING_START, NodeType.SUBSCRIPT, NodeType.TRUE, NodeType.TRY_STATEMENT, NodeType.TUPLE, NodeType.TUPLE_PATTERN, NodeType.TYPE, NodeType.TYPE_ALIAS_STATEMENT, NodeType.TYPE_CONVERSION, NodeType.TYPE_PARAMETER, NodeType.TYPED_DEFAULT_PARAMETER, NodeType.TYPED_PARAMETER, NodeType.UNARY_OPERATOR, NodeType.UNION_PATTERN, NodeType.UNION_TYPE, NodeType.WHILE_STATEMENT, NodeType.WILDCARD_IMPORT, NodeType.WITH_CLAUSE, NodeType.WITH_ITEM, NodeType.WITH_STATEMENT, NodeType.YIELD})¶
All named node types from tree-sitter-python’s grammar.
Linter¶
The Linter class is the main entry point for
running rules programmatically. See the Quickstart for CLI
usage and Plugin development for testing rules.
Linter engine - orchestrates rules, file processing, and autofixes.
Default (–jobs=1): single process with Rust rayon parallelism (all CPUs, low memory). With –jobs=N (N>1): N subprocesses for parallel Python rules (higher memory).
- class rude.core.linter.CheckOptions[source]¶
Bases:
objectOptions for parallel checking.
- Parameters:
- class rude.core.linter.Linter[source]¶
Bases:
objectMain linter engine.
Example:
linter = Linter() linter.register(NoEval()) for diag in linter.check_file("src/main.py"): print(diag) # With autofix diagnostics, result = linter.fix_file("src/main.py") if result: Path("src/main.py").write_text(result.source)
- Parameters:
debug (
bool)
- check_paths_parallel(paths, options=None, *, already_resolved=False)[source]¶
Lint paths with parallel execution.
Default (workers=None or 1): Rust rayon in a single Python process. workers > 1: N subprocesses, each running Rust rayon + Python rules.
- Parameters:
- Yields:
(path, diagnostic) tuples
- Return type:
Configuration¶
Handles pyproject.toml parsing and rule selection. See the
Configuration guide for user-facing documentation.
Configuration from pyproject.toml.
- class rude.core.config.Config[source]¶
Rude configuration from [tool.rude].
- Parameters:
- resolve_path(path)[source]¶
Resolve a local-rules path relative to the config file.
Raises ValueError if the resolved path escapes the project root.
- __init__(select=<factory>, ignore=<factory>, plugins=<factory>, local_rules=<factory>, rule_options=<factory>, config_path=None)¶
Parser¶
Tree-sitter parser interface for parsing Python source into syntax trees.
Tree-sitter parser for Python.
- rude.core.parser.parse(source)[source]¶
Parse Python source bytes into a tree-sitter tree.
- Parameters:
source (
bytes)- Return type:
TSTree
Rule Discovery¶
Discovers and loads rules from entry points, local files, and plugins. See Plugin development for the plugin loading mechanism.
Rule discovery from built-in, plugins, and local sources.
File Finder¶
Discovers Python files with .gitignore support and automatic directory
skipping. See Configuration for the file filtering
documentation.
File discovery with gitignore support using fast os.scandir.