Skip to content

Commit d52ac5b

Browse files
authored
refactor: Enable ruff and ament_mypy checks and fix lint errors (#1063)
* Enable flake8-bugbear and fix lint errors * Enable flake8-builtins and fix lint errors * Enable flake8-datetimez and fix lint errors * Enable flake8-executable and fix lint errors * Fix lint error in rosapi_node * Enable flake8-future-annotations and fix lint errors * Enable flake8-implicit-str-concat and fix lint errors * Enable flake8-pie and fix lint errors * Enable flake8-raise and fix lint errors * Enable flake8-return and fix lint errors * Enable flake8-simplify and fix lint errors * Enable flake8-type-checking and fix lint errors * Enable flake8-unused-arguments and fix lint errors * Enable flake8-use-pathlib and fix lint errors * Enable Perflint and fix lint errors * Enable pyupgrade and fix lint errors * Enable refurb and fix lint errors * Enable ruff-specific checks and fix errors * Fix subscribe test * Fix mypy errors * rosapi: type check test methods * Fix rosapi_node lint errors * Set max line length to 120 and fix some of the errors * Fix the rest of 'line too long' errors * Don't change argument names in public API methods * Enable flake8-errmsg and fix lint errors * Enable flake8-logging and fix lint error * Enable flake8-pyi and fix lint errors * Fix pylint errors * Add comments to ruff config * Fix trailing whitespace * Enable flake8-logging-format * Simplify message handler transitions * Fix other ruff lint errors * Add ament_mypy test and fix mypy errors * Fix ruff check in rosapi_node
1 parent cad53d7 commit d52ac5b

File tree

72 files changed

+738
-615
lines changed

Some content is hidden

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

72 files changed

+738
-615
lines changed

pyproject.toml

Lines changed: 75 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,71 +7,73 @@ line-length = 100
77

88
[tool.ruff.lint]
99
select = [
10-
# "AIR", # Airflow
11-
# "ERA", # Eradicate
12-
# "FAST", # FastAPI
10+
# "AIR", # Airflow, We don't use this framework
11+
# "ERA", # Eradicate, We allow commented-out code
12+
# "FAST", # FastAPI, We don't use this framework
1313

1414
# flake8 extensions
15-
"YTT", # flake8-2020
16-
# "ANN", # flake8-annotations
17-
"ASYNC", # flake8-async
18-
"S", # flake8-bandit
19-
# "BLE", # flake8-blind-except
20-
# "FBT", # flake8-boolean-trap
21-
# "B", # flake8-bugbear
22-
# "A", # flake8-builtins
23-
# "COM", # flake8-commas
24-
"C4", # flake8-comprehensions
25-
# "CPY", # flake8-copyright
26-
# "DTZ", # flake8-datetimez
27-
"T10", # flake8-debugger
28-
# "DJ", # flake8-django
29-
# "EM", # flake8-errmsg
30-
# "EXE", # flake8-executable
31-
# "FIX", # flake8-fixme
32-
# "FA", # flake8-future-annotations
33-
"INT", # flake8-gettext
34-
# "ISC", # flake8-implicit-str-concat
35-
"ICN", # flake8-import-conventions
36-
# "LOG", # flake8-logging
37-
# "G", # flake8-logging-format
38-
# "INP", # flake8-no-pep420
39-
# "PIE", # flake8-pie
40-
# "T20", # flake8-print
41-
# "PYI", # flake8-pyi
42-
# "PT", # flake8-pytest-style
43-
"Q", # flake8-quotes
44-
# "RSE", # flake8-raise
45-
# "RET", # flake8-return
46-
# "SLF", # flake8-self
47-
# "SIM", # flake8-simplify
48-
"SLOT", # flake8-slots
49-
"TID", # flake8-tidy-imports
50-
# "TD", # flake8-todos
51-
# "TC", # flake8-type-checking
52-
# "ARG", # flake8-unused-arguments
53-
# "PTH", # flake8-use-pathlib
15+
"YTT", # flake8-2020
16+
# "ANN", # flake8-annotations, There are too many missing annotations right now (TODO)
17+
"ASYNC", # flake8-async
18+
"S", # flake8-bandit
19+
# "BLE", # flake8-blind-except, Too much hassle to fix (TODO)
20+
# "FBT", # flake8-boolean-trap, We allow boolean traps
21+
"B", # flake8-bugbear
22+
"A", # flake8-builtins
23+
# "COM", # flake8-commas, We don't require trailing commas
24+
"C4", # flake8-comprehensions
25+
# "CPY", # flake8-copyright, preview feature
26+
"DTZ", # flake8-datetimez
27+
"T10", # flake8-debugger
28+
# "DJ", # flake8-django, We don't use this framework
29+
"EM", # flake8-errmsg
30+
"EXE", # flake8-executable
31+
# "FIX", # flake8-fixme, too many TODOs to fix them now
32+
"FA", # flake8-future-annotations
33+
"INT", # flake8-gettext
34+
"ISC", # flake8-implicit-str-concat
35+
"ICN", # flake8-import-conventions
36+
"LOG", # flake8-logging
37+
"G", # flake8-logging-format
38+
# "INP", # flake8-no-pep420, false positives with launch tests
39+
"PIE", # flake8-pie
40+
# "T20", # flake8-print, We allow some print statements
41+
"PYI", # flake8-pyi
42+
# "PT", # flake8-pytest-style, Too many errors to fix for now (TODO)
43+
"Q", # flake8-quotes
44+
"RSE", # flake8-raise
45+
"RET", # flake8-return
46+
# "SLF", # flake8-self, Too many "Private member accessed" errors (TODO)
47+
"SIM", # flake8-simplify
48+
"SLOT", # flake8-slots
49+
"TID", # flake8-tidy-imports
50+
# "TD", # flake8-todos, We don't enforce format for TODO comments
51+
"TC", # flake8-type-checking
52+
"ARG", # flake8-unused-arguments
53+
"PTH", # flake8-use-pathlib
5454

55-
"FLY", # flynt
56-
"I", # isort
57-
"C90", # mccabe
58-
"NPY", # numpy
59-
"PD", # pandas-vet
60-
# "N", # pep8-naming
61-
# "PERF", # Perflint
62-
"E", # pycodestyle errors
63-
"W", # pycodestyle warnings
64-
# "DOC", # pydoclint
65-
"D", # pydocstyle
66-
"F", # pyflakes
67-
"PGH", # pygrep-hooks
68-
# "PL", # pylint
69-
# "UP", # pyupgrade
70-
# "FURB", # refurb
71-
# "RUF", # ruff
72-
# "TRY", # tryceratops
55+
"FLY", # flynt
56+
"I", # isort
57+
"C90", # mccabe
58+
"NPY", # numpy
59+
"PD", # pandas-vet
60+
# "N", # pep8-naming, Can't fix without breaking API
61+
"PERF", # Perflint
62+
"E", # pycodestyle errors
63+
"W", # pycodestyle warnings
64+
# "DOC", # pydoclint, preview feature
65+
"D", # pydocstyle
66+
"F", # pyflakes
67+
"PGH", # pygrep-hooks
68+
"PL", # pylint
69+
"UP", # pyupgrade
70+
"FURB", # refurb
71+
"RUF", # ruff
72+
# "TRY", # tryceratops, Too many "Create your own exception" errors (TODO)
7373
]
7474
ignore = [
75+
"SIM108", # Opinionated: ternary operator does not always look simpler
76+
7577
# Undocumented code
7678
"D100",
7779
"D101",
@@ -89,8 +91,20 @@ ignore = [
8991
"S101", # assert
9092
"S110", # try-except-pass
9193
"S311", # suspicious-non-cryptographic-random-usage
94+
95+
# Pylint "too-many" errors
96+
"PLR0911",
97+
"PLR0912",
98+
"PLR0913",
99+
"PLR0914",
100+
"PLR0915",
101+
"PLR0916",
102+
"PLR0917",
103+
104+
"PLR2004", # magic-value-comparison, Too many to fix for now (TODO)
105+
"PLW0603", # global-statement, Will need a more sophisticated solution to fix this (TODO)
92106
]
93107

94108
mccabe.max-complexity = 36
95109

96-
pycodestyle.max-line-length = 217
110+
pycodestyle.max-line-length = 120

rosapi/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ if(BUILD_TESTING)
2626
find_package(ament_cmake_pytest REQUIRED)
2727
ament_add_pytest_test(${PROJECT_NAME}_test_stringify_field_types test/test_stringify_field_types.py)
2828
ament_add_pytest_test(${PROJECT_NAME}_test_typedefs test/test_typedefs.py)
29+
30+
find_package(ament_cmake_mypy REQUIRED)
31+
ament_mypy()
2932
endif()

rosapi/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ action servers and managing ROS parameters.
3333
<exec_depend>rosidl_adapter</exec_depend>
3434
<exec_depend>rosidl_runtime_py</exec_depend>
3535

36+
<test_depend>ament_cmake_mypy</test_depend>
3637
<test_depend>ament_cmake_pytest</test_depend>
3738
<test_depend>geometry_msgs</test_depend>
3839
<test_depend>rmw_dds_common</test_depend>

rosapi/scripts/rosapi_node

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class Rosapi(Node):
159159
def get_globs(self):
160160
return glob_helper.get_globs(self)
161161

162-
def get_topics(self, request, response):
162+
def get_topics(self, _request, response):
163163
"""
164164
Return a list of all the topics being published.
165165
@@ -168,7 +168,7 @@ class Rosapi(Node):
168168
response.topics, response.types = proxy.get_topics_and_types(self.globs.topics)
169169
return response
170170

171-
def get_interfaces(self, request, response):
171+
def get_interfaces(self, _request, response):
172172
"""
173173
Return a list of all the interfaces in the system.
174174
@@ -186,7 +186,7 @@ class Rosapi(Node):
186186
response.topics = proxy.get_topics_for_type(request.type, self.globs.topics)
187187
return response
188188

189-
def get_topics_and_raw_types(self, request, response):
189+
def get_topics_and_raw_types(self, _request, response):
190190
"""
191191
Return a list of all the topics being published, and their raw types.
192192
@@ -196,11 +196,11 @@ class Rosapi(Node):
196196
"""
197197
response.topics, response.types = proxy.get_topics_and_types(self.globs.topics)
198198
response.typedefs_full_text = [
199-
objectutils.get_typedef_full_text(type) for type in response.types
199+
objectutils.get_typedef_full_text(type_name) for type_name in response.types
200200
]
201201
return response
202202

203-
def get_services(self, request, response):
203+
def get_services(self, _request, response):
204204
"""
205205
Return a list of all the services being advertised.
206206
@@ -218,7 +218,7 @@ class Rosapi(Node):
218218
response.services = proxy.get_services_for_type(request.type, self.globs.services)
219219
return response
220220

221-
def get_nodes(self, request, response):
221+
def get_nodes(self, _request, response):
222222
"""
223223
Return a list of all the nodes that are registered.
224224
@@ -240,7 +240,7 @@ class Rosapi(Node):
240240
) = proxy.get_node_info(request.node)
241241
return response
242242

243-
def get_action_servers(self, request, response):
243+
def get_action_servers(self, _request, response):
244244
"""
245245
Return a list of action servers based on actions standard topics.
246246
@@ -377,11 +377,11 @@ class Rosapi(Node):
377377
params.delete_param(request.node_name, request.name, self.globs.params)
378378
return response
379379

380-
def get_param_names(self, request, response):
380+
def get_param_names(self, _request, response):
381381
response.names = params.get_param_names(self.globs.params)
382382
return response
383383

384-
def get_time(self, request, response):
384+
def get_time(self, _request, response):
385385
response.time = Clock(clock_type=ClockType.ROS_TIME).now().to_msg()
386386
return response
387387

@@ -390,10 +390,10 @@ class Rosapi(Node):
390390

391391
def _print_malformed_param_name_warning(self, param_name):
392392
self.get_logger().warn(
393-
"Malformed parameter name: {}; expecting <node_name>:<param_name>".format(param_name)
393+
f"Malformed parameter name: {param_name}; expecting <node_name>:<param_name>"
394394
)
395395

396-
def get_ros_version(self, request, response):
396+
def get_ros_version(self, _request, response):
397397
response.version = 2
398398
response.distro = str(os.environ["ROS_DISTRO"])
399399
return response

rosapi/src/rosapi/glob_helper.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
#!/usr/bin/env python
2-
31
import fnmatch
4-
from collections import namedtuple
2+
from typing import NamedTuple
53

64
from rcl_interfaces.msg import ParameterType
75

8-
Globs = namedtuple("Globs", ["topics", "services", "params"])
6+
7+
class Globs(NamedTuple):
8+
topics: list
9+
services: list
10+
params: list
911

1012

1113
def get_globs(node):
@@ -32,8 +34,7 @@ def filter_globs(globs, full_list):
3234
# If the globs are empty (weren't defined in the params), return the full list
3335
if globs is not None and len(globs) > 0:
3436
return list(filter(lambda x: any_match(x, globs), full_list))
35-
else:
36-
return full_list
37+
return full_list
3738

3839

3940
def any_match(query, globs):

0 commit comments

Comments
 (0)