Skip to content

Enable bugbear lints#818

Open
rumpelsepp wants to merge 2 commits into
masterfrom
bugbear
Open

Enable bugbear lints#818
rumpelsepp wants to merge 2 commits into
masterfrom
bugbear

Conversation

@rumpelsepp

@rumpelsepp rumpelsepp commented Dec 1, 2025

Copy link
Copy Markdown
Member
  • linter: Enable bugbear lints
  • fix: Address all ruff issues found by enabling bugbear
$ ruff check
B023 Function definition does not bind loop variable `max_lines`
    --> src/gallia/cli/cursed_hr.py:1041:32
     |
1039 |                 nonlocal display_entries
1040 |
1041 |                 for _ in range(max_lines - 1):
     |                                ^^^^^^^^^
1042 |                     old_entry_start = entry_start
1043 |                     old_line_start = line_start
     |

B023 Function definition does not bind loop variable `display_entries`
    --> src/gallia/cli/cursed_hr.py:1061:20
     |
1059 |                 nonlocal line_start
1060 |
1061 |                 if display_entries[0].entry_line_number == 0:
     |                    ^^^^^^^^^^^^^^^
1062 |                     if entry_start > 0:
1063 |                         entry_start = max(0, entry_start - 1)
     |

B027 `AsyncScript.setup` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/command/base.py:129:5
    |
127 |         self.log_file_handlers = []
128 |
129 |     async def setup(self) -> None: ...
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130 |
131 |     @abstractmethod
    |

B027 `AsyncScript.teardown` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/command/base.py:134:5
    |
132 |     async def main(self) -> None: ...
133 |
134 |     async def teardown(self) -> None: ...
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
135 |
136 |     async def run(self) -> int:
    |

B011 Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
   --> src/gallia/commands/script/vecu.py:102:28
    |
100 |                     transport = UnixUDSServerTransport(server, target)
101 |                 case _:
102 |                     assert False
    |                            ^^^^^
103 |
104 |         if sys.platform.startswith("win32"):
    |
help: Replace `assert False`

B011 Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
   --> src/gallia/commands/script/vecu.py:109:28
    |
107 |                     transport = TCPUDSServerTransport(server, target)
108 |                 case _:
109 |                     assert False
    |                            ^^^^^
110 |
111 |         try:
    |
help: Replace `assert False`

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/plugins/plugin.py:119:17
    |
117 |                 _merge_command_trees(cmd, value)
118 |             except ValueError as e:
119 |                 raise ValueError(f"{key} {str(e)}")
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120 |         else:
121 |             raise ValueError(f"{key} ]: There already exists a leaf command")
    |

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1240:45
     |
1238 |         pdu = pack("!B", self.RESPONSE_SERVICE_ID)
1239 |
1240 |         for data_identifier, data_record in zip(self.data_identifiers, self.data_records):
     |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1241 |             pdu = pdu + to_bytes(data_identifier, 2) + data_record
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1270:40
     |
1268 |             return all(
1269 |                 req_id == resp_id
1270 |                 for req_id, resp_id in zip(request.data_identifiers, self.data_identifiers)
     |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1271 |             )
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1630:84
     |
1628 |           )
1629 |
1630 |           for source_data_identifier, position_in_source_data_record, memory_size in zip(
     |  ____________________________________________________________________________________^
1631 | |             self.source_data_identifiers, self.positions_in_source_data_record, self.memory_sizes
1632 | |         ):
     | |_________^
1633 |               pdu = (
1634 |                   pdu
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1733:30
     |
1731 |         # In case the address_and_length_format_identifier is None, this calculates it based on the longest address and size
1732 |         # Otherwise it checks for all addresses and size if they can be represented with its length constraints.
1733 |         for address, size in zip(self.memory_addresses, self.memory_sizes):
     |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1734 |             computed_address_and_length_format_identifier, _, _ = uds_memory_parameters(
1735 |                 address, size, address_and_length_format_identifier
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1777:44
     |
1775 |         )
1776 |
1777 |         for memory_address, memory_size in zip(self.memory_addresses, self.memory_sizes):
     |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1778 |             _, address, size = uds_memory_parameters(
1779 |                 memory_address, memory_size, self.address_and_length_format_identifier
     |
help: Add explicit value for parameter `strict=`

B007 Loop control variable `dtc_ext_data_record` not used within loop body
    --> src/gallia/services/uds/core/service.py:2744:41
     |
2742 |             self.dtc_and_status_record = dtc_and_status_record
2743 |
2744 |         for dtc_ext_data_record_number, dtc_ext_data_record in dtc_ext_data_records.items():
     |                                         ^^^^^^^^^^^^^^^^^^^
2745 |             check_range(dtc_ext_data_record_number, "dtc_ext_data_record_number", 0, 0xFD)
     |
help: Rename unused `dtc_ext_data_record` to `_dtc_ext_data_record`

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/services/uds/helpers.py:106:17
    |
104 |             # RequestResponseMismatch takes priority over MalformedResponse
105 |             if len(pdu) >= 3 and pdu[2] != request.service_id:
106 |                 raise RequestResponseMismatch(request, response)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
107 |         else:
108 |             response = service.RawPositiveResponse(pdu)
    |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/services/uds/helpers.py:111:17
    |
109 |             # RequestResponseMismatch takes priority over MalformedResponse
110 |             if response.service_id != request.service_id:
111 |                 raise RequestResponseMismatch(request, response)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
112 |
113 |         raise MalformedResponse(request, response, str(e)) from e
    |

B027 `UDSServer.setup` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/services/uds/server.py:222:5
    |
220 |               self.state.session = 1
221 |
222 | /     async def setup(self) -> None:
223 | |         pass
    | |____________^
224 |
225 |       async def teardown(self) -> None:
    |

B027 `UDSServer.teardown` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/services/uds/server.py:225:5
    |
223 |           pass
224 |
225 | /     async def teardown(self) -> None:
226 | |         pass
    | |____________^
227 |
228 |       async def respond_without_state_change(
    |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
  --> src/gallia/transports/_ctypes_vector_xl_wrapper.py:26:5
   |
24 |     from _winapi import WaitForSingleObject
25 | except ImportError:
26 |     raise RuntimeError("platform does not provide WaitForSingleObject")
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/transports/doip.py:976:13
    |
974 |             # missing responses
975 |             logger.debug("DoIP message was ACKed with TargetUnreachable")
976 |             raise TimeoutError
    |             ^^^^^^^^^^^^^^^^^^
977 |
978 |         return len(data)
    |

Found 19 errors.
No fixes available (8 hidden fixes can be enabled with the `--unsafe-fixes` option).

$ ruff check
B023 Function definition does not bind loop variable `max_lines`
    --> src/gallia/cli/cursed_hr.py:1041:32
     |
1039 |                 nonlocal display_entries
1040 |
1041 |                 for _ in range(max_lines - 1):
     |                                ^^^^^^^^^
1042 |                     old_entry_start = entry_start
1043 |                     old_line_start = line_start
     |

B023 Function definition does not bind loop variable `display_entries`
    --> src/gallia/cli/cursed_hr.py:1061:20
     |
1059 |                 nonlocal line_start
1060 |
1061 |                 if display_entries[0].entry_line_number == 0:
     |                    ^^^^^^^^^^^^^^^
1062 |                     if entry_start > 0:
1063 |                         entry_start = max(0, entry_start - 1)
     |

B027 `AsyncScript.setup` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/command/base.py:129:5
    |
127 |         self.log_file_handlers = []
128 |
129 |     async def setup(self) -> None: ...
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130 |
131 |     @AbstractMethod
    |

B027 `AsyncScript.teardown` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/command/base.py:134:5
    |
132 |     async def main(self) -> None: ...
133 |
134 |     async def teardown(self) -> None: ...
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
135 |
136 |     async def run(self) -> int:
    |

B011 Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
   --> src/gallia/commands/script/vecu.py:102:28
    |
100 |                     transport = UnixUDSServerTransport(server, target)
101 |                 case _:
102 |                     assert False
    |                            ^^^^^
103 |
104 |         if sys.platform.startswith("win32"):
    |
help: Replace `assert False`

B011 Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
   --> src/gallia/commands/script/vecu.py:109:28
    |
107 |                     transport = TCPUDSServerTransport(server, target)
108 |                 case _:
109 |                     assert False
    |                            ^^^^^
110 |
111 |         try:
    |
help: Replace `assert False`

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/plugins/plugin.py:119:17
    |
117 |                 _merge_command_trees(cmd, value)
118 |             except ValueError as e:
119 |                 raise ValueError(f"{key} {str(e)}")
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120 |         else:
121 |             raise ValueError(f"{key} ]: There already exists a leaf command")
    |

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1240:45
     |
1238 |         pdu = pack("!B", self.RESPONSE_SERVICE_ID)
1239 |
1240 |         for data_identifier, data_record in zip(self.data_identifiers, self.data_records):
     |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1241 |             pdu = pdu + to_bytes(data_identifier, 2) + data_record
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1270:40
     |
1268 |             return all(
1269 |                 req_id == resp_id
1270 |                 for req_id, resp_id in zip(request.data_identifiers, self.data_identifiers)
     |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1271 |             )
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1630:84
     |
1628 |           )
1629 |
1630 |           for source_data_identifier, position_in_source_data_record, memory_size in zip(
     |  ____________________________________________________________________________________^
1631 | |             self.source_data_identifiers, self.positions_in_source_data_record, self.memory_sizes
1632 | |         ):
     | |_________^
1633 |               pdu = (
1634 |                   pdu
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1733:30
     |
1731 |         # In case the address_and_length_format_identifier is None, this calculates it based on the longest address and size
1732 |         # Otherwise it checks for all addresses and size if they can be represented with its length constraints.
1733 |         for address, size in zip(self.memory_addresses, self.memory_sizes):
     |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1734 |             computed_address_and_length_format_identifier, _, _ = uds_memory_parameters(
1735 |                 address, size, address_and_length_format_identifier
     |
help: Add explicit value for parameter `strict=`

B905 `zip()` without an explicit `strict=` parameter
    --> src/gallia/services/uds/core/service.py:1777:44
     |
1775 |         )
1776 |
1777 |         for memory_address, memory_size in zip(self.memory_addresses, self.memory_sizes):
     |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1778 |             _, address, size = uds_memory_parameters(
1779 |                 memory_address, memory_size, self.address_and_length_format_identifier
     |
help: Add explicit value for parameter `strict=`

B007 Loop control variable `dtc_ext_data_record` not used within loop body
    --> src/gallia/services/uds/core/service.py:2744:41
     |
2742 |             self.dtc_and_status_record = dtc_and_status_record
2743 |
2744 |         for dtc_ext_data_record_number, dtc_ext_data_record in dtc_ext_data_records.items():
     |                                         ^^^^^^^^^^^^^^^^^^^
2745 |             check_range(dtc_ext_data_record_number, "dtc_ext_data_record_number", 0, 0xFD)
     |
help: Rename unused `dtc_ext_data_record` to `_dtc_ext_data_record`

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/services/uds/helpers.py:106:17
    |
104 |             # RequestResponseMismatch takes priority over MalformedResponse
105 |             if len(pdu) >= 3 and pdu[2] != request.service_id:
106 |                 raise RequestResponseMismatch(request, response)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
107 |         else:
108 |             response = service.RawPositiveResponse(pdu)
    |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/services/uds/helpers.py:111:17
    |
109 |             # RequestResponseMismatch takes priority over MalformedResponse
110 |             if response.service_id != request.service_id:
111 |                 raise RequestResponseMismatch(request, response)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
112 |
113 |         raise MalformedResponse(request, response, str(e)) from e
    |

B027 `UDSServer.setup` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/services/uds/server.py:222:5
    |
220 |               self.state.session = 1
221 |
222 | /     async def setup(self) -> None:
223 | |         pass
    | |____________^
224 |
225 |       async def teardown(self) -> None:
    |

B027 `UDSServer.teardown` is an empty method in an abstract base class, but has no abstract decorator
   --> src/gallia/services/uds/server.py:225:5
    |
223 |           pass
224 |
225 | /     async def teardown(self) -> None:
226 | |         pass
    | |____________^
227 |
228 |       async def respond_without_state_change(
    |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
  --> src/gallia/transports/_ctypes_vector_xl_wrapper.py:26:5
   |
24 |     from _winapi import WaitForSingleObject
25 | except ImportError:
26 |     raise RuntimeError("platform does not provide WaitForSingleObject")
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
   --> src/gallia/transports/doip.py:976:13
    |
974 |             # missing responses
975 |             logger.debug("DoIP message was ACKed with TargetUnreachable")
976 |             raise TimeoutError
    |             ^^^^^^^^^^^^^^^^^^
977 |
978 |         return len(data)
    |

Found 19 errors.
No fixes available (8 hidden fixes can be enabled with the `--unsafe-fixes` option).
@stale

stale Bot commented May 15, 2026

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale Bot added the stale label May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant