fix: add type annotations to converter files
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-02 07:01:40 +00:00
parent 72a65bcda8
commit 5ef0b3cb72

View File

@@ -1,4 +1,6 @@
from typing import List, Optional """Implementation of regex to English conversion."""
from typing import Any, List
from ..parser import ( from ..parser import (
Alternation, Alternation,
@@ -15,6 +17,7 @@ from ..parser import (
def quantifier_description(quantifier: Quantifier, child_desc: str) -> str: def quantifier_description(quantifier: Quantifier, child_desc: str) -> str:
"""Generate description for a quantifier."""
if quantifier.min == 0 and quantifier.max == 1: if quantifier.min == 0 and quantifier.max == 1:
base = "optionally" base = "optionally"
elif quantifier.min == 0 and quantifier.max == Quantifier.MAX_UNBOUNDED: elif quantifier.min == 0 and quantifier.max == Quantifier.MAX_UNBOUNDED:
@@ -37,6 +40,7 @@ def quantifier_description(quantifier: Quantifier, child_desc: str) -> str:
def literal_description(node: Literal) -> str: def literal_description(node: Literal) -> str:
"""Generate description for a literal character."""
if node.value == " ": if node.value == " ":
return "a space" return "a space"
elif node.value == "\t": elif node.value == "\t":
@@ -52,6 +56,7 @@ def literal_description(node: Literal) -> str:
def character_class_description(node: CharacterClass) -> str: def character_class_description(node: CharacterClass) -> str:
"""Generate description for a character class."""
parts = [] parts = []
if node.inverted: if node.inverted:
@@ -90,6 +95,7 @@ def character_class_description(node: CharacterClass) -> str:
def special_sequence_description(node: SpecialSequence) -> str: def special_sequence_description(node: SpecialSequence) -> str:
"""Generate description for a special sequence."""
sequences = { sequences = {
".": "any single character", ".": "any single character",
r"\d": "a digit (0-9)", r"\d": "a digit (0-9)",
@@ -111,6 +117,7 @@ def special_sequence_description(node: SpecialSequence) -> str:
def anchor_description(node: Anchor) -> str: def anchor_description(node: Anchor) -> str:
"""Generate description for an anchor."""
anchors = { anchors = {
"^": "the start of the string", "^": "the start of the string",
"$": "the end of the string", "$": "the end of the string",
@@ -121,6 +128,7 @@ def anchor_description(node: Anchor) -> str:
def group_description(node: Group) -> str: def group_description(node: Group) -> str:
"""Generate description for a group."""
if node.name: if node.name:
name_desc = f"named '{node.name}'" name_desc = f"named '{node.name}'"
elif not node.capturing: elif not node.capturing:
@@ -136,6 +144,7 @@ def group_description(node: Group) -> str:
def alternation_description(node: Alternation) -> str: def alternation_description(node: Alternation) -> str:
"""Generate description for an alternation."""
option_descs = [] option_descs = []
for option in node.options: for option in node.options:
if option: if option:
@@ -150,6 +159,7 @@ def alternation_description(node: Alternation) -> str:
def backreference_description(node: Backreference) -> str: def backreference_description(node: Backreference) -> str:
"""Generate description for a backreference."""
if isinstance(node.reference, int): if isinstance(node.reference, int):
return f"whatever was matched by capture group {node.reference}" return f"whatever was matched by capture group {node.reference}"
else: else:
@@ -157,6 +167,7 @@ def backreference_description(node: Backreference) -> str:
def generate_description(nodes: List[ASTNode]) -> str: def generate_description(nodes: List[ASTNode]) -> str:
"""Generate a human-readable description for a list of AST nodes."""
if not nodes: if not nodes:
return "an empty pattern" return "an empty pattern"
@@ -201,6 +212,15 @@ def generate_description(nodes: List[ASTNode]) -> str:
def convert_to_english(pattern: str, flavor: str = "pcre") -> str: def convert_to_english(pattern: str, flavor: str = "pcre") -> str:
"""Convert a regex pattern to human-readable English.
Args:
pattern: The regex pattern to convert.
flavor: The regex flavor (pcre, javascript, python, go).
Returns:
A human-readable English description of the pattern.
"""
try: try:
ast = parse_regex(pattern) ast = parse_regex(pattern)
return generate_description(ast) return generate_description(ast)
@@ -209,10 +229,19 @@ def convert_to_english(pattern: str, flavor: str = "pcre") -> str:
def convert_to_english_verbose(pattern: str, flavor: str = "pcre") -> dict: def convert_to_english_verbose(pattern: str, flavor: str = "pcre") -> dict:
"""Convert a regex pattern to detailed structure.
Args:
pattern: The regex pattern to convert.
flavor: The regex flavor.
Returns:
A dictionary with pattern analysis.
"""
try: try:
ast = parse_regex(pattern) ast = parse_regex(pattern)
result = { result: dict[str, Any] = {
"pattern": pattern, "pattern": pattern,
"flavor": flavor, "flavor": flavor,
"description": generate_description(ast), "description": generate_description(ast),
@@ -234,8 +263,9 @@ def convert_to_english_verbose(pattern: str, flavor: str = "pcre") -> dict:
} }
def node_to_dict(node: ASTNode) -> dict: def node_to_dict(node: ASTNode) -> dict[str, Any]:
result = {"type": type(node).__name__} """Convert an AST node to a dictionary."""
result: dict[str, Any] = {"type": type(node).__name__}
if hasattr(node, 'position'): if hasattr(node, 'position'):
result["position"] = node.position result["position"] = node.position