From 3920eb6d847d56e77c0697871f6891d0bdb58fbc Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 14 Feb 2026 11:37:37 +0100 Subject: [PATCH 01/15] (F001) cleanup after restructure [README.md] small updates [__init__] small updates --- OMPython/__init__.py | 7 ++++--- README.md | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/OMPython/__init__.py b/OMPython/__init__.py index 282923a7..78c8959e 100644 --- a/OMPython/__init__.py +++ b/OMPython/__init__.py @@ -6,7 +6,7 @@ ``` import OMPython omc = OMPython.OMCSessionLocal() -omc.sendExpression("command") +omc.sendExpression("getVersion()") ``` """ @@ -58,15 +58,16 @@ ModelicaDoERunner, ) +# the imports below are compatibility functionality (OMPython v4.0.0) from OMPython.ModelicaSystem import ( ModelicaSystem, - ModelicaSystemDoE, ModelicaSystemCmd, + ModelicaSystemDoE, ) from OMPython.OMCSession import ( OMCSessionCmd, - OMCSessionZMQ, OMCSessionException, + OMCSessionZMQ, OMCProcessLocal, OMCProcessPort, diff --git a/README.md b/README.md index a9cf3bdc..56730349 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ OMPython is a Python interface that uses ZeroMQ to communicate with OpenModelica ## Dependencies -- Python 3.x supported -- PyZMQ is required + - Python >= 3.10 supported with complete functionality for Python >= 3.12 + - Additional packages: numpy, psutil, pyparsing and pyzmq ## Installation @@ -49,8 +49,8 @@ help(OMPython) ``` ```python -from OMPython import OMCSessionLocal -omc = OMCSessionLocal() +import OMPython +omc = OMPython.OMCSessionLocal() omc.sendExpression("getVersion()") ``` From 9e7339e8a3f141c979122fbe3419c464a6f836e6 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 22:52:30 +0200 Subject: [PATCH 02/15] update OMParser * make it independent of any global state * use a dataclass * *NO* behaviour change! --- OMPython/OMParser.py | 244 ++++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 131 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index a82a9ca0..dc0e7359 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -32,12 +32,14 @@ Version: 1.0 """ +import dataclasses as dc from typing import Any -result: dict[str, Any] = {} -next_set = [] -next_set.append('') +@dc.dataclass +class OMParserData: + result: dict[str, Any] = dc.field(default_factory=lambda: dict()) + next_set: list[str] = dc.field(default_factory=lambda: ['']) def bool_from_string(string): @@ -66,21 +68,21 @@ def typeCheck(string): raise ValueError(f"String contains un-handled datatype: {repr(string)}!") -def make_values(strings, name): +def make_values(parsed: OMParserData, strings: str, name: str): if strings[0] == "(" and strings[-1] == ")": strings = strings[1:-1] if strings[0] == "{" and strings[-1] == "}": strings = strings[1:-1] # find the highest Set number of SET - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name if strings[0] == "\"" and strings[-1] == "\"": strings = strings.replace("\\\"", "\"") - result[main_set_name]['Values'] = [] - result[main_set_name]['Values'].append(strings) + parsed.result[main_set_name]['Values'] = [] + parsed.result[main_set_name]['Values'].append(strings) else: anchor = 0 position = 0 @@ -111,7 +113,7 @@ def make_values(strings, name): position += 1 - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name @@ -123,9 +125,9 @@ def make_values(strings, name): value = prop_str[anchor:i] value = (value.lstrip()).rstrip() if "=" in value: - result[main_set_name]['Elements'][name]['Properties']['Results'] = {} + parsed.result[main_set_name]['Elements'][name]['Properties']['Results'] = {} else: - result[main_set_name]['Elements'][name]['Properties']['Values'] = [] + parsed.result[main_set_name]['Elements'][name]['Properties']['Values'] = [] values.append(value) anchor = i + 1 elif c == "{": @@ -157,12 +159,13 @@ def make_values(strings, name): if len(multiple_values) != 0: multiple_values_type_checked = [typeCheck(val) for val in multiple_values] - result[main_set_name]['Elements'][name]['Properties']['Results'][varName] = multiple_values_type_checked + parsed.result[main_set_name]['Elements'][name]['Properties']['Results'][varName] = \ + multiple_values_type_checked elif varName != "" and varValue != "": - result[main_set_name]['Elements'][name]['Properties']['Results'][varName] = varValue + parsed.result[main_set_name]['Elements'][name]['Properties']['Results'][varName] = varValue else: if varValue != "": - result[main_set_name]['Elements'][name]['Properties']['Values'].append(varValue) + parsed.result[main_set_name]['Elements'][name]['Properties']['Values'].append(varValue) def delete_elements(strings): @@ -191,7 +194,7 @@ def delete_elements(strings): return strings -def make_subset_sets(strings, name): +def make_subset_sets(parsed: OMParserData, strings: str, name: str): main_set_name = "SET1" subset_name = "Subset1" set_name = "Set1" @@ -207,18 +210,18 @@ def make_subset_sets(strings, name): if "SET" in name: # find the highest SET number - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name # find the highest Subset number - for each_name in result[main_set_name]: + for each_name in parsed.result[main_set_name]: if each_name.find("Subset") != -1: subset_name = each_name highest_count = 1 # find the highest Set number & make the next Set in Subset - for each_name in result[main_set_name][subset_name]: + for each_name in parsed.result[main_set_name][subset_name]: if each_name.find("Set") != -1: the_num = each_name.replace('Set', '') the_num = int(the_num) @@ -231,24 +234,24 @@ def make_subset_sets(strings, name): the_num += 1 set_name = 'Set' + str(the_num) - result[main_set_name][subset_name] = {} - result[main_set_name][subset_name][set_name] = [] - result[main_set_name][subset_name][set_name] = items + parsed.result[main_set_name][subset_name] = {} + parsed.result[main_set_name][subset_name][set_name] = [] + parsed.result[main_set_name][subset_name][set_name] = items else: - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name - if "Subset1" not in result[main_set_name]['Elements'][name]['Properties']: - result[main_set_name]['Elements'][name]['Properties'][subset_name] = {} + if "Subset1" not in parsed.result[main_set_name]['Elements'][name]['Properties']: + parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name] = {} - for each_name in result[main_set_name]['Elements'][name]['Properties']: + for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: if each_name.find("Subset") != -1: subset_name = each_name highest_count = 1 - for each_name in result[main_set_name]['Elements'][name]['Properties'][subset_name]: + for each_name in parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name]: if each_name.find("Set") != -1: the_num = each_name.replace('Set', '') the_num = int(the_num) @@ -261,11 +264,11 @@ def make_subset_sets(strings, name): the_num += 1 set_name = 'Set' + str(the_num) - result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = [] - result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = items + parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = [] + parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = items -def make_sets(strings, name): +def make_sets(parsed: OMParserData, strings: str, name: str): if strings == "{}": return main_set_name = "SET1" @@ -283,13 +286,13 @@ def make_sets(strings, name): each_item = (each_item.lstrip()).rstrip() items.append(each_item) - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name if "SET" in name: highest_count = 1 - for each_name in result[main_set_name]: + for each_name in parsed.result[main_set_name]: if each_name.find("Set") != -1: the_num = each_name.replace('Set', '') the_num = int(the_num) @@ -302,12 +305,12 @@ def make_sets(strings, name): the_num += 1 set_name = 'Set' + str(the_num) - result[main_set_name][set_name] = [] - result[main_set_name][set_name] = items + parsed.result[main_set_name][set_name] = [] + parsed.result[main_set_name][set_name] = items else: highest_count = 1 - for each_name in result[main_set_name]['Elements'][name]['Properties']: + for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: if each_name.find("Set") != -1: the_num = each_name.replace('Set', '') the_num = int(the_num) @@ -319,23 +322,23 @@ def make_sets(strings, name): else: the_num += 1 set_name = 'Set' + str(the_num) - result[main_set_name]['Elements'][name]['Properties'][set_name] = [] - result[main_set_name]['Elements'][name]['Properties'][set_name] = items + parsed.result[main_set_name]['Elements'][name]['Properties'][set_name] = [] + parsed.result[main_set_name]['Elements'][name]['Properties'][set_name] = items -def get_inner_sets(strings, for_this, name): +def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str): start = 0 end = 0 main_set_name = "SET1" subset_name = "Subset1" if "{{" in strings: - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name if "SET" in name: highest_count = 1 - for each_name in result[main_set_name]: + for each_name in parsed.result[main_set_name]: if each_name.find("Subset") != -1: the_num = each_name.replace('Subset', '') the_num = int(the_num) @@ -347,10 +350,10 @@ def get_inner_sets(strings, for_this, name): else: the_num += 1 subset_name = subset_name + str(the_num) - result[main_set_name][subset_name] = {} + parsed.result[main_set_name][subset_name] = {} else: highest_count = 1 - for each_name in result[main_set_name]['Elements'][name]['Properties']: + for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: if each_name.find("Subset") != -1: the_num = each_name.replace('Subset', '') the_num = int(the_num) @@ -362,7 +365,7 @@ def get_inner_sets(strings, for_this, name): else: the_num += 1 subset_name = "Subset" + str(the_num) - result[main_set_name]['Elements'][name]['Properties'][subset_name] = {} + parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name] = {} start = strings.find("{{") end = strings.find("}}") @@ -375,7 +378,7 @@ def get_inner_sets(strings, for_this, name): inner_set = sets[inner_set_start:inner_set_end + 1] sets = sets.replace(inner_set, '') index = 0 - make_subset_sets(inner_set, name) + make_subset_sets(parsed=parsed, strings=inner_set, name=name) index += 1 elif "{" in strings: position = 0 @@ -391,11 +394,11 @@ def get_inner_sets(strings, for_this, name): if b_count == 0: mark_end = position + 1 sets = strings[mark_start:mark_end] - make_sets(sets, name) + make_sets(parsed=parsed, strings=sets, name=name) position += 1 -def make_elements(strings): +def make_elements(parsed: OMParserData, strings: str): index = 0 main_set_name = "SET1" @@ -416,12 +419,12 @@ def make_elements(strings): original_name = name name = name + str(1) - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name highest_count = 1 - for each_name in result[main_set_name]['Elements']: + for each_name in parsed.result[main_set_name]['Elements']: if original_name in each_name: the_num = each_name.replace(original_name, '') the_num = int(the_num) @@ -434,8 +437,8 @@ def make_elements(strings): the_num += 1 name = original_name + str(the_num) - result[main_set_name]['Elements'][name] = {} - result[main_set_name]['Elements'][name]['Properties'] = {} + parsed.result[main_set_name]['Elements'][name] = {} + parsed.result[main_set_name]['Elements'][name]['Properties'] = {} brace_count = 0 @@ -485,7 +488,7 @@ def make_elements(strings): element_str = element_str.replace(sets, '') position = 0 if len(sets) > 1: - get_inner_sets(sets, "Subset", name) + get_inner_sets(parsed=parsed, strings=sets, for_this="Subset", name=name) elif char == "{": start = position end = element_str.find("}") @@ -503,38 +506,20 @@ def make_elements(strings): element_str = element_str.replace(element_str[start:end + 1], '').strip() position = 0 if len(sets) > 1: - get_inner_sets(sets, "Set", name) + get_inner_sets(parsed=parsed, strings=sets, for_this="Set", name=name) position += 1 - make_values(element_str, name) + make_values(parsed=parsed, strings=element_str, name=name) index += 1 -def check_for_next_string(next_string): - anchor = 0 - position = 0 - stop = 0 - - # remove braces & keep only the SET's values - while position < len(next_string): - check_str = next_string[position] - if check_str == "{": - anchor = position - elif check_str == "}": - stop = position - delStr = next_string[anchor:stop + 1] - next_string = next_string.replace(delStr, '') - position = -1 - position += 1 - - if isinstance(next_string, str): - if len(next_string) == 0: - next_set = "" - return next_set - - -def get_the_set(string): - - def skip_all_inner_sets(position): +def get_the_set(parsed: OMParserData, string: str): + def skip_all_inner_sets( + parsed: OMParserData, + inner_sets: list, + next_set_list: list, + string: str, + position: int, + ): position += 1 count = 1 main_count = 1 @@ -586,10 +571,10 @@ def skip_all_inner_sets(position): last_set = skip position = skip next_set_list.append(string[mark_index:skip]) - if next_set[0] == '': - next_set[0] = string[mark_index:skip] + if parsed.next_set[0] == '': + parsed.next_set[0] = string[mark_index:skip] else: - next_set[0] = next_set[0] + string[mark_index:skip] + parsed.next_set[0] = parsed.next_set[0] + string[mark_index:skip] break elif ch == "(": brace_count += 1 @@ -638,10 +623,10 @@ def skip_all_inner_sets(position): last_subset = skip position = skip next_set_list.append(string[mark_index:skip]) - if next_set[0] == '': - next_set[0] = string[mark_index:skip] + if parsed.next_set[0] == '': + parsed.next_set[0] = string[mark_index:skip] else: - next_set[0] = next_set[0] + string[mark_index:skip] + parsed.next_set[0] = parsed.next_set[0] + string[mark_index:skip] break elif ch == "(": brace_count += 1 @@ -671,7 +656,7 @@ def skip_all_inner_sets(position): position += 1 else: - next_set[0] = "" + parsed.next_set[0] = "" return len(string) - 1 max_of_sets = max(last_set, last_subset) @@ -684,7 +669,7 @@ def skip_all_inner_sets(position): # Main entry of get_the_string() index = 0 count = 0 - next_set[0] = '' + parsed.next_set[0] = '' inner_sets = [] next_set_list = [] end = len(string) @@ -696,7 +681,13 @@ def skip_all_inner_sets(position): count += 1 if count == 1: anchor = index - index = skip_all_inner_sets(index) + index = skip_all_inner_sets( + parsed=parsed, + string=string, + inner_sets=inner_sets, + next_set_list=next_set_list, + position=index, + ) if index == (len(string) - 1): if string[index] == "}": count -= 1 @@ -709,7 +700,7 @@ def skip_all_inner_sets(position): main_set = string[anchor:end + 1] current_set = main_set - if next_set[0] != "": + if parsed.next_set[0] != "": for each_next in next_set_list: current_set = current_set.replace(each_next, '').strip() @@ -726,22 +717,21 @@ def skip_all_inner_sets(position): check_string = ''.join(e for e in current_set if e.isalnum()) if len(check_string) > 0: - return current_set, next_set[0] + return current_set, parsed.next_set[0] else: current_set = "" - return current_set, next_set[0] + return current_set, parsed.next_set[0] else: - return current_set, next_set[0] + return current_set, parsed.next_set[0] else: raise ValueError(f"The following String has no {{}}s to proceed: {repr(string)}!") # End of get_the_string() -# String parsing function for SimulationResults - -def formatSimRes(strings): - result['SimulationResults'] = {} +# String parsing function for SimulationResults +def formatSimRes(parsed: OMParserData, strings: str): + parsed.result['SimulationResults'] = {} simRes = strings[strings.find(' resultFile') + 1:strings.find('\nend SimulationResult')] simRes = simRes.translate(None, "\\") simRes = simRes.split('\n') @@ -757,9 +747,9 @@ def formatSimRes(strings): value = i[i.find("= ") + 1:i.find(",")] value = (value.lstrip()).rstrip() value = typeCheck(value) - result['SimulationResults'][var] = value + parsed.result['SimulationResults'][var] = value - result['SimulationOptions'] = {} + parsed.result['SimulationOptions'] = {} while index < len(options): update = False @@ -777,13 +767,12 @@ def formatSimRes(strings): index = index + 1 if update: opVal = typeCheck(opVal) - result['SimulationOptions'][opVar] = opVal - -# string parsing function for Record types + parsed.result['SimulationOptions'][opVar] = opVal -def formatRecords(strings): - result['RecordResults'] = {} +# string parsing function for Record types +def formatRecords(parsed: OMParserData, strings: str): + parsed.result['RecordResults'] = {} recordName = strings[strings.find("record ") + 1:strings.find("\n")] recordName = recordName.replace("ecord ", '').strip() strings = strings.replace(("end " + recordName + ";"), '').strip() @@ -797,17 +786,17 @@ def formatRecords(strings): value = (value.lstrip()).rstrip() value = typeCheck(value) if var != "": - result['RecordResults'][var] = value - result['RecordResults']['RecordName'] = recordName + parsed.result['RecordResults'][var] = value + parsed.result['RecordResults']['RecordName'] = recordName # Main entry to the OMParser module -def check_for_values(string): +def check_for_values(parsed: OMParserData, string: str): main_set_name = "SET1" if len(string) == 0: - return result + return parsed.result # changing untyped results to typed results if string[0] == "(": @@ -820,11 +809,11 @@ def check_for_values(string): return string if "record SimulationResult" in string: - formatSimRes(string) - return result + formatSimRes(parsed=parsed, strings=string) + return parsed.result if "record " in string: - formatRecords(string) - return result + formatRecords(parsed=parsed, strings=string) + return parsed.result string = typeCheck(string) @@ -833,58 +822,51 @@ def check_for_values(string): if string.find("{") == -1: return string - current_set, next_set = get_the_set(string) + current_set, next_set = get_the_set(parsed=parsed, string=string) - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: the_num = each_name.replace("SET", '') the_num = int(the_num) the_num = the_num + 1 main_set_name = "SET" + str(the_num) - result[main_set_name] = {} + parsed.result[main_set_name] = {} if current_set != "": if current_set[1] == "\"" and current_set[-2] == "\"": - make_values(current_set, "SET") + make_values(parsed=parsed, strings=current_set, name="SET") current_set = "" check_for_next_iteration = ''.join(e for e in next_set if e.isalnum()) if len(check_for_next_iteration) > 0: - check_for_values(next_set) + check_for_values(parsed=parsed, string=next_set) elif "(" in current_set: - for each_name in result: + for each_name in parsed.result: if each_name.find("SET") != -1: main_set_name = each_name - result[main_set_name]['Elements'] = {} + parsed.result[main_set_name]['Elements'] = {} - make_elements(current_set) + make_elements(parsed=parsed, strings=current_set) current_set = delete_elements(current_set) if "{{" in current_set: - get_inner_sets(current_set, "Subset", main_set_name) + get_inner_sets(parsed=parsed, strings=current_set, for_this="Subset", name=main_set_name) if "{" in current_set: - get_inner_sets(current_set, "Set", main_set_name) + get_inner_sets(parsed=parsed, strings=current_set, for_this="Set", name=main_set_name) check_for_next_iteration = ''.join(e for e in next_set if e not in {""}) if len(check_for_next_iteration) > 0: - check_for_values(next_set) + check_for_values(parsed=parsed, string=next_set) else: check_for_next_iteration = ''.join(e for e in next_set if e.isalnum()) if len(check_for_next_iteration) > 0: - check_for_values(next_set) + check_for_values(parsed=parsed, string=next_set) - return result + return parsed.result -# TODO: hack to be able to use one entry point which also resets the (global) variable results -# this should be checked such that the content of this file can be used as class with correct handling of -# variable usage def om_parser_basic(string: str): - result_return = check_for_values(string=string) - - global result - result = {} - - return result_return + parsed = OMParserData() + return check_for_values(parsed=parsed, string=string) From 087d7227d9338e74fa563b48fd013c0a2d7945ac Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 22:57:27 +0200 Subject: [PATCH 03/15] replace Python2 code by Python3 equivalent code --- OMPython/OMParser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index dc0e7359..d634dbdf 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -733,7 +733,7 @@ def skip_all_inner_sets( def formatSimRes(parsed: OMParserData, strings: str): parsed.result['SimulationResults'] = {} simRes = strings[strings.find(' resultFile') + 1:strings.find('\nend SimulationResult')] - simRes = simRes.translate(None, "\\") + simRes = simRes.replace("\\", "") simRes = simRes.split('\n') simOps = simRes.pop(1) options = simOps[simOps.find('"startTime') + 1:simOps.find('",')] @@ -777,7 +777,7 @@ def formatRecords(parsed: OMParserData, strings: str): recordName = recordName.replace("ecord ", '').strip() strings = strings.replace(("end " + recordName + ";"), '').strip() recordItems = strings[strings.find("\n") + 1: len(strings)] - recordItems = recordItems.translate(None, "\\") + recordItems = recordItems.replace("\\", "") recordItems = recordItems.split("\n") for each_item in recordItems: var = each_item[each_item.find('') + 1:each_item.find(" =")] From 44b1e61a835922c315ab91085deb537ca2021cbb Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:00:14 +0200 Subject: [PATCH 04/15] fix small bug in if condition --- OMPython/OMParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index d634dbdf..1ccffc8d 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -674,7 +674,7 @@ def skip_all_inner_sets( next_set_list = [] end = len(string) - if "{" and "}" in string: + if "{" in string and "}" in string: while index < len(string): character = string[index] if character == "{": From e43c14c4c3736f2a5a722b72964f1c3661af26a8 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:01:00 +0200 Subject: [PATCH 05/15] make code more readable --- OMPython/OMParser.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 1ccffc8d..565a48ab 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -76,7 +76,7 @@ def make_values(parsed: OMParserData, strings: str, name: str): # find the highest Set number of SET for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name if strings[0] == "\"" and strings[-1] == "\"": @@ -114,7 +114,7 @@ def make_values(parsed: OMParserData, strings: str, name: str): position += 1 for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name values = [] @@ -211,7 +211,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): if "SET" in name: # find the highest SET number for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name # find the highest Subset number @@ -222,7 +222,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 # find the highest Set number & make the next Set in Subset for each_name in parsed.result[main_set_name][subset_name]: - if each_name.find("Set") != -1: + if "SET" in each_name: the_num = each_name.replace('Set', '') the_num = int(the_num) if the_num > highest_count: @@ -240,7 +240,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): else: for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name if "Subset1" not in parsed.result[main_set_name]['Elements'][name]['Properties']: @@ -252,7 +252,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name]: - if each_name.find("Set") != -1: + if "SET" in each_name: the_num = each_name.replace('Set', '') the_num = int(the_num) if the_num > highest_count: @@ -287,13 +287,13 @@ def make_sets(parsed: OMParserData, strings: str, name: str): items.append(each_item) for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name if "SET" in name: highest_count = 1 for each_name in parsed.result[main_set_name]: - if each_name.find("Set") != -1: + if "SET" in each_name: the_num = each_name.replace('Set', '') the_num = int(the_num) if the_num > highest_count: @@ -311,7 +311,7 @@ def make_sets(parsed: OMParserData, strings: str, name: str): else: highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: - if each_name.find("Set") != -1: + if "SET" in each_name: the_num = each_name.replace('Set', '') the_num = int(the_num) if the_num > highest_count: @@ -334,7 +334,7 @@ def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str) if "{{" in strings: for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name if "SET" in name: highest_count = 1 @@ -420,7 +420,7 @@ def make_elements(parsed: OMParserData, strings: str): name = name + str(1) for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name highest_count = 1 @@ -825,7 +825,7 @@ def check_for_values(parsed: OMParserData, string: str): current_set, next_set = get_the_set(parsed=parsed, string=string) for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: the_num = each_name.replace("SET", '') the_num = int(the_num) the_num = the_num + 1 @@ -843,7 +843,7 @@ def check_for_values(parsed: OMParserData, string: str): elif "(" in current_set: for each_name in parsed.result: - if each_name.find("SET") != -1: + if "SET" in each_name: main_set_name = each_name parsed.result[main_set_name]['Elements'] = {} From fd7efc3c6b6a06d7b8e5a3d7fd2e9784c3f0d108 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:16:19 +0200 Subject: [PATCH 06/15] new function: get_set_name() - mypy checks --- OMPython/OMParser.py | 110 ++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 565a48ab..8d63a695 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -194,6 +194,25 @@ def delete_elements(strings): return strings +def get_set_name( + search_str: str, + each_name: str, + highest_count: int, +) -> tuple[int, str]: + the_num_str = each_name.replace(search_str, '') + the_num = int(the_num_str) + if the_num > highest_count: + highest_count = the_num + the_num += 1 + elif highest_count > the_num: + the_num = highest_count + 1 + else: + the_num += 1 + set_name = search_str + str(the_num) + + return highest_count, set_name + + def make_subset_sets(parsed: OMParserData, strings: str, name: str): main_set_name = "SET1" subset_name = "Subset1" @@ -223,16 +242,11 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): # find the highest Set number & make the next Set in Subset for each_name in parsed.result[main_set_name][subset_name]: if "SET" in each_name: - the_num = each_name.replace('Set', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - set_name = 'Set' + str(the_num) + highest_count, set_name = get_set_name( + search_str='Set', + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name][subset_name] = {} parsed.result[main_set_name][subset_name][set_name] = [] @@ -253,16 +267,11 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name]: if "SET" in each_name: - the_num = each_name.replace('Set', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - set_name = 'Set' + str(the_num) + highest_count, set_name = get_set_name( + search_str='Set', + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = [] parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name][set_name] = items @@ -294,16 +303,11 @@ def make_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 for each_name in parsed.result[main_set_name]: if "SET" in each_name: - the_num = each_name.replace('Set', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - set_name = 'Set' + str(the_num) + highest_count, set_name = get_set_name( + search_str='Set', + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name][set_name] = [] parsed.result[main_set_name][set_name] = items @@ -312,16 +316,12 @@ def make_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: if "SET" in each_name: - the_num = each_name.replace('Set', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - set_name = 'Set' + str(the_num) + highest_count, set_name = get_set_name( + search_str='Set', + each_name=each_name, + highest_count=highest_count, + ) + parsed.result[main_set_name]['Elements'][name]['Properties'][set_name] = [] parsed.result[main_set_name]['Elements'][name]['Properties'][set_name] = items @@ -340,31 +340,21 @@ def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str) highest_count = 1 for each_name in parsed.result[main_set_name]: if each_name.find("Subset") != -1: - the_num = each_name.replace('Subset', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - subset_name = subset_name + str(the_num) + highest_count, subset_name = get_set_name( + search_str='Subset', + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name][subset_name] = {} else: highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: if each_name.find("Subset") != -1: - the_num = each_name.replace('Subset', '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - subset_name = "Subset" + str(the_num) + highest_count, subset_name = get_set_name( + search_str='Subset', + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name] = {} start = strings.find("{{") From 7066862821f53e05268aff76ff4cc0922d7a95c5 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:28:15 +0200 Subject: [PATCH 07/15] more mypy fix (same variable for str and int) --- OMPython/OMParser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 8d63a695..418fefa3 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -816,8 +816,8 @@ def check_for_values(parsed: OMParserData, string: str): for each_name in parsed.result: if "SET" in each_name: - the_num = each_name.replace("SET", '') - the_num = int(the_num) + the_num_str = each_name.replace("SET", '') + the_num = int(the_num_str) the_num = the_num + 1 main_set_name = "SET" + str(the_num) From a9406bc5d4a9adfecd73fff077e62f94afd23e4e Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:28:32 +0200 Subject: [PATCH 08/15] use get_set_name() in make_elements() --- OMPython/OMParser.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 418fefa3..a08edb88 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -416,16 +416,11 @@ def make_elements(parsed: OMParserData, strings: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements']: if original_name in each_name: - the_num = each_name.replace(original_name, '') - the_num = int(the_num) - if the_num > highest_count: - highest_count = the_num - the_num += 1 - elif highest_count > the_num: - the_num = highest_count + 1 - else: - the_num += 1 - name = original_name + str(the_num) + highest_count, name = get_set_name( + search_str=original_name, + each_name=each_name, + highest_count=highest_count, + ) parsed.result[main_set_name]['Elements'][name] = {} parsed.result[main_set_name]['Elements'][name]['Properties'] = {} From 68f9adbfb28f19b00526d1b948d302f47e4c3462 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:31:05 +0200 Subject: [PATCH 09/15] improve get_elements_name() --- OMPython/OMParser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index a08edb88..c6a42dc4 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -199,6 +199,9 @@ def get_set_name( each_name: str, highest_count: int, ) -> tuple[int, str]: + if not each_name.startswith(search_str): + raise ValueError(f"Invalid name: {each_name} - searched for {search_str}") + the_num_str = each_name.replace(search_str, '') the_num = int(the_num_str) if the_num > highest_count: From bc9ac97afa4864a4f435da4df1d8c408433809be Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:32:03 +0200 Subject: [PATCH 10/15] improve check in make_elements() --- OMPython/OMParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index c6a42dc4..8e95e388 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -418,7 +418,7 @@ def make_elements(parsed: OMParserData, strings: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements']: - if original_name in each_name: + if each_name.startswith(original_name): highest_count, name = get_set_name( search_str=original_name, each_name=each_name, From 2fee2cfd773369cb3e9cfb1dc59c3736f110fed9 Mon Sep 17 00:00:00 2001 From: syntron Date: Sat, 27 Jun 2026 23:48:14 +0200 Subject: [PATCH 11/15] fix remaining mypy errors --- OMPython/OMParser.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 8e95e388..c3fd5169 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -658,8 +658,8 @@ def skip_all_inner_sets( index = 0 count = 0 parsed.next_set[0] = '' - inner_sets = [] - next_set_list = [] + inner_sets: list[str] = [] + next_set_list: list[str] = [] end = len(string) if "{" in string and "}" in string: @@ -722,14 +722,14 @@ def formatSimRes(parsed: OMParserData, strings: str): parsed.result['SimulationResults'] = {} simRes = strings[strings.find(' resultFile') + 1:strings.find('\nend SimulationResult')] simRes = simRes.replace("\\", "") - simRes = simRes.split('\n') - simOps = simRes.pop(1) + simRes_splitted = simRes.split('\n') + simOps = simRes_splitted.pop(1) options = simOps[simOps.find('"startTime') + 1:simOps.find('",')] options = options + "," index = 0 anchor = 0 - for i in simRes: + for i in simRes_splitted: var = i[i.find('') + 1:i.find(" =")] var = (var.lstrip()).rstrip() value = i[i.find("= ") + 1:i.find(",")] @@ -766,8 +766,8 @@ def formatRecords(parsed: OMParserData, strings: str): strings = strings.replace(("end " + recordName + ";"), '').strip() recordItems = strings[strings.find("\n") + 1: len(strings)] recordItems = recordItems.replace("\\", "") - recordItems = recordItems.split("\n") - for each_item in recordItems: + recordItems_splitted = recordItems.split("\n") + for each_item in recordItems_splitted: var = each_item[each_item.find('') + 1:each_item.find(" =")] var = (var.lstrip()).rstrip() value = each_item[each_item.find("= ") + 1:each_item.find(",")] From 6b0fabddb191fac2fd5b55e57eb98a090bcebf74 Mon Sep 17 00:00:00 2001 From: syntron Date: Sun, 28 Jun 2026 00:10:10 +0200 Subject: [PATCH 12/15] use '.startswith()' instead of ' in ' --- OMPython/OMParser.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index c3fd5169..acb4cebf 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -76,7 +76,7 @@ def make_values(parsed: OMParserData, strings: str, name: str): # find the highest Set number of SET for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name if strings[0] == "\"" and strings[-1] == "\"": @@ -114,7 +114,7 @@ def make_values(parsed: OMParserData, strings: str, name: str): position += 1 for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name values = [] @@ -230,10 +230,10 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): each_item = typeCheck(each_item) items.append(each_item) - if "SET" in name: + if name.startswith("SET"): # find the highest SET number for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name # find the highest Subset number @@ -244,7 +244,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 # find the highest Set number & make the next Set in Subset for each_name in parsed.result[main_set_name][subset_name]: - if "SET" in each_name: + if each_name.startswith("SET"): highest_count, set_name = get_set_name( search_str='Set', each_name=each_name, @@ -257,7 +257,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): else: for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name if "Subset1" not in parsed.result[main_set_name]['Elements'][name]['Properties']: @@ -269,7 +269,7 @@ def make_subset_sets(parsed: OMParserData, strings: str, name: str): highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties'][subset_name]: - if "SET" in each_name: + if each_name.startswith("SET"): highest_count, set_name = get_set_name( search_str='Set', each_name=each_name, @@ -299,13 +299,13 @@ def make_sets(parsed: OMParserData, strings: str, name: str): items.append(each_item) for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name - if "SET" in name: + if name.startswith("SET"): highest_count = 1 for each_name in parsed.result[main_set_name]: - if "SET" in each_name: + if each_name.startswith("SET"): highest_count, set_name = get_set_name( search_str='Set', each_name=each_name, @@ -318,7 +318,7 @@ def make_sets(parsed: OMParserData, strings: str, name: str): else: highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: - if "SET" in each_name: + if each_name.startswith("SET"): highest_count, set_name = get_set_name( search_str='Set', each_name=each_name, @@ -337,12 +337,12 @@ def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str) if "{{" in strings: for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name - if "SET" in name: + if each_name.startswith("SET"): highest_count = 1 for each_name in parsed.result[main_set_name]: - if each_name.find("Subset") != -1: + if each_name.startswith("Subset"): highest_count, subset_name = get_set_name( search_str='Subset', each_name=each_name, @@ -352,7 +352,7 @@ def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str) else: highest_count = 1 for each_name in parsed.result[main_set_name]['Elements'][name]['Properties']: - if each_name.find("Subset") != -1: + if each_name.startswith("Subset"): highest_count, subset_name = get_set_name( search_str='Subset', each_name=each_name, @@ -413,7 +413,7 @@ def make_elements(parsed: OMParserData, strings: str): name = name + str(1) for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name highest_count = 1 @@ -813,7 +813,7 @@ def check_for_values(parsed: OMParserData, string: str): current_set, next_set = get_the_set(parsed=parsed, string=string) for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): the_num_str = each_name.replace("SET", '') the_num = int(the_num_str) the_num = the_num + 1 @@ -831,7 +831,7 @@ def check_for_values(parsed: OMParserData, string: str): elif "(" in current_set: for each_name in parsed.result: - if "SET" in each_name: + if each_name.startswith("SET"): main_set_name = each_name parsed.result[main_set_name]['Elements'] = {} From 91f0d78e22d80cfd279894c06a189d69ce8370e1 Mon Sep 17 00:00:00 2001 From: syntron Date: Sun, 28 Jun 2026 00:32:40 +0200 Subject: [PATCH 13/15] further improve checks in get_set_name() --- OMPython/OMParser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index acb4cebf..8b4bcb80 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -201,6 +201,8 @@ def get_set_name( ) -> tuple[int, str]: if not each_name.startswith(search_str): raise ValueError(f"Invalid name: {each_name} - searched for {search_str}") + if not each_name[len(search_str):].isdigit(): + raise ValueError(f"Invalid name: {each_name} - no digits after {search_str}") the_num_str = each_name.replace(search_str, '') the_num = int(the_num_str) From f6c80933936b4e9d815ab9ae2b9cff5fd6c88b9e Mon Sep 17 00:00:00 2001 From: syntron Date: Sun, 28 Jun 2026 00:39:45 +0200 Subject: [PATCH 14/15] fix copy & paste error - use (correct) name instead of each_name --- OMPython/OMParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 8b4bcb80..3c1fa58a 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -341,7 +341,7 @@ def get_inner_sets(parsed: OMParserData, strings: str, for_this: str, name: str) for each_name in parsed.result: if each_name.startswith("SET"): main_set_name = each_name - if each_name.startswith("SET"): + if name.startswith("SET"): highest_count = 1 for each_name in parsed.result[main_set_name]: if each_name.startswith("Subset"): From 81b3a48b0fbea43cc4ba0c474abf9401e37bbc78 Mon Sep 17 00:00:00 2001 From: syntron Date: Sun, 28 Jun 2026 12:58:29 +0200 Subject: [PATCH 15/15] add intermediate value for the result before returning it - simpler debugging --- OMPython/OMParser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index 3c1fa58a..98dd5f99 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -859,4 +859,5 @@ def check_for_values(parsed: OMParserData, string: str): def om_parser_basic(string: str): parsed = OMParserData() - return check_for_values(parsed=parsed, string=string) + parsed_str = check_for_values(parsed=parsed, string=string) + return parsed_str