Skip to content

Commit 4c5a99b

Browse files
committed
fix(pyright): fix pyright linting issues
And then had to fix some mypy and pylint stuff
1 parent 236f6b5 commit 4c5a99b

6 files changed

Lines changed: 90 additions & 42 deletions

ardupilot_methodic_configurator/backend_flightcontroller_commands.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
FlightControllerConnectionProtocol,
3131
FlightControllerParamsProtocol,
3232
)
33+
from ardupilot_methodic_configurator.backend_flightcontroller_protocols import (
34+
MavlinkConnection as MavlinkConnectionType,
35+
)
3336

3437

3538
class FlightControllerCommands:
@@ -78,7 +81,7 @@ def __init__(
7881
self._last_battery_message_time: float = 0.0
7982

8083
@property
81-
def master(self) -> Optional[mavutil.mavlink_connection]:
84+
def master(self) -> "Optional[MavlinkConnectionType]":
8285
"""Get master connection - delegates to connection manager."""
8386
return self._connection_manager.master
8487

@@ -120,9 +123,9 @@ def send_command_and_wait_ack( # pylint: disable=too-many-arguments,too-many-po
120123

121124
try:
122125
# Send the command
123-
self.master.mav.command_long_send(
124-
self.master.target_system,
125-
self.master.target_component,
126+
self.master.mav.command_long_send( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
127+
self.master.target_system, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
128+
self.master.target_component, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
126129
command,
127130
0, # confirmation
128131
param1,
@@ -137,7 +140,9 @@ def send_command_and_wait_ack( # pylint: disable=too-many-arguments,too-many-po
137140
# Wait for acknowledgment
138141
start_time = time_time()
139142
while time_time() - start_time < timeout:
140-
msg = self.master.recv_match(type="COMMAND_ACK", blocking=False)
143+
msg = self.master.recv_match( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
144+
type="COMMAND_ACK", blocking=False
145+
)
141146
if msg and msg.command == command:
142147
# Map result codes to error messages
143148
result_messages = {
@@ -301,9 +306,9 @@ def test_all_motors(self, nr_of_motors: int, throttle_percent: int, timeout_seco
301306

302307
for i in range(nr_of_motors):
303308
# MAV_CMD_DO_MOTOR_TEST command for all motors
304-
self.master.mav.command_long_send(
305-
self.master.target_system,
306-
self.master.target_component,
309+
self.master.mav.command_long_send( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
310+
self.master.target_system, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
311+
self.master.target_component, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
307312
mavutil.mavlink.MAV_CMD_DO_MOTOR_TEST,
308313
0, # confirmation
309314
param1=i + 1, # motor number (1-based)
@@ -463,7 +468,9 @@ def get_battery_status(self) -> tuple[Union[tuple[float, float], None], str]:
463468

464469
try:
465470
# Try to get real telemetry data
466-
battery_status = self.master.recv_match(type="BATTERY_STATUS", blocking=False, timeout=self.BATTERY_STATUS_TIMEOUT)
471+
battery_status = self.master.recv_match( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
472+
type="BATTERY_STATUS", blocking=False, timeout=self.BATTERY_STATUS_TIMEOUT
473+
)
467474
if battery_status:
468475
# Convert from millivolts to volts, and centiamps to amps using pure business logic
469476
voltage, current = convert_battery_telemetry_units(

ardupilot_methodic_configurator/backend_flightcontroller_connection.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from os import readlink as os_readlink
1919
from time import sleep as time_sleep
2020
from time import time as time_time
21-
from typing import Any, Callable, ClassVar, NoReturn, Optional, Union
21+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, NoReturn, Optional, Union
2222

2323
import serial.tools.list_ports
2424
import serial.tools.list_ports_common
@@ -29,6 +29,9 @@
2929
from ardupilot_methodic_configurator import _
3030
from ardupilot_methodic_configurator.data_model_flightcontroller_info import FlightControllerInfo
3131

32+
if TYPE_CHECKING:
33+
from ardupilot_methodic_configurator.backend_flightcontroller_protocols import MavlinkConnection
34+
3235

3336
class FakeSerialForTests:
3437
"""
@@ -121,7 +124,7 @@ def __init__(
121124
122125
"""
123126
self.info = info
124-
self.master: Optional[mavutil.mavlink_connection] = None
127+
self.master: Optional[MavlinkConnection] = None
125128
self.comport: Union[mavutil.SerialPort, serial.tools.list_ports_common.ListPortInfo, None] = None
126129
self._baudrate = baudrate
127130
self._network_ports = network_ports or self.DEFAULT_NETWORK_PORTS
@@ -148,7 +151,7 @@ def disconnect(self) -> None:
148151
"""Close the connection to the flight controller."""
149152
if self.master is not None:
150153
with contextlib.suppress(Exception):
151-
self.master.close()
154+
self.master.close() # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
152155
self.master = None
153156

154157
def add_connection(self, connection_string: str) -> bool:
@@ -294,7 +297,7 @@ def _create_mavlink_connection( # pylint: disable=too-many-arguments, too-many-
294297
timeout: int = 5,
295298
retries: int = 3,
296299
progress_callback: Union[None, Callable[[int, int], None]] = None,
297-
) -> mavutil.mavlink_connection:
300+
) -> mavutil.mavlink_connection: # pyright: ignore[reportGeneralTypeIssues]
298301
"""
299302
Factory method for creating MAVLink connections.
300303
@@ -334,7 +337,13 @@ def _detect_vehicles_from_heartbeats(self, timeout: int) -> dict[tuple[int, int]
334337
detected_vehicles: dict[tuple[int, int], Any] = {}
335338

336339
while time_time() - start_time < timeout:
337-
m = self.master.recv_match(type="HEARTBEAT", blocking=False) if self.master else None
340+
m = (
341+
self.master.recv_match( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
342+
type="HEARTBEAT", blocking=False
343+
)
344+
if self.master
345+
else None
346+
)
338347
if m is None:
339348
time_sleep(self.HEARTBEAT_POLL_DELAY)
340349
continue
@@ -394,7 +403,13 @@ def _retrieve_autopilot_version_and_banner(self, timeout: int) -> str:
394403

395404
# Request AUTOPILOT_VERSION message
396405
self._request_message(mavutil.mavlink.MAVLINK_MSG_ID_AUTOPILOT_VERSION)
397-
m = self.master.recv_match(type="AUTOPILOT_VERSION", blocking=True, timeout=timeout) if self.master else None
406+
m = (
407+
self.master.recv_match( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
408+
type="AUTOPILOT_VERSION", blocking=True, timeout=timeout
409+
)
410+
if self.master
411+
else None
412+
)
398413

399414
return self._process_autopilot_version(m, banner_msgs)
400415

@@ -404,9 +419,9 @@ def _request_banner(self) -> None:
404419
if self.master is not None:
405420
# Note: Don't wait for ACK here as banner requests are fire-and-forget
406421
# and we handle the response via STATUS_TEXT messages
407-
self.master.mav.command_long_send(
408-
self.master.target_system,
409-
self.master.target_component,
422+
self.master.mav.command_long_send( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
423+
self.master.target_system, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
424+
self.master.target_component, # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
410425
mavutil.mavlink.MAV_CMD_DO_SEND_BANNER,
411426
0,
412427
0,
@@ -429,7 +444,9 @@ def _receive_banner_text(self) -> list[str]:
429444
start_time = time_time()
430445
banner_msgs: list[str] = []
431446
while self.master:
432-
msg = self.master.recv_match(type="STATUSTEXT", blocking=False)
447+
msg = self.master.recv_match( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
448+
type="STATUSTEXT", blocking=False
449+
)
433450
if msg:
434451
if banner_msgs:
435452
banner_msgs.append(msg.text)
@@ -455,7 +472,7 @@ def _request_message(self, message_id: int) -> None:
455472
system_id = int(self.info.system_id) if self.info.system_id else 0
456473
component_id = int(self.info.component_id) if self.info.component_id else 0
457474

458-
self.master.mav.command_long_send(
475+
self.master.mav.command_long_send( # type: ignore[union-attr] # pyright: ignore[reportAttributeAccessIssue]
459476
system_id,
460477
component_id,
461478
mavutil.mavlink.MAV_CMD_REQUEST_MESSAGE,
@@ -627,27 +644,29 @@ def _extract_firmware_type_from_banner(self, banner_msgs: list[str], os_custom_v
627644

628645
return firmware_type
629646

630-
def _populate_flight_controller_info(self, m: MAVLink_autopilot_version_message) -> None:
647+
def _populate_flight_controller_info(self, m: Optional[MAVLink_autopilot_version_message]) -> None:
631648
"""
632649
Populate flight controller info from AUTOPILOT_VERSION message.
633650
634651
Args:
635-
m: The AUTOPILOT_VERSION MAVLink message
652+
m: The AUTOPILOT_VERSION MAVLink message, or None
636653
637654
"""
655+
if m is None:
656+
return
638657
self.info.set_capabilities(m.capabilities)
639658
self.info.set_flight_sw_version(m.flight_sw_version)
640659
self.info.set_usb_vendor_and_product_ids(m.vendor_id, m.product_id) # must be done before set_board_version()
641660
self.info.set_board_version(m.board_version)
642661
self.info.set_flight_custom_version(m.flight_custom_version)
643662
self.info.set_os_custom_version(m.os_custom_version)
644663

645-
def _process_autopilot_version(self, m: MAVLink_autopilot_version_message, banner_msgs: list[str]) -> str:
664+
def _process_autopilot_version(self, m: Optional[MAVLink_autopilot_version_message], banner_msgs: list[str]) -> str:
646665
"""
647666
Process AUTOPILOT_VERSION message and banner messages to extract flight controller info.
648667
649668
Args:
650-
m: The AUTOPILOT_VERSION MAVLink message
669+
m: The AUTOPILOT_VERSION MAVLink message, or None if not received
651670
banner_msgs: List of banner messages received from flight controller
652671
653672
Returns:
@@ -921,7 +940,10 @@ def comport_device(self) -> str:
921940
return ""
922941
return str(self.comport.device)
923942

924-
def set_master_for_testing(self, master: Optional[mavutil.mavlink_connection]) -> None:
943+
def set_master_for_testing(
944+
self,
945+
master: Optional[mavutil.mavlink_connection], # pyright: ignore[reportGeneralTypeIssues]
946+
) -> None:
925947
"""
926948
Set the MAVLink connection for testing purposes.
927949

ardupilot_methodic_configurator/backend_flightcontroller_files.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def __init__(
6666
self._connection_manager: FlightControllerConnectionProtocol = connection_manager
6767

6868
@property
69-
def master(self) -> Optional[mavutil.mavlink_connection]:
69+
def master(self) -> Optional[mavutil.mavlink_connection]: # pyright: ignore[reportGeneralTypeIssues]
7070
"""Get master connection."""
7171
return self._connection_manager.master
7272

@@ -168,15 +168,15 @@ def get_progress_callback(completion: float) -> None:
168168
logging_error(_("Error during flight log download: %(error)s"), {"error": str(e)})
169169
return False
170170

171-
def _get_last_log_number(self, mavftp_instance: "MAVFTP") -> Union[int, None]:
171+
def _get_last_log_number(self, mavftp_instance: "MAVFTP") -> Optional[int]: # pyright: ignore[reportInvalidTypeForm]
172172
"""
173173
Get the last log number using multiple fallback methods.
174174
175175
Args:
176176
mavftp_instance: MAVFTP object for file operations
177177
178178
Returns:
179-
int: Last log number, or None if not found
179+
Optional[int]: Last log number, or None if not found
180180
181181
"""
182182
# Method 1: Try to get LASTLOG.TXT
@@ -197,15 +197,18 @@ def _get_last_log_number(self, mavftp_instance: "MAVFTP") -> Union[int, None]:
197197
logging_error(_("Could not determine the last log number using any method"))
198198
return None
199199

200-
def _get_log_number_from_lastlog_txt(self, mavftp_instance: "MAVFTP") -> Union[int, None]:
200+
def _get_log_number_from_lastlog_txt(
201+
self,
202+
mavftp_instance: "MAVFTP", # pyright: ignore[reportInvalidTypeForm]
203+
) -> Optional[int]:
201204
"""
202205
Try to get the log number from LASTLOG.TXT file.
203206
204207
Args:
205208
mavftp_instance: MAVFTP object for file operations
206209
207210
Returns:
208-
int: Log number from LASTLOG.TXT, or None if not available
211+
Optional[int]: Log number from LASTLOG.TXT, or None if not available
209212
210213
"""
211214
logging_info(_("Trying to get log number from LASTLOG.TXT"))
@@ -222,7 +225,10 @@ def _get_log_number_from_lastlog_txt(self, mavftp_instance: "MAVFTP") -> Union[i
222225
logging_warning(_("Failed to get log number from LASTLOG.TXT: %(error)s"), {"error": str(e)})
223226
return None
224227

225-
def _get_log_number_from_directory_listing(self, mavftp_instance: "MAVFTP") -> Union[int, None]:
228+
def _get_log_number_from_directory_listing(
229+
self,
230+
mavftp_instance: "MAVFTP", # pyright: ignore[reportInvalidTypeForm]
231+
) -> Optional[int]:
226232
"""
227233
Try to get the highest log number by listing the logs directory using MAVFTP.
228234
@@ -257,15 +263,18 @@ def _get_log_number_from_directory_listing(self, mavftp_instance: "MAVFTP") -> U
257263
logging_warning(_("Failed to get log number from directory listing: %(error)s"), {"error": str(e)})
258264
return None
259265

260-
def _get_log_number_by_scanning(self, mavftp_instance: "MAVFTP") -> Union[int, None]:
266+
def _get_log_number_by_scanning(
267+
self,
268+
mavftp_instance: "MAVFTP", # pyright: ignore[reportInvalidTypeForm]
269+
) -> Optional[int]:
261270
"""
262271
Try to find the last log using binary search for efficiency.
263272
264273
Args:
265274
mavftp_instance: MAVFTP object for file operations
266275
267276
Returns:
268-
int: Last log number found using binary search, or None if not found
277+
Optional[int]: Highest log number found, or None if not found
269278
270279
"""
271280
logging_info(_("Trying to find log number using binary search"))
@@ -311,7 +320,11 @@ def _get_log_number_by_scanning(self, mavftp_instance: "MAVFTP") -> Union[int, N
311320
return None
312321

313322
def _download_log_file(
314-
self, mavftp_instance: "MAVFTP", remote_filenumber: int, local_filename: str, get_progress_callback: Callable
323+
self,
324+
mavftp_instance: "MAVFTP", # pyright: ignore[reportInvalidTypeForm]
325+
remote_filenumber: int,
326+
local_filename: str,
327+
get_progress_callback: Callable,
315328
) -> bool:
316329
"""
317330
Download the actual log file from the flight controller.
@@ -344,15 +357,15 @@ def _download_log_file(
344357
logging_error(_("Failed to download log file: %(error)s"), {"error": str(e)})
345358
return False
346359

347-
def _extract_log_number_from_file(self, temp_lastlog_file: str) -> Union[int, None]:
360+
def _extract_log_number_from_file(self, temp_lastlog_file: str) -> Optional[int]:
348361
"""
349362
Extract log number from LASTLOG.TXT file and clean up the temporary file.
350363
351364
Args:
352-
temp_lastlog_file: Path to temporary LASTLOG.TXT file
365+
temp_lastlog_file: Path to the file containing the log number
353366
354367
Returns:
355-
int: Log number extracted from file, or None if extraction failed
368+
Optional[int]: Log number from the file, or None if not found or parsing failed
356369
357370
"""
358371
try:

ardupilot_methodic_configurator/backend_flightcontroller_mavftp_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from ardupilot_methodic_configurator.backend_mavftp import MAVFTP
1616

1717

18-
def create_mavftp(master: Union[mavutil.mavlink_connection, None]) -> MAVFTP:
18+
def create_mavftp(master: Union[mavutil.mavlink_connection, None]) -> MAVFTP: # pyright: ignore[reportGeneralTypeIssues]
1919
"""
2020
Factory function for creating MAVFTP instances.
2121
@@ -37,7 +37,9 @@ def create_mavftp(master: Union[mavutil.mavlink_connection, None]) -> MAVFTP:
3737
return MAVFTP(master, target_system=master.target_system, target_component=master.target_component)
3838

3939

40-
def create_mavftp_safe(master: Union[mavutil.mavlink_connection, None]) -> Optional[MAVFTP]:
40+
def create_mavftp_safe(
41+
master: Union[mavutil.mavlink_connection, None], # pyright: ignore[reportGeneralTypeIssues]
42+
) -> Optional[MAVFTP]: # pyright: ignore[reportGeneralTypeIssues]
4143
"""
4244
Factory function for creating MAVFTP instances with safe error handling.
4345

ardupilot_methodic_configurator/backend_flightcontroller_params.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def __init__(
6868
self.fc_parameters: dict[str, float] = fc_parameters if fc_parameters is not None else {}
6969

7070
@property
71-
def master(self) -> Optional[mavutil.mavlink_connection]:
71+
def master(self) -> Optional[mavutil.mavlink_connection]: # pyright: ignore[reportGeneralTypeIssues]
7272
"""Get master connection."""
7373
return self._connection_manager.master
7474

0 commit comments

Comments
 (0)