holado 0.2.5__py3-none-any.whl → 0.2.7__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.
Potentially problematic release.
This version of holado might be problematic. Click here for more details.
- holado/__init__.py +9 -1
- holado/common/handlers/object.py +2 -1
- holado/common/handlers/undefined.py +16 -6
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/METADATA +1 -1
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/RECORD +32 -31
- holado_core/common/block/scope_steps.py +2 -2
- holado_core/common/resource/persisted_method_to_call_manager.py +18 -5
- holado_core/common/tools/tools.py +26 -9
- holado_core/tests/behave/steps/common/tables_steps.py +1 -1
- holado_helper/initialize_holado.py +72 -0
- holado_helper/script/action.py +21 -9
- holado_helper/script/initialize_script.py +3 -23
- holado_helper/script/script.py +2 -2
- holado_protobuf/ipc/protobuf/protobuf_messages.py +1 -1
- holado_scripting/common/tools/evaluate_parameters.py +23 -5
- holado_scripting/common/tools/expression_evaluator.py +115 -113
- holado_scripting/tests/behave/steps/scenario/if_steps.py +2 -2
- holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +1 -1
- holado_scripting/text/interpreter/text_interpreter.py +20 -21
- holado_test/behave/behave_environment.py +31 -12
- holado_test/scenario/step_tools.py +11 -12
- holado_test/scenario/tester_tools.py +3 -1
- holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +3 -2
- holado_value/common/tables/converters/value_table_converter.py +1 -1
- holado_value/common/tables/value_table_cell.py +5 -1
- holado_value/common/tools/value.py +56 -33
- holado_value/common/tools/value_types.py +6 -0
- test_holado/features/NonReg/{ipc → holado_binary}/bit_series.feature +13 -0
- test_holado/features/NonReg/test_steps/common.feature +1 -1
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/WHEEL +0 -0
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/licenses/LICENSE +0 -0
- /test_holado/features/NonReg/{ipc → holado_binary}/bit_series.error.feature +0 -0
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
# Usually, it is copied and adapted for specific usage.
|
|
17
17
|
|
|
18
18
|
import os
|
|
19
|
-
import sys
|
|
20
19
|
import logging
|
|
21
20
|
import argparse
|
|
21
|
+
from holado_helper.initialize_holado import insert_sys_path, insert_sys_paths
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def _chdir(path):
|
|
@@ -26,26 +26,6 @@ def _chdir(path):
|
|
|
26
26
|
os.chdir(path)
|
|
27
27
|
return res
|
|
28
28
|
|
|
29
|
-
def __insert_sys_path(path):
|
|
30
|
-
if path not in sys.path:
|
|
31
|
-
sys.path.insert(0, path)
|
|
32
|
-
|
|
33
|
-
def _insert_sys_paths(additional_sys_paths=None):
|
|
34
|
-
# Insert additional paths
|
|
35
|
-
if additional_sys_paths is not None:
|
|
36
|
-
for sp in additional_sys_paths:
|
|
37
|
-
__insert_sys_path(sp)
|
|
38
|
-
|
|
39
|
-
# Insert Holado paths
|
|
40
|
-
holado_path = os.getenv('HOLADO_PATH')
|
|
41
|
-
if holado_path is None:
|
|
42
|
-
# If HolAdo sources are not cloned on this environment, use path within this installation
|
|
43
|
-
from holado import get_holado_path
|
|
44
|
-
holado_path = get_holado_path()
|
|
45
|
-
__insert_sys_path(os.path.join(holado_path) )
|
|
46
|
-
__insert_sys_path(os.path.join(holado_path, "src") )
|
|
47
|
-
__insert_sys_path(os.path.join(holado_path, "tests", "behave") )
|
|
48
|
-
|
|
49
29
|
def _initialize_holado(TSessionContext=None, logging_config_file_path=None, log_level=logging.WARNING, log_in_file=False, with_session_path=False, **kwargs):
|
|
50
30
|
import holado
|
|
51
31
|
session_kwargs={'with_session_path':with_session_path or log_in_file}
|
|
@@ -67,7 +47,7 @@ def initialize(work_dir_path=None, change_work_dir=True,
|
|
|
67
47
|
|
|
68
48
|
if additional_sys_paths:
|
|
69
49
|
sys_paths.extend(additional_sys_paths)
|
|
70
|
-
|
|
50
|
+
insert_sys_paths(sys_paths)
|
|
71
51
|
|
|
72
52
|
logging_config_file_path=None
|
|
73
53
|
for dir_path in [res, work_dir_path, os.getcwd()]:
|
|
@@ -84,7 +64,7 @@ def initialize(work_dir_path=None, change_work_dir=True,
|
|
|
84
64
|
def change_working_dir(work_dir_path=None):
|
|
85
65
|
if work_dir_path:
|
|
86
66
|
res = _chdir(work_dir_path)
|
|
87
|
-
|
|
67
|
+
insert_sys_path(work_dir_path)
|
|
88
68
|
return res
|
|
89
69
|
else:
|
|
90
70
|
return None
|
holado_helper/script/script.py
CHANGED
|
@@ -76,7 +76,7 @@ class Script(object):
|
|
|
76
76
|
return parser
|
|
77
77
|
|
|
78
78
|
def change_working_dir(self, work_dir_path):
|
|
79
|
-
from initialize_script import change_working_dir as init_cd # @UnresolvedImport
|
|
79
|
+
from holado_helper.script.initialize_script import change_working_dir as init_cd # @UnresolvedImport
|
|
80
80
|
|
|
81
81
|
# If user working dir is not yet defined, save current working dir as user working dir
|
|
82
82
|
if self.__user_work_dir is None:
|
|
@@ -90,7 +90,7 @@ class Script(object):
|
|
|
90
90
|
|
|
91
91
|
def initialize(self):
|
|
92
92
|
if self.args is not None and hasattr(self.args, 'log_level') and hasattr(self.args, 'log_in_file'):
|
|
93
|
-
from initialize_script import change_logging_config # @UnresolvedImport
|
|
93
|
+
from holado_helper.script.initialize_script import change_logging_config # @UnresolvedImport
|
|
94
94
|
change_logging_config(log_level=self.args.log_level, log_in_file=self.args.log_in_file)
|
|
95
95
|
|
|
96
96
|
def run(self):
|
|
@@ -301,7 +301,7 @@ class ProtobufMessages(object):
|
|
|
301
301
|
if ValueTableManager.verify_table_is_name_value_table(fields_table, raise_exception=False):
|
|
302
302
|
self.__set_object_fields_with_name_value_table(res, fields_table)
|
|
303
303
|
else:
|
|
304
|
-
raise TechnicalException(f"When defining parameter fields_table, it must be a Name/Value table")
|
|
304
|
+
raise TechnicalException(f"When defining parameter fields_table, it must be a Name/Value table: [{Typing.get_object_class_fullname(fields_table)}]\n{fields_table.represent(4)}")
|
|
305
305
|
elif fields_dict is not None:
|
|
306
306
|
self.__set_object_fields_with_dict(res, fields_dict)
|
|
307
307
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#################################################
|
|
12
12
|
|
|
13
13
|
import copy
|
|
14
|
+
from holado.common.handlers.undefined import undefined_value
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class EvaluateParameters(object):
|
|
@@ -23,7 +24,8 @@ class EvaluateParameters(object):
|
|
|
23
24
|
|
|
24
25
|
def __init__(self, do_interpret=True, do_eval_variable=True, do_eval=True, \
|
|
25
26
|
raise_on_interpret_error=True, raise_on_variable_eval_error=True, raise_on_eval_error=True,
|
|
26
|
-
do_interpret_recursively=False, do_eval_variable_recursively=False
|
|
27
|
+
do_interpret_recursively=False, do_eval_variable_recursively=False,
|
|
28
|
+
result_type=undefined_value):
|
|
27
29
|
"""
|
|
28
30
|
Constructor
|
|
29
31
|
@param
|
|
@@ -36,9 +38,11 @@ class EvaluateParameters(object):
|
|
|
36
38
|
self.raise_on_interpret_error = raise_on_interpret_error
|
|
37
39
|
self.raise_on_variable_eval_error = raise_on_variable_eval_error
|
|
38
40
|
self.raise_on_eval_error = raise_on_eval_error
|
|
41
|
+
self.result_type = result_type
|
|
42
|
+
self.result_is_str = result_type is str
|
|
39
43
|
|
|
40
44
|
def __str__(self)->str:
|
|
41
|
-
return f"{{interpret:({self.do_interpret},recursive:{self.do_interpret_recursively},raise:{self.raise_on_interpret_error}) ; eval variable:({self.do_eval_variable},recursive:{self.do_eval_variable_recursively},raise:{self.raise_on_variable_eval_error}) ; eval:({self.do_eval},raise:{self.raise_on_eval_error})}}"
|
|
45
|
+
return f"{{interpret:({self.do_interpret},recursive:{self.do_interpret_recursively},raise:{self.raise_on_interpret_error}) ; eval variable:({self.do_eval_variable},recursive:{self.do_eval_variable_recursively},raise:{self.raise_on_variable_eval_error}) ; eval:({self.do_eval},raise:{self.raise_on_eval_error}) ; result type:{self.result_type}}}"
|
|
42
46
|
|
|
43
47
|
def with_interpret(self, do_interpret):
|
|
44
48
|
"""
|
|
@@ -160,6 +164,20 @@ class EvaluateParameters(object):
|
|
|
160
164
|
@return Same parameters but without raise
|
|
161
165
|
"""
|
|
162
166
|
return self.with_raise(False)
|
|
167
|
+
|
|
168
|
+
def with_result_type(self, result_type=undefined_value):
|
|
169
|
+
"""
|
|
170
|
+
Note: if result_type types are same, self instance is returned, else a new one is returned
|
|
171
|
+
@param result_type Evaluation result type
|
|
172
|
+
@return Same parameters but with result_type
|
|
173
|
+
"""
|
|
174
|
+
if self.result_type == result_type:
|
|
175
|
+
return self
|
|
176
|
+
else:
|
|
177
|
+
res = copy.deepcopy(self)
|
|
178
|
+
res.result_type = result_type
|
|
179
|
+
res.result_is_str = result_type is str
|
|
180
|
+
return res
|
|
163
181
|
|
|
164
182
|
@staticmethod
|
|
165
183
|
def default(raise_exception=True):
|
|
@@ -178,7 +196,7 @@ class EvaluateParameters(object):
|
|
|
178
196
|
@return Default evaluate parameters with raises
|
|
179
197
|
"""
|
|
180
198
|
if EvaluateParameters.__instance_default is None:
|
|
181
|
-
EvaluateParameters.__instance_default = EvaluateParameters(True, True, True, True, True, True)
|
|
199
|
+
EvaluateParameters.__instance_default = EvaluateParameters(True, True, True, True, True, True, undefined_value)
|
|
182
200
|
return EvaluateParameters.__instance_default
|
|
183
201
|
|
|
184
202
|
@staticmethod
|
|
@@ -187,7 +205,7 @@ class EvaluateParameters(object):
|
|
|
187
205
|
@return Default evaluate parameters without any raise
|
|
188
206
|
"""
|
|
189
207
|
if EvaluateParameters.__instance_default_without_raise is None:
|
|
190
|
-
EvaluateParameters.__instance_default_without_raise = EvaluateParameters(True, True, True, False, False, False)
|
|
208
|
+
EvaluateParameters.__instance_default_without_raise = EvaluateParameters(True, True, True, False, False, False, undefined_value)
|
|
191
209
|
return EvaluateParameters.__instance_default_without_raise
|
|
192
210
|
|
|
193
211
|
@staticmethod
|
|
@@ -204,7 +222,7 @@ class EvaluateParameters(object):
|
|
|
204
222
|
@return Default evaluate parameters without any raise
|
|
205
223
|
"""
|
|
206
224
|
if EvaluateParameters.__instance_nothing is None:
|
|
207
|
-
EvaluateParameters.__instance_nothing = EvaluateParameters(False, False, False, False, False, False)
|
|
225
|
+
EvaluateParameters.__instance_nothing = EvaluateParameters(False, False, False, False, False, False, undefined_value)
|
|
208
226
|
return EvaluateParameters.__instance_nothing
|
|
209
227
|
|
|
210
228
|
|
|
@@ -25,7 +25,7 @@ from holado_scripting.common.tools.evaluate_parameters import EvaluateParameters
|
|
|
25
25
|
from holado.holado_config import Config
|
|
26
26
|
from holado_multitask.multitasking.multitask_manager import MultitaskManager
|
|
27
27
|
from holado_python.standard_library.typing import Typing
|
|
28
|
-
from holado.common.handlers.undefined import undefined_value
|
|
28
|
+
from holado.common.handlers.undefined import undefined_value, not_applicable
|
|
29
29
|
|
|
30
30
|
logger = logging.getLogger(__name__)
|
|
31
31
|
|
|
@@ -47,52 +47,49 @@ class ExpressionEvaluator(object):
|
|
|
47
47
|
self.__variable_manager = variable_manager
|
|
48
48
|
|
|
49
49
|
def evaluate_expression(self, expression, unescape_string_method=None, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
50
|
-
value_type, value, value_to_eval = self.extract_expression_information(expression, unescape_string_method)
|
|
50
|
+
value_type, value, value_to_eval = self.extract_expression_information(expression, unescape_string_method, eval_params=eval_params)
|
|
51
51
|
if value_to_eval is not undefined_value:
|
|
52
|
-
|
|
52
|
+
if ValueTypes.is_string(value_type):
|
|
53
|
+
eval_params = eval_params.with_result_type(str)
|
|
54
|
+
res_type, res = self.evaluate_expression_of_information(value_type, value_to_eval, eval_params=eval_params, log_level=log_level)
|
|
55
|
+
if Tools.do_log(logger, log_level):
|
|
56
|
+
logger.log(log_level, f"Evaluate expression [{expression}] => ({value_type.name}, {value}, '{value_to_eval}') => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})")
|
|
53
57
|
else:
|
|
54
|
-
res = value
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return res
|
|
58
|
+
res_type, res = value_type, value
|
|
59
|
+
if Tools.do_log(logger, log_level):
|
|
60
|
+
logger.log(log_level, f"Evaluate expression [{expression}] => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})")
|
|
61
|
+
return res_type, res
|
|
58
62
|
|
|
59
63
|
def evaluate_python_expression(self, expression, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
60
|
-
res = self.evaluate_expression_of_information(ValueTypes.Symbol, expression, eval_params=eval_params)
|
|
64
|
+
res_type, res = self.evaluate_expression_of_information(ValueTypes.Symbol, expression, eval_params=eval_params, log_level=log_level)
|
|
61
65
|
if Tools.do_log(logger, log_level):
|
|
62
|
-
logger.log(log_level, f"Evaluate python expression [{expression}] => [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})")
|
|
63
|
-
return res
|
|
66
|
+
logger.log(log_level, f"Evaluate python expression [{expression}] => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})")
|
|
67
|
+
return res_type, res
|
|
64
68
|
|
|
65
|
-
def extract_expression_information(self, expression, unescape_string_method=None, log_level=logging.TRACE): # @UndefinedVariable
|
|
66
|
-
res = self.__extract_expression_information(expression, unescape_string_method=unescape_string_method)
|
|
69
|
+
def extract_expression_information(self, expression, unescape_string_method=None, eval_params=EvaluateParameters.default(), log_level=logging.TRACE): # @UndefinedVariable
|
|
70
|
+
res = self.__extract_expression_information(expression, unescape_string_method=unescape_string_method, eval_params=eval_params)
|
|
67
71
|
if Tools.do_log(logger, log_level):
|
|
68
72
|
logger.log(log_level, f"Extract expression information [{expression}] => {res}")
|
|
69
73
|
return res
|
|
70
74
|
|
|
71
|
-
def __extract_expression_information(self, expression, unescape_string_method=None):
|
|
75
|
+
def __extract_expression_information(self, expression, unescape_string_method=None, eval_params=EvaluateParameters.default()):
|
|
72
76
|
if isinstance(expression, str):
|
|
73
|
-
return self.__extract_expression_information_str(expression, unescape_string_method =
|
|
77
|
+
return self.__extract_expression_information_str(expression, unescape_string_method=unescape_string_method, eval_params=eval_params)
|
|
74
78
|
else:
|
|
75
|
-
return self.__extract_value_information(expression)
|
|
79
|
+
return (*self.__extract_value_information(expression, from_symbol=False, from_str=False), undefined_value)
|
|
76
80
|
|
|
77
|
-
def __extract_expression_information_str(self, expression, unescape_string_method=None):
|
|
81
|
+
def __extract_expression_information_str(self, expression, unescape_string_method=None, eval_params=EvaluateParameters.default()):
|
|
78
82
|
if unescape_string_method is None:
|
|
79
83
|
from holado_test.scenario.step_tools import StepTools
|
|
80
84
|
unescape_string_method = StepTools.unescape_string
|
|
81
85
|
|
|
82
86
|
try:
|
|
83
87
|
expr_content = expression.strip()
|
|
84
|
-
|
|
85
|
-
# Manage usual types
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return (ValueTypes.NotApplicable, undefined_value, undefined_value)
|
|
90
|
-
elif Converter.is_boolean(expr_content):
|
|
91
|
-
return (ValueTypes.Boolean, Converter.to_boolean(expr_content), undefined_value)
|
|
92
|
-
elif Converter.is_integer(expr_content):
|
|
93
|
-
return (ValueTypes.Integer, int(expr_content), undefined_value)
|
|
94
|
-
elif Converter.is_float(expr_content):
|
|
95
|
-
return (ValueTypes.Float, float(expr_content), undefined_value)
|
|
88
|
+
|
|
89
|
+
# Manage usual types
|
|
90
|
+
value_type, value = self.__extract_value_information(expr_content, from_symbol=not eval_params.result_is_str, from_str=not eval_params.result_is_str)
|
|
91
|
+
if value_type != ValueTypes.String:
|
|
92
|
+
return (value_type, value, undefined_value)
|
|
96
93
|
|
|
97
94
|
# Manage strings
|
|
98
95
|
for end_sym, val_type in [(Config.DYNAMIC_SYMBOL, ValueTypes.DynamicString),
|
|
@@ -104,73 +101,73 @@ class ExpressionEvaluator(object):
|
|
|
104
101
|
if unescape_string_method is not None:
|
|
105
102
|
text = unescape_string_method(text)
|
|
106
103
|
return (val_type, undefined_value, text)
|
|
107
|
-
|
|
108
|
-
# # Manage evaluated values
|
|
109
|
-
# try:
|
|
110
|
-
# value_evaluated = eval(expr_content)
|
|
111
|
-
# evaluated = True
|
|
112
|
-
# except (SyntaxError, NameError, ValueError):
|
|
113
|
-
# evaluated = False
|
|
114
|
-
# if evaluated:
|
|
115
|
-
# if isinstance(value_evaluated, bool):
|
|
116
|
-
# value_type = ValueTypes.Boolean
|
|
117
|
-
# elif isinstance(value_evaluated, int):
|
|
118
|
-
# value_type = ValueTypes.Integer
|
|
119
|
-
# elif isinstance(value_evaluated, float):
|
|
120
|
-
# value_type = ValueTypes.Float
|
|
121
|
-
# elif isinstance(value_evaluated, str):
|
|
122
|
-
# value_type = ValueTypes.String
|
|
123
|
-
# else:
|
|
124
|
-
# value_type = ValueTypes.Generic
|
|
125
|
-
# return (value_type, value_evaluated)
|
|
126
104
|
|
|
127
105
|
# Else consider content as a symbol
|
|
128
106
|
return (ValueTypes.Symbol, undefined_value, expr_content)
|
|
129
107
|
except Exception as exc:
|
|
130
108
|
raise TechnicalException(f"Error while extracting expression information in expression [{expression}] (type: {Typing.get_object_class_fullname(expression)})") from exc
|
|
131
109
|
|
|
132
|
-
def extract_value_information(self, value):
|
|
133
|
-
return self.__extract_value_information(value)
|
|
110
|
+
def extract_value_information(self, value, *, from_symbol=True, from_str=True):
|
|
111
|
+
return self.__extract_value_information(value, from_symbol=from_symbol, from_str=from_str)
|
|
134
112
|
|
|
135
|
-
def __extract_value_information(self, value):
|
|
113
|
+
def __extract_value_information(self, value, *, from_symbol=False, from_str=False):
|
|
136
114
|
if value is undefined_value:
|
|
137
|
-
return (ValueTypes.Undefined, undefined_value
|
|
115
|
+
return (ValueTypes.Undefined, undefined_value)
|
|
116
|
+
elif value is not_applicable:
|
|
117
|
+
return (ValueTypes.NotApplicable, not_applicable)
|
|
138
118
|
elif value is None:
|
|
139
|
-
return (ValueTypes.Null, None
|
|
119
|
+
return (ValueTypes.Null, None)
|
|
140
120
|
elif isinstance(value, bool):
|
|
141
|
-
return (ValueTypes.Boolean, value
|
|
121
|
+
return (ValueTypes.Boolean, value)
|
|
142
122
|
elif isinstance(value, int):
|
|
143
|
-
return (ValueTypes.Integer, value
|
|
123
|
+
return (ValueTypes.Integer, value)
|
|
144
124
|
elif isinstance(value, float):
|
|
145
|
-
return (ValueTypes.Float, value
|
|
125
|
+
return (ValueTypes.Float, value)
|
|
146
126
|
elif isinstance(value, str):
|
|
147
|
-
|
|
127
|
+
if from_symbol:
|
|
128
|
+
if value == Config.NONE_SYMBOL:
|
|
129
|
+
return (ValueTypes.Null, None)
|
|
130
|
+
elif value == Config.NOT_APPLICABLE_SYMBOL:
|
|
131
|
+
return (ValueTypes.NotApplicable, not_applicable)
|
|
132
|
+
|
|
133
|
+
if from_str:
|
|
134
|
+
if Converter.is_boolean(value):
|
|
135
|
+
return (ValueTypes.Boolean, Converter.to_boolean(value))
|
|
136
|
+
elif Converter.is_integer(value):
|
|
137
|
+
return (ValueTypes.Integer, int(value))
|
|
138
|
+
elif Converter.is_float(value):
|
|
139
|
+
return (ValueTypes.Float, float(value))
|
|
140
|
+
|
|
141
|
+
return (ValueTypes.String, value)
|
|
148
142
|
else:
|
|
149
|
-
return (ValueTypes.Generic, value
|
|
143
|
+
return (ValueTypes.Generic, value)
|
|
150
144
|
|
|
151
|
-
def evaluate_expression_of_information(self, value_type, value, eval_params=EvaluateParameters.default()):
|
|
152
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
153
|
-
logger.
|
|
154
|
-
res = self.__evaluate_expression_of_information(value_type, value, eval_params=eval_params)
|
|
155
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
156
|
-
logger.
|
|
157
|
-
return res
|
|
145
|
+
def evaluate_expression_of_information(self, value_type, value, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
146
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
147
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluating expression of information ({value_type.name}, {value}, {eval_params})") # @UndefinedVariable
|
|
148
|
+
res_type, res = self.__evaluate_expression_of_information(value_type, value, eval_params=eval_params, log_level=log_level)
|
|
149
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
150
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluate expression of information ({value_type.name}, {value}) => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})") # @UndefinedVariable
|
|
151
|
+
return res_type, res
|
|
158
152
|
|
|
159
|
-
def __evaluate_expression_of_information(self, value_type, value, eval_params=EvaluateParameters.default()):
|
|
160
|
-
if value_type in [ValueTypes.
|
|
161
|
-
return
|
|
153
|
+
def __evaluate_expression_of_information(self, value_type, value, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
154
|
+
if value_type in [ValueTypes.NotApplicable]:
|
|
155
|
+
return (value_type, not_applicable)
|
|
156
|
+
elif value_type in [ValueTypes.Null]:
|
|
157
|
+
return (value_type, None)
|
|
162
158
|
elif value_type in [ValueTypes.Boolean, ValueTypes.Integer, ValueTypes.Float, ValueTypes.Generic]:
|
|
163
|
-
return value
|
|
164
|
-
elif
|
|
165
|
-
|
|
159
|
+
return (value_type, value)
|
|
160
|
+
elif ValueTypes.is_string(value_type):
|
|
161
|
+
eval_params = eval_params.with_result_type(str)
|
|
162
|
+
return self.__evaluate_expression_of_information_string(value_type, value, eval_params=eval_params, log_level=log_level)
|
|
166
163
|
elif value_type in [ValueTypes.Symbol]:
|
|
167
|
-
return self.__evaluate_expression_of_information_symbol(value, eval_params=eval_params)
|
|
164
|
+
return self.__evaluate_expression_of_information_symbol(value, eval_params=eval_params, log_level=log_level)
|
|
168
165
|
else:
|
|
169
|
-
return value
|
|
166
|
+
return self.__extract_value_information(value)
|
|
170
167
|
|
|
171
|
-
def __evaluate_expression_of_information_string(self, value_type, value, eval_params=EvaluateParameters.default_without_raise()):
|
|
168
|
+
def __evaluate_expression_of_information_string(self, value_type, value, eval_params=EvaluateParameters.default_without_raise(), log_level=logging.DEBUG):
|
|
172
169
|
if eval_params.do_interpret:
|
|
173
|
-
res = self.__text_interpreter.interpret(value, eval_params=eval_params)
|
|
170
|
+
res = self.__text_interpreter.interpret(value, eval_params=eval_params, log_level=log_level)
|
|
174
171
|
else:
|
|
175
172
|
res = value
|
|
176
173
|
|
|
@@ -180,75 +177,80 @@ class ExpressionEvaluator(object):
|
|
|
180
177
|
res = str(res)
|
|
181
178
|
|
|
182
179
|
if value_type == ValueTypes.DynamicString:
|
|
183
|
-
|
|
180
|
+
res = self.__dynamic_text_manager.get(res)
|
|
184
181
|
elif value_type == ValueTypes.ThreadDynamicString:
|
|
185
|
-
|
|
182
|
+
res = self.__dynamic_text_manager.get(res, scope=MultitaskManager.get_thread_id())
|
|
186
183
|
elif value_type == ValueTypes.UniqueString:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
184
|
+
res = res + self.__unique_value_manager.new_string(padding_length=Config.unique_string_padding_length)
|
|
185
|
+
|
|
186
|
+
return self.extract_value_information(res, from_symbol=not eval_params.result_is_str, from_str=not eval_params.result_is_str)
|
|
190
187
|
|
|
191
|
-
def __evaluate_expression_of_information_symbol(self, value, eval_params=EvaluateParameters.default()):
|
|
192
|
-
if
|
|
193
|
-
logger.
|
|
188
|
+
def __evaluate_expression_of_information_symbol(self, value, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
189
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
190
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluating symbol ([{value}], {eval_params})") # @UndefinedVariable
|
|
194
191
|
res = value
|
|
195
192
|
|
|
196
193
|
# Replace explicit interpret parts
|
|
197
194
|
if eval_params.do_interpret and isinstance(res, str):
|
|
198
|
-
res, _, is_evaluated = self.__evaluate_interpret_expression(res, eval_params=eval_params)
|
|
195
|
+
res, _, is_evaluated = self.__evaluate_interpret_expression(res, eval_params=eval_params, log_level=log_level)
|
|
199
196
|
if is_evaluated:
|
|
200
197
|
# If symbol is already evaluated, stop evaluation process
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
# Note: evaluation of string was already done if asked, thus just evaluate symbols
|
|
199
|
+
res_type, res = self.__extract_value_information(res, from_symbol=not eval_params.result_is_str, from_str=not eval_params.result_is_str)
|
|
200
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
201
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluate symbol [{value}] => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (after interpret, with evaluate parameters: {eval_params})") # @UndefinedVariable
|
|
202
|
+
return res_type, res
|
|
204
203
|
# if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
205
204
|
# logger.trace(f"Evaluate symbol [{value}] - after interpret: [{res}] (type: {Typing.get_object_class_fullname(res)}) (with evaluate parameters: {eval_params})")
|
|
206
205
|
|
|
207
206
|
# Evaluate variable expression
|
|
208
207
|
# Note: if an eval must be done after interpret, variable shouldn't be evaluated unless it can makes failing eval
|
|
209
208
|
if eval_params.do_eval_variable and isinstance(res, str) and len(res) > 0:
|
|
210
|
-
result, is_evaluated = self.__evaluate_variable_expression(res, eval_params=eval_params)
|
|
209
|
+
result, is_evaluated = self.__evaluate_variable_expression(res, eval_params=eval_params, log_level=log_level)
|
|
211
210
|
if is_evaluated:
|
|
212
211
|
# If symbol is a variable expression, don't evaluate the result of the variable
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
res_type, res = self.__extract_value_information(result, from_symbol=False, from_str=False)
|
|
213
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
214
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluate symbol [{value}] => ({res_type.name}) [{res}] (type: {Typing.get_object_class_fullname(res)}) (after variable evaluation, with evaluate parameters: {eval_params})") # @UndefinedVariable
|
|
215
|
+
return res_type, res
|
|
216
216
|
|
|
217
217
|
# Evaluate expression
|
|
218
218
|
# if eval_params.do_eval and (isinstance(res, str) or isinstance(res, bytes)): # Commented as it doesn't work currently with bytes
|
|
219
219
|
if eval_params.do_eval and isinstance(res, str):
|
|
220
|
-
res = self.__evaluate_expression(res, locals_={}, eval_params=eval_params)
|
|
220
|
+
res = self.__evaluate_expression(res, locals_={}, eval_params=eval_params, log_level=log_level)
|
|
221
221
|
|
|
222
222
|
# logger.debug(f"Evaluate symbol [{value}] => [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
# Note: evaluation of string was already done if asked, thus just evaluate symbols
|
|
224
|
+
res_type, res = self.__extract_value_information(res, from_symbol=not eval_params.result_is_str, from_str=not eval_params.result_is_str)
|
|
225
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
226
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Evaluate symbol [{value}] => [{res}] (type: {Typing.get_object_class_fullname(res)}) (after full evaluation, with evaluate parameters: {eval_params})") # @UndefinedVariable
|
|
227
|
+
return res_type, res
|
|
226
228
|
|
|
227
|
-
def __evaluate_interpret_expression(self, value, eval_params=EvaluateParameters.default()):
|
|
229
|
+
def __evaluate_interpret_expression(self, value, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
228
230
|
result, is_interpreted, is_evaluated = value, False, False
|
|
229
231
|
|
|
230
232
|
nb_sections = self.__text_interpreter.get_number_of_sections(value)
|
|
231
233
|
if nb_sections > 0:
|
|
232
234
|
# If eval is authorized, and many sections exists, prefer interpret sections and eval result
|
|
233
235
|
if eval_params.do_eval and nb_sections > 1:
|
|
234
|
-
result, locals_ = self.__text_interpreter._interpret_sections(value, eval_params=eval_params)
|
|
236
|
+
result, locals_ = self.__text_interpreter._interpret_sections(value, eval_params=eval_params, log_level=log_level)
|
|
235
237
|
if result != value:
|
|
236
|
-
result = self.__evaluate_expression(result, locals_, eval_params=eval_params)
|
|
238
|
+
result = self.__evaluate_expression(result, locals_, eval_params=eval_params, log_level=log_level)
|
|
237
239
|
is_evaluated = True
|
|
238
240
|
else:
|
|
239
|
-
result = self.__text_interpreter.interpret(value, eval_params=eval_params)
|
|
241
|
+
result = self.__text_interpreter.interpret(value, eval_params=eval_params, log_level=log_level)
|
|
240
242
|
is_interpreted = result != value
|
|
241
243
|
|
|
242
244
|
# Manage recursive interpret, only in case of first interpret and if it wasn't evaluated
|
|
243
245
|
if eval_params.do_interpret_recursively and is_interpreted and not is_evaluated and isinstance(result, str):
|
|
244
|
-
new_result, new_is_interpreted, new_is_evaluated = self.__evaluate_interpret_expression(result, eval_params.with_raise_on_interpret_error(False))
|
|
246
|
+
new_result, new_is_interpreted, new_is_evaluated = self.__evaluate_interpret_expression(result, eval_params.with_raise_on_interpret_error(False), log_level=log_level)
|
|
245
247
|
if new_is_interpreted:
|
|
246
248
|
result = new_result
|
|
247
249
|
is_evaluated = new_is_evaluated
|
|
248
250
|
|
|
249
251
|
return result, is_interpreted, is_evaluated
|
|
250
252
|
|
|
251
|
-
def __evaluate_variable_expression(self, value, eval_params=EvaluateParameters.default()):
|
|
253
|
+
def __evaluate_variable_expression(self, value, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
252
254
|
is_evaluated, result = False, None
|
|
253
255
|
|
|
254
256
|
if self.__variable_manager.exists_variable(value):
|
|
@@ -261,20 +263,20 @@ class ExpressionEvaluator(object):
|
|
|
261
263
|
if eval_params.raise_on_variable_eval_error:
|
|
262
264
|
raise exc
|
|
263
265
|
else:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
if Tools.do_log(logger, log_level):
|
|
267
|
+
logger.log(log_level, f"Error while evaluating variable expression [{value}]: {Tools.represent_exception(exc)}\n -> traceback:\n{traceback.represent_stack(indent=4)}")
|
|
266
268
|
else:
|
|
267
269
|
is_evaluated = True
|
|
268
270
|
|
|
269
271
|
# Manage recursive evaluation, only in case of first variable evaluation
|
|
270
272
|
if eval_params.do_eval_variable_recursively and is_evaluated and isinstance(result, str) and result != value:
|
|
271
|
-
new_result, new_is_evaluated = self.__evaluate_variable_expression(result, eval_params.with_raise_on_variable_eval_error(False))
|
|
273
|
+
new_result, new_is_evaluated = self.__evaluate_variable_expression(result, eval_params.with_raise_on_variable_eval_error(False), log_level=log_level)
|
|
272
274
|
if new_is_evaluated:
|
|
273
275
|
result = new_result
|
|
274
276
|
|
|
275
277
|
return result, is_evaluated
|
|
276
278
|
|
|
277
|
-
def __evaluate_expression(self, value, locals_, eval_params=EvaluateParameters.default()):
|
|
279
|
+
def __evaluate_expression(self, value, locals_, eval_params=EvaluateParameters.default(), log_level=logging.DEBUG):
|
|
278
280
|
res = value
|
|
279
281
|
while True:
|
|
280
282
|
try:
|
|
@@ -301,20 +303,20 @@ class ExpressionEvaluator(object):
|
|
|
301
303
|
|
|
302
304
|
# If no import is done
|
|
303
305
|
if not is_imported:
|
|
304
|
-
if Tools.do_log(logger, logging.DEBUG):
|
|
305
|
-
logger.
|
|
306
|
+
if Tools.do_log(logger, logging.DEBUG, max_log_level=log_level):
|
|
307
|
+
logger.log(Tools.do_log_level(logging.DEBUG, log_level), f"Error while evaluating expression [{value}]: {exc}")
|
|
306
308
|
break
|
|
307
309
|
except Exception as exc:
|
|
308
310
|
if eval_params.raise_on_eval_error:
|
|
309
311
|
raise exc
|
|
310
312
|
else:
|
|
311
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
312
|
-
logger.
|
|
313
|
-
elif Tools.do_log(logger, logging.DEBUG):
|
|
313
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
314
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), f"Error while evaluating expression [{value}]: {Tools.represent_exception(exc)}") # @UndefinedVariable
|
|
315
|
+
elif Tools.do_log(logger, logging.DEBUG, max_log_level=log_level):
|
|
314
316
|
if isinstance(exc, SyntaxError):
|
|
315
|
-
logger.
|
|
317
|
+
logger.log(Tools.do_log_level(logging.DEBUG, log_level), f"Error while evaluating expression [{value}]: {repr(exc)}")
|
|
316
318
|
else:
|
|
317
|
-
logger.
|
|
319
|
+
logger.log(Tools.do_log_level(logging.DEBUG, log_level), f"Error while evaluating expression [{value}]: [{Typing.get_object_class_fullname(exc)}] {exc}")
|
|
318
320
|
break
|
|
319
321
|
else:
|
|
320
322
|
if not isinstance(result, types.ModuleType):
|
|
@@ -374,7 +376,7 @@ class ExpressionEvaluator(object):
|
|
|
374
376
|
|
|
375
377
|
def extract_string_value(self, expression, unescape_string_method=None, log_level=logging.DEBUG):
|
|
376
378
|
value_type, value_str, value_to_eval = self.extract_expression_information(expression, unescape_string_method)
|
|
377
|
-
if
|
|
379
|
+
if ValueTypes.is_string(value_type):
|
|
378
380
|
if value_to_eval is not undefined_value:
|
|
379
381
|
res = value_to_eval
|
|
380
382
|
else:
|
|
@@ -382,6 +384,6 @@ class ExpressionEvaluator(object):
|
|
|
382
384
|
else:
|
|
383
385
|
res = expression
|
|
384
386
|
if Tools.do_log(logger, log_level):
|
|
385
|
-
logger.
|
|
387
|
+
logger.log(log_level, f"Extract string value [{expression}] => ({value_type}, '{value_str}') => [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
386
388
|
return res
|
|
387
389
|
|
|
@@ -49,7 +49,7 @@ def __get_expression_evaluator():
|
|
|
49
49
|
def step_impl(context, condition_expression):
|
|
50
50
|
__get_scope_manager().log_conditions_info(f"Before evaluation of if condition expression [{condition_expression}]")
|
|
51
51
|
__get_scope_manager().increase_condition_level()
|
|
52
|
-
cond = __get_expression_evaluator().evaluate_python_expression(condition_expression)
|
|
52
|
+
_, cond = __get_expression_evaluator().evaluate_python_expression(condition_expression)
|
|
53
53
|
if isinstance(cond, bool) or Converter.is_boolean(cond):
|
|
54
54
|
if isinstance(cond, bool) and cond or Converter.is_boolean(cond) and Converter.to_boolean(cond):
|
|
55
55
|
__get_scope_manager().enter_in_valid_condition()
|
|
@@ -61,7 +61,7 @@ def step_impl(context, condition_expression):
|
|
|
61
61
|
def step_impl(context, condition_expression):
|
|
62
62
|
__get_scope_manager().leave_condition()
|
|
63
63
|
if not __get_scope_manager().had_valid_condition():
|
|
64
|
-
cond = __get_expression_evaluator().evaluate_python_expression(condition_expression)
|
|
64
|
+
_, cond = __get_expression_evaluator().evaluate_python_expression(condition_expression)
|
|
65
65
|
if isinstance(cond, bool) or Converter.is_boolean(cond):
|
|
66
66
|
if isinstance(cond, bool) and cond or Converter.is_boolean(cond) and Converter.to_boolean(cond):
|
|
67
67
|
__get_scope_manager().enter_in_valid_condition()
|
|
@@ -38,7 +38,7 @@ class FunctionHexToBytes(BaseFunction):
|
|
|
38
38
|
|
|
39
39
|
# Evaluate parameter
|
|
40
40
|
if isinstance(src, str):
|
|
41
|
-
src_eval = self.__expression_evaluator.evaluate_expression(src)
|
|
41
|
+
_, src_eval = self.__expression_evaluator.evaluate_expression(src)
|
|
42
42
|
if isinstance(src_eval, bytes) or isinstance(src_eval, str):
|
|
43
43
|
src = src_eval
|
|
44
44
|
else:
|