Skip to content

Commit

Permalink
🐛 version 1.7.33
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Oct 30, 2023
1 parent 7e425e2 commit a377953
Show file tree
Hide file tree
Showing 13 changed files with 219 additions and 166 deletions.
268 changes: 157 additions & 111 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion entry_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

if __name__ == '__main__':
import pytest
pytest.main([__file__, "-vs", "--durations=0"])
pytest.main([__file__, "-v", "--durations=0"])


10 changes: 7 additions & 3 deletions exam1.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@
if cmd == ".tab":
print(interface.tab())
elif cmd.startswith(".enter"):
content = cmd[6:].lstrip()
_res = interface.enter([content] if content else None)
_res = interface.enter(None)
if _res.result:
res = _res.result
elif _res.exception:
print(_res.exception)
break
else:
print(interface.current())
_res = interface.enter([cmd])
if _res.result:
res = _res.result
elif _res.exception:
print(_res.exception)
break
print(res.matched)
print(res.all_matched_args)
3 changes: 2 additions & 1 deletion src/arclet/alconna/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .config import namespace as namespace
from .core import Alconna as Alconna
from .duplication import Duplication as Duplication
from .exceptions import InvalidArgs as InvalidArgs
from .exceptions import InvalidParam as InvalidParam
from .exceptions import NullMessage as NullMessage
from .exceptions import ParamsUnmatched as ParamsUnmatched
Expand All @@ -49,7 +50,7 @@
from .typing import UnpackVar as UnpackVar
from .typing import Up as Up

__version__ = "1.7.32"
__version__ = "1.7.33"

# backward compatibility
Arpamar = Arparma
Expand Down
18 changes: 8 additions & 10 deletions src/arclet/alconna/_internal/_analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
from ..action import Action
from ..args import Args
from ..arparma import Arparma
from ..base import Option, Subcommand, Help, Shortcut, Completion
from ..base import Completion, Help, Option, Shortcut, Subcommand
from ..completion import comp_ctx
from ..config import config
from ..exceptions import ArgumentMissing, FuzzyMatchSuccess, ParamsUnmatched, PauseTriggered, SpecialOptionTriggered
from ..exceptions import ArgumentMissing, FuzzyMatchSuccess, InvalidParam, ParamsUnmatched, PauseTriggered, SpecialOptionTriggered
from ..manager import ShortcutArgs, command_manager
from ..model import HeadResult, OptionResult, Sentence, SubcommandResult
from ..output import output_manager
Expand Down Expand Up @@ -308,14 +308,14 @@ def process(self, argv: Argv[TDC]) -> Arparma[TDC]:
Raises:
ValueError: 快捷命令查找失败
ParamsUnmatched: 参数不匹配
InvalidParam: 参数不匹配
ArgumentMissing: 参数缺失
"""
if argv.message_cache and argv.token in self.used_tokens and (res := command_manager.get_record(argv.token)):
return res
try:
self.header_result = analyse_header(self.command_header, argv)
except ParamsUnmatched as e:
except InvalidParam as e:
_next = e.args[1]
if _next.__class__ is not str or not _next:
if self.command.meta.raise_exception:
Expand All @@ -338,7 +338,7 @@ def process(self, argv: Argv[TDC]) -> Arparma[TDC]:
return self.export(argv, True)

except RuntimeError as e:
exc = ParamsUnmatched(lang.require("header", "error").format(target=argv.release(recover=True)[0]))
exc = InvalidParam(lang.require("header", "error").format(target=argv.release(recover=True)[0]))
if self.command.meta.raise_exception:
raise exc from e
return self.export(argv, True, exc)
Expand All @@ -357,9 +357,7 @@ def process(self, argv: Argv[TDC]) -> Arparma[TDC]:
exc = ParamsUnmatched(lang.require("analyser", "param_unmatched").format(target=argv.next(move=False)[0]))
else:
exc = ArgumentMissing(lang.require("analyser", "param_missing"))
if comp_ctx.get(None):
if isinstance(exc, ParamsUnmatched):
argv.free(argv.context.separators if argv.context else None)
if comp_ctx.get(None) and isinstance(exc, ArgumentMissing):
raise PauseTriggered(prompt(self, argv), exc)
if self.command.meta.raise_exception:
raise exc
Expand All @@ -374,15 +372,15 @@ def analyse(self, argv: Argv[TDC]) -> Arparma[TDC] | None:
return self.export(argv, True)
except SpecialOptionTriggered as sot:
return _SPECIAL[sot.args[0]](self, argv)
except (ParamsUnmatched, ArgumentMissing) as e1:
except (InvalidParam, ArgumentMissing) as e1:
if (rest := argv.release()) and isinstance(rest[-1], str):
if rest[-1] in argv.completion_names and "completion" not in argv.namespace.disable_builtin_options:
argv.bak_data[-1] = argv.bak_data[-1][: -len(rest[-1])].rstrip()
return handle_completion(self, argv)
if (handler := argv.special.get(rest[-1])) and handler not in argv.namespace.disable_builtin_options:
return _SPECIAL[handler](self, argv)
if comp_ctx.get(None):
if isinstance(e1, ParamsUnmatched):
if isinstance(e1, InvalidParam):
argv.free(argv.context.separators if argv.context else None)
raise PauseTriggered(prompt(self, argv), e1) from e1
if self.command.meta.raise_exception:
Expand Down
2 changes: 2 additions & 0 deletions src/arclet/alconna/_internal/_argv.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ def addon(self, data: Iterable[str | Any]) -> Self:
continue
if res := self.to_text(d):
d = res
if isinstance(d, str) and not (d := d.strip()):
continue
if isinstance(d, str) and i > 0 and isinstance(self.raw_data[-1], str):
self.raw_data[-1] += f"{self.separators[0]}{d}"
else:
Expand Down
28 changes: 14 additions & 14 deletions src/arclet/alconna/_internal/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from ..base import Option, Subcommand
from ..completion import Prompt, comp_ctx
from ..config import config
from ..exceptions import ArgumentMissing, FuzzyMatchSuccess, ParamsUnmatched, PauseTriggered, SpecialOptionTriggered
from ..exceptions import ArgumentMissing, FuzzyMatchSuccess, InvalidParam, PauseTriggered, SpecialOptionTriggered
from ..model import HeadResult, OptionResult, Sentence
from ..output import output_manager
from ..typing import KWBool
Expand Down Expand Up @@ -40,7 +40,7 @@ def _validate(argv: Argv, target: Arg[Any], value: BasePattern[Any], result: dic
if res.flag == "error":
if target.optional:
return
raise ParamsUnmatched(target.field.get_unmatch_tips(arg, res.error.args[0]))
raise InvalidParam(target.field.get_unmatch_tips(arg, res.error.args[0]))
result[target.name] = res._value # noqa


Expand Down Expand Up @@ -144,11 +144,11 @@ def step_keyword(argv: Argv, args: Args, result: dict[str, Any]):
break
for arg in args.argument.keyword_only.values():
if arg.value.base.exec(may_arg).flag == "valid": # type: ignore
raise ParamsUnmatched(lang.require("args", "key_missing").format(target=may_arg, key=arg.name))
raise InvalidParam(lang.require("args", "key_missing").format(target=may_arg, key=arg.name))
for name in args.argument.keyword_only:
if levenshtein(_key, name) >= config.fuzzy_threshold:
raise FuzzyMatchSuccess(lang.require("fuzzy", "matched").format(source=name, target=_key))
raise ParamsUnmatched(lang.require("args", "key_not_found").format(name=_key))
raise InvalidParam(lang.require("args", "key_not_found").format(name=_key))
arg = args.argument.keyword_only[_key]
value = arg.value.base # type: ignore
if not _m_arg:
Expand Down Expand Up @@ -255,7 +255,7 @@ def handle_option(argv: Argv, opt: Option) -> tuple[str, OptionResult]:
if error:
if argv.fuzzy_match and levenshtein(name, opt.name) >= config.fuzzy_threshold:
raise FuzzyMatchSuccess(lang.require("fuzzy", "matched").format(source=name, target=opt.name))
raise ParamsUnmatched(lang.require("option", "name_error").format(source=opt.name, target=name))
raise InvalidParam(lang.require("option", "name_error").format(source=opt.name, target=name))
name = opt.dest
return (
(name, OptionResult(None, analyse_args(argv, opt.args)))
Expand Down Expand Up @@ -331,7 +331,7 @@ def analyse_compact_params(analyser: SubAnalyser, argv: Argv):
analyser.subcommands_result[param.command.dest] = param.result()
_data.clear()
return True
except ParamsUnmatched as e:
except InvalidParam as e:
if argv.context.__class__ is Arg:
raise e
argv.data_reset(_data, _index)
Expand Down Expand Up @@ -367,7 +367,7 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
_param = analyser.compile_params[_text]
elif analyser.compact_params and (res := analyse_compact_params(analyser, argv)):
if res.__class__ is str:
raise ParamsUnmatched(res)
raise InvalidParam(res)
argv.context = None
return True
else:
Expand All @@ -382,7 +382,7 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
return True
if _param.__class__ is Option:
if _param.requires and analyser.sentences != _param.requires:
raise ParamsUnmatched(
raise InvalidParam(
lang.require("option", "require_error").format(source=_param.name, target=" ".join(analyser.sentences))
)
analyse_option(analyser, argv, _param)
Expand All @@ -392,7 +392,7 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
_data, _index = argv.data_set()
try:
if opt.requires and analyser.sentences != opt.requires:
raise ParamsUnmatched(
raise InvalidParam(
lang.require("option", "require_error").format(
source=opt.name, target=" ".join(analyser.sentences)
)
Expand All @@ -409,7 +409,7 @@ def analyse_param(analyser: SubAnalyser, argv: Argv, seps: tuple[str, ...] | Non
raise exc # type: ignore # noqa
elif _param is not None:
if _param.command.requires and analyser.sentences != _param.command.requires:
raise ParamsUnmatched(
raise InvalidParam(
lang.require("subcommand", "require_error").format(
source=_param.command.name, target=" ".join(analyser.sentences)
)
Expand Down Expand Up @@ -467,13 +467,13 @@ def analyse_header(header: Header, argv: Argv) -> HeadResult:
argv.rollback(may_cmd)
if argv.fuzzy_match:
_handle_fuzzy(header, head_text)
raise ParamsUnmatched(lang.require("header", "error").format(target=head_text), head_text)
raise InvalidParam(lang.require("header", "error").format(target=head_text), head_text)
if _m_str and may_cmd:
if argv.fuzzy_match:
_handle_fuzzy(header, f"{head_text} {may_cmd}")
raise ParamsUnmatched(lang.require("header", "error").format(target=may_cmd), may_cmd)
raise InvalidParam(lang.require("header", "error").format(target=may_cmd), may_cmd)
argv.rollback(may_cmd)
raise ParamsUnmatched(lang.require("header", "error").format(target=head_text), None)
raise InvalidParam(lang.require("header", "error").format(target=head_text), None)


def _handle_fuzzy(header: Header, source: str):
Expand Down Expand Up @@ -520,7 +520,7 @@ def handle_shortcut(analyser: Analyser, argv: Argv):
output_manager.send(analyser.command.name, lambda: "\n".join(data))
else:
if not opt_v.get("name"):
raise ParamsUnmatched(lang.require("shortcut", "name_require"))
raise ArgumentMissing(lang.require("shortcut", "name_require"))
if opt_v.get("action") == "delete":
msg = analyser.command.shortcut(opt_v["name"], delete=True)
elif opt_v["command"] == "_":
Expand Down
24 changes: 12 additions & 12 deletions src/arclet/alconna/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from nepattern import AllParam, AnyOne, BasePattern, MatchMode, RawStr, UnionPattern, all_patterns, type_parser
from tarina import Empty, get_signature, lang

from .exceptions import InvalidParam
from .exceptions import InvalidArgs
from .typing import KeyWordVar, KWBool, MultiVar, UnpackVar


Expand Down Expand Up @@ -114,16 +114,16 @@ def __init__(
flags (list[ArgFlag], optional): 参数单元的标识. Defaults to None.
"""
if not isinstance(name, str) or name.startswith("$"):
raise InvalidParam(lang.require("args", "name_error"))
raise InvalidArgs(lang.require("args", "name_error"))
if not name.strip():
raise InvalidParam(lang.require("args", "name_empty"))
raise InvalidArgs(lang.require("args", "name_empty"))
self.name = name
_value = type_parser(value or RawStr(name))
default = field if isinstance(field, Field) else Field(field)
if isinstance(_value, UnionPattern) and _value.optional:
default.default = Empty if default.default is None else default.default
if _value is Empty:
raise InvalidParam(lang.require("args", "value_error").format(target=name))
raise InvalidArgs(lang.require("args", "value_error").format(target=name))
self.value = _value
self.field = default
self.notice = notice
Expand Down Expand Up @@ -341,34 +341,34 @@ def __check_vars__(self):
self._visit.add(arg.name)
if isinstance(arg.value, UnpackVar):
if len(self._visit) > 1:
raise InvalidParam("Unpack var can only put in the first position")
raise InvalidArgs("Unpack var can only put in the first position")
if len(self.argument) > 1:
raise InvalidParam("Args can only contain one arg if using Unpack var")
raise InvalidArgs("Args can only contain one arg if using Unpack var")
_gen_unpack = getattr(arg.value, "unpack", gen_unpack)
self.argument.unpack = (arg, _gen_unpack(arg.value))
break
if isinstance(arg.value, MultiVar):
if isinstance(arg.value.base, KeyWordVar):
if self.argument.var_keyword:
raise InvalidParam(lang.require("args", "duplicate_kwargs"))
raise InvalidArgs(lang.require("args", "duplicate_kwargs"))
if self.argument.var_positional and arg.value.base.sep in self.argument.var_positional[1].separators: # noqa: E501
raise InvalidParam("varkey cannot use the same sep as varpos's Arg")
raise InvalidArgs("varkey cannot use the same sep as varpos's Arg")
self.argument.var_keyword = (arg.value, arg)
elif self.argument.var_positional:
raise InvalidParam(lang.require("args", "duplicate_varargs"))
raise InvalidArgs(lang.require("args", "duplicate_varargs"))
elif self.argument.keyword_only:
raise InvalidParam(lang.require("args", "exclude_mutable_args"))
raise InvalidArgs(lang.require("args", "exclude_mutable_args"))
else:
self.argument.var_positional = (arg.value, arg)
elif isinstance(arg.value, KeyWordVar):
if self.argument.var_keyword:
raise InvalidParam(lang.require("args", "exclude_mutable_args"))
raise InvalidArgs(lang.require("args", "exclude_mutable_args"))
self.argument.keyword_only[arg.name] = arg
else:
self.argument.normal.append(arg)
if arg.optional:
if self.argument.var_keyword or self.argument.var_positional:
raise InvalidParam(lang.require("args", "exclude_mutable_args"))
raise InvalidArgs(lang.require("args", "exclude_mutable_args"))
self.optional_count += 1
self.argument.clear()
self.argument.extend(_tmp)
Expand Down
6 changes: 3 additions & 3 deletions src/arclet/alconna/arparma.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def __init__(
origin: TDC,
matched: bool = False,
header_match: HeadResult | None = None,
error_info: type[BaseException] | BaseException | None = None,
error_info: type[Exception] | Exception | None = None,
error_data: list[str | Any] | None = None,
main_args: dict[str, Any] | None = None,
options: dict[str, OptionResult] | None = None,
Expand All @@ -130,7 +130,7 @@ def __init__(
origin (TDC): 原始数据
matched (bool, optional): 是否匹配
header_match (HeadResult | None, optional): 命令头匹配结果
error_info (type[BaseException] | BaseException | None, optional): 错误信息
error_info (type[Exception] | Exception | None, optional): 错误信息
error_data (list[str | Any] | None, optional): 错误数据
main_args (dict[str, Any] | None, optional): 主参数匹配结果
options (dict[str, OptionResult] | None, optional): 选项匹配结果
Expand Down Expand Up @@ -278,7 +278,7 @@ def call(self, target: Callable[..., T]) -> T:
bind.apply_defaults()
return target(*bind.args, **bind.kwargs)

def fail(self, exc: type[BaseException] | BaseException):
def fail(self, exc: type[Exception] | Exception):
"""生成一个失败的 `Arparma`"""
return Arparma(self.source, self.origin, False, self.header_match, error_info=exc)

Expand Down
4 changes: 2 additions & 2 deletions src/arclet/alconna/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from .action import Action, store
from .args import Arg, Args
from .exceptions import InvalidParam
from .exceptions import InvalidArgs
from .model import OptionResult, SubcommandResult


Expand Down Expand Up @@ -89,7 +89,7 @@ def __init__(
requires (str | list[str] | tuple[str, ...] | set[str] | None, optional): 命令节点需求前缀
"""
if not name:
raise InvalidParam(lang.require("common", "name_empty"))
raise InvalidArgs(lang.require("common", "name_empty"))
_parts = name.split(" ")
self.name = _parts[-1]
self.requires = ([requires] if isinstance(requires, str) else list(requires)) if requires else []
Expand Down
Loading

0 comments on commit a377953

Please sign in to comment.