diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 86345d5a..ae3adced 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -45,6 +45,7 @@ import sys import tempfile import time +from typing import Optional import uuid import pyparsing import zmq @@ -106,20 +107,23 @@ def sendExpression(self, command, parsed=True): """ pass - def ask(self, question, opt=None, parsed=True): - p = (question, opt, parsed) + def _ask(self, question: str, opt: Optional[list[str]] = None, parsed: Optional[bool] = True): + + if opt is None: + expression = question + elif isinstance(opt, list): + expression = f"{question}({','.join([str(x) for x in opt])})" + else: + raise Exception(f"Invalid definition of options for {repr(question)}: {repr(opt)}") + + p = (expression, parsed) if self._readonly and question != 'getErrorString': # can use cache if readonly if p in self._omc_cache: return self._omc_cache[p] - if opt: - expression = f'{question}({opt})' - else: - expression = question - - logger.debug('OMC ask: %s - parsed: %s', expression, parsed) + logger.debug('OMC ask: %s (parsed=%s)', expression, parsed) try: res = self.sendExpression(expression, parsed=parsed) @@ -134,68 +138,68 @@ def ask(self, question, opt=None, parsed=True): # TODO: Open Modelica Compiler API functions. Would be nice to generate these. def loadFile(self, filename): - return self.ask('loadFile', f'"{filename}"') + return self._ask(question='loadFile', opt=[f'"{filename}"']) def loadModel(self, className): - return self.ask('loadModel', className) + return self._ask(question='loadModel', opt=[className]) def isModel(self, className): - return self.ask('isModel', className) + return self._ask(question='isModel', opt=[className]) def isPackage(self, className): - return self.ask('isPackage', className) + return self._ask(question='isPackage', opt=[className]) def isPrimitive(self, className): - return self.ask('isPrimitive', className) + return self._ask(question='isPrimitive', opt=[className]) def isConnector(self, className): - return self.ask('isConnector', className) + return self._ask(question='isConnector', opt=[className]) def isRecord(self, className): - return self.ask('isRecord', className) + return self._ask(question='isRecord', opt=[className]) def isBlock(self, className): - return self.ask('isBlock', className) + return self._ask(question='isBlock', opt=[className]) def isType(self, className): - return self.ask('isType', className) + return self._ask(question='isType', opt=[className]) def isFunction(self, className): - return self.ask('isFunction', className) + return self._ask(question='isFunction', opt=[className]) def isClass(self, className): - return self.ask('isClass', className) + return self._ask(question='isClass', opt=[className]) def isParameter(self, className): - return self.ask('isParameter', className) + return self._ask(question='isParameter', opt=[className]) def isConstant(self, className): - return self.ask('isConstant', className) + return self._ask(question='isConstant', opt=[className]) def isProtected(self, className): - return self.ask('isProtected', className) + return self._ask(question='isProtected', opt=[className]) def getPackages(self, className="AllLoadedClasses"): - return self.ask('getPackages', className) + return self._ask(question='getPackages', opt=[className]) def getClassRestriction(self, className): - return self.ask('getClassRestriction', className) + return self._ask(question='getClassRestriction', opt=[className]) def getDerivedClassModifierNames(self, className): - return self.ask('getDerivedClassModifierNames', className) + return self._ask(question='getDerivedClassModifierNames', opt=[className]) def getDerivedClassModifierValue(self, className, modifierName): - return self.ask('getDerivedClassModifierValue', f'{className}, {modifierName}') + return self._ask(question='getDerivedClassModifierValue', opt=[className, modifierName]) def typeNameStrings(self, className): - return self.ask('typeNameStrings', className) + return self._ask(question='typeNameStrings', opt=[className]) def getComponents(self, className): - return self.ask('getComponents', className) + return self._ask(question='getComponents', opt=[className]) def getClassComment(self, className): try: - return self.ask('getClassComment', className) + return self._ask(question='getClassComment', opt=[className]) except pyparsing.ParseException as ex: logger.warning("Method 'getClassComment' failed for %s", className) logger.warning('OMTypedParser error: %s', ex.msg) @@ -203,27 +207,27 @@ def getClassComment(self, className): def getNthComponent(self, className, comp_id): """ returns with (type, name, description) """ - return self.ask('getNthComponent', f'{className}, {comp_id}') + return self._ask(question='getNthComponent', opt=[className, comp_id]) def getNthComponentAnnotation(self, className, comp_id): - return self.ask('getNthComponentAnnotation', f'{className}, {comp_id}') + return self._ask(question='getNthComponentAnnotation', opt=[className, comp_id]) def getImportCount(self, className): - return self.ask('getImportCount', className) + return self._ask(question='getImportCount', opt=[className]) def getNthImport(self, className, importNumber): # [Path, id, kind] - return self.ask('getNthImport', f'{className}, {importNumber}') + return self._ask(question='getNthImport', opt=[className, importNumber]) def getInheritanceCount(self, className): - return self.ask('getInheritanceCount', className) + return self._ask(question='getInheritanceCount', opt=[className]) def getNthInheritedClass(self, className, inheritanceDepth): - return self.ask('getNthInheritedClass', f'{className}, {inheritanceDepth}') + return self._ask(question='getNthInheritedClass', opt=[className, inheritanceDepth]) def getParameterNames(self, className): try: - return self.ask('getParameterNames', className) + return self._ask(question='getParameterNames', opt=[className]) except KeyError as ex: logger.warning('OMPython error: %s', ex) # FIXME: OMC returns with a different structure for empty parameter set @@ -231,29 +235,29 @@ def getParameterNames(self, className): def getParameterValue(self, className, parameterName): try: - return self.ask('getParameterValue', f'{className}, {parameterName}') + return self._ask(question='getParameterValue', opt=[className, parameterName]) except pyparsing.ParseException as ex: logger.warning('OMTypedParser error: %s', ex.msg) return "" def getComponentModifierNames(self, className, componentName): - return self.ask('getComponentModifierNames', f'{className}, {componentName}') + return self._ask(question='getComponentModifierNames', opt=[className, componentName]) def getComponentModifierValue(self, className, componentName): - return self.ask(question='getComponentModifierValue', opt=f'{className}, {componentName}') + return self._ask(question='getComponentModifierValue', opt=[className, componentName]) def getExtendsModifierNames(self, className, componentName): - return self.ask('getExtendsModifierNames', f'{className}, {componentName}') + return self._ask(question='getExtendsModifierNames', opt=[className, componentName]) def getExtendsModifierValue(self, className, extendsName, modifierName): - return self.ask(question='getExtendsModifierValue', opt=f'{className}, {extendsName}, {modifierName}') + return self._ask(question='getExtendsModifierValue', opt=[className, extendsName, modifierName]) def getNthComponentModification(self, className, comp_id): # FIXME: OMPython exception Results KeyError exception # get {$Code(....)} field # \{\$Code\((\S*\s*)*\)\} - value = self.ask('getNthComponentModification', f'{className}, {comp_id}', parsed=False) + value = self._ask(question='getNthComponentModification', opt=[className, comp_id], parsed=False) value = value.replace("{$Code(", "") return value[:-3] # return self.re_Code.findall(value) @@ -269,15 +273,13 @@ def getNthComponentModification(self, className, comp_id): # end getClassNames; def getClassNames(self, className=None, recursive=False, qualified=False, sort=False, builtin=False, showProtected=False): - value = self.ask( - 'getClassNames', - (f'{className}, ' if className else '') + - f'recursive={str(recursive).lower()}, ' - f'qualified={str(qualified).lower()}, ' - f'sort={str(sort).lower()}, ' - f'builtin={str(builtin).lower()}, ' - f'showProtected={str(showProtected).lower()}' - ) + value = self._ask(question='getClassNames', + opt=[className] if className else [] + [f'recursive={str(recursive).lower()}', + f'qualified={str(qualified).lower()}', + f'sort={str(sort).lower()}', + f'builtin={str(builtin).lower()}', + f'showProtected={str(showProtected).lower()}'] + ) return value