From e357b27433567dbdd4a5cb3c7ca53a4e8798a421 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 15 Oct 2022 17:53:02 -0700 Subject: [PATCH] more granular type annotations --- docs/lib.md | 4 ++-- jc/cli.py | 29 ++++++++++++++--------------- jc/lib.py | 34 +++++++++++++++++++++++++++++----- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/docs/lib.md b/docs/lib.md index 4c36b0c5..0067f932 100644 --- a/docs/lib.md +++ b/docs/lib.md @@ -162,7 +162,7 @@ subset of `parser_mod_list()`. ```python def parser_info(parser_mod_name: str, - documentation: bool = False) -> JSONDictType + documentation: bool = False) -> ParserInfoType ``` Returns a dictionary that includes the parser module metadata. @@ -183,7 +183,7 @@ Parameters: ```python def all_parser_info(documentation: bool = False, show_hidden: bool = False, - show_deprecated: bool = False) -> List[JSONDictType] + show_deprecated: bool = False) -> List[ParserInfoType] ``` Returns a list of dictionaries that includes metadata for all parser diff --git a/jc/cli.py b/jc/cli.py index b00f0f72..02682786 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -14,7 +14,8 @@ from typing import List, Dict, Union, Optional, TextIO from types import ModuleType from .lib import ( __version__, parser_info, all_parser_info, parsers, _get_parser, _parser_is_streaming, - parser_mod_list, standard_parser_mod_list, plugin_parser_mod_list, streaming_parser_mod_list + parser_mod_list, standard_parser_mod_list, plugin_parser_mod_list, streaming_parser_mod_list, + JSONDictType ) from . import utils from .cli_data import ( @@ -25,10 +26,8 @@ from .shell_completions import bash_completion, zsh_completion from . import tracebackplus from .exceptions import LibraryNotInstalled, ParseError -MetadataType = Dict[ - str, - Optional[Union[str, int, float, List[str], datetime]] -] +MetadataType = Dict[str, Optional[Union[str, int, float, List[str], datetime]]] +AboutJCType = Dict[str, Union[str, int, List[str]]] # make pygments import optional PYGMENTS_INSTALLED: bool = False @@ -79,8 +78,8 @@ class JcCli(): ) def __init__(self) -> None: - self.data_in: Optional[Union[str, bytes,TextIO]] = None - self.data_out: Optional[Union[List[Dict], Dict]] = None + self.data_in: Optional[Union[str, bytes, TextIO]] = None + self.data_out: Optional[Union[List[JSONDictType], JSONDictType, AboutJCType]] = None self.options: List[str] = [] self.args: List[str] = [] self.parser_module: Optional[ModuleType] = None @@ -195,11 +194,11 @@ class JcCli(): ptext = '' padding_char = ' ' for p in all_parser_info(show_hidden=self.show_hidden, show_deprecated=False): - parser_arg = p.get('argument', 'UNKNOWN') - padding = self.pad - len(parser_arg) - parser_desc = p.get('description', 'No description available.') - indent_text = padding_char * self.indent - padding_text = padding_char * padding + parser_arg: str = p.get('argument', 'UNKNOWN') + padding: int = self.pad - len(parser_arg) + parser_desc: str = p.get('description', 'No description available.') + indent_text: str = padding_char * self.indent + padding_text: str = padding_char * padding ptext += indent_text + parser_arg + padding_text + parser_desc + '\n' return ptext @@ -615,9 +614,9 @@ class JcCli(): if isinstance(self.data_out, dict): if '_jc_meta' not in self.data_out: - self.data_out['_jc_meta'] = {} + self.data_out['_jc_meta'] = {} # type: ignore - self.data_out['_jc_meta'].update(meta_obj) + self.data_out['_jc_meta'].update(meta_obj) # type: ignore elif isinstance(self.data_out, list): if not self.data_out: @@ -628,7 +627,7 @@ class JcCli(): if '_jc_meta' not in item: item['_jc_meta'] = {} - item['_jc_meta'].update(meta_obj) + item['_jc_meta'].update(meta_obj) # type: ignore else: utils.error_message(['Parser returned an unsupported object type.']) diff --git a/jc/lib.py b/jc/lib.py index b4f9d579..2a7e8993 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -7,6 +7,30 @@ from typing import Dict, List, Iterable, Union, Iterator from types import ModuleType from jc import appdirs +if sys.version_info >= (3, 8): + from typing import TypedDict + ParserInfoType = TypedDict( + 'ParserInfoType', + { + "name": str, + "argument": str, + "version": str, + "description": str, + "author": str, + "author_email": str, + "compatible": List[str], + "magic_commands": List[str], + "documentation": str, + "streaming": bool, + "plugin": bool, + "hidden": bool, + "deprecated": bool + }, + total=False + ) +else: + ParserInfoType = Dict + JSONDictType = Dict[str, Union[str, int, float, bool, List, Dict, None]] __version__ = '1.22.1' @@ -453,7 +477,7 @@ def streaming_parser_mod_list( return plist -def parser_info(parser_mod_name: str, documentation: bool = False) -> JSONDictType: +def parser_info(parser_mod_name: str, documentation: bool = False) -> ParserInfoType: """ Returns a dictionary that includes the parser module metadata. @@ -469,7 +493,7 @@ def parser_info(parser_mod_name: str, documentation: bool = False) -> JSONDictTy # ensure parser_mod_name is a true module name and not a cli name parser_mod_name = _cliname_to_modname(parser_mod_name) parser_mod = _get_parser(parser_mod_name) - info_dict: JSONDictType = {} + info_dict: ParserInfoType = {} if hasattr(parser_mod, 'info'): info_dict['name'] = parser_mod_name @@ -478,7 +502,7 @@ def parser_info(parser_mod_name: str, documentation: bool = False) -> JSONDictTy for k, v in parser_entry.items(): if not k.startswith('__'): - info_dict[k] = v + info_dict[k] = v # type: ignore if _modname_to_cliname(parser_mod_name) in local_parsers: info_dict['plugin'] = True @@ -495,7 +519,7 @@ def all_parser_info( documentation: bool = False, show_hidden: bool = False, show_deprecated: bool = False -) -> List[JSONDictType]: +) -> List[ParserInfoType]: """ Returns a list of dictionaries that includes metadata for all parser modules. By default only non-hidden, non-deprecated parsers are @@ -521,7 +545,7 @@ def all_parser_info( plist.append(_cliname_to_modname(p)) - p_info_list: List[JSONDictType] = [parser_info(p, documentation=documentation) for p in plist] + p_info_list: List[ParserInfoType] = [parser_info(p, documentation=documentation) for p in plist] return p_info_list