From 5310cb9b5d044ee2f56c67589af699d550065467 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 29 Oct 2025 21:30:01 +0100 Subject: [PATCH 1/5] define flake8 config in pyproject.toml / remove setup.py --- .pre-commit-config.yaml | 2 ++ pyproject.toml | 6 ++++++ setup.cfg | 2 -- 3 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 setup.cfg diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 48f9ac643..484570b61 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,8 @@ repos: rev: '7.2.0' hooks: - id: flake8 + additional_dependencies: + - Flake8-pyproject - repo: https://github.com/codespell-project/codespell rev: v2.4.1 diff --git a/pyproject.toml b/pyproject.toml index 14d509fa6..c38559e28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,3 +32,9 @@ Documentation = "https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/ompy Issues = "https://github.com/OpenModelica/OMPython/issues" "Release Notes" = "https://github.com/OpenModelica/OMPython/releases" Download = "https://pypi.org/project/OMPython/#files" + +[tool.flake8] +extend-ignore = [ + 'E501', # line too long + 'E741', # ambiguous variable name 'l' +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index af2829890..000000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -extend-ignore = E501,E741 From bb0d3f2d5065831ab85194a52af310041fcfd6f9 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 29 Oct 2025 21:32:00 +0100 Subject: [PATCH 2/5] fix flake8 E741 - ambiguous variable name --- OMPython/OMTypedParser.py | 2 +- pyproject.toml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/OMPython/OMTypedParser.py b/OMPython/OMTypedParser.py index 40a345f7b..0f9ac4088 100644 --- a/OMPython/OMTypedParser.py +++ b/OMPython/OMTypedParser.py @@ -52,7 +52,7 @@ ) -def convertNumbers(s, l, toks): +def convertNumbers(s, loc, toks): n = toks[0] try: return int(n) diff --git a/pyproject.toml b/pyproject.toml index c38559e28..73bdb0fd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,5 +36,4 @@ Download = "https://pypi.org/project/OMPython/#files" [tool.flake8] extend-ignore = [ 'E501', # line too long - 'E741', # ambiguous variable name 'l' ] From 0da1bf554c154d094f5ccf376632cc68e2d49050 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 29 Oct 2025 21:48:31 +0100 Subject: [PATCH 3/5] cleanup OMTypedParser * function names * PEP8 renames in pyparsing (setParseAction() => set_parse_action()) * long lines --- OMPython/OMCSession.py | 2 +- OMPython/OMTypedParser.py | 66 +++++++++++++++++++++++++-------------- tests/test_typedParser.py | 2 +- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/OMPython/OMCSession.py b/OMPython/OMCSession.py index 47e2fd746..10b3d5468 100644 --- a/OMPython/OMCSession.py +++ b/OMPython/OMCSession.py @@ -54,7 +54,7 @@ import zmq # TODO: replace this with the new parser -from OMPython.OMTypedParser import parseString as om_parser_typed +from OMPython.OMTypedParser import om_parser_typed from OMPython.OMParser import om_parser_basic # define logger using the current module name as ID diff --git a/OMPython/OMTypedParser.py b/OMPython/OMTypedParser.py index 0f9ac4088..de6148145 100644 --- a/OMPython/OMTypedParser.py +++ b/OMPython/OMTypedParser.py @@ -31,6 +31,8 @@ __status__ = "Prototype" __maintainer__ = "https://openmodelica.org" +from typing import Any + from pyparsing import ( Combine, Dict, @@ -52,7 +54,7 @@ ) -def convertNumbers(s, loc, toks): +def convert_numbers(s, loc, toks): n = toks[0] try: return int(n) @@ -60,7 +62,7 @@ def convertNumbers(s, loc, toks): return float(n) -def convertString2(s, s2): +def convert_string2(s, s2): tmp = s2[0].replace("\\\"", "\"") tmp = tmp.replace("\"", "\\\"") tmp = tmp.replace("\'", "\\'") @@ -68,29 +70,29 @@ def convertString2(s, s2): tmp = tmp.replace("\n", "\\n") tmp = tmp.replace("\r", "\\r") tmp = tmp.replace("\t", "\\t") - return "'"+tmp+"'" + return "'" + tmp + "'" -def convertString(s, s2): +def convert_string(s, s2): return s2[0].replace("\\\"", '"') -def convertDict(d): +def convert_dict(d): return dict(d[0]) -def convertTuple(t): +def convert_tuple(t): return tuple(t[0]) -def evaluateExpression(s, loc, toks): +def evaluate_expression(s, loc, toks): # Convert the tokens (ParseResults) into a string expression flat_list = [item for sublist in toks[0] for item in sublist] expr = "".join(flat_list) try: # Evaluate the expression safely return eval(expr) - except Exception: + except (SyntaxError, NameError): return expr @@ -102,42 +104,60 @@ def evaluateExpression(s, loc, toks): (Word("*/", exact=1), 2, opAssoc.LEFT), (Word("+-", exact=1), 2, opAssoc.LEFT), ], -).setParseAction(evaluateExpression) +).set_parse_action(evaluate_expression) omcRecord = Forward() omcValue = Forward() # pyparsing's replace_with (and thus replaceWith) has incorrect type # annotation: https://github.com/pyparsing/pyparsing/issues/602 -TRUE = Keyword("true").setParseAction(replaceWith(True)) # type: ignore -FALSE = Keyword("false").setParseAction(replaceWith(False)) # type: ignore -NONE = (Keyword("NONE") + Suppress("(") + Suppress(")")).setParseAction(replaceWith(None)) # type: ignore +TRUE = Keyword("true").set_parse_action(replaceWith(True)) # type: ignore +FALSE = Keyword("false").set_parse_action(replaceWith(False)) # type: ignore +NONE = (Keyword("NONE") + Suppress("(") + Suppress(")")).set_parse_action(replaceWith(None)) # type: ignore SOME = (Suppress(Keyword("SOME")) + Suppress("(") + omcValue + Suppress(")")) -omcString = QuotedString(quoteChar='"', escChar='\\', multiline=True).setParseAction(convertString) +omcString = QuotedString(quoteChar='"', escChar='\\', multiline=True).set_parse_action(convert_string) omcNumber = Combine(Optional('-') + ('0' | Word('123456789', nums)) + Optional('.' + Word(nums)) + Optional(Word('eE', exact=1) + Word(nums + '+-', nums))) # ident = Word(alphas + "_", alphanums + "_") | Combine("'" + Word(alphanums + "!#$%&()*+,-./:;<>=?@[]^{}|~ ") + "'") -ident = Word(alphas + "_", alphanums + "_") | QuotedString(quoteChar='\'', escChar='\\').setParseAction(convertString2) +ident = (Word(alphas + "_", alphanums + "_") + | QuotedString(quoteChar='\'', escChar='\\').set_parse_action(convert_string2)) fqident = Forward() fqident << ((ident + "." + fqident) | ident) omcValues = delimitedList(omcValue) -omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).setParseAction(convertTuple) -omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).setParseAction(convertTuple) -omcArraySpecialTypes = Group(Suppress('{') + delimitedList(arrayDimension) + Suppress('}')).setParseAction(convertTuple) -omcValue << (omcString | omcNumber | omcRecord | omcArray | omcArraySpecialTypes | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident)) +omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).set_parse_action(convert_tuple) +omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).set_parse_action(convert_tuple) +omcArraySpecialTypes = Group(Suppress('{') + + delimitedList(arrayDimension) + + Suppress('}')).set_parse_action(convert_tuple) +omcValue << (omcString + | omcNumber + | omcRecord + | omcArray + | omcArraySpecialTypes + | omcTuple + | SOME + | TRUE + | FALSE + | NONE + | Combine(fqident)) recordMember = delimitedList(Group(ident + Suppress('=') + omcValue)) -omcRecord << Group(Suppress('record') + Suppress(fqident) + Dict(recordMember) + Suppress('end') + Suppress(fqident) + Suppress(';')).setParseAction(convertDict) +omcRecord << Group(Suppress('record') + + Suppress(fqident) + + Dict(recordMember) + + Suppress('end') + + Suppress(fqident) + + Suppress(';')).set_parse_action(convert_dict) omcGrammar = Optional(omcValue) + StringEnd() -omcNumber.setParseAction(convertNumbers) +omcNumber.set_parse_action(convert_numbers) -def parseString(string): - res = omcGrammar.parseString(string) +def om_parser_typed(string) -> Any: + res = omcGrammar.parse_string(string) if len(res) == 0: - return + return None return res[0] diff --git a/tests/test_typedParser.py b/tests/test_typedParser.py index 60daedec5..8e74a556b 100644 --- a/tests/test_typedParser.py +++ b/tests/test_typedParser.py @@ -1,6 +1,6 @@ from OMPython import OMTypedParser -typeCheck = OMTypedParser.parseString +typeCheck = OMTypedParser.om_parser_typed def test_newline_behaviour(): From a1c67f7ed278f028c197e915a43515326464dffa Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 29 Oct 2025 21:52:15 +0100 Subject: [PATCH 4/5] fix flake8 E501 - line too long --- OMPython/ModelicaSystem.py | 24 ++++++++++++++++-------- pyproject.toml | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index ae4a5108b..d9d4cd875 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -916,7 +916,8 @@ def getSimulationOptions(self, names: Optional[str | list[str]] = None) -> dict[ Examples: >>> mod.getSimulationOptions() - {'startTime': '0', 'stopTime': '1.234', 'stepSize': '0.002', 'tolerance': '1.1e-08', 'solver': 'dassl', 'outputFormat': 'mat'} + {'startTime': '0', 'stopTime': '1.234', + 'stepSize': '0.002', 'tolerance': '1.1e-08', 'solver': 'dassl', 'outputFormat': 'mat'} >>> mod.getSimulationOptions("stopTime") ['1.234'] >>> mod.getSimulationOptions(["tolerance", "stopTime"]) @@ -1099,8 +1100,10 @@ def simulate( Examples: mod.simulate() mod.simulate(resultfile="a.mat") - mod.simulate(simflags="-noEventEmit -noRestart -override=e=0.3,g=10") # set runtime simulation flags, deprecated - mod.simulate(simargs={"noEventEmit": None, "noRestart": None, "override": "override": {"e": 0.3, "g": 10}}) # using simargs + # set runtime simulation flags, deprecated + mod.simulate(simflags="-noEventEmit -noRestart -override=e=0.3,g=10") + # using simargs + mod.simulate(simargs={"noEventEmit": None, "noRestart": None, "override": "override": {"e": 0.3, "g": 10}}) """ if resultfile is None: @@ -1385,7 +1388,8 @@ def setSimulationOptions( ) -> bool: """ This method is used to set simulation options. It can be called: - with a sequence of simulation options name and assigning corresponding values as arguments as show in the example below: + with a sequence of simulation options name and assigning corresponding values as arguments as show in the + example below: usage >>> setSimulationOptions("Name=value") # depreciated >>> setSimulationOptions(["Name1=value1","Name2=value2"]) # depreciated @@ -1409,7 +1413,8 @@ def setLinearizationOptions( ) -> bool: """ This method is used to set linearization options. It can be called: - with a sequence of linearization options name and assigning corresponding value as arguments as show in the example below + with a sequence of linearization options name and assigning corresponding value as arguments as show in the + example below usage >>> setLinearizationOptions("Name=value") # depreciated >>> setLinearizationOptions(["Name1=value1","Name2=value2"]) # depreciated @@ -1433,7 +1438,8 @@ def setOptimizationOptions( ) -> bool: """ This method is used to set optimization options. It can be called: - with a sequence of optimization options name and assigning corresponding values as arguments as show in the example below: + with a sequence of optimization options name and assigning corresponding values as arguments as show in the + example below: usage >>> setOptimizationOptions("Name=value") # depreciated >>> setOptimizationOptions(["Name1=value1","Name2=value2"]) # depreciated @@ -1573,7 +1579,8 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs", Examples: >>> mod.convertMo2Fmu() '/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu' - >>> mod.convertMo2Fmu(version="2.0", fmuType="me|cs|me_cs", fileNamePrefix="", includeResources=True) + >>> mod.convertMo2Fmu(version="2.0", fmuType="me|cs|me_cs", fileNamePrefix="", + includeResources=True) '/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu' """ @@ -1596,7 +1603,8 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs", # to convert FMU to Modelica model def convertFmu2Mo(self, fmuName): # 20 """ - In order to load FMU, at first it needs to be translated into Modelica model. This method is used to generate Modelica model from the given FMU. It generates "fmuName_me_FMU.mo". + In order to load FMU, at first it needs to be translated into Modelica model. This method is used to generate + Modelica model from the given FMU. It generates "fmuName_me_FMU.mo". Currently, it only supports Model Exchange conversion. usage >>> convertFmu2Mo("c:/BouncingBall.Fmu") diff --git a/pyproject.toml b/pyproject.toml index 73bdb0fd4..e82745c99 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,6 @@ Issues = "https://github.com/OpenModelica/OMPython/issues" Download = "https://pypi.org/project/OMPython/#files" [tool.flake8] +max-line-length = 120 extend-ignore = [ - 'E501', # line too long ] From 8e736f7d1c75fc90a9d5467dff158e115ecb4238 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 29 Oct 2025 22:08:21 +0100 Subject: [PATCH 5/5] flake8 - fix test_linearization.py --- tests/test_linearization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_linearization.py b/tests/test_linearization.py index ccfd29a88..5805f7953 100644 --- a/tests/test_linearization.py +++ b/tests/test_linearization.py @@ -67,12 +67,12 @@ def test_getters(tmp_path): mod.setInputs(u1=10, u2=0) [A, B, C, D] = mod.linearize() - g = float(mod.getParameters("g")[0]) - l = float(mod.getParameters("l")[0]) + param_g = float(mod.getParameters("g")[0]) + param_l = float(mod.getParameters("l")[0]) assert mod.getLinearInputs() == ["u1", "u2"] assert mod.getLinearStates() == ["omega", "phi"] assert mod.getLinearOutputs() == ["y1", "y2"] - assert np.isclose(A, [[0, g/l], [1, 0]]).all() + assert np.isclose(A, [[0, param_g / param_l], [1, 0]]).all() assert np.isclose(B, [[0, 0], [0, 1]]).all() assert np.isclose(C, [[0.5, 1], [0, 1]]).all() assert np.isclose(D, [[1, 0], [1, 0]]).all()