Rule & Component Library¶
This section documents the concrete implementations of all rules, selectors, and constraints.
Rule Handlers
Contains concrete implementations of executable validation rules.
This module defines the handler classes for both “short” (pre-defined) and “full” (custom selector/constraint) rules. Each class in this module implements the Rule protocol from definitions.py and encapsulates the logic for a specific type of validation check. The RuleFactory uses these classes to instantiate the correct handler for each rule defined in a JSON file.
- class code_validator.rules_library.basic_rules.CheckLinterRule(config: ShortRuleConfig, console: Console)¶
Handles the ‘check_linter_pep8’ short rule by running flake8.
This rule executes the flake8 linter as an external subprocess on the source code to check for style and common programming errors. It is configurable via the ‘params’ field in the JSON rule.
- execute(tree: Module | None, source_code: str | None = None) bool¶
Executes the flake8 linter on the source code via a subprocess.
It constructs a command-line call to flake8, passing the source code via stdin. This approach ensures isolation and uses flake8’s stable CLI interface.
- Parameters:
tree – Not used by this rule.
source_code – The raw source code string to be linted.
- Returns:
True if no PEP8 violations are found, False otherwise.
- class code_validator.rules_library.basic_rules.CheckSyntaxRule(config: ShortRuleConfig, console: Console)¶
Handles the ‘check_syntax’ short rule.
Note
The actual syntax validation is performed preemptively in the core validator engine when it calls ast.parse(). Therefore, this rule’s execute method will only be called if the syntax is already valid. Its primary purpose is to exist so that a check_syntax rule can be formally defined in the JSON configuration.
- execute(tree: Module | None, source_code: str | None = None) bool¶
Confirms that syntax is valid.
This method is guaranteed to be called only after a successful AST parsing.
- Returns:
Always returns True.
- class code_validator.rules_library.basic_rules.FullRuleHandler(config: FullRuleConfig, selector: Selector, constraint: Constraint, console: Console)¶
Handles a full, custom rule composed of a selector and a constraint.
This class acts as a generic executor for complex rules. It does not contain any specific validation logic itself but instead orchestrates the interaction between a Selector and a Constraint object.
- config¶
The dataclass object holding the rule’s config.
- Type:
- _constraint¶
The constraint object for checking the nodes.
- Type:
- execute(tree: Module | None, source_code: str | None = None) bool¶
Executes the rule by running the selector and applying the constraint.
- Parameters:
tree – The enriched AST of the source code.
source_code – Not used by this rule.
- Returns:
The boolean result of applying the constraint to the selected nodes.
Selectors
Contains concrete implementations of all Selector components.
Each class in this module implements the Selector protocol and is responsible for finding and returning specific types of nodes from an Abstract Syntax Tree. They use ast.walk to traverse the tree and can be constrained to specific scopes via the ScopedSelector base class, which uses the scope_handler. These classes are instantiated by the SelectorFactory.
- class code_validator.rules_library.selector_nodes.AssignmentSelector(**kwargs: Any)¶
Selects assignment nodes (= or := or type-annotated).
This can find assignments to simple variables (x = 5) and attributes (self.player = …).
- JSON Params:
name (str): The full name of the variable or attribute being assigned to.
- select(tree: Module) list[AST]¶
Finds all ast.Assign or ast.AnnAssign nodes matching the target name.
- class code_validator.rules_library.selector_nodes.AstNodeSelector(**kwargs: Any)¶
A generic selector for finding any AST node by its class name.
This is a powerful, low-level selector for advanced use cases.
- JSON Params:
- node_type (str | list[str]): The name(s) of the AST node types to find,
as defined in the ast module (e.g., “For”, “While”, “Try”).
- select(tree: Module) list[AST]¶
Finds all AST nodes that are instances of the specified types.
- class code_validator.rules_library.selector_nodes.ClassDefSelector(**kwargs: Any)¶
Selects class definition (class) nodes from an AST.
- JSON Params:
name (str): The name of the class to find. Use “*” to find all.
- select(tree: Module) list[AST]¶
Finds all ast.ClassDef nodes that match the name criteria.
- class code_validator.rules_library.selector_nodes.FunctionCallSelector(**kwargs: Any)¶
Selects function call nodes from an AST.
This can find simple function calls (my_func()) and method calls (requests.get()).
- JSON Params:
name (str): The full name of the function being called.
- select(tree: Module) list[AST]¶
Finds all ast.Call nodes that match the name criteria.
- class code_validator.rules_library.selector_nodes.FunctionDefSelector(**kwargs: Any)¶
Selects function definition (def) nodes from an AST.
- JSON Params:
name (str): The name of the function to find. Use “*” to find all.
- select(tree: Module) list[AST]¶
Finds all ast.FunctionDef nodes that match the name criteria.
- class code_validator.rules_library.selector_nodes.ImportStatementSelector(**kwargs: Any)¶
Selects import nodes (import or from…import) from an AST.
- JSON Params:
name (str): The name of the module to find (e.g., “os”, “requests”).
- select(tree: Module) list[AST]¶
Finds all import-related nodes that match the name criteria.
- class code_validator.rules_library.selector_nodes.LiteralSelector(**kwargs: Any)¶
Selects literal nodes (e.g., numbers, strings), ignoring docstrings.
- JSON Params:
name (str): The type of literal to find. Supported: “number”, “string”.
- select(tree: Module) list[AST]¶
Finds all ast.Constant nodes that match the type criteria.
This method traverses the given AST (or a sub-tree defined by in_scope) and collects all number or string literals. It contains special logic to intelligently ignore nodes that are likely to be docstrings or parts of f-strings to avoid false positives.
- Parameters:
tree – The root of the AST (the module object) to be searched.
- Returns:
A list of ast.Constant nodes matching the criteria.
- class code_validator.rules_library.selector_nodes.ScopedSelector(**kwargs: Any)¶
An abstract base class for selectors that support scoping.
This class provides a common mechanism for subclasses to narrow their search to a specific part of the AST (e.g., a single function or class) before performing their selection logic.
- in_scope_config¶
The configuration dictionary or string that defines the desired scope.
- Type:
dict | str | None
- select(tree: Module) list[AST]¶
Abstract select method to be implemented by subclasses.
- class code_validator.rules_library.selector_nodes.UsageSelector(**kwargs: Any)¶
Selects nodes where a variable or attribute is used (read).
This finds nodes in a “load” context, meaning the value of the variable is being accessed, not assigned.
- JSON Params:
name (str): The name of the variable or attribute being used.
- select(tree: Module) list[AST]¶
Finds all ast.Name nodes (in load context) matching the name.
Constraints
Contains concrete implementations of all Constraint components.
Each class in this module implements the Constraint protocol and encapsulates the logic for a specific condition that can be checked against a list of AST nodes. These classes are instantiated by the ConstraintFactory based on the “constraint” block in a JSON rule.
The module also includes helper functions for processing AST nodes, which are used internally by the constraint classes.
- class code_validator.rules_library.constraint_logic.IsForbiddenConstraint(**kwargs: Any)¶
Checks that no nodes were found by the selector.
This is the inverse of IsRequiredConstraint and is used to forbid certain constructs, such as specific function calls or imports.
- check(nodes: list[AST]) bool¶
Checks if the list of nodes is empty.
- class code_validator.rules_library.constraint_logic.IsRequiredConstraint(**kwargs: Any)¶
Checks that at least one node was found by the selector.
This constraint is used to enforce the presence of a required language construct. It can also check for an exact number of occurrences.
Supports smart typo detection when no nodes are found - analyzes similar names in the same scope and provides helpful suggestions.
- JSON Params:
- count (int, optional): If provided, checks if the number of found
nodes is exactly equal to this value.
- check(nodes: list[AST]) bool¶
Checks if the list of nodes is not empty or matches expected count.
- check_with_context(nodes: list[AST], target_name: str, scope_config: dict[str, Any] | str, ast_tree: Module, file_path: str, console) tuple[bool, str | None]¶
Enhanced check with typo detection support.
Performs the standard constraint check, and if it fails due to no nodes being found, analyzes potential typos and provides helpful suggestions.
- Parameters:
nodes – List of AST nodes found by the selector
target_name – The name that was being searched for
scope_config – Scope configuration for the search
ast_tree – The complete AST tree for analysis
file_path – Path to the source file
console – Console instance for output
- Returns:
Tuple of (constraint_result, typo_suggestion_message)
- class code_validator.rules_library.constraint_logic.MustBeTypeConstraint(**kwargs: Any)¶
Checks the type of the value in an assignment statement.
It works for simple literals (numbers, strings, lists, etc.) and for calls to built-in type constructors (e.g., list(), dict()).
- JSON Params:
expected_type (str): The name of the type, e.g., “str”, “int”, “list”.
- check(nodes: list[AST]) bool¶
Checks if the assigned value has the expected Python type.
- class code_validator.rules_library.constraint_logic.MustHaveArgsConstraint(**kwargs: Any)¶
Checks that a FunctionDef node has a specific signature.
This constraint can check for an exact number of arguments or for an exact sequence of argument names, ignoring self or cls in methods.
- JSON Params:
count (int, optional): The exact number of arguments required. names (list[str], optional): The exact list of argument names in order. exact_match (bool, optional): Used with names. If False, only checks
for presence, not for exact list match. Defaults to True.
- check(nodes: list[AST]) bool¶
Checks if the function signature matches the criteria.
- class code_validator.rules_library.constraint_logic.MustInheritFromConstraint(**kwargs: Any)¶
Checks that a ClassDef node inherits from a specific parent class.
This constraint is designed to work with a selector that returns a single ast.ClassDef node. It can resolve both simple names (e.g., Exception) and attribute-based names (e.g., arcade.Window).
- JSON Params:
parent_name (str): The expected name of the parent class.
- check(nodes: list[AST]) bool¶
Checks if the found class node inherits from the specified parent.
- class code_validator.rules_library.constraint_logic.NameMustBeInConstraint(**kwargs: Any)¶
Checks if the name of a found node is in an allowed list of names.
This is useful for rules like restricting global variables to a pre-defined set of constants.
- JSON Params:
allowed_names (list[str]): A list of strings containing the allowed names.
- check(nodes: list[AST]) bool¶
Checks if all found node names are in the allowed set.
- class code_validator.rules_library.constraint_logic.ValueMustBeInConstraint(**kwargs: Any)¶
Checks if the value of a found literal node is in an allowed list.
This is primarily used to check for “magic numbers” or “magic strings”, allowing only a specific set of literal values to be present.
- JSON Params:
allowed_values (list): A list of allowed literal values (e.g., [0, 1]).
- check(nodes: list[AST]) bool¶
Checks if all found literal values are in the allowed set.