### Install Natrix using various package managers Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md Instructions on how to install the Natrix tool using common Python package managers like pip, uv, and poetry. Choose the method that best suits your project setup. ```bash pip install natrix ``` ```bash uv add natrix ``` ```bash poetry add natrix ``` -------------------------------- ### Install pre-commit hooks Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md Command to install the pre-commit hooks defined in your project's .pre-commit-config.yaml file, making them active for future commits. ```bash pre-commit install ``` -------------------------------- ### Configure pre-commit hook for Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md YAML configuration for integrating Natrix with pre-commit. This snippet defines a repository and a hook for Natrix, ensuring it runs automatically before each commit. ```yaml repos: - repo: https://github.com/AlbertoCentonze/natrix rev: v0.1.9 # Use the latest version hooks: - id: natrix ``` -------------------------------- ### Minimal Natrix Configuration Example Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md A very basic Natrix configuration demonstrating how to simply disable a rule without any other specific file or path settings. This is useful for quickly getting started or for projects where default settings are mostly sufficient. ```TOML [tool.natrix] disabled_rules = ["NTX7"] ``` -------------------------------- ### Lint a single Vyper contract with Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md Demonstrates how to use Natrix to lint a single Vyper contract file. You can use either the explicit 'lint' subcommand or simply provide the file path directly. ```bash natrix lint path/to/your/contract.vy ``` ```bash natrix path/to/your/contract.vy ``` -------------------------------- ### Generate explicit exports for a Vyper contract using Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md Illustrates how Natrix can generate code snippets to help fix specific issues, such as generating explicit exports for a given Vyper contract file. ```bash natrix codegen exports path/to/your/contract.vy ``` -------------------------------- ### Lint multiple Vyper contracts or a directory with Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/quick-start.md Shows how to apply Natrix linting to multiple Vyper contract files or an entire directory containing contracts. Similar to single file linting, the 'lint' subcommand is optional. ```bash natrix lint path/to/contracts/ ``` ```bash natrix path/to/contracts/ ``` -------------------------------- ### Install Natrix via pip Source: https://github.com/albertocentonze/natrix/blob/main/README.md Instructions to install the Natrix linter using Python's pip package manager. Natrix currently requires `uv` to be installed separately for full functionality. ```bash pip install natrix ``` -------------------------------- ### Vyper Code Examples for Natrix Rule Documentation Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Illustrates how to include non-compliant and compliant Vyper code examples within the rule documentation template. These examples help users understand the rule's application and expected behavior. ```vyper # Non-compliant code ... # Compliant code ... ``` -------------------------------- ### Natrix Configuration Example for Learning Project Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md A simplified Natrix configuration suitable for a learning project. It includes contracts and examples directories for linting, disables rule NTX7, and sets a higher `max_frame_size` of 35000 for the MemoryExpansion rule, potentially allowing for larger contract frames during development. ```TOML [tool.natrix] files = ["contracts/", "examples/"] disabled_rules = ["NTX7"] [tool.natrix.rule_configs.MemoryExpansion] max_frame_size = 35000 ``` -------------------------------- ### Natrix Configuration Example for DeFi Protocol Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md An example `pyproject.toml` configuration tailored for a DeFi protocol project. It specifies core and interface contract directories, adds custom `snekmate` and `vyper-utils` libraries to import paths, disables rule NTX7, and customizes the MemoryExpansion rule with a `max_frame_size` of 15000 and the ArgNamingConvention rule with a specific pattern. ```TOML [tool.natrix] files = ["contracts/core/", "contracts/interfaces/", "tests/unit/"] path = ["lib/snekmate", "lib/vyper-utils"] disabled_rules = ["NTX7"] [tool.natrix.rule_configs.MemoryExpansion] max_frame_size = 15000 [tool.natrix.rule_configs.ArgNamingConvention] pattern = "^_[a-z][a-z0-9_]*$" ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/albertocentonze/natrix/blob/main/README.md Command to install the configured pre-commit hooks in your Git repository. This activates the hooks defined in `pre-commit-config.yaml`, making them run automatically before each commit. ```bash pre-commit install ``` -------------------------------- ### Vyper Argument Naming Convention Examples Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/argument-naming.md Illustrates compliant and non-compliant argument naming in Vyper smart contracts. The `myFunction` shows a non-compliant argument `arg1`, while `anotherFunction` demonstrates compliant arguments starting with an underscore. ```Vyper # Non-compliant - argument 'arg1' does not start with '_' @external def myFunction(arg1: uint256, _arg2: String[10]): pass # Compliant @external def anotherFunction(_input_value: address, _another_param: bool): pass ``` -------------------------------- ### Step-by-Step Example: Enforce Function Naming Rule in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md A comprehensive example demonstrating the creation of a `FunctionNamingRule` that enforces snake_case for function names, including initialization, issue reporting, and handling special cases like interface functions. ```python from natrix.rules.common import BaseRule, RuleRegistry from natrix.ast_node import FunctionDefNode import re @RuleRegistry.register class FunctionNamingRule(BaseRule): """ Enforces function naming conventions. Functions should use snake_case naming. """ CODE = "NTX100" MESSAGE = "Function '{}' should use snake_case naming" def __init__(self, pattern=r"^[a-z_][a-z0-9_]*$"): super().__init__( severity="warning", code=self.CODE, message=self.MESSAGE, ) self.pattern = re.compile(pattern) def visit_FunctionDef(self, node: FunctionDefNode): # Skip interface functions if node.is_from_interface: return function_name = node.get("name") # Skip special functions if function_name.startswith("__"): return if not self.pattern.match(function_name): self.add_issue(node, function_name) ``` -------------------------------- ### Configure Natrix via pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/README.md Example `pyproject.toml` configuration for Natrix, allowing specification of files or directories to lint, additional paths for imports, rules to disable, and rule-specific configurations. This provides project-wide customization for linting behavior. ```toml [tool.natrix] # Files or directories to lint (relative to pyproject.toml) files = ["contracts/", "tests/contracts/"] # Additional paths to search for imports path = ["lib", "vendor/contracts"] # Rules to disable disabled_rules = ["NTX1", "NTX2"] # Rule-specific configurations [tool.natrix.rule_configs.RuleName] param = "value" ``` -------------------------------- ### Basic Node Operations with Node Class Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to create a `Node` object from AST data, safely access its properties using `get()`, and navigate the AST tree by accessing parent and children nodes. ```python from natrix.ast_node import Node # Create a node from AST data node = Node(ast_dict) # Access node properties safely node_type = node.get("ast_type") function_name = node.get("name", default="unknown") # Navigate the AST tree parent = node.parent children = node.children ``` -------------------------------- ### Finding Immediate Children with get_children Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Example demonstrating how to use the `get_children` method of the `Node` class to retrieve immediate child nodes of a specific type. ```python # Get all direct children of a specific type statements = function_node.get_children("Expr") ``` -------------------------------- ### Configure Files and Directories for Natrix Linting Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md These examples illustrate how to define which files or directories Natrix should analyze. You can specify a single file, multiple files and directories, or use relative paths which are resolved from the `pyproject.toml` location. If no `files` are configured, Natrix defaults to scanning the current directory and subdirectories for `.vy` files. ```TOML [tool.natrix] # Single file files = ["contract.vy"] # Multiple files and directories files = ["contracts/", "tests/", "standalone.vy"] # Relative paths are resolved relative to pyproject.toml location files = ["src/contracts/", "../shared/contracts/"] ``` -------------------------------- ### Markdown Template for Natrix Rule Documentation Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Provides a standardized Markdown template for creating new rule documentation files, including sections for rule properties, background, purpose, and code examples. This template ensures consistency across all rule documentation. ```markdown # Rule Name | Property | Value | |----------|-------| | Rule Code | `NTXN` | | Severity | Warning/Style/Optimization/Important | | Configuration | `param_name` - Description (default: value) | ## Background Brief explanation of why this rule exists. ## Purpose What the rule detects or enforces. ## Example ```vyper # Non-compliant code ... # Compliant code ... ``` ## Configuration ### pyproject.toml ```toml [tool.natrix.rule_configs.RuleName] param = "value" ``` ### Command Line ```bash natrix --rule-config RuleName.param=value ``` ``` -------------------------------- ### Vyper Constant Naming Convention Example Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/constant-naming.md This Vyper code snippet illustrates the constant naming convention. It provides an example of a non-compliant constant, `threshold_value`, which does not follow the UPPER_SNAKE_CASE rule. Conversely, it showcases compliant constants, `MAX_VALUE` and `TOTAL_SUPPLY`, that correctly adhere to the `UPPER_SNAKE_CASE` standard. ```vyper # Non-compliant - constant 'threshold_value' is not in UPPER_SNAKE_CASE threshold_value: constant(uint256) = 1000 # Compliant MAX_VALUE: constant(uint256) = 1000 TOTAL_SUPPLY: constant(uint256) = 100000 ``` -------------------------------- ### Checking FunctionDefNode for Constructor Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Example demonstrating how to use the `is_constructor` property of `FunctionDefNode` to identify if a function is a constructor. ```python if func_node.is_constructor: # Handle constructor logic pass ``` -------------------------------- ### Specify Minimum Python Version in pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/docs/development/index.md This TOML configuration snippet defines the minimum required Python version for the Natrix project, ensuring compatibility with Python 3.10 or higher. ```toml requires-python = ">=3.10" ``` -------------------------------- ### Specify Import Paths via Natrix Command Line Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This command-line example shows how to specify additional import paths directly when running Natrix, using the `-p` flag. This achieves the same effect as configuring the `path` option in `pyproject.toml`. ```Bash natrix contract.vy -p lib vendor/contracts ../shared ``` -------------------------------- ### Configure Argument Naming Rule in pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/argument-naming.md Shows how to configure the `ArgumentNaming` rule within `pyproject.toml` to set the `pattern` for argument names. The default pattern `^_` requires arguments to start with an underscore. ```TOML [tool.natrix.rule_configs.ArgumentNaming] pattern = "^_" # Default: Arguments must start with underscore ``` -------------------------------- ### Vyper Function View Decorator Compliance Example Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-view.md This example demonstrates both non-compliant and compliant Vyper functions concerning the `@view` decorator. The `get_balance` function is non-compliant because it reads contract state (`self.user_balance`) but lacks the `@view` modifier. In contrast, `get_balance_view` is compliant as it correctly includes `@view` for a state-reading function. ```vyper # Storage variable user_balance: public(uint256) # Non-compliant - function reads state but isn't marked as @view @external def get_balance() -> uint256: return self.user_balance # Compliant @view @external def get_balance_view() -> uint256: return self.user_balance ``` -------------------------------- ### Vyper Unused Event Detection Example Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/unused-event.md This example demonstrates both non-compliant and compliant Vyper code regarding event usage. The non-compliant section defines an `Approval` event that is never emitted, while the compliant section shows how to properly define and emit both `Transfer` and `Approval` events. ```vyper # Non-compliant code event Transfer: sender: indexed(address) receiver: indexed(address) amount: uint256 event Approval: # This event is never used owner: indexed(address) spender: indexed(address) amount: uint256 @external def transfer(to: address, amount: uint256): # Only Transfer event is emitted log Transfer(msg.sender, to, amount) # Compliant code event Transfer: sender: indexed(address) receiver: indexed(address) amount: uint256 event Approval: owner: indexed(address) spender: indexed(address) amount: uint256 @external def transfer(to: address, amount: uint256): log Transfer(msg.sender, to, amount) @external def approve(spender: address, amount: uint256): log Approval(msg.sender, spender, amount) ``` -------------------------------- ### Finding Ancestor Nodes with get_ancestor Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Examples demonstrating how to use the `get_ancestor` method of the `Node` class to find containing function definitions or any ancestor matching specified types. ```python # Find the containing function containing_function = node.get_ancestor("FunctionDef") # Find any ancestor matching types container = node.get_ancestor(("FunctionDef", "For", "If")) ``` -------------------------------- ### Finding Descendant Nodes with get_descendants Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Examples demonstrating how to use the `get_descendants` method of the `Node` class to find function definitions, nodes with specific properties, and multiple node types within the AST. ```python # Find all function definitions functions = root.get_descendants("FunctionDef") # Find nodes with specific properties assigns = root.get_descendants("Assign", filters={"target.id": "total"}) # Multiple node types control_flow = root.get_descendants(("If", "For", "While")) ``` -------------------------------- ### Safe Property Access with Node.get() Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to safely access simple, nested, and array-indexed properties of a `Node` object using the `get()` method, including the use of default values. ```python # Simple property access line_number = node.get("lineno") # Nested property access target_name = node.get("target.id") decorator_name = node.get("decorator_list.0.id") # With default values node_name = node.get("name", default="anonymous") ``` -------------------------------- ### Configure Argument Naming Rule via Command Line Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/argument-naming.md Demonstrates how to override the default argument naming pattern using the `natrix` command-line interface. This example sets the pattern to enforce snake_case for arguments. ```Bash # Use snake_case for arguments natrix --rule-config ArgumentNaming.pattern="^[a-z_][a-z0-9_]*$" ``` -------------------------------- ### Identifying and Correcting Implicit Internal Functions in Vyper Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-internal.md This snippet demonstrates the NTX3 rule in Vyper. The non-compliant example shows a function that is implicitly internal but lacks the `@internal` decorator. The compliant example explicitly marks the internal function, improving code clarity as per Vyper 0.4.0 guidelines. ```vyper # Non-compliant - function is internal but not marked with @internal def helper_function(x: uint256) -> uint256: return x * 2 # Compliant @internal def _helper_function(x: uint256) -> uint256: return x * 2 ``` -------------------------------- ### Checking FunctionDefNode for Interface Function Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Example demonstrating how to use the `is_from_interface` property of `FunctionDefNode` to determine if a function originates from an interface definition. ```python if func_node.is_from_interface: # Skip interface functions return ``` -------------------------------- ### Vyper Compliant Explicit Export of Functions Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-export.md This Vyper example demonstrates the compliant way to export functions by explicitly listing them (`erc20.transfer`, `erc20.mint`). This approach clearly defines the contract's public interface, preventing accidental exposure of internal logic and improving readability. ```vyper # my_token.vy import erc20 # Compliant - explicitly lists the functions to be exposed exports: (erc20.transfer, erc20.mint) # you can clearly tell that you are exposing a function to mint ``` -------------------------------- ### Vyper ERC20 Contract Example with External Functions Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-export.md This Vyper code defines a simple ERC20-like contract with two external functions, `transfer` and `mint`, demonstrating typical public interface methods that might be imported by other contracts. ```vyper # erc20 @external def transfer(): # ... does something ... pass @external def mint(): # ... does something else ... pass ``` -------------------------------- ### Vyper Function Modifier Ordering Examples Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/modifiers-ordering.md Illustrates the recommended and non-compliant ordering of function decorators in Vyper. The rule suggests placing visibility decorators first (@external, @internal, @deploy), followed by mutability decorators (@pure, @view, @nonpayable, @payable), and finally security decorators (@nonreentrant, @reentrant). ```vyper # Non-compliant - incorrect ordering @view @external # visibility should come before mutability def get_balance() -> uint256: return self.balance @nonreentrant @external # visibility should come before security @payable def deposit(): self.balance += msg.value # Compliant - correct ordering @external # visibility first @view # mutability second def get_balance_correct() -> uint256: return self.balance @external # visibility first @payable # mutability second @nonreentrant # security last def deposit_correct(): self.balance += msg.value # Functions without explicit visibility (defaults to internal) # Non-compliant @nonreentrant @view # mutability should come before security def internal_func() -> uint256: return self.balance # Compliant @view # mutability first @nonreentrant # security second def internal_func_correct() -> uint256: return self.balance ``` -------------------------------- ### Identifying and Resolving Unused Imports in Vyper Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/unused-imports.md This example demonstrates both non-compliant and compliant Vyper code regarding import statements. The non-compliant section shows imports that are declared but never used, triggering a warning. The compliant section illustrates how to correctly use an imported interface, ensuring the import serves a purpose within the contract. ```vyper # Non-compliant code from ethereum.ercs import IERC20 # Warning: Import 'IERC20' is not used from ethereum.ercs import IERC721 # Warning: Import 'IERC721' is not used counter: uint256 @external def increment(): self.counter += 1 # Compliant code from ethereum.ercs import IERC20 token: IERC20 @external def set_token(addr: address): self.token = IERC20(addr) ``` -------------------------------- ### Globally Disable Specific Natrix Linting Rules Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md These examples demonstrate how to disable one or more specific Natrix rules across your entire project. Rules are identified by their codes (e.g., 'NTX8', 'NTX1', 'NTX7', 'NTX11'). This is useful for ignoring certain checks that may not be relevant to your project's requirements. ```TOML [tool.natrix] # Disable single rule disabled_rules = ["NTX8"] # Disable multiple rules disabled_rules = ["NTX1", "NTX7", "NTX11"] ``` -------------------------------- ### Vyper Function Purity Rule Example: Missing vs. Compliant @pure Decorator Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-pure.md This Vyper code snippet illustrates the `NTX5` rule. The first function, `calculate_sum`, is non-compliant because it performs a pure calculation (addition) without accessing contract state, yet it lacks the `@pure` decorator. The second function, `calculate_sum_pure`, is compliant as it performs the same pure calculation and correctly includes the `@pure` decorator, adhering to the recommended style for functions that do not interact with state. ```vyper # Non-compliant - function doesn't access state but isn't marked as @pure @external def calculate_sum(_a: uint256, _b: uint256) -> uint256: return _a + _b # Compliant @pure @external def calculate_sum_pure(_a: uint256, _b: uint256) -> uint256: return _a + _b ``` -------------------------------- ### Vyper Example: Identifying and Fixing Unused Function Arguments Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/unused-argument.md This Vyper code snippet demonstrates the `NTX10` rule for detecting unused function arguments. The `process` function is non-compliant as its `_unused` argument is declared but never referenced, indicating a potential issue. In contrast, the `process_fixed` function is compliant because all its arguments (`_value` and `_modifier`) are actively used within the function body, illustrating best practices for argument usage. ```vyper # Non-compliant - argument '_unused' is never used in the function @external def process(_value: uint256, _unused: address) -> uint256: return _value * 2 # Compliant - all arguments are used @external def process_fixed(_value: uint256, _modifier: uint256) -> uint256: return _value * _modifier ``` -------------------------------- ### Handling Intentionally Unused Loop Variables in Vyper Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/unused-variable.md This example illustrates how to manage loop variables that are intentionally unused to avoid linter warnings. The `repeat_operation` function is non-compliant because its loop variable `i` is declared but not used. The `repeat_operation_fixed` function demonstrates the compliant approach by using an underscore (`_`) as the loop variable name, signaling that it is intentionally unused and preventing false positive warnings. ```vyper @external def repeat_operation(count: uint256): # Non-compliant - 'i' is declared but never used for i: uint256 in range(count): # Some operation that doesn't use 'i' pass @external def repeat_operation_fixed(count: uint256): # Compliant - using '_' indicates intentionally unused variable for _: uint256 in range(count): # Some operation that doesn't use the loop variable pass ``` -------------------------------- ### Bash Command to Build MkDocs Documentation Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Provides the command-line instruction to build the MkDocs documentation. Running this command verifies that all documentation changes are correctly processed and the site can be generated without errors. ```bash mkdocs build ``` -------------------------------- ### Natrix Command Line Interface Options Source: https://github.com/albertocentonze/natrix/blob/main/README.md A comprehensive list of command-line options available for Natrix, including displaying help, checking the version, listing available rules, disabling specific rules, configuring rule parameters, and adding extra import paths. ```bash natrix --help natrix --version natrix lint --list-rules natrix lint --disable NTX1 NTX2 natrix lint --rule-config RuleName.param=value natrix lint -p /path/to/libs /another/path natrix codegen exports contract.vy ``` -------------------------------- ### Analyze Vyper Contract Annotated AST Source: https://github.com/albertocentonze/natrix/blob/main/CLAUDE.md This command-line utility helps in analyzing Vyper smart contracts by outputting their annotated abstract syntax tree (AST). It is particularly useful for understanding contract structure, identifying patterns, and planning implementation details during rule development or debugging. ```Shell vyper -f annotated_ast path/to/contract.vy ``` -------------------------------- ### YAML Configuration for MkDocs Navigation Update Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Illustrates how to add a new rule entry to the `mkdocs.yml` navigation structure under the 'Rules' section. This ensures the new rule documentation is accessible through the site's navigation. ```yaml nav: - Rules: - Rule Name (NTXN): rules/rule-name.md ``` -------------------------------- ### Bash Command Line Configuration for Natrix Rule Parameters Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Demonstrates how to configure Natrix rule parameters directly via the command line using the `natrix --rule-config` option. This provides a flexible way to override configurations for specific runs. ```bash natrix --rule-config RuleName.param=value ``` -------------------------------- ### Natrix Core Architecture and Output Formats Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Overview of Natrix's core architecture, including its AST processing pipeline steps (Vyper Compilation, Node Wrapping, Rule Application, Issue Collection) and supported output formats (CLI and JSON). JSON output is recommended for programmatic integration. ```APIDOC Core Architecture: AST Processing Pipeline: 1. Vyper Compilation: Compile .vy files to annotated AST 2. Node Wrapping: Wrap raw AST in Node objects for easy traversal 3. Rule Application: Apply registered rules using the visitor pattern 4. Issue Collection: Gather and format rule violations Output Formats: - CLI Output: Colored terminal output with source code snippets (default) - JSON Output: Machine-readable format for programmatic integration (enabled with --json flag) Returns an array of issue objects suitable for IDE integration, CI/CD pipelines, or other automated tools. ``` -------------------------------- ### Define Configurable Natrix Rules in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Shows how to create a rule that accepts configuration parameters through its `__init__` method, allowing for flexible rule behavior based on external settings like thresholds or patterns. ```python class ConfigurableRule(BaseRule): def __init__(self, threshold=100, pattern="^_"): super().__init__() self.threshold = threshold self.pattern = re.compile(pattern) ``` -------------------------------- ### List All Available Natrix Rule Codes Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This command allows you to view all the available rule codes that Natrix provides. This is helpful for identifying which rules can be disabled or configured. ```Bash natrix --list-rules ``` -------------------------------- ### TOML Configuration for Natrix Rule Parameters in pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/docs/CONTRIBUTING.md Shows how to configure Natrix rule parameters within the `pyproject.toml` file using the `tool.natrix.rule_configs` section. This method allows for project-wide rule configuration. ```toml [tool.natrix.rule_configs.RuleName] param = "value" ``` -------------------------------- ### Utilize Natrix AST Tools for Vyper Compilation in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to use `parse_file` to convert a Vyper file into an AST and `vyper_compile` to compile Vyper code into different formats like annotated AST or metadata. ```python from natrix.ast_tools import parse_file, vyper_compile, VyperASTVisitor # Parse a Vyper file to AST ast_data = parse_file("contract.vy") root_node = Node(ast_data) # Compile with specific format ast_only = vyper_compile("contract.vy", "annotated_ast") metadata = vyper_compile("contract.vy", "metadata") ``` -------------------------------- ### Natrix Basic Configuration in pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This snippet demonstrates the fundamental structure for configuring Natrix within your `pyproject.toml` file. It covers specifying files or directories to lint, globally disabling specific rules, adding custom import paths, and setting up rule-specific configurations like `max_frame_size` for MemoryExpansion and `pattern` for ArgNamingConvention. ```TOML [tool.natrix] # Files or directories to lint (relative to pyproject.toml location) files = ["contracts/", "tests/contracts/"] # Rules to disable globally disabled_rules = ["NTX1", "NTX2"] # Additional paths to search for imports path = ["lib", "vendor/contracts"] # Rule-specific configurations [tool.natrix.rule_configs.MemoryExpansion] max_frame_size = 25000 [tool.natrix.rule_configs.ArgNamingConvention] pattern = "^_[a-z][a-z0-9_]*$" ``` -------------------------------- ### Implement AST Visitor Methods in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to create a custom rule class inheriting from `BaseRule` and implement `visit_` methods for specific AST node types like `FunctionDef`, `Assign`, and `Name` to process the Abstract Syntax Tree. ```python class MyRule(BaseRule): def visit_FunctionDef(self, node): """Called for every function definition""" if self._should_flag(node): self.add_issue(node, "Function violates rule") def visit_Assign(self, node): """Called for every assignment""" pass def visit_Name(self, node): """Called for every name reference""" pass ``` -------------------------------- ### Natrix VyperASTVisitor API Reference Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Documents the `VyperASTVisitor` base class for traversing Vyper AST nodes, showing how to extend it with `visit_` methods and use it to process an AST. ```APIDOC class MyVisitor(VyperASTVisitor): def visit_FunctionDef(self, node): print(f"Found function: {node.get('name')}") def visit_Assign(self, node): print(f"Assignment at line {node.get('lineno')}") # Usage: visitor = MyVisitor() visitor.visit(root_node) ``` -------------------------------- ### Defining a Custom Rule with BaseRule Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Illustrates how to define a custom rule by inheriting from `BaseRule`, registering it with `RuleRegistry`, and initializing it with a unique code, message, severity, and custom parameters. ```python from natrix.rules.common import BaseRule, RuleRegistry from natrix.ast_node import Node @RuleRegistry.register class MyRule(BaseRule): CODE = "NTX999" # Unique rule identifier MESSAGE = "Following pattern is not allowed: {}" # Format string for messages def __init__(self, custom_param="default"): super().__init__( severity="warning", # "error", "warning", "info" code=self.CODE, message=self.MESSAGE, ) self.custom_param = custom_param ``` -------------------------------- ### Integrate Natrix as a Pre-commit Hook Source: https://github.com/albertocentonze/natrix/blob/main/README.md Configuration snippet for `pre-commit-config.yaml` to integrate Natrix as a pre-commit hook. This ensures that Vyper contracts are automatically checked for issues before a commit is finalized, enforcing code quality. ```yaml repos: - repo: https://github.com/albertocentonze/natrix rev: v0.1.9 # Use the latest version hooks: - id: natrix ``` -------------------------------- ### Register Natrix Rules using Decorator in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Presents the recommended approach for rule registration using the `@RuleRegistry.register` decorator directly above the rule class definition. ```python @RuleRegistry.register # Recommended approach class MyRule(BaseRule): pass ``` -------------------------------- ### Specify Additional Import Paths for Vyper Compiler in Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This configuration allows you to specify additional directories where the Vyper compiler, used by Natrix, should look for imported modules. Paths can be single or multiple, and are resolved relative to the `pyproject.toml` file. These paths are added to the default system and `lib/pypi` paths. ```TOML [tool.natrix] # Single path path = ["lib"] # Multiple paths path = ["lib", "vendor/contracts", "../shared"] # Paths are resolved relative to pyproject.toml location ``` -------------------------------- ### Test Natrix Rules with Pytest in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Illustrates how to write a pytest unit test for a custom Natrix rule, including setting up a test contract, parsing it, running the rule, and asserting the expected number and content of issues. ```python import pytest from natrix.ast_tools import parse_file from natrix.ast_node import Node def test_function_naming_rule(): # Create test contract test_contract = """ @external def badFunctionName(): # Should trigger rule pass @external def good_function_name(): # Should pass pass """ # Parse and test with open("test.vy", "w") as f: f.write(test_contract) ast_data = parse_file("test.vy") rule = FunctionNamingRule() issues = rule.run(ast_data) assert len(issues) == 1 assert "badFunctionName" in issues[0].message ``` -------------------------------- ### Enable JSON Output for Natrix Linting Results Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This command-line flag enables Natrix to output linting issues as a JSON array. This format is ideal for programmatic integration with IDEs, CI/CD pipelines, or other development tools, allowing for easy parsing and processing of results. ```Bash natrix contract.vy --json ``` -------------------------------- ### Node Class Traversal Methods API Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md API documentation for `Node` class methods used for traversing the Abstract Syntax Tree (AST), including `get_descendants`, `get_children`, and `get_ancestor`, detailing their parameters and return types. ```APIDOC Node: get_descendants(node_type=None, filters=None, include_self=False, reverse=False) description: Find all descendant nodes matching criteria. parameters: node_type: Optional. A string or tuple of strings representing the AST node type(s) to match. filters: Optional. A dictionary of properties to filter by. include_self: Optional. Boolean, if True, includes the current node in the search. reverse: Optional. Boolean, if True, traverses in reverse order. returns: List of matching Node objects. get_children(node_type=None, filters=None, reverse=False) description: Find immediate children only. parameters: node_type: Optional. A string or tuple of strings representing the AST node type(s) to match. filters: Optional. A dictionary of properties to filter by. reverse: Optional. Boolean, if True, traverses in reverse order. returns: List of matching Node objects. get_ancestor(node_type=None) description: Find parent nodes. parameters: node_type: Optional. A string or tuple of strings representing the AST node type(s) to match. returns: The first matching ancestor Node object, or None if not found. ``` -------------------------------- ### Configure Argument Naming Rule via Python Class Instantiation Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/argument-naming.md Illustrates how to programmatically configure the `ArgumentNamingRule` by instantiating its class in Python. This method allows setting a custom `pattern`, such as requiring camelCase for arguments. ```Python # Require camelCase for arguments ArgumentNamingRule(pattern="^[a-z][a-zA-Z0-9]*$") ``` -------------------------------- ### Accessing FunctionDefNode Memory Accesses Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to iterate through the `memory_accesses` property of a `FunctionDefNode` to print details about memory read/write operations. ```python for access in func_node.memory_accesses: print(f"{access.type}: {access.var}") # "read: balance" ``` -------------------------------- ### Lint a Vyper Contract or Directory Source: https://github.com/albertocentonze/natrix/blob/main/README.md Commands to lint a specific Vyper contract file or all Vyper contracts in the current directory using Natrix. This helps identify common issues and enforce coding standards. ```bash natrix lint file_to_lint.vy natrix lint # or simply natrix ``` -------------------------------- ### FunctionDefNode Class Properties API Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md API documentation for key properties of the `FunctionDefNode` class, including `modifiers`, `is_constructor`, `is_from_interface`, and `memory_accesses`, detailing their types and purpose. ```APIDOC FunctionDefNode: properties: modifiers: List[str] description: Get function decorators. Returns a list of strings like ["external", "view", "nonreentrant"]. is_constructor: bool description: Check if the function is a constructor. is_from_interface: bool description: Check if the function is from an interface definition. memory_accesses: List[MemoryAccess] description: Get all memory read/write operations within the function. ``` -------------------------------- ### Instantiate Memory Expansion Rule with Custom Threshold in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/memory-expansion.md This Python snippet illustrates how to programmatically instantiate the `MemoryExpansionRule` with a custom `max_frame_size`. It sets the threshold to 10,000 bytes, allowing for fine-grained control within a Python application. ```python # Custom threshold of 10,000 bytes MemoryExpansionRule(max_frame_size=10_000) ``` -------------------------------- ### Manually Register Natrix Rules in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Shows how to explicitly register a custom rule class with the `RuleRegistry` using `RuleRegistry.register()`. ```python from natrix.rules.common import RuleRegistry # Register a rule class RuleRegistry.register(MyRule) ``` -------------------------------- ### Casting to FunctionDefNode Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Shows how to cast or create a `FunctionDefNode` instance from a generic `Node` object, specifically when the node represents a function definition. ```python from natrix.ast_node import FunctionDefNode # Cast or create FunctionDefNode if node.ast_type == "FunctionDef": func_node = FunctionDefNode(node.node_dict, parent=node.parent) ``` -------------------------------- ### Configure Argument Naming Convention Rule (NTX11) in Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This configuration snippet demonstrates how to customize the 'Argument Naming Convention' rule (NTX11) by defining a custom `pattern`. This allows you to enforce a specific naming convention for arguments, overriding the default pattern of `"^_"`. ```TOML [tool.natrix.rule_configs.ArgNamingConvention] pattern = "^_[a-z][a-z0-9_]*$" # Default: "^_" ``` -------------------------------- ### Configure Memory Expansion Rule in pyproject.toml Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/memory-expansion.md This TOML snippet shows how to configure the `MemoryExpansion` rule within a `pyproject.toml` file. It sets the `max_frame_size` property to 25,000 bytes, overriding the default threshold for the rule. ```toml [tool.natrix.rule_configs.MemoryExpansion] max_frame_size = 25000 ``` -------------------------------- ### Natrix CLI Command for Automatic Export Generation Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-export.md This bash command shows how to use the `natrix codegen exports` utility to automatically generate explicit export declarations for a given Vyper contract file. The output can then be copied into your contract to fix implicit export issues. ```bash natrix codegen exports path/to/erc20.vy ``` -------------------------------- ### Generate Explicit Exports for Vyper Contract Source: https://github.com/albertocentonze/natrix/blob/main/README.md Command to generate explicit exports for a given Vyper contract file. This feature can be useful for creating clear interfaces or documentation for contract functionalities. ```bash natrix codegen exports path/to/contract.vy ``` -------------------------------- ### Vyper Non-Compliant Function with Large DynArray Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/memory-expansion.md This Vyper code snippet demonstrates a non-compliant function where a `DynArray` with a very large upper bound is passed by value. This pattern can lead to significant memory expansion and high gas costs, triggering the Memory Expansion rule (NTX1). ```vyper # Non-compliant - large array passed by value can cause memory expansion issues @external def process_large_array(_data: DynArray[uint256, 100_000_000]) -> uint256: _sum: uint256 = 0 for i: uint256 in range(1000): _sum += _data[i] return _sum ``` -------------------------------- ### Report Rule Violations with add_issue in Python Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Illustrates how to use the `self.add_issue` method within a visitor method to report rule violations, including message formatting with arguments based on node properties. ```python def visit_FunctionDef(self, node): function_name = node.get("name") if len(function_name) > 50: # Message formatting with arguments self.add_issue(node, function_name, len(function_name)) ``` -------------------------------- ### Accessing FunctionDefNode Modifiers Source: https://github.com/albertocentonze/natrix/blob/main/docs/api/index.md Demonstrates how to access the `modifiers` property of a `FunctionDefNode` to retrieve a list of function decorators and check for specific modifiers. ```python # Returns list like ["external", "view", "nonreentrant"] decorators = func_node.modifiers # Check for specific modifiers is_external = "external" in func_node.modifiers is_view = "view" in func_node.modifiers ``` -------------------------------- ### Optimize Vyper Storage Access by Caching Variables Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/storage-caching.md This snippet illustrates the gas-saving benefits of caching storage variables in Vyper. It presents a non-compliant function that accesses a storage variable multiple times, leading to higher gas costs, alongside a compliant version that caches the variable in a local memory variable, thereby reducing redundant storage reads and optimizing gas usage. ```vyper # Storage variable user_balance: public(uint256) # Non-compliant - accessing storage variable multiple times @external def process_balance() -> uint256: if self.user_balance > 100: return self.user_balance - 100 else: return self.user_balance # Compliant - caching storage variable @external def process_balance_cached() -> uint256: balance_cache: uint256 = self.user_balance if balance_cache > 100: return balance_cache - 100 else: return balance_cache ``` -------------------------------- ### Override Memory Expansion Rule via Command Line Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/memory-expansion.md This Bash command demonstrates how to temporarily override the `max_frame_size` threshold for the `MemoryExpansion` rule during a single `natrix` run. It sets the limit to 25,000 bytes using the `--rule-config` flag. ```bash # Override threshold for a single run natrix --rule-config MemoryExpansion.max_frame_size=25000 ``` -------------------------------- ### Vyper Non-Compliant Implicit Export Using __interface__ Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/implicit-export.md This Vyper snippet illustrates a non-compliant export pattern where a contract implicitly exposes all functions from an imported module (`erc20`) using `erc20.__interface__`. This approach can lead to unintended exposure of internal functions, such as `mint`, if not explicitly controlled. ```vyper # my_token.vy import erc20 # Non-compliant - exposes all functions from MyHelperFunctions, including potentially _internal_logic exports: (erc20.__interface__) # this also exposes the function to mint, which might not always be intended ``` -------------------------------- ### Detecting print statements in Vyper smart contracts Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/print-left.md This Vyper code snippet illustrates the 'Print Left' rule (NTX6). The `debug_function` is non-compliant because it contains a `print` statement, which is typically used for debugging and should be removed before deployment. In contrast, the `production_function` is compliant as it does not include any `print` statements, representing the desired state for production code. ```vyper @external def debug_function(): # Non-compliant - print statement left in the code print("Debug info") @external def production_function(): # This function is compliant as it doesn't contain print statements pass ``` -------------------------------- ### Configure Memory Expansion Rule (NTX1) in Natrix Source: https://github.com/albertocentonze/natrix/blob/main/docs/configuration.md This snippet shows how to customize the 'Memory Expansion' rule (NTX1) by setting its `max_frame_size` parameter. This allows you to adjust the maximum allowed frame size for memory expansion operations, overriding the default value of 20000. ```TOML [tool.natrix.rule_configs.MemoryExpansion] max_frame_size = 25000 # Default: 20000 ``` -------------------------------- ### Detecting Unused Variables in Vyper Functions Source: https://github.com/albertocentonze/natrix/blob/main/docs/rules/unused-variable.md This snippet demonstrates the 'Unused Variable' rule (NTX8) in Vyper. The `process_data` function is non-compliant because the `temp` variable is declared but never utilized. In contrast, the `process_data_fixed` function is compliant as its `temp` variable is correctly used, illustrating the rule's application. ```vyper @external def process_data(_value: uint256) -> uint256: # Non-compliant - variable declared but never used temp: uint256 = _value * 2 return _value @external def process_data_fixed(_value: uint256) -> uint256: # Compliant - all declared variables are used temp: uint256 = _value * 2 return temp ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.