From 103237ac8e2743a7be24fc682d0a00b1929b44cc Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:36:08 +0200 Subject: [PATCH 01/10] [OMParser] use a single entry point for OMParser --- OMPython/OMCSession.py | 11 +++-------- OMPython/OMParser.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 63fbba00..43de2f9c 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -52,7 +52,7 @@ # TODO: replace this with the new parser from OMPython import OMTypedParser -from OMPython import OMParser +from OMPython.OMParser import om_parser_basic # define logger using the current module name as ID @@ -81,9 +81,6 @@ def __init__(self, readonly=False): self._readonly = readonly self._omc_cache = {} - def clearOMParserResult(self): - OMParser.result = {} - def execute(self, command): warnings.warn("This function is depreciated and will be removed in future versions; " "please use sendExpression() instead", DeprecationWarning, stacklevel=1) @@ -246,8 +243,7 @@ def getComponentModifierValue(self, className, componentName): logger.warning('OMTypedParser error: %s', ex.message) result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) try: - answer = OMParser.check_for_values(result) - OMParser.result = {} + answer = om_parser_basic(result) return answer[2:] except (TypeError, UnboundLocalError) as ex: logger.warning('OMParser error: %s', ex) @@ -264,8 +260,7 @@ def getExtendsModifierValue(self, className, extendsName, modifierName): logger.warning('OMTypedParser error: %s', ex.message) result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) try: - answer = OMParser.check_for_values(result) - OMParser.result = {} + answer = om_parser_basic(result) return answer[2:] except (TypeError, UnboundLocalError) as ex: logger.warning('OMParser error: %s', ex) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index f1708947..c9bb1796 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -892,3 +892,15 @@ def check_for_values(string): check_for_values(next_set) return result + + +# TODO: hack to be able to use one entry point wich 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 From 36a54f0bf2b0e48ea1b0c38cff9354e9f2a88d24 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:38:40 +0200 Subject: [PATCH 02/10] [OMTypedParser] use a single entry point for OMTypedParser --- OMPython/OMCSession.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 43de2f9c..029569fe 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -51,7 +51,7 @@ import warnings # TODO: replace this with the new parser -from OMPython import OMTypedParser +from OMPython.OMTypedParser import parseString as om_parser_typed from OMPython.OMParser import om_parser_basic @@ -567,7 +567,7 @@ def sendExpression(self, command, parsed=True): else: result = self._omc.recv_string() if parsed is True: - answer = OMTypedParser.parseString(result) + answer = om_parser_typed(result) return answer else: return result From 7f74995e85fff13cb3b65f4a6879b86faaf5d4c8 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:45:43 +0200 Subject: [PATCH 03/10] [OMCSessionBase] fix exception handling for pyparsing.ParseException * fix ex.message => ex.msg --- OMPython/OMCSession.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 029569fe..f96f0ccd 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -194,7 +194,7 @@ def getClassComment(self, className): return self.ask('getClassComment', className) except pyparsing.ParseException as ex: logger.warning("Method 'getClassComment' failed for %s", className) - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) return 'No description available' def getNthComponent(self, className, comp_id): @@ -229,7 +229,7 @@ def getParameterValue(self, className, parameterName): try: return self.ask('getParameterValue', f'{className}, {parameterName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) return "" def getComponentModifierNames(self, className, componentName): @@ -240,7 +240,7 @@ def getComponentModifierValue(self, className, componentName): # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' return self.ask('getComponentModifierValue', f'{className}, {componentName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) try: answer = om_parser_basic(result) @@ -257,7 +257,7 @@ def getExtendsModifierValue(self, className, extendsName, modifierName): # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' return self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) try: answer = om_parser_basic(result) From 12edd0d03872e44a9ff98d3945ff1c12fe61997c Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:53:18 +0200 Subject: [PATCH 04/10] [OMCSessionBase] simplify the two use cases of OMParser.om_parse_basic() --- OMPython/OMCSession.py | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index f96f0ccd..9c495f13 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -128,6 +128,24 @@ def ask(self, question, opt=None, parsed=True): return res + def _ask_with_fallback(self, question: str, opt: str = None): + """ + Version of ask() with OMTypedParser as fallback for OMParser which is used in ask() => sendExpression() if + parsed is set to True. + """ + try: + # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' + return self.ask(question=question, opt=opt) + except pyparsing.ParseException as ex: + logger.warning('OMTypedParser error: %s', ex.msg) + result = self.ask(question=question, opt=opt, parsed=False) + try: + answer = om_parser_basic(result) + return answer[2:] + except (TypeError, UnboundLocalError) as ex: + logger.warning('OMParser error: %s', ex) + return result + # TODO: Open Modelica Compiler API functions. Would be nice to generate these. def loadFile(self, filename): return self.ask('loadFile', f'"{filename}"') @@ -236,35 +254,15 @@ def getComponentModifierNames(self, className, componentName): return self.ask('getComponentModifierNames', f'{className}, {componentName}') def getComponentModifierValue(self, className, componentName): - try: - # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' - return self.ask('getComponentModifierValue', f'{className}, {componentName}') - except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.msg) - result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) - try: - answer = om_parser_basic(result) - return answer[2:] - except (TypeError, UnboundLocalError) as ex: - logger.warning('OMParser error: %s', ex) - return result + return self._ask_with_fallback(question='getComponentModifierValue', + opt=f'{className}, {componentName}') def getExtendsModifierNames(self, className, componentName): return self.ask('getExtendsModifierNames', f'{className}, {componentName}') def getExtendsModifierValue(self, className, extendsName, modifierName): - try: - # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' - return self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}') - except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.msg) - result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) - try: - answer = om_parser_basic(result) - return answer[2:] - except (TypeError, UnboundLocalError) as ex: - logger.warning('OMParser error: %s', ex) - return result + return self._ask_with_fallback(question='getExtendsModifierValue', + opt=f'{className}, {extendsName}, {modifierName}') def getNthComponentModification(self, className, comp_id): # FIXME: OMPython exception Results KeyError exception From fbd5c5065eb857135ee31da8b1b4d90f3d9fc42c Mon Sep 17 00:00:00 2001 From: Adeel Asghar Date: Tue, 29 Apr 2025 09:26:12 +0200 Subject: [PATCH 05/10] Return unchanged result from `_ask_with_fallback` Fix typo --- OMPython/OMCSession.py | 13 +++++++------ OMPython/OMParser.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 9c495f13..8face06e 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -140,8 +140,7 @@ def _ask_with_fallback(self, question: str, opt: str = None): logger.warning('OMTypedParser error: %s', ex.msg) result = self.ask(question=question, opt=opt, parsed=False) try: - answer = om_parser_basic(result) - return answer[2:] + return om_parser_basic(result) except (TypeError, UnboundLocalError) as ex: logger.warning('OMParser error: %s', ex) return result @@ -254,15 +253,17 @@ def getComponentModifierNames(self, className, componentName): return self.ask('getComponentModifierNames', f'{className}, {componentName}') def getComponentModifierValue(self, className, componentName): - return self._ask_with_fallback(question='getComponentModifierValue', - opt=f'{className}, {componentName}') + result = self._ask_with_fallback(question='getComponentModifierValue', + opt=f'{className}, {componentName}') + return result[2:] def getExtendsModifierNames(self, className, componentName): return self.ask('getExtendsModifierNames', f'{className}, {componentName}') def getExtendsModifierValue(self, className, extendsName, modifierName): - return self._ask_with_fallback(question='getExtendsModifierValue', - opt=f'{className}, {extendsName}, {modifierName}') + result = self._ask_with_fallback(question='getExtendsModifierValue', + opt=f'{className}, {extendsName}, {modifierName}') + return result[2:] def getNthComponentModification(self, className, comp_id): # FIXME: OMPython exception Results KeyError exception diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index c9bb1796..1377fc6a 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -894,7 +894,7 @@ def check_for_values(string): return result -# TODO: hack to be able to use one entry point wich also resets the (global) variable results +# 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): From 2f93ad3b0bd54c69f8ca44c51a4b8651017c19da Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:36:08 +0200 Subject: [PATCH 06/10] [OMParser] use a single entry point for OMParser --- OMPython/OMCSession.py | 11 +++-------- OMPython/OMParser.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 63fbba00..43de2f9c 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -52,7 +52,7 @@ # TODO: replace this with the new parser from OMPython import OMTypedParser -from OMPython import OMParser +from OMPython.OMParser import om_parser_basic # define logger using the current module name as ID @@ -81,9 +81,6 @@ def __init__(self, readonly=False): self._readonly = readonly self._omc_cache = {} - def clearOMParserResult(self): - OMParser.result = {} - def execute(self, command): warnings.warn("This function is depreciated and will be removed in future versions; " "please use sendExpression() instead", DeprecationWarning, stacklevel=1) @@ -246,8 +243,7 @@ def getComponentModifierValue(self, className, componentName): logger.warning('OMTypedParser error: %s', ex.message) result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) try: - answer = OMParser.check_for_values(result) - OMParser.result = {} + answer = om_parser_basic(result) return answer[2:] except (TypeError, UnboundLocalError) as ex: logger.warning('OMParser error: %s', ex) @@ -264,8 +260,7 @@ def getExtendsModifierValue(self, className, extendsName, modifierName): logger.warning('OMTypedParser error: %s', ex.message) result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) try: - answer = OMParser.check_for_values(result) - OMParser.result = {} + answer = om_parser_basic(result) return answer[2:] except (TypeError, UnboundLocalError) as ex: logger.warning('OMParser error: %s', ex) diff --git a/OMPython/OMParser.py b/OMPython/OMParser.py index f1708947..c9bb1796 100644 --- a/OMPython/OMParser.py +++ b/OMPython/OMParser.py @@ -892,3 +892,15 @@ def check_for_values(string): check_for_values(next_set) return result + + +# TODO: hack to be able to use one entry point wich 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 From 7c5be8c7d8f27cc7c1136243ba9561633fd7a504 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:38:40 +0200 Subject: [PATCH 07/10] [OMTypedParser] use a single entry point for OMTypedParser --- OMPython/OMCSession.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 43de2f9c..029569fe 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -51,7 +51,7 @@ import warnings # TODO: replace this with the new parser -from OMPython import OMTypedParser +from OMPython.OMTypedParser import parseString as om_parser_typed from OMPython.OMParser import om_parser_basic @@ -567,7 +567,7 @@ def sendExpression(self, command, parsed=True): else: result = self._omc.recv_string() if parsed is True: - answer = OMTypedParser.parseString(result) + answer = om_parser_typed(result) return answer else: return result From e0bc792f5ab4692602ab3b38f2b28adc679df07e Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:45:43 +0200 Subject: [PATCH 08/10] [OMCSessionBase] fix exception handling for pyparsing.ParseException * fix ex.message => ex.msg --- OMPython/OMCSession.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 029569fe..f96f0ccd 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -194,7 +194,7 @@ def getClassComment(self, className): return self.ask('getClassComment', className) except pyparsing.ParseException as ex: logger.warning("Method 'getClassComment' failed for %s", className) - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) return 'No description available' def getNthComponent(self, className, comp_id): @@ -229,7 +229,7 @@ def getParameterValue(self, className, parameterName): try: return self.ask('getParameterValue', f'{className}, {parameterName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) return "" def getComponentModifierNames(self, className, componentName): @@ -240,7 +240,7 @@ def getComponentModifierValue(self, className, componentName): # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' return self.ask('getComponentModifierValue', f'{className}, {componentName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) try: answer = om_parser_basic(result) @@ -257,7 +257,7 @@ def getExtendsModifierValue(self, className, extendsName, modifierName): # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' return self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}') except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.message) + logger.warning('OMTypedParser error: %s', ex.msg) result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) try: answer = om_parser_basic(result) From a9063655cc79347e51c63b9a9ebf38b89ba90c3c Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 24 Apr 2025 20:53:18 +0200 Subject: [PATCH 09/10] [OMCSessionBase] simplify the two use cases of OMParser.om_parse_basic() --- OMPython/OMCSession.py | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index f96f0ccd..9c495f13 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -128,6 +128,24 @@ def ask(self, question, opt=None, parsed=True): return res + def _ask_with_fallback(self, question: str, opt: str = None): + """ + Version of ask() with OMTypedParser as fallback for OMParser which is used in ask() => sendExpression() if + parsed is set to True. + """ + try: + # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' + return self.ask(question=question, opt=opt) + except pyparsing.ParseException as ex: + logger.warning('OMTypedParser error: %s', ex.msg) + result = self.ask(question=question, opt=opt, parsed=False) + try: + answer = om_parser_basic(result) + return answer[2:] + except (TypeError, UnboundLocalError) as ex: + logger.warning('OMParser error: %s', ex) + return result + # TODO: Open Modelica Compiler API functions. Would be nice to generate these. def loadFile(self, filename): return self.ask('loadFile', f'"{filename}"') @@ -236,35 +254,15 @@ def getComponentModifierNames(self, className, componentName): return self.ask('getComponentModifierNames', f'{className}, {componentName}') def getComponentModifierValue(self, className, componentName): - try: - # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' - return self.ask('getComponentModifierValue', f'{className}, {componentName}') - except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.msg) - result = self.ask('getComponentModifierValue', f'{className}, {componentName}', parsed=False) - try: - answer = om_parser_basic(result) - return answer[2:] - except (TypeError, UnboundLocalError) as ex: - logger.warning('OMParser error: %s', ex) - return result + return self._ask_with_fallback(question='getComponentModifierValue', + opt=f'{className}, {componentName}') def getExtendsModifierNames(self, className, componentName): return self.ask('getExtendsModifierNames', f'{className}, {componentName}') def getExtendsModifierValue(self, className, extendsName, modifierName): - try: - # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' - return self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}') - except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.msg) - result = self.ask('getExtendsModifierValue', f'{className}, {extendsName}, {modifierName}', parsed=False) - try: - answer = om_parser_basic(result) - return answer[2:] - except (TypeError, UnboundLocalError) as ex: - logger.warning('OMParser error: %s', ex) - return result + return self._ask_with_fallback(question='getExtendsModifierValue', + opt=f'{className}, {extendsName}, {modifierName}') def getNthComponentModification(self, className, comp_id): # FIXME: OMPython exception Results KeyError exception From 6a6b50194ccfcc98a21b24df2455948a343e59ef Mon Sep 17 00:00:00 2001 From: Adeel Asghar Date: Wed, 30 Apr 2025 11:47:49 +0200 Subject: [PATCH 10/10] Do not strip the result The output of `getComponentModifierValue` is changed so we don't need to strip the result. And the output of `getExtendsModifierValue` is changed in https://github.com/OpenModelica/OpenModelica/pull/13533 Removed `_ask_with_fallback` and moved the fallback code to `sendExpression` --- OMPython/OMCSession.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 6b370cff..7b3e647f 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -128,23 +128,6 @@ def ask(self, question, opt=None, parsed=True): return res - def _ask_with_fallback(self, question: str, opt: str = None): - """ - Version of ask() with OMTypedParser as fallback for OMParser which is used in ask() => sendExpression() if - parsed is set to True. - """ - try: - # FIXME: OMPython exception UnboundLocalError exception for 'Modelica.Fluid.Machines.ControlledPump' - return self.ask(question=question, opt=opt) - except pyparsing.ParseException as ex: - logger.warning('OMTypedParser error: %s', ex.msg) - result = self.ask(question=question, opt=opt, parsed=False) - try: - return om_parser_basic(result) - except (TypeError, UnboundLocalError) as ex: - logger.warning('OMParser error: %s', ex) - return result - # TODO: Open Modelica Compiler API functions. Would be nice to generate these. def loadFile(self, filename): return self.ask('loadFile', f'"{filename}"') @@ -253,15 +236,13 @@ def getComponentModifierNames(self, className, componentName): return self.ask('getComponentModifierNames', f'{className}, {componentName}') def getComponentModifierValue(self, className, componentName): - return self._ask_with_fallback(question='getComponentModifierValue', - opt=f'{className}, {componentName}') + return self.ask(question='getComponentModifierValue', opt=f'{className}, {componentName}') def getExtendsModifierNames(self, className, componentName): return self.ask('getExtendsModifierNames', f'{className}, {componentName}') def getExtendsModifierValue(self, className, extendsName, modifierName): - return self._ask_with_fallback(question='getExtendsModifierValue', - opt=f'{className}, {extendsName}, {modifierName}') + return self.ask(question='getExtendsModifierValue', opt=f'{className}, {extendsName}, {modifierName}') def getNthComponentModification(self, className, comp_id): # FIXME: OMPython exception Results KeyError exception @@ -564,7 +545,14 @@ def sendExpression(self, command, parsed=True): else: result = self._omc.recv_string() if parsed is True: - answer = om_parser_typed(result) - return answer + try: + return om_parser_typed(result) + except pyparsing.ParseException as ex: + logger.warning('OMTypedParser error: %s. Returning the basic parser result.', ex.msg) + try: + return om_parser_basic(result) + except (TypeError, UnboundLocalError) as ex: + logger.warning('OMParser error: %s. Returning the unparsed result.', ex) + return result else: return result