vex-ast 0.2.2__py3-none-any.whl → 0.2.3__py3-none-any.whl
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.
- vex_ast/ast/vex_nodes.py +15 -2
- vex_ast/parser/factory.py +7 -1
- vex_ast/parser/python_parser.py +7 -1
- vex_ast/registry/signature.py +44 -1
- vex_ast/serialization/json_deserializer.py +13 -2
- vex_ast/serialization/schema.py +3 -4
- vex_ast/utils/errors.py +2 -2
- {vex_ast-0.2.2.dist-info → vex_ast-0.2.3.dist-info}/METADATA +1 -1
- {vex_ast-0.2.2.dist-info → vex_ast-0.2.3.dist-info}/RECORD +12 -12
- {vex_ast-0.2.2.dist-info → vex_ast-0.2.3.dist-info}/WHEEL +0 -0
- {vex_ast-0.2.2.dist-info → vex_ast-0.2.3.dist-info}/licenses/LICENSE +0 -0
- {vex_ast-0.2.2.dist-info → vex_ast-0.2.3.dist-info}/top_level.txt +0 -0
vex_ast/ast/vex_nodes.py
CHANGED
@@ -91,8 +91,21 @@ class VexAPICall(FunctionCall):
|
|
91
91
|
return False, self._validation_error
|
92
92
|
|
93
93
|
# Convert args and kwargs to appropriate format
|
94
|
-
arg_values = [
|
95
|
-
|
94
|
+
arg_values = []
|
95
|
+
for arg in self.args:
|
96
|
+
# For string literals, use their actual string value for validation
|
97
|
+
if hasattr(arg, 'value') and hasattr(arg, '__class__') and arg.__class__.__name__ == 'StringLiteral':
|
98
|
+
arg_values.append(arg.value)
|
99
|
+
else:
|
100
|
+
arg_values.append(arg)
|
101
|
+
|
102
|
+
kwarg_values = {}
|
103
|
+
for kw in (self.keywords or []):
|
104
|
+
# For string literals, use their actual string value for validation
|
105
|
+
if hasattr(kw.value, 'value') and hasattr(kw.value, '__class__') and kw.value.__class__.__name__ == 'StringLiteral':
|
106
|
+
kwarg_values[kw.name] = kw.value.value
|
107
|
+
else:
|
108
|
+
kwarg_values[kw.name] = kw.value
|
96
109
|
|
97
110
|
# Validate against the signature
|
98
111
|
valid, error = signature.validate_arguments(arg_values, kwarg_values)
|
vex_ast/parser/factory.py
CHANGED
@@ -123,6 +123,12 @@ class NodeFactory:
|
|
123
123
|
"""Create a function definition node."""
|
124
124
|
return FunctionDefinition(name, args, body, return_annotation, location)
|
125
125
|
|
126
|
+
def create_argument(self, name: str, annotation: Optional[Expression] = None,
|
127
|
+
default: Optional[Expression] = None,
|
128
|
+
location: Optional[SourceLocation] = None) -> Argument:
|
129
|
+
"""Create an argument node."""
|
130
|
+
return Argument(name, annotation, default, location)
|
131
|
+
|
126
132
|
def create_return_statement(self, value: Optional[Expression] = None,
|
127
133
|
location: Optional[SourceLocation] = None) -> ReturnStatement:
|
128
134
|
"""Create a return statement node."""
|
@@ -176,4 +182,4 @@ class NodeFactory:
|
|
176
182
|
return Program(body, location)
|
177
183
|
|
178
184
|
# Global factory instance for simple use cases
|
179
|
-
default_factory = NodeFactory()
|
185
|
+
default_factory = NodeFactory()
|
vex_ast/parser/python_parser.py
CHANGED
@@ -692,7 +692,13 @@ class PythonParser(BaseParser):
|
|
692
692
|
f"Syntax error: {e.msg}",
|
693
693
|
loc
|
694
694
|
)
|
695
|
-
|
695
|
+
|
696
|
+
# Only raise if the error handler is configured to do so
|
697
|
+
if self.error_handler._raise_on_error:
|
698
|
+
raise VexSyntaxError(f"Syntax error: {e.msg}", loc) from e
|
699
|
+
|
700
|
+
# Return an empty program if we're not raising
|
701
|
+
return self.factory.create_program([])
|
696
702
|
|
697
703
|
except Exception as e:
|
698
704
|
# Handle other parsing errors
|
vex_ast/registry/signature.py
CHANGED
@@ -138,6 +138,49 @@ class VexFunctionSignature:
|
|
138
138
|
if param_name in kwargs:
|
139
139
|
return False, f"Duplicate argument '{param_name}' for {self.name}"
|
140
140
|
|
141
|
-
#
|
141
|
+
# Type checking for arguments
|
142
|
+
from ..types.type_checker import type_checker
|
143
|
+
from ..types.enums import EnumType
|
144
|
+
|
145
|
+
# Check positional arguments
|
146
|
+
for i, arg in enumerate(args):
|
147
|
+
if i >= len(self.parameters):
|
148
|
+
break
|
149
|
+
|
150
|
+
param = self.parameters[i]
|
151
|
+
expected_type = param.type
|
152
|
+
|
153
|
+
# Handle string literals for enum types
|
154
|
+
if isinstance(expected_type, EnumType) and isinstance(arg, str):
|
155
|
+
if arg not in expected_type.values:
|
156
|
+
return False, f"Invalid enum value '{arg}' for parameter '{param.name}' in {self.name}"
|
157
|
+
continue
|
158
|
+
|
159
|
+
# Handle other types
|
160
|
+
if hasattr(arg, 'get_type'):
|
161
|
+
arg_type = arg.get_type()
|
162
|
+
if arg_type and not type_checker.is_compatible(arg_type, expected_type):
|
163
|
+
return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {arg_type}"
|
164
|
+
|
165
|
+
# Check keyword arguments
|
166
|
+
for kwarg_name, kwarg_value in kwargs.items():
|
167
|
+
# Find the parameter
|
168
|
+
param = next((p for p in self.parameters if p.name == kwarg_name), None)
|
169
|
+
if not param:
|
170
|
+
continue # Already checked for unknown kwargs above
|
171
|
+
|
172
|
+
expected_type = param.type
|
173
|
+
|
174
|
+
# Handle string literals for enum types
|
175
|
+
if isinstance(expected_type, EnumType) and isinstance(kwarg_value, str):
|
176
|
+
if kwarg_value not in expected_type.values:
|
177
|
+
return False, f"Invalid enum value '{kwarg_value}' for parameter '{param.name}' in {self.name}"
|
178
|
+
continue
|
179
|
+
|
180
|
+
# Handle other types
|
181
|
+
if hasattr(kwarg_value, 'get_type'):
|
182
|
+
kwarg_type = kwarg_value.get_type()
|
183
|
+
if kwarg_type and not type_checker.is_compatible(kwarg_type, expected_type):
|
184
|
+
return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {kwarg_type}"
|
142
185
|
|
143
186
|
return True, None
|
@@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Type, Union, cast
|
|
10
10
|
from ..ast.interfaces import IAstNode
|
11
11
|
from ..parser.factory import NodeFactory
|
12
12
|
from ..utils.source_location import SourceLocation
|
13
|
-
from ..utils.errors import ErrorHandler
|
13
|
+
from ..utils.errors import ErrorHandler, ErrorType
|
14
14
|
|
15
15
|
|
16
16
|
class DeserializationFactory:
|
@@ -153,6 +153,7 @@ class DeserializationFactory:
|
|
153
153
|
"WhileLoop": self.node_factory.create_while_loop,
|
154
154
|
"ForLoop": self.node_factory.create_for_loop,
|
155
155
|
"FunctionDefinition": self.node_factory.create_function_definition,
|
156
|
+
"Argument": self.node_factory.create_argument,
|
156
157
|
"ReturnStatement": self.node_factory.create_return_statement,
|
157
158
|
"BreakStatement": self.node_factory.create_break_statement,
|
158
159
|
"ContinueStatement": self.node_factory.create_continue_statement,
|
@@ -198,11 +199,21 @@ class DeserializationFactory:
|
|
198
199
|
except TypeError as e:
|
199
200
|
# If the factory method doesn't accept the kwargs, report an error
|
200
201
|
if self.error_handler:
|
201
|
-
self.error_handler.
|
202
|
+
self.error_handler.add_error(
|
203
|
+
error_type=ErrorType.INTERNAL_ERROR,
|
204
|
+
message=f"Failed to create {node_type}: {str(e)}"
|
205
|
+
)
|
202
206
|
raise ValueError(f"Failed to deserialize {node_type}: {str(e)}")
|
203
207
|
|
204
208
|
# Specific node creation methods for complex cases
|
205
209
|
|
210
|
+
def _create_attributeaccess(self, data: Dict[str, Any],
|
211
|
+
location: Optional[SourceLocation]) -> IAstNode:
|
212
|
+
"""Create an AttributeAccess node from serialized data."""
|
213
|
+
object_expr = self._deserialize_value(data.get("object"))
|
214
|
+
attribute = data.get("attribute", "")
|
215
|
+
return self.node_factory.create_attribute_access(object_expr, attribute, location)
|
216
|
+
|
206
217
|
def _create_program(self, data: Dict[str, Any],
|
207
218
|
location: Optional[SourceLocation]) -> IAstNode:
|
208
219
|
"""Create a Program node from serialized data."""
|
vex_ast/serialization/schema.py
CHANGED
@@ -453,16 +453,15 @@ def _generate_definitions() -> Dict[str, Any]:
|
|
453
453
|
return definitions
|
454
454
|
|
455
455
|
|
456
|
-
def export_schema_to_file(filepath: str, indent: int = 2) -> None:
|
456
|
+
def export_schema_to_file(schema: Dict[str, Any], filepath: str, indent: int = 2) -> None:
|
457
457
|
"""
|
458
|
-
Save the
|
458
|
+
Save the schema to a file.
|
459
459
|
|
460
460
|
Args:
|
461
|
+
schema: The schema to save
|
461
462
|
filepath: The path to save the schema to
|
462
463
|
indent: The indentation level for pretty-printing
|
463
464
|
"""
|
464
|
-
schema = generate_ast_schema()
|
465
|
-
|
466
465
|
# Ensure the directory exists
|
467
466
|
os.makedirs(os.path.dirname(os.path.abspath(filepath)), exist_ok=True)
|
468
467
|
|
vex_ast/utils/errors.py
CHANGED
@@ -50,7 +50,7 @@ class ErrorObserver(Protocol[T_Error]):
|
|
50
50
|
class ErrorHandler:
|
51
51
|
"""Manages error collection and notification."""
|
52
52
|
|
53
|
-
def __init__(self, raise_on_error: bool =
|
53
|
+
def __init__(self, raise_on_error: bool = True):
|
54
54
|
self._errors: List[Error] = []
|
55
55
|
self._raise_on_error = raise_on_error
|
56
56
|
self._observers: List[ErrorObserver] = []
|
@@ -109,4 +109,4 @@ class VexSyntaxError(VexAstError):
|
|
109
109
|
|
110
110
|
def __init__(self, message: str, location: Optional[SourceLocation] = None):
|
111
111
|
self.location = location
|
112
|
-
super().__init__(message)
|
112
|
+
super().__init__(message)
|
@@ -11,12 +11,12 @@ vex_ast/ast/navigator.py,sha256=9DaVXrknBbBr4omAAMHQnZL9Wpj5wjtoCS6_lni8MYM,7529
|
|
11
11
|
vex_ast/ast/operators.py,sha256=I-yWvhsrz-OxmBZs5zIss_GTZF5S-nwcSmIzvAVtddM,3160
|
12
12
|
vex_ast/ast/statements.py,sha256=OWRthjYGmTuNozYAHjh_Enp5t-hR1PphtPnFg31FeWw,11841
|
13
13
|
vex_ast/ast/validators.py,sha256=ySpi5H0XRdGXXMFAfmuVEyc3Q9mMXhubZAkP4N8NL3c,4717
|
14
|
-
vex_ast/ast/vex_nodes.py,sha256=
|
14
|
+
vex_ast/ast/vex_nodes.py,sha256=8Wq9vl8Mp70E3fxEut9tB6WZE1z0Q_i5V0qh_5Zoeag,11981
|
15
15
|
vex_ast/parser/README.md,sha256=P1qq_97skpgluLDpNu9V_pAdkuF9StjkzOEXJJYpEuM,2565
|
16
16
|
vex_ast/parser/__init__.py,sha256=LGHnFm3UzR4Nw7royGH3c_2RqeY66y8O6DdXHbm9yL4,504
|
17
|
-
vex_ast/parser/factory.py,sha256=
|
17
|
+
vex_ast/parser/factory.py,sha256=ryTs8dQej8GbATyc7H4NUUISL1Bq65eIjyq84HaFTlo,9098
|
18
18
|
vex_ast/parser/interfaces.py,sha256=Ttc0bD_5X420ZCT9MLUf_wE1aZLWLkaJRQqCwBy9wIs,956
|
19
|
-
vex_ast/parser/python_parser.py,sha256=
|
19
|
+
vex_ast/parser/python_parser.py,sha256=EHcro2NqVLScOBBG0XuWUMiT7Dmqep4M9scGOxpJoYw,29947
|
20
20
|
vex_ast/parser/strategies.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
vex_ast/registry/README.md,sha256=J8xEXEscEZhWa6wmn05kjE395AjrV7p2h7nq4SXI5uE,1535
|
22
22
|
vex_ast/registry/__init__.py,sha256=dXT8OS7uLyBSdQKZDWrtbANzgSWcg9HUQDA1EaLOvjQ,1188
|
@@ -24,7 +24,7 @@ vex_ast/registry/api.py,sha256=yyW-TsCIULTzePAoyMvEqD_RNlkFSb4PLpiSkw6ueQk,5460
|
|
24
24
|
vex_ast/registry/categories.py,sha256=y5tnCzHQ9PPg9hOzOMgyE1ZAhcsjgeFSrgqdJrdqHEg,4885
|
25
25
|
vex_ast/registry/language_map.py,sha256=eekN3k-K9g90GFi4--If3nfJCyarUJxDWDCDvLm7mdU,2656
|
26
26
|
vex_ast/registry/registry.py,sha256=gvsQKyeXWp84T2uDB4O_WQgKCeq8W9udl8TD5MnPZzc,6661
|
27
|
-
vex_ast/registry/signature.py,sha256=
|
27
|
+
vex_ast/registry/signature.py,sha256=_Lde3bteVVdYG31fN4v62UViWSVyxi4U3mYT1-9b4A0,7881
|
28
28
|
vex_ast/registry/simulation_behavior.py,sha256=WwkVKae0owtv3WTrfnVH93rpsh9lbqJ_RSAVmpIVA_k,313
|
29
29
|
vex_ast/registry/validation.py,sha256=xq5UjSWYAcRxjxsCGg3WU5RtPN-DB-JAqKqDNGvnJGk,1973
|
30
30
|
vex_ast/registry/functions/__init__.py,sha256=X9aw0-Y9Q6Gcx01zepP8G_20ybfwC-LDPQfkK2RDOrE,207
|
@@ -35,9 +35,9 @@ vex_ast/registry/functions/motor.py,sha256=Vby44hV1goNFgFQEFDlv7z_9uGQeuvLMABplO
|
|
35
35
|
vex_ast/registry/functions/sensors.py,sha256=BdhLV5gSWD5HO-o3JRXhbGQF7s1Ybk3b6VLLqVau1i0,6410
|
36
36
|
vex_ast/registry/functions/timing.py,sha256=DqwMVPk7VKDeZB4S3NI7wOYgM1R52dcdgaVIb9135Jg,3204
|
37
37
|
vex_ast/serialization/__init__.py,sha256=qPTEiMjU8hpVxNH5z4MY7Yj60AxuFurjXZStjhWWf6o,835
|
38
|
-
vex_ast/serialization/json_deserializer.py,sha256=
|
38
|
+
vex_ast/serialization/json_deserializer.py,sha256=GCfm8XAF_90FswlizFy59fyZwjZtE94yPR_FWWWAE20,11108
|
39
39
|
vex_ast/serialization/json_serializer.py,sha256=YvMRUpqXjtbxlIvathEIywUqbH3Ne6GSRODfFB0QCGM,4465
|
40
|
-
vex_ast/serialization/schema.py,sha256=
|
40
|
+
vex_ast/serialization/schema.py,sha256=BNBYruht3fmuGoVGv5fuMwdIEqLu7OZ1XZS8gzdom0w,14440
|
41
41
|
vex_ast/types/README.md,sha256=Wd3jBShiNXNc3iJ69Qps5_0mBq8QVEd_Gz5OachfS34,1029
|
42
42
|
vex_ast/types/__init__.py,sha256=naLOT_-qHWxzYj4nwxjCB5dfL6tcIt7TjMEaRaXMWbU,2163
|
43
43
|
vex_ast/types/base.py,sha256=hCPCeBNnD5p29Mim-ouRTkG6Lfa8NXrsdYLO8xsbFtM,2258
|
@@ -47,7 +47,7 @@ vex_ast/types/primitives.py,sha256=t_4kEVyPSmKRHEIRQcp-X5Yq46JbG1SxzlvHb0vL4IA,1
|
|
47
47
|
vex_ast/types/type_checker.py,sha256=emzhmc6AlH71w0DrKLlZRMBlJNZAuENihvRXTenqg_Q,1083
|
48
48
|
vex_ast/utils/README.md,sha256=Y9RJMQTqQbpjVkvYJmpeRihD1zfW9PhNL_LgoDJ84ak,1945
|
49
49
|
vex_ast/utils/__init__.py,sha256=azzhhFoMykqOkVVm6X2V7dFW3jGBkOvEgnEP1JTCS3g,621
|
50
|
-
vex_ast/utils/errors.py,sha256=
|
50
|
+
vex_ast/utils/errors.py,sha256=T1sOqWR3-0dYqmXAKDwO7VXIHCGZMnF_gEIGmFWy8Ps,3850
|
51
51
|
vex_ast/utils/source_location.py,sha256=r857ypqUBqex2y_R0RzZo7pz5di9qtEeWFFQ4HwzYQE,1297
|
52
52
|
vex_ast/utils/type_definitions.py,sha256=2rB85B1vZL1GLWItBuJJpyr-vmp3W346EMMX2TPZ99Q,313
|
53
53
|
vex_ast/visitors/README.md,sha256=BKDj8LMuBlCrzgSSLmCkbET7WIqgxe-oCkqQbqXekrE,2725
|
@@ -56,8 +56,8 @@ vex_ast/visitors/analyzer.py,sha256=cBT5PRbtfQ_Dt1qiHN-wdO5KnC2yl-Ul5RasXg9geHY,
|
|
56
56
|
vex_ast/visitors/base.py,sha256=Ph0taTIVMHV_QjXfDd0ipZnCXVJErkyRtPpfwfzo-kY,4859
|
57
57
|
vex_ast/visitors/printer.py,sha256=CUY_73hxm7MoC-63JeIXaVYnZ8QqtfMqbek2R2HMEmE,5411
|
58
58
|
vex_ast/visitors/transformer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
vex_ast-0.2.
|
60
|
-
vex_ast-0.2.
|
61
|
-
vex_ast-0.2.
|
62
|
-
vex_ast-0.2.
|
63
|
-
vex_ast-0.2.
|
59
|
+
vex_ast-0.2.3.dist-info/licenses/LICENSE,sha256=IOSlfCuxGv4OAg421BRDKVi16RZ7-5kCMJ4B16r4kuc,69
|
60
|
+
vex_ast-0.2.3.dist-info/METADATA,sha256=2TsjEVVuPN94XQ8QOW5bHItBbFh3IAvn1uuCoEJe8nQ,5295
|
61
|
+
vex_ast-0.2.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
62
|
+
vex_ast-0.2.3.dist-info/top_level.txt,sha256=MoZGrpKgNUDiqL9gWp4q3wMw3q93XPEEjmBNPJQcNAs,8
|
63
|
+
vex_ast-0.2.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|