From 4f71b7e94f4946abdfb1feb4a4b88bacf4bcd02d Mon Sep 17 00:00:00 2001 From: Likianta Date: Tue, 2 Jan 2024 10:50:08 +0800 Subject: [PATCH] fix: fix parsing `*args` --- CHANGELOG.zh.md | 5 ++ argsense/parser/func_parser.py | 114 ++++++++++++++++++++++----------- pyproject.toml | 6 +- 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.zh.md b/CHANGELOG.zh.md index e4e2abc..ff6f167 100644 --- a/CHANGELOG.zh.md +++ b/CHANGELOG.zh.md @@ -14,6 +14,11 @@ --- +### 0.5.5 (2024-01-02) + +- 添加 `:empty` 来传递空字符串 +- 修复对 `*args` 的处理 + ### 0.5.4 (2023-11-03) - 修复 args 参数无法通过 kwargs 语法传递的问题 diff --git a/argsense/parser/func_parser.py b/argsense/parser/func_parser.py index a975a14..aac273f 100644 --- a/argsense/parser/func_parser.py +++ b/argsense/parser/func_parser.py @@ -38,6 +38,14 @@ class T: 'kwargs': t.List[t.Tuple[ParamName, PlainParamType, t.Any]], 'return': PlainParamType, # noqa }) + ''' e.g. + { + 'name': 'run', + 'args': [('appid', 'str'), ('*', 'list')], + 'kwargs': [('_version', 'str', None), ('**', 'dict', {})], + 'return': 'none', + } + ''' class FuncInfo: @@ -49,41 +57,71 @@ class FuncInfo: target: t.Callable transport_help: bool # FIXME: temp solution - @classmethod - def global_kwargs(cls) -> T.KwArgsInfo: - return { # noqa - ':help' : { - 'cname' : '--help', - 'ctype' : ParamType.FLAG, - 'desc' : 'show help message and exit', - 'default' : False, # False means `not explicitly set by user`. - # for example, when user inputs in command line: - # `argsense xxx.py -h` # -> True - # `argsense xxx.py` # -> False - }, - ':helpx': { - 'cname' : '--helpx', - 'ctype' : ParamType.FLAG, - 'desc' : 'expand all command helps', - 'default' : False, - }, - } + GLOBAL_CNAME_2_NAME: t.Dict[str, str] = { + '--help' : ':help', + '--helpx' : ':helpx', + '-h' : ':help', + '-hh' : ':helpx', + # DELETE: below are deprecated + '--:help' : ':help', + '--:helpx': ':helpx', + '-:h' : ':help', + '-:hh' : ':helpx', + } + GLOBAL_KWARGS: T.KwArgsInfo = { # noqa + ':help' : { + 'cname' : '--help', + 'ctype' : ParamType.FLAG, + 'desc' : 'show help message and exit', + 'default': False, # False means `not explicitly set by user`. + # for example, when user inputs in command line: + # `argsense xxx.py -h` # -> True + # `argsense xxx.py` # -> False + }, + ':helpx': { + 'cname' : '--helpx', + 'ctype' : ParamType.FLAG, + 'desc' : 'expand all command helps', + 'default': False, + }, + } - @classmethod - def global_cname_2_name(cls) -> t.Dict[str, str]: - return { - '--help' : ':help', - '--helpx' : ':helpx', - '-h' : ':help', - '-hh' : ':helpx', - # DELETE: below are deprecated - '--:help' : ':help', - '--:helpx': ':helpx', - '-:h' : ':help', - '-:hh' : ':helpx', - } + # @classmethod + # def global_kwargs(cls) -> T.KwArgsInfo: + # return { # noqa + # ':help' : { + # 'cname' : '--help', + # 'ctype' : ParamType.FLAG, + # 'desc' : 'show help message and exit', + # 'default' : False, # False means `not explicitly set by user`. + # # for example, when user inputs in command line: + # # `argsense xxx.py -h` # -> True + # # `argsense xxx.py` # -> False + # }, + # ':helpx': { + # 'cname' : '--helpx', + # 'ctype' : ParamType.FLAG, + # 'desc' : 'expand all command helps', + # 'default' : False, + # }, + # } + # + # @classmethod + # def global_cname_2_name(cls) -> t.Dict[str, str]: + # return { + # '--help' : ':help', + # '--helpx' : ':helpx', + # '-h' : ':help', + # '-hh' : ':helpx', + # # DELETE: below are deprecated + # '--:help' : ':help', + # '--:helpx': ':helpx', + # '-:h' : ':help', + # '-:hh' : ':helpx', + # } def __init__(self, info: T.RawInfo): + # print(info, ':lv') from ..converter import name_2_cname from ..converter import type_2_ctype @@ -92,14 +130,16 @@ def __init__(self, info: T.RawInfo): self.desc = '' # self.return_type = info['return'] self.args = {} - self.kwargs = FuncInfo.global_kwargs().copy() - self.cname_2_name = FuncInfo.global_cname_2_name().copy() + self.kwargs = FuncInfo.GLOBAL_KWARGS.copy() + self.cname_2_name = FuncInfo.GLOBAL_CNAME_2_NAME.copy() self.transport_help = False for name, type in info['args']: cname = name_2_cname(name, style='arg') self._append_cname(name, cname) - self._append_cname(name, name_2_cname(name, style='opt')) # alias + if cname != '*': + # alias of "option" style + self._append_cname(name, name_2_cname(name, style='opt')) self.args[name] = { 'cname': cname, 'ctype': type_2_ctype(type), @@ -123,8 +163,8 @@ def local_kwargs(self) -> T.KwArgsInfo: def _append_cname(self, name: str, cname: str) -> None: assert cname not in self.cname_2_name, ( f'duplicate cname: `{cname}` (for `{name}`). ' - f'make sure you have not defined `xxx`, `_xxx` and `xxx_` ' - f'(or something like this) in the same function.' + f'make sure you have not defined parameters like `xxx`, `_xxx` and ' + f'`xxx_` in the same function.' ) self.cname_2_name[cname] = name diff --git a/pyproject.toml b/pyproject.toml index 9f77c48..d70c121 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "argsense" -version = "0.5.5a0" +version = "0.5.5" homepage = "https://github.com/likianta/argsense-cli" description = "New command line interface based on Python Rich library." readme = "README.md" @@ -11,15 +11,15 @@ license = "MIT" python = "^3.8" pysimplegui = { version = "*", optional = true } rich = "*" -textual = "*" # TODO: trogon = "*" +textual = "*" [tool.poetry.extras] gui = ["pysimplegui"] # pip install argsense[gui] [[tool.poetry.source]] name = "tsinghua" -url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/" +url = "https://pypi.tuna.tsinghua.edu.cn/simple/" priority = "default" [tool.poetry.scripts]