Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMPROVEMENT: activated most of ruff linting rules #77

Merged
merged 2 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.3
rev: v0.8.0
hooks:
- id: ruff
args: [ --fix ]
Expand Down
4 changes: 2 additions & 2 deletions MethodicConfigurator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Python package initialization file. Loads translations and declares version information.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand Down
173 changes: 111 additions & 62 deletions MethodicConfigurator/annotate_params.py

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions MethodicConfigurator/ardupilot_methodic_configurator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python3

"""
The main application file. calls four sub-applications.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand All @@ -15,6 +17,7 @@
from logging import getLevelName as logging_getLevelName
from logging import info as logging_info
from sys import exit as sys_exit
from typing import Union
from webbrowser import open as webbrowser_open

from MethodicConfigurator import _, __version__
Expand All @@ -38,6 +41,7 @@ def argument_parser() -> argparse.Namespace:

Returns:
argparse.Namespace: An object containing the parsed arguments.

"""
parser = argparse.ArgumentParser(
description=_(
Expand All @@ -60,7 +64,7 @@ def argument_parser() -> argparse.Namespace:
return add_common_arguments_and_parse(parser)


def connect_to_fc_and_read_parameters(args) -> tuple[FlightController, str]:
def connect_to_fc_and_read_parameters(args: argparse.Namespace) -> tuple[FlightController, str]:
flight_controller = FlightController(args.reboot_time)

error_str = flight_controller.connect(args.device, log_errors=False)
Expand All @@ -86,7 +90,7 @@ def component_editor(
flight_controller: FlightController,
vehicle_type: str,
local_filesystem: LocalFilesystem,
vehicle_dir_window,
vehicle_dir_window: Union[None, VehicleDirectorySelectionWindow],
) -> None:
component_editor_window = ComponentEditorWindow(__version__, local_filesystem)
if (
Expand Down
18 changes: 12 additions & 6 deletions MethodicConfigurator/argparse_check_range.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Check the range of an Argparse parameter.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Dmitriy Kovalev
Expand All @@ -11,15 +11,15 @@
"""

from argparse import Action, ArgumentError, ArgumentParser, Namespace
from collections.abc import Sequence
from operator import ge, gt, le, lt
from typing import Any, Union

from MethodicConfigurator import _


class CheckRange(Action):
"""
Check if the Argparse argument value is within the specified range
"""
"""Check if the Argparse argument value is within the specified range."""

def __init__(self, *args, **kwargs) -> None:
if "min" in kwargs and "inf" in kwargs:
Expand Down Expand Up @@ -52,7 +52,13 @@ def interval(self) -> str:
msg = _("valid range: {_lo}, {_up}")
return msg.format(**locals())

def __call__(self, parser: ArgumentParser, namespace: Namespace, values, option_string=None) -> None:
def __call__(
self,
parser: ArgumentParser, # noqa: ARG002
namespace: Namespace,
values: Union[str, Sequence[Any], None],
option_string: Union[None, str] = None, # noqa: ARG002
) -> None:
if not isinstance(values, (int, float)):
raise ArgumentError(self, _("Value must be a number."))

Expand Down
72 changes: 40 additions & 32 deletions MethodicConfigurator/backend_filesystem.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Filesystem operations.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand Down Expand Up @@ -54,14 +54,15 @@ def is_within_tolerance(x: float, y: float, atol: float = 1e-08, rtol: float = 1
the sum of the absolute tolerance (`atol`) and the product of the relative tolerance (`rtol`)
and the absolute value of `y`.

Parameters:
- x (float): The first number to compare.
- y (float): The second number to compare.
- atol (float, optional): The absolute tolerance. Defaults to 1e-08.
- rtol (float, optional): The relative tolerance. Defaults to 1e-03.
Args:
x (float): The first number to compare.
y (float): The second number to compare.
atol (float, optional): The absolute tolerance. Defaults to 1e-08.
rtol (float, optional): The relative tolerance. Defaults to 1e-03.

Returns:
- bool: True if the difference is within the tolerance, False otherwise.
bool: True if the difference is within the tolerance, False otherwise.

"""
return abs(x - y) <= atol + (rtol * abs(y))

Expand All @@ -74,12 +75,13 @@ class LocalFilesystem(VehicleComponents, ConfigurationSteps, ProgramSettings):
reading parameters from files, and handling configuration steps. It is designed to simplify
the interaction with the local filesystem for managing ArduPilot configuration files.

Attributes:
Args:
vehicle_dir (str): The directory path where the vehicle configuration files are stored.
vehicle_type (str): The type of the vehicle (e.g., "ArduCopter", "Rover").
file_parameters (dict): A dictionary of parameters read from intermediate parameter files.
param_default_dict (dict): A dictionary of default parameter values.
doc_dict (dict): A dictionary containing documentation for each parameter.

"""

def __init__(self, vehicle_dir: str, vehicle_type: str, fw_version: str, allow_editing_template_files: bool) -> None:
Expand Down Expand Up @@ -227,6 +229,7 @@ def read_params_from_files(self) -> dict[str, dict[str, "Par"]]:
Returns:
- Dict[str, Dict[str, 'Par']]: A dictionary with filenames as keys and as values
a dictionary with (parameter names, values) pairs.

"""
parameters: dict[str, dict[str, Par]] = {}
if os_path.isdir(self.vehicle_dir):
Expand All @@ -243,18 +246,19 @@ def read_params_from_files(self) -> dict[str, dict[str, "Par"]]:
return parameters

@staticmethod
def str_to_bool(s) -> Optional[bool]:
def str_to_bool(s: str) -> Optional[bool]:
"""
Converts a string representation of a boolean value to a boolean.

This function interprets the string 'true', 'yes', '1' as True, and 'false', 'no', '0' as False.
Any other input will return None.

Parameters:
- s (str): The string to convert.
Args:
s (str): The string to convert.

Returns:
- Optional[bool]: True, False, or None if the string does not match any known boolean representation.
Optional[bool]: True, False, or None if the string does not match any known boolean representation.

"""
if s.lower() == "true" or s.lower() == "yes" or s.lower() == "1":
return True
Expand All @@ -269,10 +273,11 @@ def export_to_param(self, params: dict[str, "Par"], filename_out: str, annotate_
This function formats the provided parameters into a string suitable for a .param file,
writes the string to the specified output file, and optionally updates the parameter documentation.

Parameters:
- params (Dict[str, 'Par']): A dictionary of parameters to export.
- filename_out (str): The name of the output file.
- annotate_doc (bool, optional): Whether to update the parameter documentation. Defaults to True.
Args:
params (Dict[str, 'Par']): A dictionary of parameters to export.
filename_out (str): The name of the output file.
annotate_doc (bool, optional): Whether to update the parameter documentation. Defaults to True.

"""
Par.export_to_param(Par.format_params(params), os_path.join(self.vehicle_dir, filename_out))
if annotate_doc:
Expand All @@ -284,11 +289,12 @@ def vehicle_configuration_file_exists(self, filename: str) -> bool:
"""
Check if a vehicle configuration file exists in the vehicle directory.

Parameters:
- filename (str): The name of the file to check.
Args:
filename (str): The name of the file to check.

Returns:
- bool: True if the file exists and is a file (not a directory), False otherwise.
bool: True if the file exists and is a file (not a directory), False otherwise.

"""
return os_path.exists(os_path.join(self.vehicle_dir, filename)) and os_path.isfile(
os_path.join(self.vehicle_dir, filename)
Expand All @@ -304,6 +310,7 @@ def __all_intermediate_parameter_file_comments(self) -> dict[str, str]:

Returns:
- Dict[str, str]: A dictionary mapping parameter names to their comments.

"""
ret = {}
for params in self.file_parameters.values():
Expand All @@ -320,11 +327,12 @@ def annotate_intermediate_comments_to_param_dict(self, param_dict: dict[str, flo
intermediate parameter files to create a new dictionary where each parameter is represented
by a 'Par' object containing both the value and the comment.

Parameters:
- param_dict (Dict[str, float]): A dictionary of parameters with only values.
Args:
param_dict (Dict[str, float]): A dictionary of parameters with only values.

Returns:
- Dict[str, 'Par']: A dictionary of parameters with intermediate parameter file comments.
Dict[str, 'Par']: A dictionary of parameters with intermediate parameter file comments.

"""
ret = {}
ip_comments = self.__all_intermediate_parameter_file_comments()
Expand All @@ -341,12 +349,13 @@ def categorize_parameters(self, param: dict[str, "Par"]) -> tuple[dict[str, "Par
- Non-default, writable calibrations
- Non-default, writable non-calibrations

Parameters:
- param (Dict[str, 'Par']): A dictionary mapping parameter names to their 'Par' objects.
Args:
param (Dict[str, 'Par']): A dictionary mapping parameter names to their 'Par' objects.

Returns:
- Tuple[Dict[str, "Par"], Dict[str, "Par"], Dict[str, "Par"]]: A tuple of three dictionaries.
Tuple[Dict[str, "Par"], Dict[str, "Par"], Dict[str, "Par"]]: A tuple of three dictionaries.
Each dictionary represents one of the categories mentioned above.

"""
non_default__read_only_params = {}
non_default__writable_calibrations = {}
Expand Down Expand Up @@ -374,9 +383,7 @@ def get_directory_name_from_full_path(full_path: str) -> str:
normalized_path = os_path.normpath(full_path)

# Split the path into head and tail, then get the basename of the tail
directory_name = os_path.basename(os_path.split(normalized_path)[1])

return directory_name
return os_path.basename(os_path.split(normalized_path)[1])

# Extract the vehicle name from the directory path
def get_vehicle_directory_name(self) -> str:
Expand All @@ -390,7 +397,7 @@ def zip_file_exists(self) -> bool:
zip_file_path = self.zip_file_path()
return os_path.exists(zip_file_path) and os_path.isfile(zip_file_path)

def add_configuration_file_to_zip(self, zipf, filename) -> None:
def add_configuration_file_to_zip(self, zipf: ZipFile, filename: str) -> None:
if self.vehicle_configuration_file_exists(filename):
zipf.write(os_path.join(self.vehicle_dir, filename), arcname=filename)

Expand All @@ -403,9 +410,10 @@ def zip_files(self, files_to_zip: list[tuple[bool, str]]) -> None:
intermediate parameter files. The method checks for the existence of each file before
attempting to add it to the zip archive.

Parameters:
- files_to_zip (List[Tuple[bool, str]]): A list of tuples, where each tuple contains a boolean
Args:
files_to_zip (List[Tuple[bool, str]]): A list of tuples, where each tuple contains a boolean
indicating if the file was written and a string for the filename.

"""
zip_file_path = self.zip_file_path()
with ZipFile(zip_file_path, "w") as zipf:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Manages configuration steps at the filesystem level.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand Down Expand Up @@ -32,6 +32,7 @@ class ConfigurationSteps:
Attributes:
configuration_steps_filename (str): The name of the file containing documentation for the configuration files.
configuration_steps (dict): A dictionary containing the configuration steps.

"""

def __init__(self, _vehicle_dir: str, vehicle_type: str) -> None:
Expand Down
23 changes: 13 additions & 10 deletions MethodicConfigurator/backend_filesystem_program_settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Manages program settings at the filesystem level.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand Down Expand Up @@ -79,19 +79,22 @@ def valid_directory_name(dir_name: str) -> bool:
invalid for directory names in many operating systems. It does not guarantee that the name
is valid in all contexts or operating systems, as directory name validity can vary.

Parameters:
- dir_name (str): The directory name to check.
Args:
dir_name (str): The directory name to check.

Returns:
- bool: True if the directory name matches the allowed pattern, False otherwise.
bool: True if the directory name matches the allowed pattern, False otherwise.

"""
# Include os.sep in the pattern
pattern = r"^[\w" + re_escape(os_sep) + "-]+$"
return re_match(pattern, dir_name) is not None

@staticmethod
def __user_config_dir() -> str:
user_config_directory = user_config_dir(".ardupilot_methodic_configurator", False, roaming=True, ensure_exists=True)
user_config_directory = user_config_dir(
".ardupilot_methodic_configurator", appauthor=False, roaming=True, ensure_exists=True
)

if not os_path.exists(user_config_directory):
error_msg = _("The user configuration directory '{user_config_directory}' does not exist.")
Expand All @@ -100,12 +103,12 @@ def __user_config_dir() -> str:
error_msg = _("The path '{user_config_directory}' is not a directory.")
raise NotADirectoryError(error_msg.format(**locals()))

return user_config_directory # type: ignore[no-any-return] # workaround a mypy bug
return user_config_directory

@staticmethod
def __site_config_dir() -> str:
site_config_directory = site_config_dir(
".ardupilot_methodic_configurator", False, version=None, multipath=False, ensure_exists=True
".ardupilot_methodic_configurator", appauthor=False, version=None, multipath=False, ensure_exists=True
)

if not os_path.exists(site_config_directory):
Expand All @@ -115,7 +118,7 @@ def __site_config_dir() -> str:
error_msg = _("The path '{site_config_directory}' is not a directory.")
raise NotADirectoryError(error_msg.format(**locals()))

return site_config_directory # type: ignore[no-any-return] # workaround a mypy bug
return site_config_directory

@staticmethod
def __get_settings_as_dict() -> dict[str, Any]:
Expand Down Expand Up @@ -151,7 +154,7 @@ def __get_settings_as_dict() -> dict[str, Any]:
return settings

@staticmethod
def __set_settings_from_dict(settings) -> None:
def __set_settings_from_dict(settings: dict) -> None:
settings_path = os_path.join(ProgramSettings.__user_config_dir(), "settings.json")

with open(settings_path, "w", encoding="utf-8") as settings_file:
Expand Down
6 changes: 3 additions & 3 deletions MethodicConfigurator/backend_filesystem_vehicle_components.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

"""
Manages vehicle components at the filesystem level.

This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator

SPDX-FileCopyrightText: 2024 Amilcar do Carmo Lucas <[email protected]>
Expand Down Expand Up @@ -52,7 +52,7 @@ def load_vehicle_components_json_data(self, vehicle_dir: str) -> dict[Any, Any]:
self.vehicle_components = data
return data

def save_vehicle_components_json_data(self, data, vehicle_dir: str) -> bool:
def save_vehicle_components_json_data(self, data: dict, vehicle_dir: str) -> bool:
filepath = os_path.join(vehicle_dir, self.vehicle_components_json_filename)
try:
with open(filepath, "w", encoding="utf-8") as file:
Expand Down
Loading
Loading