diff --git a/CHANGELOG.md b/CHANGELOG.md index c17c8d12..0feaf48e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 更新日志 +## Alconna 1.7.38 + +### 修复 + +- 修复 `command_manager.dump` +- 修复 `CompSession` 在执行过程中受到其他命令解析干扰的问题 + ## Alconna 1.7.37 ### 改进 diff --git a/src/arclet/alconna/__init__.py b/src/arclet/alconna/__init__.py index 2aaddf86..78c73a4e 100644 --- a/src/arclet/alconna/__init__.py +++ b/src/arclet/alconna/__init__.py @@ -50,7 +50,7 @@ from .typing import UnpackVar as UnpackVar from .typing import Up as Up -__version__ = "1.7.37" +__version__ = "1.7.38" # backward compatibility Arpamar = Arparma diff --git a/src/arclet/alconna/_internal/_analyser.py b/src/arclet/alconna/_internal/_analyser.py index 812e38d7..0eee0309 100644 --- a/src/arclet/alconna/_internal/_analyser.py +++ b/src/arclet/alconna/_internal/_analyser.py @@ -358,7 +358,7 @@ def process(self, argv: Argv[TDC]) -> Arparma[TDC]: else: exc = ArgumentMissing(lang.require("analyser", "param_missing")) if comp_ctx.get(None) and isinstance(exc, ArgumentMissing): - raise PauseTriggered(prompt(self, argv), exc) + raise PauseTriggered(prompt(self, argv), exc, argv) if self.command.meta.raise_exception: raise exc return self.export(argv, True, exc) @@ -382,7 +382,7 @@ def analyse(self, argv: Argv[TDC]) -> Arparma[TDC] | None: if comp_ctx.get(None): if isinstance(e1, InvalidParam): argv.free(argv.context.separators if argv.context else None) - raise PauseTriggered(prompt(self, argv), e1) from e1 + raise PauseTriggered(prompt(self, argv), e1, argv) from e1 if self.command.meta.raise_exception: raise return self.export(argv, True, e1) diff --git a/src/arclet/alconna/_internal/_handlers.py b/src/arclet/alconna/_internal/_handlers.py index d4f7c790..253238b1 100644 --- a/src/arclet/alconna/_internal/_handlers.py +++ b/src/arclet/alconna/_internal/_handlers.py @@ -721,7 +721,7 @@ def handle_completion(analyser: Analyser, argv: Argv, trigger: str | None = None """处理补全选项触发""" if res := prompt(analyser, argv, trigger): if comp_ctx.get(None): - raise PauseTriggered(res, trigger) + raise PauseTriggered(res, trigger, argv) prompt_other = lang.require("completion", "prompt_other") node = lang.require('completion', 'node') node = f"{node}\n" if node else "" diff --git a/src/arclet/alconna/completion.py b/src/arclet/alconna/completion.py index f6c1b24c..e7cc1e65 100644 --- a/src/arclet/alconna/completion.py +++ b/src/arclet/alconna/completion.py @@ -66,6 +66,10 @@ def __init__(self, source: Alconna): self.trigger = None self._token = None + self.raw_data = [] + self.bak_data = [] + self.current_index = 0 + @property def available(self): """表示当前补全会话是否可用。""" @@ -108,7 +112,9 @@ def enter(self, content: list | None = None) -> EnterResult: ValueError: 当前没有可用的补全选项, 或者当前补全选项不可用。 """ argv = command_manager.resolve(self.source.command) - _b, _r, _i, _n = argv.bak_data.copy(), argv.raw_data.copy(), argv.current_index, argv.ndata + argv.raw_data = self.raw_data.copy() + argv.bak_data = self.bak_data.copy() + argv.current_index = self.current_index if content: input_ = content else: @@ -122,9 +128,9 @@ def enter(self, content: list | None = None) -> EnterResult: argv.next(move=True) input_ = [prompt.text] if isinstance(self.trigger, InvalidParam): - argv.raw_data = argv.bak_data[: max(_i, 1)] + argv.raw_data = argv.bak_data[: max(self.current_index, 1)] argv.addon(input_) - argv.raw_data.extend(_r[max(_i, 1) :]) + argv.raw_data.extend(self.raw_data[max(self.current_index, 1) :]) else: argv.raw_data = argv.bak_data.copy() argv.addon(input_) @@ -149,7 +155,6 @@ def enter(self, content: list | None = None) -> EnterResult: if isinstance(exc, PauseTriggered): self.fresh(exc) return EnterResult(exception=self.trigger if isinstance(self.trigger, InvalidParam) else None) - argv.bak_data, argv.raw_data, argv.current_index, argv.ndata = _b, _r, _i, _n return EnterResult(exception=exc) self.exit() return EnterResult(res) # noqa # type: ignore @@ -171,6 +176,9 @@ def clear(self): self.index = 0 self.prompts.clear() self.source.reset() + self.raw_data = [] + self.bak_data = [] + self.current_index = 0 return self def exit(self): @@ -214,6 +222,10 @@ def fresh(self, exc: PauseTriggered): self.clear() self.push(*exc.args[0]) self.trigger = exc.args[1] + argv = exc.args[2] + self.raw_data = argv.raw_data + self.bak_data = argv.bak_data + self.current_index = argv.current_index return True diff --git a/src/arclet/alconna/manager.py b/src/arclet/alconna/manager.py index 8a1dd971..9afc1f13 100644 --- a/src/arclet/alconna/manager.py +++ b/src/arclet/alconna/manager.py @@ -76,8 +76,15 @@ def load_cache(self) -> None: def dump_cache(self) -> None: """保存缓存""" + data = {} + for key, short in self.__shortcuts.items(): + if isinstance(short, dict): + data[key] = {k: v for k, v in short.items() if k != "wrapper"} + else: + data[key] = short with shelve.open(self.cache_path) as db: - db["shortcuts"] = self.__shortcuts + db["shortcuts"] = data + data.clear() @property def get_loaded_namespaces(self):