Skip to content

Commit 112290a

Browse files
authored
Introduce ruff as linter and formatter (#601)
Previously, the project only ran `pycodestyle` in CI for style checks and had no autoformatter, so formatting and import order were enforced manually and inconsistently. This change introduces `ruff` for both formatting and linting, configured in `ruff.toml`, and replaces `pycodestyle` in CI. The `CONTRIBUTING.md` is updated to document the new workflow. The formatter enforces double quotes, space indentation, and docstring code formatting (line length 120, target py310). The following lint rule groups are enabled and the codebase was fixed to comply: - `E`/`W`: pycodestyle errors and warnings - `I`: import order (isort) - `F4`: imports and `__future__` usage - `F5`: format strings (e.g. unnecessary f-strings) - `F7`: control flow (`return`/`break`/`continue` placement) - `F8`: undefined and unused names - `D201`/`D204`/`D211`/`D300`: basic docstring formatting - `COM818`: trailing comma enforcement - `PIE`: small readability improvements - `RUF100`: unused `noqa` statements Several rule groups are ignored for now (see the `TODO` in `ruff.toml`). Rules like `F403`/`F405` are ignored due to high existing star-import usage, while groups such as `N` (naming), `B` (bugbear), `S` (security), and `BLE` (blind except) are left for a later evaluation of whether to promote them to linting. Fixes #412
1 parent 43b0c16 commit 112290a

89 files changed

Lines changed: 10496 additions & 5152 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ jobs:
116116
- name: Check typing with MyPy
117117
run: |
118118
python -m mypy basyx test
119-
- name: Check code style with PyCodestyle
120-
run: |
121-
python -m pycodestyle --count --max-line-length 120 basyx test
122119
123120
sdk-readme-codeblocks:
124121
# This job runs the same static code analysis (mypy and pycodestyle) on the codeblocks in our docstrings.
@@ -265,9 +262,6 @@ jobs:
265262
- name: Check typing with MyPy
266263
run: |
267264
python -m mypy aas_compliance_tool test
268-
- name: Check code style with PyCodestyle
269-
run: |
270-
python -m pycodestyle --count --max-line-length 120 aas_compliance_tool test
271265
272266
compliance-tool-package:
273267
# This job checks if we can build our compliance_tool package
@@ -316,9 +310,6 @@ jobs:
316310
- name: Check typing with MyPy
317311
run: |
318312
python -m mypy app test
319-
- name: Check code style with PyCodestyle
320-
run: |
321-
python -m pycodestyle --count --max-line-length 120 app test
322313
323314
server-repository-docker:
324315
# This job checks if we can build our server package

CONTRIBUTING.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ before new code can be added:
143143
- We run the developed unittests and aim for a code coverage of at least 80%.
144144
- We perform static code analysis for type-checking and codestyle, not just in the code itself, but also in codeblocks
145145
that are inside docstrings and the `README.md`.
146+
- We apply a set of [ruff](https://docs.astral.sh/ruff/) linter rules (see [ruff.toml](ruff.toml)) to ensure a certain
147+
codestyle and prevent issues / bad practices to arise.
146148
- We check that the automatically generated developer documentation compiles.
147149
- We check that the Python Versions we support match between the different subprojects in the monorepository and are
148150
not End of Life.
@@ -164,8 +166,8 @@ pip install .[dev]
164166
165167
Running all checks:
166168
```bash
169+
ruff check
167170
mypy basyx test
168-
pycodestyle --max-line-length 120 basyx test
169171
python -m unittest
170172
coverage run --source basyx --branch -m unittest
171173
coverage report -m
@@ -185,6 +187,7 @@ of it without error.
185187
For that, you need to have Docker installed on your system.
186188
In the directory with the `Dockerfile`:
187189
```bash
190+
ruff check
188191
docker build -t basyx-python-server .
189192
docker run --name basyx-python-server basyx-python-server
190193
```
@@ -204,8 +207,8 @@ itself.
204207

205208
Then you can run the checks via:
206209
```bash
210+
ruff check
207211
mypy basyx test
208-
pycodestyle --max-line-length 120 basyx test
209212
python -m unittest
210213
coverage run --source basyx --branch -m unittest
211214
coverage report -m

compliance_tool/aas_compliance_tool/cli.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@
1212
"""
1313
import argparse
1414
import datetime
15-
1615
import logging
1716

1817
import pyecma376_2
19-
2018
from basyx.aas.adapter import aasx
21-
from basyx.aas.adapter.xml import write_aas_xml_file
22-
from aas_compliance_tool import compliance_check_xml as compliance_tool_xml, \
23-
compliance_check_json as compliance_tool_json, \
24-
compliance_check_aasx as compliance_tool_aasx
2519
from basyx.aas.adapter.json import write_aas_json_file
26-
from basyx.aas.examples.data import create_example, create_example_aas_binding, TEST_PDF_FILE
20+
from basyx.aas.adapter.xml import write_aas_xml_file
21+
from basyx.aas.examples.data import TEST_PDF_FILE, create_example, create_example_aas_binding
22+
23+
from aas_compliance_tool import compliance_check_aasx as compliance_tool_aasx
24+
from aas_compliance_tool import compliance_check_json as compliance_tool_json
25+
from aas_compliance_tool import compliance_check_xml as compliance_tool_xml
2726
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status
2827

2928

compliance_tool/aas_compliance_tool/compliance_check_aasx.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,15 @@
1414
import datetime
1515
import logging
1616
from typing import Optional, Tuple, cast
17-
import io
18-
from lxml import etree # type: ignore
1917

2018
import pyecma376_2
21-
22-
from aas_compliance_tool import compliance_check_json, compliance_check_xml
2319
from basyx.aas import model
2420
from basyx.aas.adapter import aasx
25-
from basyx.aas.adapter.xml import xml_deserialization
2621
from basyx.aas.adapter.json import json_deserialization
27-
from basyx.aas.examples.data import example_aas, create_example_aas_binding
22+
from basyx.aas.adapter.xml import xml_deserialization
23+
from basyx.aas.examples.data import create_example_aas_binding, example_aas
2824
from basyx.aas.examples.data._helper import AASDataChecker, DataChecker
25+
2926
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status
3027

3128

compliance_tool/aas_compliance_tool/compliance_check_json.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager` by adding new steps and associated
1212
:class:`LogRecords <logging.LogRecord>`
1313
"""
14-
import os
15-
import json
1614
import logging
17-
from typing import Optional, IO
15+
from typing import Optional
1816

19-
from basyx.aas import (model)
17+
from basyx.aas import model
2018
from basyx.aas.adapter.json import json_deserialization
21-
from basyx.aas.examples.data import example_aas, create_example
19+
from basyx.aas.examples.data import create_example, example_aas
2220
from basyx.aas.examples.data._helper import AASDataChecker
21+
2322
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status
2423

2524

compliance_tool/aas_compliance_tool/compliance_check_xml.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager` by adding new steps and associated
1212
:class:`LogRecords <logging.LogRecord>`
1313
"""
14-
import os
15-
from lxml import etree # type: ignore
1614
import logging
1715
from typing import Optional
1816

1917
from basyx.aas import model
2018
from basyx.aas.adapter.xml import xml_deserialization
21-
from basyx.aas.examples.data import example_aas, create_example
19+
from basyx.aas.examples.data import create_example, example_aas
2220
from basyx.aas.examples.data._helper import AASDataChecker
21+
2322
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status
2423

2524

compliance_tool/aas_compliance_tool/state_manager.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
This module defines a :class:`~.ComplianceToolStateManager` to store :class:`LogRecords <logging.LogRecord>`
99
for single steps in a compliance check of the compliance tool
1010
"""
11-
import logging
1211
import enum
12+
import logging
1313
import pprint
14-
from typing import List, Dict
14+
from typing import Dict, List
15+
1516
from basyx.aas.examples.data._helper import DataChecker
1617

1718

@@ -25,6 +26,7 @@ class Status(enum.IntEnum):
2526
:cvar FAILED:
2627
:cvar NOT_EXECUTED:
2728
"""
29+
2830
SUCCESS = 0
2931
SUCCESS_WITH_WARNINGS = 1 # never used
3032
FAILED = 2
@@ -39,6 +41,7 @@ class Step:
3941
:ivar status: Status of the step from type Status
4042
:ivar log_list: List of :class:`LogRecords <logging.LogRecord>` which belong to this step
4143
"""
44+
4245
def __init__(self, name: str, status: Status, log_list: List[logging.LogRecord]):
4346
self.name = name
4447
self.status = status
@@ -65,6 +68,7 @@ class ComplianceToolStateManager(logging.Handler):
6568
6669
:ivar steps: List of :class:`Steps <.Step>`
6770
"""
71+
6872
def __init__(self):
6973
"""
7074
steps: List of steps. Each step consist of a step name, a step status and LogRecords belong to to this step.

compliance_tool/test/_test_helper.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import io
2-
from typing import Literal, Type, Optional
31
import datetime
2+
import io
43
import logging
4+
from typing import Literal, Optional, Type
55

66
import pyecma376_2
7-
8-
from basyx.aas.examples.data import create_example_aas_binding, TEST_PDF_FILE
7+
from basyx.aas.examples.data import TEST_PDF_FILE, create_example_aas_binding
98

109

1110
def create_example_aas_core_properties() -> pyecma376_2.OPCCoreProperties:

compliance_tool/test/test_aas_compliance_tool.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
import datetime
88
import hashlib
99
import io
10-
import os
1110
import tempfile
1211
import unittest
1312
from contextlib import redirect_stderr, redirect_stdout
1413
from io import StringIO
15-
from unittest.mock import patch, ANY
14+
from unittest.mock import ANY, patch
1615

1716
from aas_compliance_tool.cli import main, parse_cli_arguments
1817
from basyx.aas import model

compliance_tool/test/test_compliance_check_aasx.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
import unittest
88
from unittest import mock
99

10-
from ._test_helper import create_example_aas_core_properties, create_read_into_mock
1110
from aas_compliance_tool import compliance_check_aasx as compliance_tool
1211
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status
13-
1412
from basyx.aas.examples.data._helper import CheckResult
1513

14+
from ._test_helper import create_example_aas_core_properties, create_read_into_mock
15+
1616

1717
class ComplianceToolAASXTest(unittest.TestCase):
1818

0 commit comments

Comments
 (0)