Skip to content

Commit be3121e

Browse files
committed
Initial v3 support
1 parent 100b896 commit be3121e

38 files changed

Lines changed: 386 additions & 325 deletions

‎handsdown/ast_parser/analyzers/base_analyzer.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Base AST analyzer.
33
"""
4-
from typing import List
54

65
import handsdown.ast_parser.smart_ast as ast
76

@@ -14,7 +13,7 @@ class BaseAnalyzer(ast.NodeVisitor):
1413
"""
1514

1615
def __init__(self) -> None:
17-
self.related_names: List[str] = []
16+
self.related_names: list[str] = []
1817

1918
def get_docstring(self, node: ast.AST) -> str:
2019
"""

‎handsdown/ast_parser/analyzers/expression_analyzer.py‎

Lines changed: 10 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
AST analyzer for `ast.expr` records.
33
"""
4-
from typing import Dict, List, Type
54

65
import handsdown.ast_parser.smart_ast as ast
76
from handsdown.ast_parser.analyzers.base_analyzer import BaseAnalyzer
@@ -20,13 +19,13 @@ class ExpressionAnalyzer(BaseAnalyzer):
2019
def __init__(self) -> None:
2120
super().__init__()
2221
self._logger = get_logger()
23-
self.parts: List[Node] = []
22+
self.parts: list[Node] = []
2423

2524
# dummy value to replace unknown nodes and operators
2625
UNKNOWN = "..."
2726

2827
# representation map for binary operators
29-
BINOP_SYMBOLS: Dict[Type[ast.AST], str] = {
28+
BINOP_SYMBOLS: dict[type[ast.AST], str] = {
3029
ast.Add: "+",
3130
ast.Sub: "-",
3231
ast.Mult: "*",
@@ -42,10 +41,10 @@ def __init__(self) -> None:
4241
}
4342

4443
# representation map for boolean operators
45-
BOOLOP_SYMBOLS: Dict[Type[ast.AST], str] = {ast.And: "and", ast.Or: "or"}
44+
BOOLOP_SYMBOLS: dict[type[ast.AST], str] = {ast.And: "and", ast.Or: "or"}
4645

4746
# representation map for comparison operators
48-
CMPOP_SYMBOLS: Dict[Type[ast.AST], str] = {
47+
CMPOP_SYMBOLS: dict[type[ast.AST], str] = {
4948
ast.Eq: "==",
5049
ast.NotEq: "!=",
5150
ast.Lt: "<",
@@ -59,14 +58,14 @@ def __init__(self) -> None:
5958
}
6059

6160
# representation map for unary operators
62-
UNARYOP_SYMBOLS: Dict[Type[ast.AST], str] = {
61+
UNARYOP_SYMBOLS: dict[type[ast.AST], str] = {
6362
ast.Invert: "~",
6463
ast.Not: "not",
6564
ast.UAdd: "+",
6665
ast.USub: "-",
6766
}
6867

69-
def visit_Str(self, node: ast.Str) -> None:
68+
def visit_Constant(self, node: ast.Constant) -> None:
7069
"""
7170
Parse info from `ast.Str` node and put it to `parts`.
7271
@@ -77,40 +76,11 @@ def visit_Str(self, node: ast.Str) -> None:
7776
Arguments:
7877
node -- AST node.
7978
"""
80-
value = node.s
79+
value = node.value
8180
if isinstance(value, bytes):
8281
value = value.decode(ENCODING)
8382
self.parts.append(repr(value))
8483

85-
def visit_Bytes(self, node: ast.Bytes) -> None:
86-
"""
87-
Parse info from `ast.Bytes` node and put it to `parts`.
88-
89-
Examples::
90-
91-
b"my_string"
92-
93-
Arguments:
94-
node -- AST node.
95-
"""
96-
value = node.s
97-
self.parts.append(repr(value))
98-
99-
def visit_Num(self, node: ast.Num) -> None:
100-
"""
101-
Parse info from `ast.Num` node and put it to `parts`.
102-
103-
Examples::
104-
105-
123
106-
123.456
107-
108-
Arguments:
109-
node -- AST node.
110-
"""
111-
value = node.n
112-
self.parts.append(repr(value))
113-
11484
def visit_Name(self, node: ast.Name) -> None:
11585
"""
11686
Parse info from `ast.Name` node and put it to `parts`.
@@ -125,20 +95,6 @@ def visit_Name(self, node: ast.Name) -> None:
12595
self.parts.append(node.id)
12696
self.related_names.append(node.id)
12797

128-
def visit_NameConstant(self, node: ast.NameConstant) -> None:
129-
"""
130-
Parse info from `ast.NameConstant` node and put it to `parts`.
131-
132-
Examples::
133-
134-
None
135-
True
136-
137-
Arguments:
138-
node -- AST node.
139-
"""
140-
self.parts.append(repr(node.value))
141-
14298
def visit_Subscript(self, node: ast.Subscript) -> None:
14399
"""
144100
Parse info from `ast.Subscript` node and put it to `parts`.
@@ -522,19 +478,6 @@ def visit_Index(self, node: ast.Index) -> None:
522478
return
523479
self.parts.append(node.value) # type: ignore
524480

525-
def visit_Ellipsis(self, node: ast.ASTEllipsis) -> None:
526-
"""
527-
Parse info from `ast.Ellipsis` node and put it to `parts`.
528-
529-
Examples::
530-
531-
...
532-
533-
Arguments:
534-
node -- AST node.
535-
"""
536-
self.parts.append("...")
537-
538481
def visit_Slice(self, node: ast.Slice) -> None:
539482
"""
540483
Parse info from `ast.Slice` node and put it to `parts`.
@@ -572,8 +515,8 @@ def visit_JoinedStr(self, node: ast.JoinedStr) -> None:
572515
"""
573516
self.parts.append("f'")
574517
for value in node.values:
575-
if isinstance(value, (ast.Str, ast.Constant)):
576-
str_value = value.s
518+
if isinstance(value, ast.Constant):
519+
str_value = value.value
577520
if isinstance(str_value, bytes):
578521
str_value = str_value.decode(ENCODING)
579522
self.parts.append(str_value)
@@ -726,7 +669,7 @@ def visit_Yield(self, node: ast.Yield) -> None:
726669
727670
Examples::
728671
729-
yield
672+
Yield:
730673
yield value
731674
732675
Arguments:

‎handsdown/ast_parser/analyzers/function_analyzer.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""
22
AST analyzer for `ast.FunctionDef` records.
33
"""
4-
from typing import Any, List, Optional, Sequence
4+
from collections.abc import Sequence
5+
from typing import Any, List, Optional
56

67
import handsdown.ast_parser.smart_ast as ast
78
from handsdown.ast_parser.analyzers.base_analyzer import BaseAnalyzer

‎handsdown/ast_parser/analyzers/module_analyzer.py‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""
22
AST analyzer for `ast.Module` records.
33
"""
4-
from typing import List, Union
4+
5+
from typing import Union
56

67
import handsdown.ast_parser.smart_ast as ast
78
from handsdown.ast_parser.analyzers.base_analyzer import BaseAnalyzer
@@ -15,11 +16,11 @@ class ModuleAnalyzer(BaseAnalyzer):
1516

1617
def __init__(self) -> None:
1718
super().__init__()
18-
self.all_names: List[str] = []
19-
self.import_nodes: List[ASTImport] = []
20-
self.function_nodes: List[ASTFunctionDef] = []
21-
self.attribute_nodes: List[Union[ast.Assign, ast.AnnAssign]] = []
22-
self.class_nodes: List[ast.ClassDef] = []
19+
self.all_names: list[str] = []
20+
self.import_nodes: list[ASTImport] = []
21+
self.function_nodes: list[ASTFunctionDef] = []
22+
self.attribute_nodes: list[Union[ast.Assign, ast.AnnAssign]] = []
23+
self.class_nodes: list[ast.ClassDef] = []
2324

2425
def visit_Import(self, node: ast.Import) -> None:
2526
"""
@@ -165,8 +166,8 @@ def visit_Assign(self, node: ast.Assign) -> None:
165166
# gather public names from `__all__` directive
166167
if name == "__all__" and isinstance(node.value, (ast.List, ast.Tuple, ast.Set)):
167168
for element in node.value.elts:
168-
if isinstance(element, (ast.Str, ast.Constant)):
169-
value = element.s
169+
if isinstance(element, ast.Constant):
170+
value = element.value
170171
if isinstance(value, bytes):
171172
value = value.decode("utf-8")
172173
self.all_names.append(value)

‎handsdown/ast_parser/module_record_list.py‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""
22
Aggregation of `ModuleRecord` objects.
33
"""
4-
from typing import Any, Dict, Iterator, List, Optional, Set
4+
from collections.abc import Iterator
5+
from typing import Any
56

67
from handsdown.ast_parser.node_records.module_record import ModuleRecord
78
from handsdown.utils.import_string import ImportString
@@ -15,10 +16,10 @@ class ModuleRecordList:
1516

1617
def __init__(self) -> None:
1718
self._logger = get_logger()
18-
self.data: List[ModuleRecord] = []
19-
self.import_string_map: Dict[ImportString, Any] = {}
19+
self.data: list[ModuleRecord] = []
20+
self.import_string_map: dict[ImportString, Any] = {}
2021

21-
def find_module_record(self, import_string: ImportString) -> Optional[ModuleRecord]:
22+
def find_module_record(self, import_string: ImportString) -> ModuleRecord | None:
2223
"""
2324
Find `ModuleRecord` by it's import string.
2425
@@ -40,7 +41,7 @@ def find_module_record(self, import_string: ImportString) -> Optional[ModuleReco
4041

4142
return None
4243

43-
def get_package_names(self) -> Set[str]:
44+
def get_package_names(self) -> set[str]:
4445
"""
4546
Get top level import strings.
4647

‎handsdown/ast_parser/node_records/argument_record.py‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Wrapper for an `ast.arg` node.
33
"""
4-
from typing import List, Optional, Set
54

65
import handsdown.ast_parser.smart_ast as ast
76
from handsdown.ast_parser.node_records.expression_record import ExpressionRecord
@@ -25,19 +24,19 @@ def __init__(
2524
self,
2625
node: ast.arg,
2726
name: str,
28-
type_hint: Optional[ast.expr] = None,
27+
type_hint: ast.expr | None = None,
2928
prefix: str = "",
3029
) -> None:
3130
super().__init__(node)
32-
self._default: Optional[ExpressionRecord] = None
33-
self.type_hint: Optional[ExpressionRecord] = None
31+
self._default: ExpressionRecord | None = None
32+
self.type_hint: ExpressionRecord | None = None
3433
if type_hint:
3534
self.type_hint = ExpressionRecord(type_hint)
3635
self.prefix = prefix
3736
self.name = name
3837

3938
@property
40-
def default(self) -> Optional[ExpressionRecord]:
39+
def default(self) -> ExpressionRecord | None:
4140
"""
4241
Default value of the argument.
4342
@@ -69,7 +68,7 @@ def set_default(self, node: Node) -> None:
6968
self._default = ExpressionRecord(node)
7069

7170
@property
72-
def related_names(self) -> Set[str]:
71+
def related_names(self) -> set[str]:
7372
"""
7473
Set of related names.
7574
"""
@@ -81,8 +80,8 @@ def related_names(self) -> Set[str]:
8180

8281
return result
8382

84-
def _render_parts(self) -> List[RenderExpr]:
85-
parts: List[RenderExpr] = []
83+
def _render_parts(self) -> list[RenderExpr]:
84+
parts: list[RenderExpr] = []
8685
if self.prefix:
8786
parts.append(self.prefix)
8887

‎handsdown/ast_parser/node_records/attribute_record.py‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Wrapper for an `ast.Assign` node of a module or class attribute.
33
"""
4-
from typing import List, Optional, Set, Union
54

65
import handsdown.ast_parser.smart_ast as ast
76
from handsdown.ast_parser.node_records.expression_record import ExpressionRecord
@@ -17,9 +16,9 @@ class AttributeRecord(NodeRecord):
1716
node -- AST node.
1817
"""
1918

20-
def __init__(self, node: Union[ast.Assign, ast.AnnAssign]) -> None:
19+
def __init__(self, node: ast.Assign | ast.AnnAssign) -> None:
2120
super().__init__(node)
22-
self.default: Optional[ExpressionRecord] = None
21+
self.default: ExpressionRecord | None = None
2322
first_target = node.targets[0] if isinstance(node, ast.Assign) else node.target
2423
assert isinstance(first_target, ast.Name)
2524
self.name = first_target.id
@@ -30,7 +29,7 @@ def __init__(self, node: Union[ast.Assign, ast.AnnAssign]) -> None:
3029
)
3130

3231
@property
33-
def related_names(self) -> Set[str]:
32+
def related_names(self) -> set[str]:
3433
"""
3534
Set of related names.
3635
"""
@@ -40,8 +39,8 @@ def related_names(self) -> Set[str]:
4039

4140
return result
4241

43-
def _render_parts(self) -> List[RenderExpr]:
44-
parts: List[RenderExpr] = []
42+
def _render_parts(self) -> list[RenderExpr]:
43+
parts: list[RenderExpr] = []
4544
parts.append(self.name)
4645
if self.value is not None:
4746
parts.append(" = ")

0 commit comments

Comments
 (0)