openscad-parser 2.3.1__tar.gz → 2.3.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_parser
3
- Version: 2.3.1
3
+ Version: 2.3.2
4
4
  Summary: A PEG parser to read OpenSCAD language source code, with optional AST tree generation.
5
5
  Keywords: openscad,openscad parser,parser
6
6
  Author: Revar Desmera
@@ -22,6 +22,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Requires-Dist: arpeggio>=2.0.3
23
23
  Requires-Dist: pytest>=7.0.0 ; extra == 'dev'
24
24
  Requires-Dist: pytest-cov>=7.1.0 ; extra == 'dev'
25
+ Requires-Dist: pyyaml>=6.0 ; extra == 'dev'
25
26
  Requires-Dist: pyyaml>=6.0 ; extra == 'yaml'
26
27
  Maintainer: Revar Desmera
27
28
  Maintainer-email: Revar Desmera <revarbat@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_parser"
7
- version = "2.3.1"
7
+ version = "2.3.2"
8
8
  description = "A PEG parser to read OpenSCAD language source code, with optional AST tree generation."
9
9
  readme = "README.rst"
10
10
  authors = [
@@ -39,6 +39,7 @@ dependencies = [
39
39
  dev = [
40
40
  "pytest>=7.0.0",
41
41
  "pytest-cov>=7.1.0",
42
+ "PyYAML>=6.0",
42
43
  ]
43
44
  yaml = [
44
45
  "PyYAML>=6.0",
@@ -972,9 +972,9 @@ class ASTBuilderVisitor(PTNodeVisitor):
972
972
  for op in reversed(ops):
973
973
  if op == '-':
974
974
  result = UnaryMinusOp(expr=result, position=self._get_node_position(node))
975
- elif op == '!':
975
+ elif op == '!': # pragma: no cover
976
976
  result = LogicalNotOp(expr=result, position=self._get_node_position(node))
977
- elif op == '~':
977
+ elif op == '~': # pragma: no cover
978
978
  result = BitwiseNotOp(expr=result, position=self._get_node_position(node))
979
979
 
980
980
  return result
@@ -1048,8 +1048,6 @@ class ASTBuilderVisitor(PTNodeVisitor):
1048
1048
 
1049
1049
  def visit_vector_expr(self, node, children):
1050
1050
  elements = children if children else []
1051
- if not isinstance(elements, list):
1052
- elements = [elements]
1053
1051
  return ListComprehension(elements=elements, position=self._get_node_position(node))
1054
1052
 
1055
1053
  def visit_funclit_def(self, node, children):
@@ -1065,7 +1063,7 @@ class ASTBuilderVisitor(PTNodeVisitor):
1065
1063
  return children[0]
1066
1064
 
1067
1065
  def visit_listcomp_paren_expr(self, node, children):
1068
- return children[0] if children else None
1066
+ return children[0]
1069
1067
 
1070
1068
  def visit_listcomp_let(self, node, children):
1071
1069
  return ListCompLet(assignments=children[0], body=children[1], position=self._get_node_position(node))
@@ -1118,8 +1116,6 @@ class ASTBuilderVisitor(PTNodeVisitor):
1118
1116
  mods = children.get_rule("child_statement") if hasattr(children, "get_rule") else (children[2] if len(children) > 2 else [])
1119
1117
  if mods is None: # pragma: no cover
1120
1118
  mods = []
1121
- if not isinstance(mods, list):
1122
- mods = [mods]
1123
1119
  return ModularCall(
1124
1120
  name=name,
1125
1121
  arguments=arguments,
@@ -1131,8 +1127,6 @@ class ASTBuilderVisitor(PTNodeVisitor):
1131
1127
  initial = children[0] if isinstance(children[0], list) else [children[0]]
1132
1128
  increment = children[2] if isinstance(children[2], list) else [children[2]]
1133
1129
  body = children.get_rule('child_statement')
1134
- if not isinstance(body, list):
1135
- body = [body]
1136
1130
  return ModularCFor(
1137
1131
  initial=initial,
1138
1132
  condition=children[1],
@@ -1144,8 +1138,6 @@ class ASTBuilderVisitor(PTNodeVisitor):
1144
1138
  def visit_modular_for(self, node, children):
1145
1139
  assignments = children[0] if isinstance(children[0], list) else [children[0]]
1146
1140
  body = children.get_rule('child_statement')
1147
- if not isinstance(body, list):
1148
- body = [body]
1149
1141
  return ModularFor(
1150
1142
  assignments=assignments,
1151
1143
  body=body,
@@ -1156,8 +1148,6 @@ class ASTBuilderVisitor(PTNodeVisitor):
1156
1148
  initial = children[0] if isinstance(children[0], list) else [children[0]]
1157
1149
  increment = children[2] if isinstance(children[2], list) else [children[2]]
1158
1150
  body = children.get_rule('child_statement')
1159
- if not isinstance(body, list):
1160
- body = [body]
1161
1151
  return ModularIntersectionCFor(
1162
1152
  initial=initial,
1163
1153
  condition=children[1],
@@ -1169,46 +1159,32 @@ class ASTBuilderVisitor(PTNodeVisitor):
1169
1159
  def visit_modular_intersection_for(self, node, children):
1170
1160
  assignments = children[0] if isinstance(children[0], list) else [children[0]]
1171
1161
  body = children.get_rule('child_statement')
1172
- if not isinstance(body, list):
1173
- body = [body]
1174
1162
  return ModularIntersectionFor(assignments=assignments, body=body, position=self._get_node_position(node))
1175
1163
 
1176
1164
  def visit_modular_let(self, node, children):
1177
1165
  assignments = children[0] if isinstance(children[0], list) else [children[0]]
1178
1166
  mods = children.get_rule('child_statement')
1179
- if not isinstance(mods, list):
1180
- mods = [mods]
1181
1167
  return ModularLet(assignments=assignments, children=mods, position=self._get_node_position(node))
1182
1168
 
1183
1169
  def visit_modular_echo(self, node, children):
1184
1170
  arguments = children[0] if isinstance(children[0], list) else [children[0]]
1185
1171
  mods = children.get_rule('child_statement')
1186
- if not isinstance(mods, list):
1187
- mods = [mods]
1188
1172
  return ModularEcho(arguments=arguments, children=mods, position=self._get_node_position(node))
1189
1173
 
1190
1174
  def visit_modular_assert(self, node, children):
1191
1175
  arguments = children[0] if isinstance(children[0], list) else [children[0]]
1192
1176
  mods = children.get_rule('child_statement')
1193
- if not isinstance(mods, list):
1194
- mods = [mods]
1195
1177
  return ModularAssert(arguments=arguments, children=mods, position=self._get_node_position(node))
1196
1178
 
1197
1179
  def visit_if_statement(self, node, children):
1198
1180
  condition = children[0]
1199
1181
  true_branch = children.get_rule('child_statement')
1200
- if not isinstance(true_branch, list):
1201
- true_branch = [true_branch]
1202
1182
  return ModularIf(condition=condition, true_branch=true_branch, position=self._get_node_position(node))
1203
1183
 
1204
1184
  def visit_ifelse_statement(self, node, children):
1205
1185
  condition = children[0]
1206
1186
  true_branch = children.get_rule('child_statement')
1207
1187
  false_branch = children.get_rule('child_statement', index=1)
1208
- if not isinstance(true_branch, list):
1209
- true_branch = [true_branch]
1210
- if not isinstance(false_branch, list):
1211
- false_branch = [false_branch]
1212
1188
  return ModularIfElse(condition=condition, true_branch=true_branch, false_branch=false_branch, position=self._get_node_position(node))
1213
1189
 
1214
1190
  def visit_modifier_show_only(self, node, children):
@@ -118,9 +118,6 @@ class SourceMap:
118
118
  start_pos: Starting position in the combined string (0-indexed)
119
119
  length: Number of characters to replace
120
120
  """
121
- if length <= 0:
122
- return
123
-
124
121
  end_pos = start_pos + length
125
122
 
126
123
  # Collect segments to modify and new segments to add (for splits)
@@ -330,12 +327,6 @@ class SourceMap:
330
327
  else:
331
328
  left = mid + 1
332
329
 
333
- # Check if position is in the last segment
334
- if self._segments:
335
- last_segment = self._segments[-1]
336
- if last_segment.combined_start <= position < last_segment.combined_start + len(last_segment.content):
337
- return last_segment
338
-
339
330
  return None
340
331
 
341
332
  def _calculate_location_in_segment(self, segment: SourceSegment, offset: int,