Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/neteditTestFunctions/buildinternaltestdata.py
169673 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2008-2025 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file buildinternaltestdata.py
15
# @author Pablo Alvarez Lopez
16
# @date May 2025
17
18
"""
19
This script generates thre header file with all data needed for internal tests
20
"""
21
from __future__ import absolute_import
22
from __future__ import print_function
23
24
import ast
25
import os
26
27
28
def flattenClassTree(node, scope=None, result=None, local_vars=None):
29
if scope is None:
30
scope = []
31
if result is None:
32
result = {}
33
if local_vars is None:
34
local_vars = {}
35
36
for item in node.body:
37
if isinstance(item, ast.ClassDef):
38
scope.append(item.name)
39
flattenClassTree(item, scope, result, local_vars)
40
scope.pop()
41
42
elif isinstance(item, ast.Assign):
43
for target in item.targets:
44
if isinstance(target, ast.Name):
45
key = '.'.join(scope + [target.id])
46
value_node = item.value
47
try:
48
# evaluate if os possible
49
value = eval_ast(value_node, local_vars)
50
result[key] = value
51
local_vars[target.id] = value
52
except Exception:
53
result[key] = None
54
return result
55
56
57
def eval_ast(node, local_vars):
58
if isinstance(node, ast.Constant):
59
return node.value
60
elif isinstance(node, ast.Name):
61
return local_vars.get(node.id)
62
elif isinstance(node, ast.BinOp):
63
left = eval_ast(node.left, local_vars)
64
right = eval_ast(node.right, local_vars)
65
return eval_binop(node.op, left, right)
66
elif isinstance(node, ast.UnaryOp):
67
operand = eval_ast(node.operand, local_vars)
68
return eval_unaryop(node.op, operand)
69
else:
70
raise ValueError("Unsupported AST node: %s" % ast.dump(node))
71
72
73
def eval_binop(op, left, right):
74
if isinstance(op, ast.Add):
75
return left + right
76
elif isinstance(op, ast.Sub):
77
return left - right
78
elif isinstance(op, ast.Mult):
79
return left * right
80
elif isinstance(op, ast.Div):
81
return left / right
82
elif isinstance(op, ast.FloorDiv):
83
return left // right
84
elif isinstance(op, ast.Mod):
85
return left % right
86
elif isinstance(op, ast.Pow):
87
return left ** right
88
else:
89
raise ValueError("Unsupported binary operator: %s" % op)
90
91
92
def eval_unaryop(op, operand):
93
if isinstance(op, ast.UAdd):
94
return +operand
95
elif isinstance(op, ast.USub):
96
return -operand
97
else:
98
raise ValueError("Unsupported unary operator: %s" % op)
99
100
101
def parseIntFile(outputFolder, file):
102
# read python file
103
pythonFile = "./enums/" + file + ".py"
104
with open(pythonFile, "r", encoding="utf-8") as f:
105
tree = ast.parse(f.read(), filename=pythonFile)
106
# flatten data
107
data = flattenClassTree(tree)
108
# write header file
109
outputFile = outputFolder + "/" + file + ".txt"
110
with open(outputFile, "w", encoding="utf-8") as f:
111
for key, value in sorted(data.items()):
112
f.write('netedit.%s %s\n' % (key, value))
113
114
115
def parsePositionFile(outputFolder, file):
116
# read python file
117
pythonFile = "./enums/" + file + ".py"
118
with open(pythonFile, "r", encoding="utf-8") as f:
119
tree = ast.parse(f.read(), filename=pythonFile)
120
# flatten data
121
data = flattenClassTree(tree)
122
# write header file
123
outputFile = outputFolder + "/" + file + ".txt"
124
with open(outputFile, "w", encoding="utf-8") as f:
125
for key in sorted(data.keys()):
126
if key.endswith(".x"):
127
keyShorted = key[:-2]
128
x = data[keyShorted + ".x"]
129
y = data[keyShorted + ".y"]
130
f.write('netedit.%s %s %s\n' % (keyShorted, x, y))
131
132
133
def parseRouteFile(outputFolder, file):
134
# read python file
135
pythonFile = "./enums/" + file + ".py"
136
with open(pythonFile, "r", encoding="utf-8") as f:
137
tree = ast.parse(f.read(), filename=pythonFile)
138
# flatten data
139
data = flattenClassTree(tree)
140
# write header file
141
outputFile = outputFolder + "/" + file + ".txt"
142
with open(outputFile, "w", encoding="utf-8") as f:
143
for key in sorted(data.keys()):
144
if key.endswith(".up"):
145
keyShorted = key[:-3]
146
up = data[keyShorted + ".up"]
147
down = data[keyShorted + ".down"]
148
left = data[keyShorted + ".left"]
149
right = data[keyShorted + ".right"]
150
f.write('netedit.%s %s %s %s %s\n' % (keyShorted, up, down, left, right))
151
152
153
# main
154
if __name__ == "__main__":
155
outputFolder = "./../../data/tests"
156
# check if create folder
157
if not os.path.exists(outputFolder):
158
os.mkdir(outputFolder)
159
# calculate files for data folder
160
parseIntFile(outputFolder, "attributesEnum")
161
parseIntFile(outputFolder, "contextualMenuOperations")
162
parsePositionFile(outputFolder, "viewPositions")
163
parseRouteFile(outputFolder, "movements")
164
165