python-code-validator 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_code_validator-0.3.0/src/python_code_validator.egg-info → python_code_validator-0.4.0}/PKG-INFO +1 -1
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/pyproject.toml +1 -1
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/__init__.py +57 -57
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/components/definitions.py +91 -89
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/components/factories.py +262 -262
- python_code_validator-0.4.0/src/code_validator/components/typo_detection/__init__.py +25 -0
- python_code_validator-0.4.0/src/code_validator/components/typo_detection/algorithms.py +117 -0
- python_code_validator-0.4.0/src/code_validator/components/typo_detection/detector.py +292 -0
- python_code_validator-0.4.0/src/code_validator/components/typo_detection/formatters.py +230 -0
- python_code_validator-0.4.0/src/code_validator/components/typo_detection/scope_analyzer.py +211 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/core.py +289 -272
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/output.py +247 -238
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/rules_library/basic_rules.py +201 -174
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/rules_library/constraint_logic.py +81 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/rules_library/selector_nodes.py +473 -380
- {python_code_validator-0.3.0 → python_code_validator-0.4.0/src/python_code_validator.egg-info}/PKG-INFO +1 -1
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/python_code_validator.egg-info/SOURCES.txt +6 -0
- python_code_validator-0.4.0/tests/test_scope_validation.py +196 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/LICENSE +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/README.md +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/setup.cfg +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/__main__.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/cli.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/components/__init__.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/components/ast_utils.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/components/scope_handler.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/config.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/exceptions.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/code_validator/rules_library/__init__.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/python_code_validator.egg-info/dependency_links.txt +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/python_code_validator.egg-info/entry_points.txt +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/python_code_validator.egg-info/requires.txt +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/src/python_code_validator.egg-info/top_level.txt +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/tests/test_components.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/tests/test_scope_handler.py +0 -0
- {python_code_validator-0.3.0 → python_code_validator-0.4.0}/tests/test_validator.py +0 -0
|
@@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
|
|
|
10
10
|
# ==============================================================================
|
|
11
11
|
[project]
|
|
12
12
|
name = "python-code-validator"
|
|
13
|
-
version = "0.
|
|
13
|
+
version = "0.4.0"
|
|
14
14
|
description = "A flexible, AST-based framework for static validation of Python code using declarative JSON rules."
|
|
15
15
|
keywords = ["validation", "linter", "static analysis", "testing", "education", "ast"]
|
|
16
16
|
authors = [{ name = "Qu1nel", email = "covach.qn@gmail.com" }]
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
"""A flexible framework for static validation of Python code.
|
|
2
|
-
|
|
3
|
-
This package provides a comprehensive toolkit for statically analyzing Python
|
|
4
|
-
source code based on a declarative set of rules defined in a JSON format. It
|
|
5
|
-
allows for checking syntax, style, structure, and constraints without
|
|
6
|
-
executing the code.
|
|
7
|
-
|
|
8
|
-
The primary entry point for using this package programmatically is the
|
|
9
|
-
`StaticValidator` class.
|
|
10
|
-
|
|
11
|
-
Example:
|
|
12
|
-
A minimal example of using the validator as a library.
|
|
13
|
-
|
|
14
|
-
.. code-block:: python
|
|
15
|
-
|
|
16
|
-
from code_validator import StaticValidator, AppConfig, LogLevel
|
|
17
|
-
from code_validator.output import Console, setup_logging
|
|
18
|
-
from pathlib import Path
|
|
19
|
-
|
|
20
|
-
# Basic setup
|
|
21
|
-
logger = setup_logging(LogLevel.INFO)
|
|
22
|
-
console = Console(logger)
|
|
23
|
-
config = AppConfig(
|
|
24
|
-
solution_path=Path("path/to/solution.py"),
|
|
25
|
-
rules_path=Path("path/to/rules.json"),
|
|
26
|
-
log_level=LogLevel.INFO,
|
|
27
|
-
is_silent=False,
|
|
28
|
-
stop_on_first_fail=False
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
# Run validation
|
|
32
|
-
validator = StaticValidator(config, console)
|
|
33
|
-
is_valid = validator.run()
|
|
34
|
-
|
|
35
|
-
if is_valid:
|
|
36
|
-
print("Validation Passed!")
|
|
37
|
-
|
|
38
|
-
Attributes:
|
|
39
|
-
__version__ (str): The current version of the package.
|
|
40
|
-
__all__ (list[str]): The list of public objects exposed by the package.
|
|
41
|
-
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
from .config import AppConfig, ExitCode, LogLevel
|
|
45
|
-
from .core import StaticValidator
|
|
46
|
-
from .exceptions import RuleParsingError, ValidationFailedError
|
|
47
|
-
|
|
48
|
-
__all__ = [
|
|
49
|
-
"StaticValidator",
|
|
50
|
-
"AppConfig",
|
|
51
|
-
"ExitCode",
|
|
52
|
-
"LogLevel",
|
|
53
|
-
"ValidationFailedError",
|
|
54
|
-
"RuleParsingError",
|
|
55
|
-
]
|
|
56
|
-
|
|
57
|
-
__version__ = "0.
|
|
1
|
+
"""A flexible framework for static validation of Python code.
|
|
2
|
+
|
|
3
|
+
This package provides a comprehensive toolkit for statically analyzing Python
|
|
4
|
+
source code based on a declarative set of rules defined in a JSON format. It
|
|
5
|
+
allows for checking syntax, style, structure, and constraints without
|
|
6
|
+
executing the code.
|
|
7
|
+
|
|
8
|
+
The primary entry point for using this package programmatically is the
|
|
9
|
+
`StaticValidator` class.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
A minimal example of using the validator as a library.
|
|
13
|
+
|
|
14
|
+
.. code-block:: python
|
|
15
|
+
|
|
16
|
+
from code_validator import StaticValidator, AppConfig, LogLevel
|
|
17
|
+
from code_validator.output import Console, setup_logging
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
# Basic setup
|
|
21
|
+
logger = setup_logging(LogLevel.INFO)
|
|
22
|
+
console = Console(logger)
|
|
23
|
+
config = AppConfig(
|
|
24
|
+
solution_path=Path("path/to/solution.py"),
|
|
25
|
+
rules_path=Path("path/to/rules.json"),
|
|
26
|
+
log_level=LogLevel.INFO,
|
|
27
|
+
is_silent=False,
|
|
28
|
+
stop_on_first_fail=False
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Run validation
|
|
32
|
+
validator = StaticValidator(config, console)
|
|
33
|
+
is_valid = validator.run()
|
|
34
|
+
|
|
35
|
+
if is_valid:
|
|
36
|
+
print("Validation Passed!")
|
|
37
|
+
|
|
38
|
+
Attributes:
|
|
39
|
+
__version__ (str): The current version of the package.
|
|
40
|
+
__all__ (list[str]): The list of public objects exposed by the package.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
from .config import AppConfig, ExitCode, LogLevel
|
|
45
|
+
from .core import StaticValidator
|
|
46
|
+
from .exceptions import RuleParsingError, ValidationFailedError
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
"StaticValidator",
|
|
50
|
+
"AppConfig",
|
|
51
|
+
"ExitCode",
|
|
52
|
+
"LogLevel",
|
|
53
|
+
"ValidationFailedError",
|
|
54
|
+
"RuleParsingError",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
__version__ = "0.4.0"
|
|
@@ -1,89 +1,91 @@
|
|
|
1
|
-
"""Defines the core component interfaces for the validator using Protocols.
|
|
2
|
-
|
|
3
|
-
This module establishes the fundamental "contracts" for the main architectural
|
|
4
|
-
components: Rules, Selectors, and Constraints. By using `typing.Protocol`, we
|
|
5
|
-
ensure that any class conforming to these interfaces can be used interchangeably
|
|
6
|
-
by the system's factories and core engine. This enables a flexible and
|
|
7
|
-
decoupled plugin-style architecture, where new components can be added without
|
|
8
|
-
modifying the core logic.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import ast
|
|
12
|
-
from typing import Protocol, runtime_checkable
|
|
13
|
-
|
|
14
|
-
from ..config import FullRuleConfig, ShortRuleConfig
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@runtime_checkable
|
|
18
|
-
class Selector(Protocol):
|
|
19
|
-
"""An interface for objects that find and select specific nodes from an AST.
|
|
20
|
-
|
|
21
|
-
A Selector's main responsibility is to traverse the Abstract Syntax Tree (AST)
|
|
22
|
-
of a Python source file and return a list of nodes that match a specific
|
|
23
|
-
criterion (e.g., all function definitions, all import statements).
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
def select(self, tree: ast.Module) -> list[ast.AST]:
|
|
27
|
-
"""Selects and returns a list of relevant AST nodes from the tree.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
tree: The full, parsed AST of the source code to be searched.
|
|
31
|
-
|
|
32
|
-
Returns:
|
|
33
|
-
A list of ast.AST nodes that match the selector's criteria.
|
|
34
|
-
An empty list should be returned if no matching nodes are found.
|
|
35
|
-
"""
|
|
36
|
-
...
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@runtime_checkable
|
|
40
|
-
class Constraint(Protocol):
|
|
41
|
-
"""An interface for objects that apply a condition to a set of AST nodes.
|
|
42
|
-
|
|
43
|
-
A Constraint takes the list of nodes found by a Selector and checks if they
|
|
44
|
-
satisfy a specific condition (e.g., the list must not be empty, the node
|
|
45
|
-
must inherit from a specific class).
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
def check(self, nodes: list[ast.AST]) -> bool:
|
|
49
|
-
"""Checks if the given list of nodes satisfies the constraint.
|
|
50
|
-
|
|
51
|
-
Args:
|
|
52
|
-
nodes: A list of AST nodes provided by a Selector.
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
True if the constraint is satisfied, False otherwise.
|
|
56
|
-
"""
|
|
57
|
-
...
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@runtime_checkable
|
|
61
|
-
class Rule(Protocol):
|
|
62
|
-
"""An interface for any complete, executable validation rule.
|
|
63
|
-
|
|
64
|
-
A Rule represents a single, self-contained validation check. It can be a
|
|
65
|
-
"short" rule (like a linter check) or a "full" rule that internally uses
|
|
66
|
-
a Selector and a Constraint. The core validator engine interacts with
|
|
67
|
-
objects conforming to this protocol.
|
|
68
|
-
|
|
69
|
-
Attributes:
|
|
70
|
-
config: The dataclass object holding the configuration for this rule,
|
|
71
|
-
parsed from the JSON file.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
"""Defines the core component interfaces for the validator using Protocols.
|
|
2
|
+
|
|
3
|
+
This module establishes the fundamental "contracts" for the main architectural
|
|
4
|
+
components: Rules, Selectors, and Constraints. By using `typing.Protocol`, we
|
|
5
|
+
ensure that any class conforming to these interfaces can be used interchangeably
|
|
6
|
+
by the system's factories and core engine. This enables a flexible and
|
|
7
|
+
decoupled plugin-style architecture, where new components can be added without
|
|
8
|
+
modifying the core logic.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import ast
|
|
12
|
+
from typing import Protocol, runtime_checkable
|
|
13
|
+
|
|
14
|
+
from ..config import FullRuleConfig, ShortRuleConfig
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@runtime_checkable
|
|
18
|
+
class Selector(Protocol):
|
|
19
|
+
"""An interface for objects that find and select specific nodes from an AST.
|
|
20
|
+
|
|
21
|
+
A Selector's main responsibility is to traverse the Abstract Syntax Tree (AST)
|
|
22
|
+
of a Python source file and return a list of nodes that match a specific
|
|
23
|
+
criterion (e.g., all function definitions, all import statements).
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def select(self, tree: ast.Module) -> list[ast.AST]:
|
|
27
|
+
"""Selects and returns a list of relevant AST nodes from the tree.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
tree: The full, parsed AST of the source code to be searched.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
A list of ast.AST nodes that match the selector's criteria.
|
|
34
|
+
An empty list should be returned if no matching nodes are found.
|
|
35
|
+
"""
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@runtime_checkable
|
|
40
|
+
class Constraint(Protocol):
|
|
41
|
+
"""An interface for objects that apply a condition to a set of AST nodes.
|
|
42
|
+
|
|
43
|
+
A Constraint takes the list of nodes found by a Selector and checks if they
|
|
44
|
+
satisfy a specific condition (e.g., the list must not be empty, the node
|
|
45
|
+
must inherit from a specific class).
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def check(self, nodes: list[ast.AST]) -> bool:
|
|
49
|
+
"""Checks if the given list of nodes satisfies the constraint.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
nodes: A list of AST nodes provided by a Selector.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
True if the constraint is satisfied, False otherwise.
|
|
56
|
+
"""
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@runtime_checkable
|
|
61
|
+
class Rule(Protocol):
|
|
62
|
+
"""An interface for any complete, executable validation rule.
|
|
63
|
+
|
|
64
|
+
A Rule represents a single, self-contained validation check. It can be a
|
|
65
|
+
"short" rule (like a linter check) or a "full" rule that internally uses
|
|
66
|
+
a Selector and a Constraint. The core validator engine interacts with
|
|
67
|
+
objects conforming to this protocol.
|
|
68
|
+
|
|
69
|
+
Attributes:
|
|
70
|
+
config: The dataclass object holding the configuration for this rule,
|
|
71
|
+
parsed from the JSON file.
|
|
72
|
+
typo_suggestion: Optional typo suggestion message for user display.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
config: FullRuleConfig | ShortRuleConfig
|
|
76
|
+
typo_suggestion: str | None
|
|
77
|
+
|
|
78
|
+
def execute(self, tree: ast.Module | None, source_code: str | None = None) -> bool:
|
|
79
|
+
"""Executes the validation rule.
|
|
80
|
+
|
|
81
|
+
Depending on the rule type, this method might operate on the AST, the
|
|
82
|
+
raw source code, or both.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
tree: The full AST of the source code (for structural checks).
|
|
86
|
+
source_code: The raw source code string (e.g., for linter checks).
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
True if the validation check passes, False otherwise.
|
|
90
|
+
"""
|
|
91
|
+
...
|