From cf298957e369f2bb2a242a2e1110734a57727358 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 12 Sep 2022 16:37:10 -0400 Subject: [PATCH] Toolbox typing. --- lib/galaxy/tool_util/toolbox/base.py | 39 +++++++++++++++++++++------- mypy.ini | 2 -- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/galaxy/tool_util/toolbox/base.py b/lib/galaxy/tool_util/toolbox/base.py index ee9af7eed53..3da53d64bea 100644 --- a/lib/galaxy/tool_util/toolbox/base.py +++ b/lib/galaxy/tool_util/toolbox/base.py @@ -6,8 +6,12 @@ import time from collections import namedtuple from errno import ENOENT from typing import ( + Any, Dict, List, + Optional, + Tuple, + Union, ) from urllib.parse import urlparse @@ -108,12 +112,18 @@ class ToolBoxRegistryImpl(ToolBoxRegistry): self.__toolbox.add_tool_to_tool_panel_view(tool, tool_panel_component) +DynamicToolConfDict = Dict[str, Any] + + class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): """ Abstract container for managing a ToolPanel - containing tools and workflows optionally in labelled sections. """ + _dynamic_tool_confs: List[DynamicToolConfDict] + _tool_panel_views: Dict[str, ToolPanelView] + def __init__( self, config_filenames, @@ -187,7 +197,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): searchable=True, ) - tool_panel_views_list = [ + tool_panel_views_list: List[ToolPanelView] = [ DefaultToolPanelView(), ] @@ -416,7 +426,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): tool_cache_data_dir=tool_cache_data_dir, ) - def get_shed_config_dict_by_filename(self, filename): + def get_shed_config_dict_by_filename(self, filename) -> Optional[DynamicToolConfDict]: filename = os.path.abspath(filename) dynamic_tool_conf_paths = [] for shed_config_dict in self._dynamic_tool_confs: @@ -653,8 +663,10 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): if "/repos/" in tool_id: # test if tool came from a toolshed tool_id_without_tool_shed = tool_id.split("/repos/")[1] - available_tool_sheds = [urlparse(_) for _ in self.app.tool_shed_registry.tool_sheds.values()] - available_tool_sheds = [url.geturl().replace(f"{url.scheme}://", "", 1) for url in available_tool_sheds] + available_tool_sheds_parsed = [urlparse(_) for _ in self.app.tool_shed_registry.tool_sheds.values()] + available_tool_sheds = [ + url.geturl().replace(f"{url.scheme}://", "", 1) for url in available_tool_sheds_parsed + ] tool_ids = [f"{tool_shed}repos/{tool_id_without_tool_shed}" for tool_shed in available_tool_sheds] if tool_id in tool_ids: # move original tool_id to the top of tool_ids tool_ids.remove(tool_id) @@ -717,10 +729,10 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): return self._tools_by_id[tool_id] return None - def has_tool(self, tool_id, tool_version=None, exact=False): + def has_tool(self, tool_id: str, tool_version: Optional[str] = None, exact: bool = False): return self.get_tool(tool_id, tool_version=tool_version, exact=exact) is not None - def is_missing_shed_tool(self, tool_id): + def is_missing_shed_tool(self, tool_id: str) -> bool: """Confirm that the tool ID does reference a shed tool and is not installed.""" if tool_id is None: # This is not a tool ID. @@ -734,7 +746,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): return True return False - def get_loaded_tools_by_lineage(self, tool_id): + def get_loaded_tools_by_lineage(self, tool_id: str) -> list: """Get all loaded tools associated by lineage to the tool whose id is tool_id.""" tool_lineage = self._lineage_map.get(tool_id) if tool_lineage: @@ -754,7 +766,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): def tools(self): return self._tools_by_id.copy().items() - def dynamic_confs(self, include_migrated_tool_conf=False): + def dynamic_confs(self, include_migrated_tool_conf=False) -> List[DynamicToolConfDict]: confs = [] for dynamic_tool_conf_dict in self._dynamic_tool_confs: dynamic_tool_conf_filename = dynamic_tool_conf_dict["config_filename"] @@ -762,7 +774,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): confs.append(dynamic_tool_conf_dict) return confs - def default_shed_tool_conf_dict(self): + def default_shed_tool_conf_dict(self) -> DynamicToolConfDict: """If set, returns the first shed_tool_conf_dict corresponding to shed_tool_config_file, else the first dynamic conf.""" dynamic_confs = self.dynamic_confs(include_migrated_tool_conf=False) # Pick the first tool config that doesn't set `is_shed_conf="false"` and that is not a migrated_tool_conf @@ -838,6 +850,9 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): key = f"tool_{str(tool.id)}" if can_load_into_panel_dict: if guid and not from_cache: + assert ( + tool_shed_repository is not None + ) # tell type system if can_load_into_panel_dict, this can't be none tool.tool_shed = tool_shed_repository.tool_shed tool.repository_name = tool_shed_repository.name tool.repository_owner = tool_shed_repository.owner @@ -1143,11 +1158,12 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): tool = self._tools_by_id[tool_id] return tool.to_archive() - def reload_tool_by_id(self, tool_id): + def reload_tool_by_id(self, tool_id: str) -> Tuple[Union[str, Dict[str, str]], str]: """ Attempt to reload the tool identified by 'tool_id', if successful replace the old tool. """ + message: Union[str, Dict[str, str]] if tool_id not in self._tools_by_id: message = f"No tool with id '{escape(tool_id)}'." status = "error" @@ -1331,6 +1347,9 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): filters = self._filter_factory.build_filters(trans) return lambda element, item_type: _filter_for_panel(element, item_type, filters, context) + def _looks_like_a_tool(self, path: str) -> bool: + ... + def _filter_for_panel(item, item_type, filters, context): """ diff --git a/mypy.ini b/mypy.ini index 27c951b9c65..3538b7afa71 100644 --- a/mypy.ini +++ b/mypy.ini @@ -475,8 +475,6 @@ check_untyped_defs = False check_untyped_defs = False [mypy-galaxy.tools.data_manager.manager] check_untyped_defs = False -[mypy-galaxy.tool_util.toolbox.base] -check_untyped_defs = False [mypy-galaxy.tool_util.deps.container_resolvers.mulled] check_untyped_defs = False [mypy-galaxy.managers.context]