From 92d741b94f534060717890ffcd43465a96ef1416 Mon Sep 17 00:00:00 2001 From: RF-Tar-Railt <3165388245@qq.com> Date: Thu, 11 May 2023 00:13:14 +0800 Subject: [PATCH] :art: format core.py --- CHANGELOG.md | 1 + src/arclet/alconna/arparma.py | 22 ++++----- src/arclet/alconna/core.py | 91 +++++++++++++++-------------------- 3 files changed, 48 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac9f448..47616a7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ - `set_default` 的 `arg`, `option`, `subcommand` 合并为 `path`, 原参数仍可用 - `Arg` 中 `name` 的后缀标识符不强制需要 `';'` 作为分割, 即 `foo;?` 与 `foo?` 等价 - `Argv.preprocessor` 与 `Argv.filter_out` 现在接收 type 而不是 str +- 移除 `Alconna.reset_behaviors` ### 修复: diff --git a/src/arclet/alconna/arparma.py b/src/arclet/alconna/arparma.py index 44bdc68c..eeca59b5 100644 --- a/src/arclet/alconna/arparma.py +++ b/src/arclet/alconna/arparma.py @@ -190,19 +190,15 @@ def execute(self, behaviors: list[ArparmaBehavior] | None = None) -> Self: Returns: Self: 返回自身 """ - if behaviors := (self.source.behaviors + (behaviors or [])): - exc_behaviors = [] - for behavior in behaviors: - exc_behaviors.extend(requirement_handler(behavior)) - for b in exc_behaviors: - b.before_operate(self) - for b in exc_behaviors: - try: - b.operate(self) - except BehaveCancelled: - continue - except OutBoundsBehave as e: - return self.fail(e) + for b in behaviors: + b.before_operate(self) + for b in behaviors: + try: + b.operate(self) + except BehaveCancelled: + continue + except OutBoundsBehave as e: + return self.fail(e) return self def call(self, target: Callable[..., T], **additional) -> T: diff --git a/src/arclet/alconna/core.py b/src/arclet/alconna/core.py index 84f47ab6..42c2758c 100644 --- a/src/arclet/alconna/core.py +++ b/src/arclet/alconna/core.py @@ -3,7 +3,7 @@ import sys from dataclasses import dataclass, field -from functools import partial, reduce +from functools import partial from pathlib import Path from typing import Any, Callable, Generic, Sequence, TypeVar, overload @@ -12,7 +12,7 @@ from ._internal._analyser import Analyser, TCompile from .args import Arg, Args -from .arparma import Arparma, ArparmaBehavior +from .arparma import Arparma, ArparmaBehavior, requirement_handler from .base import Option, Subcommand from .config import Namespace, config from .duplication import Duplication @@ -26,6 +26,25 @@ TDC1 = TypeVar("TDC1", bound=DataCollection[Any]) +def add_builtin_options(options: list[Option | Subcommand], ns: Namespace) -> None: + options.append( + Option("|".join(ns.builtin_option_name['help']), help_text=lang.require("builtin", "option_help")), + ) + options.append( + Option( + "|".join(ns.builtin_option_name['shortcut']), + Args["delete;?", "delete"]["name", str]["command", str, "_"], + help_text=lang.require("builtin", "option_shortcut") + ) + ) + options.append( + Option( + "|".join(ns.builtin_option_name['completion']), + help_text=lang.require("builtin", "option_completion") + ) + ) + + @dataclass(init=True, unsafe_hash=True) class ArparmaExecutor(Generic[T]): """Arparma 执行器 @@ -113,11 +132,11 @@ def __init__( """ if not namespace: ns_config = config.default_namespace - elif isinstance(namespace, Namespace): - ns_config = config.namespaces.setdefault(namespace.name, namespace) - else: + elif isinstance(namespace, str): ns_config = config.namespaces.setdefault(namespace, Namespace(namespace)) - self.prefixes = next(filter(lambda x: isinstance(x, list), args + (ns_config.prefixes.copy(),))) # type: ignore + else: + ns_config = namespace + self.prefixes = next(filter(lambda x: isinstance(x, list), args), ns_config.prefixes.copy()) # type: ignore try: self.command = next(filter(lambda x: not isinstance(x, (list, Option, Subcommand, Args, Arg)), args)) except StopIteration: @@ -135,33 +154,20 @@ def __init__( self.meta.raise_exception = self.meta.raise_exception or ns_config.raise_exception self.meta.compact = self.meta.compact or ns_config.compact options = [i for i in args if isinstance(i, (Option, Subcommand))] - options.append( - Option("|".join(ns_config.builtin_option_name['help']), help_text=lang.require("builtin", "option_help")), - ) - options.append( - Option( - "|".join(ns_config.builtin_option_name['shortcut']), - Args["delete;?", "delete"]["name", str]["command", str, "_"], - help_text=lang.require("builtin", "option_shortcut") - ) - ) - options.append( - Option( - "|".join(ns_config.builtin_option_name['completion']), - help_text=lang.require("builtin", "option_completion") - ) - ) - name = f"{self.command or self.prefixes[0]}".replace(command_manager.sign, "") # type: ignore + add_builtin_options(options, ns_config) + name = f"{self.command or self.prefixes[0]}" # type: ignore self.path = f"{self.namespace}::{name}" + _args = Args() + for i in filter(lambda x: isinstance(x, (Args, Arg)), args): + _args << i super().__init__( "ALCONNA::", - reduce(lambda x, y: x + y, [Args()] + [i for i in args if isinstance(i, (Arg, Args))]), # type: ignore - *options, - dest=name, - separators=separators or ns_config.separators, + _args, *options, dest=name, separators=separators or ns_config.separators, ) self.name = name - self.behaviors = behaviors or [] + self.behaviors = [] + for behavior in behaviors or []: + self.behaviors.extend(requirement_handler(behavior)) command_manager.register(self) self._executors: list[ArparmaExecutor] = [] self.union = set() @@ -184,33 +190,14 @@ def reset_namespace(self, namespace: Namespace | str, header: bool = True) -> Se self.path = f"{self.namespace}::{self.name}" if header: self.prefixes = namespace.prefixes.copy() - self.options[-3] = Option( - "|".join(namespace.builtin_option_name['help']), help_text=lang.require("builtin", "option_help") - ) - self.options[-2] = Option( - "|".join(namespace.builtin_option_name['shortcut']), - Args["delete;?", "delete"]["name", str]["command", str, "_"], - help_text=lang.require("builtin", "option_shortcut") - ) - self.options[-1] = Option( - "|".join(namespace.builtin_option_name['completion']), - help_text=lang.require("builtin", "option_completion") - ) + self.options = self.options[:-3] + add_builtin_options(self.options, namespace) self.meta.fuzzy_match = namespace.fuzzy_match or self.meta.fuzzy_match self.meta.raise_exception = namespace.raise_exception or self.meta.raise_exception self._hash = self._calc_hash() command_manager.register(self) return self - def reset_behaviors(self, behaviors: list[ArparmaBehavior]) -> Self: - """重新设置解析行为器 - - Args: - behaviors (list[ArparmaBehavior]): 解析行为器 - """ - self.behaviors[1:] = behaviors - return self - def get_help(self) -> str: """返回该命令的帮助信息""" return self.formatter.format_node() @@ -298,9 +285,7 @@ def parse(self, message: TDC) -> Arparma[TDC]: def parse(self, message, *, duplication: type[T_Duplication]) -> T_Duplication: ... - def parse( - self, message: TDC, *, duplication: type[T_Duplication] | None = None - ) -> Arparma[TDC] | T_Duplication: + def parse(self, message: TDC, *, duplication: type[T_Duplication] | None = None) -> Arparma[TDC] | T_Duplication: """命令分析功能, 传入字符串或消息链, 返回一个特定的数据集合类 Args: @@ -318,7 +303,7 @@ def parse( raise e return Arparma(self.path, message, False, error_info=e) if arp.matched: - arp = arp.execute() + arp = arp.execute(self.behaviors) if self._executors: for ext in self._executors: arp.call(ext.target)