diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 85eb94e6cd9..3a68be4216f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -29,6 +29,7 @@ jobs: matrix: mypy_packages: - "nav2_smac_planner" + - "nav2_common" steps: - uses: actions/checkout@v4 diff --git a/nav2_common/nav2_common/launch/has_node_params.py b/nav2_common/nav2_common/launch/has_node_params.py index 6e386128ce0..1315cb6e281 100644 --- a/nav2_common/nav2_common/launch/has_node_params.py +++ b/nav2_common/nav2_common/launch/has_node_params.py @@ -18,7 +18,7 @@ import yaml -class HasNodeParams(launch.Substitution): +class HasNodeParams(launch.Substitution): # type: ignore """ Substitution that checks if a param file contains parameters for a node. @@ -45,7 +45,7 @@ def __init__( @property def name(self) -> List[launch.Substitution]: """Getter for name.""" - return self.__source_file + return self.__source_file # type: ignore def describe(self) -> Text: """Return a description of this substitution as a string.""" diff --git a/nav2_common/nav2_common/launch/replace_string.py b/nav2_common/nav2_common/launch/replace_string.py index cb55b883380..756960c60a2 100644 --- a/nav2_common/nav2_common/launch/replace_string.py +++ b/nav2_common/nav2_common/launch/replace_string.py @@ -18,7 +18,7 @@ import launch -class ReplaceString(launch.Substitution): +class ReplaceString(launch.Substitution): # type: ignore """ Substitution that replaces strings on a given file. @@ -28,7 +28,7 @@ class ReplaceString(launch.Substitution): def __init__( self, source_file: launch.SomeSubstitutionsType, - replacements: Dict, + replacements: Dict[Text, launch.SomeSubstitutionsType], condition: Optional[launch.Condition] = None, ) -> None: super().__init__() @@ -37,7 +37,8 @@ def __init__( # import here to avoid loop - self.__source_file = normalize_to_list_of_substitutions(source_file) + self.__source_file: List[launch.Substitution] = \ + normalize_to_list_of_substitutions(source_file) self.__replacements = {} for key in replacements: self.__replacements[key] = normalize_to_list_of_substitutions( @@ -60,7 +61,9 @@ def describe(self) -> Text: return '' def perform(self, context: launch.LaunchContext) -> Text: - yaml_filename = launch.utilities.perform_substitutions(context, self.name) + yaml_filename: Text = launch.utilities.perform_substitutions( + context, self.name + ) if self.__condition is None or self.__condition.evaluate(context): output_file = tempfile.NamedTemporaryFile(mode='w', delete=False) replacements = self.resolve_replacements(context) @@ -76,7 +79,7 @@ def perform(self, context: launch.LaunchContext) -> Text: else: return yaml_filename - def resolve_replacements(self, context): + def resolve_replacements(self, context: launch.LaunchContext) -> Dict[Text, Text]: resolved_replacements = {} for key in self.__replacements: resolved_replacements[key] = launch.utilities.perform_substitutions( @@ -84,7 +87,8 @@ def resolve_replacements(self, context): ) return resolved_replacements - def replace(self, input_file, output_file, replacements): + def replace(self, input_file: launch.SomeSubstitutionsType, + output_file: launch.SomeSubstitutionsType, replacements: Dict[Text, Text]) -> None: for line in input_file: for key, value in replacements.items(): if isinstance(key, str) and isinstance(value, str): diff --git a/nav2_common/nav2_common/launch/rewritten_yaml.py b/nav2_common/nav2_common/launch/rewritten_yaml.py index 5434f611f51..19909976e71 100644 --- a/nav2_common/nav2_common/launch/rewritten_yaml.py +++ b/nav2_common/nav2_common/launch/rewritten_yaml.py @@ -13,7 +13,7 @@ # limitations under the License. import tempfile -from typing import Dict, List, Optional, Text +from typing import Any, Dict, Generator, List, Optional, Text import launch import yaml @@ -21,18 +21,18 @@ class DictItemReference: - def __init__(self, dictionary, key): + def __init__(self, dictionary: Dict[Text, Any], key: Text): self.dictionary = dictionary self.dictKey = key - def key(self): + def key(self) -> Text: return self.dictKey - def setValue(self, value): + def setValue(self, value: Any) -> None: self.dictionary[self.dictKey] = value -class RewrittenYaml(launch.Substitution): +class RewrittenYaml(launch.Substitution): # type: ignore """ Substitution that modifies the given YAML file. @@ -42,10 +42,10 @@ class RewrittenYaml(launch.Substitution): def __init__( self, source_file: launch.SomeSubstitutionsType, - param_rewrites: Dict, + param_rewrites: Dict[Text, launch.SomeSubstitutionsType], root_key: Optional[launch.SomeSubstitutionsType] = None, - key_rewrites: Optional[Dict] = None, - convert_types=False, + key_rewrites: Optional[Dict[Text, launch.SomeSubstitutionsType]] = None, + convert_types: bool = False, ) -> None: super().__init__() """ @@ -81,7 +81,7 @@ def __init__( @property def name(self) -> List[launch.Substitution]: """Getter for name.""" - return self.__source_file + return self.__source_file # type: ignore def describe(self) -> Text: """Return a description of this substitution as a string.""" @@ -103,7 +103,8 @@ def perform(self, context: launch.LaunchContext) -> Text: rewritten_yaml.close() return rewritten_yaml.name - def resolve_rewrites(self, context): + def resolve_rewrites(self, context: launch.LaunchContext) -> \ + tuple[Dict[Text, Text], Dict[Text, Text]]: resolved_params = {} for key in self.__param_rewrites: resolved_params[key] = launch.utilities.perform_substitutions( @@ -116,7 +117,8 @@ def resolve_rewrites(self, context): ) return resolved_params, resolved_keys - def substitute_params(self, yaml, param_rewrites): + def substitute_params(self, yaml: Dict[Text, Any], + param_rewrites: Dict[Text, Text]) -> None: # substitute leaf-only parameters for key in self.getYamlLeafKeys(yaml): if key.key() in param_rewrites: @@ -132,7 +134,8 @@ def substitute_params(self, yaml, param_rewrites): yaml_keys = path.split('.') yaml = self.updateYamlPathVals(yaml, yaml_keys, rewrite_val) - def add_params(self, yaml, param_rewrites): + def add_params(self, yaml: Dict[Text, Any], + param_rewrites: Dict[Text, Text]) -> None: # add new total path parameters yaml_paths = self.pathify(yaml) for path in param_rewrites: @@ -142,7 +145,8 @@ def add_params(self, yaml, param_rewrites): if 'ros__parameters' in yaml_keys: yaml = self.updateYamlPathVals(yaml, yaml_keys, new_val) - def updateYamlPathVals(self, yaml, yaml_key_list, rewrite_val): + def updateYamlPathVals(self, yaml: Dict[Text, Any], + yaml_key_list: List[Text], rewrite_val: Any) -> Dict[Text, Any]: for key in yaml_key_list: if key == yaml_key_list[-1]: yaml[key] = rewrite_val @@ -158,7 +162,7 @@ def updateYamlPathVals(self, yaml, yaml_key_list, rewrite_val): ) return yaml - def substitute_keys(self, yaml, key_rewrites): + def substitute_keys(self, yaml: Dict[Text, Any], key_rewrites: Dict[Text, Text]) -> None: if len(key_rewrites) != 0: for key in list(yaml.keys()): val = yaml[key] @@ -169,7 +173,8 @@ def substitute_keys(self, yaml, key_rewrites): if isinstance(val, dict): self.substitute_keys(val, key_rewrites) - def getYamlLeafKeys(self, yamlData): + def getYamlLeafKeys(self, yamlData: Dict[Text, Any]) -> \ + Generator[DictItemReference, None, None]: try: for key in yamlData.keys(): for k in self.getYamlLeafKeys(yamlData[key]): @@ -178,11 +183,14 @@ def getYamlLeafKeys(self, yamlData): except AttributeError: return - def pathify(self, d, p=None, paths=None, joinchar='.'): + def pathify(self, d: Dict[Text, Any], p: Optional[Text] = None, + paths: Optional[Dict[Text, Any]] = None, joinchar: str = '.') -> Dict[Text, Any]: if p is None: paths = {} self.pathify(d, '', paths, joinchar=joinchar) return paths + + assert paths is not None pn = p if p != '': pn += joinchar @@ -195,8 +203,9 @@ def pathify(self, d, p=None, paths=None, joinchar='.'): self.pathify(e, pn + str(idx), paths, joinchar=joinchar) else: paths[p] = d + return paths - def convert(self, text_value): + def convert(self, text_value: Text) -> Any: if self.__convert_types: # try converting to int or float try: diff --git a/tools/pyproject.toml b/tools/pyproject.toml index 663c8243821..ab81e85d120 100644 --- a/tools/pyproject.toml +++ b/tools/pyproject.toml @@ -18,5 +18,10 @@ explicit_package_bases = true strict = true [[tool.mypy.overrides]] -module = ["matplotlib.*", "rtree.*"] +module = [ + "matplotlib.*", + "rtree.*", + "launch.*", +] + ignore_missing_imports = true