diff --git a/docs/command.md b/docs/command.md index 8353c44..5c0eea8 100644 --- a/docs/command.md +++ b/docs/command.md @@ -5,7 +5,7 @@ ## Usage ```python -from typing import Callable, Self +from typing import Callable, Self, Optional, List class Literal: def __init__(self, name: str): @@ -17,13 +17,13 @@ class Literal: self.sub += nodes return self - def run(self, func: Callable[[list[str]], None]) -> Self: + def run(self, func: Callable[[List[str]], None]) -> Self: return self def tip(self, tip: str) -> Self: return self - def arg(self, parse_func: Callable[[str], type | None]) -> Self: + def arg(self, parse_func: Callable[[str], Optional[type]]) -> Self: return self def error(self, callback: Callable[[str], None]) -> Self: @@ -66,7 +66,7 @@ pub enum ArgumentType { Float(f64), } -pub type CallBackFunc = Fn(Vec) -> bool; +pub type CallBackFunc = Fn(Vec<(String, ArgumentType)>) -> bool; pub enum CallBack { Fn(CallBackFunc), diff --git a/lib_not_dr/command/descriptor.py b/lib_not_dr/command/descriptor.py new file mode 100644 index 0000000..17c8cc6 --- /dev/null +++ b/lib_not_dr/command/descriptor.py @@ -0,0 +1,7 @@ +class CallBackDescriptor: + def __set_name__(self, owner, name): + self.callback_name = name + + def __set__(self, instance, value): + if + diff --git a/lib_not_dr/command/exception.py b/lib_not_dr/command/exception.py new file mode 100644 index 0000000..56aad35 --- /dev/null +++ b/lib_not_dr/command/exception.py @@ -0,0 +1,2 @@ +class IllegalArgumentName(Exception): + """参数名称或快捷名不合法""" diff --git a/lib_not_dr/command/nodes.py b/lib_not_dr/command/nodes.py new file mode 100644 index 0000000..943769a --- /dev/null +++ b/lib_not_dr/command/nodes.py @@ -0,0 +1,124 @@ +# ------------------------------- +# Difficult Rocket +# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com +# All rights reserved +# ------------------------------- + +import re +from typing import Callable, List, Optional, Union +try: + from typing import Self +except ImportError: + from typing import TypeVar + Self = TypeVar("Self") + +from .exception import IllegalArgumentName + +CallBack = Union[Callable[[str], None], str] # Equals to `Callable[[str], None] | str` +# 可调用对象或字符串作为回调 +# A callable or str as callback + +ParseArgFunc = Callable[[str], Optional[type]] +# 解析参数的函数,返回值为 None 时表示解析失败 +# function to parse argument, return None when failed + +EMPTY_WORDS = re.compile(r"\s", re.I) + + +def check_once(cls, name) -> None: + if hasattr(cls, name): + if getattr(cls, name) is not None: + raise AttributeError(f"Attribute '{name}' has been set.") + + +def check_name(name: Union[str, List[str]]) -> None: + """ + Check the name or shortcuts of argument(s) or flag(s). + The name must not be empty str, and must not contains \\t or \\n or \\f or \\r. + If that not satisfy the requirements, it will raise exception `IllegalArgumentName`. + 检查 参数或标记 的 名称或快捷方式 是否符合要求。 + 名称必须是非空的字符串,且不能包含 \\t 或 \\n 或 \\f 或 \\r。 + 如果不符合要求,将会抛出 `IllegalArgumentName` 异常。 + :param name: arguments + :return: None + """ + if isinstance(name, str) and EMPTY_WORDS.search(name): + raise IllegalArgumentName("The name of argument must not contains empty words.") + elif isinstance(name, list) and all([(not isinstance(i, str)) and EMPTY_WORDS.search(i) for i in name]): + raise IllegalArgumentName("The name of shortcut must be 'str', and must not contains empty words.") + else: + raise TypeError("The type of name must be 'str' or 'list[str]'.") + + +class Parsed: + ... + + +class Argument: + def __init__(self, name, shortcut, optional): + ... + + +class Flag: + def __init__(self, name, shortcut): + ... + + +class Literal: + def __init__(self, name: str): + self.name: str = name + self.sub: List[Self] = [] + self._tip: Optional[str] = None + self._func: Optional[CallBack] = None + self._err_callback: Optional[CallBack] = None + + def __call__(self, *nodes) -> Self: + self.sub += nodes + return self + + def arg( + self, + name: str, + shortcuts: Optional[List[str]] = None, + optional: bool = True, + type: Optional[type] = None + ) -> Self: + check_name(name) + if shortcuts is not None and len(shortcuts) != 0: + check_name(shortcuts) + Argument(...) + ... + return self + + def flag(self, name: str, shortcuts: Optional[List[str]] = None) -> Self: + check_name(name) + if shortcuts is not None and len(shortcuts) != 0: + check_name(shortcuts) + Flag(...) + ... + return self + + def error(self, callback: CallBack) -> Self: + check_once(self, "_err_callback") + self._err_callback = callback + return self + + def run(self, func: CallBack) -> Self: + check_once(self, "_func") + self._func = func + return self + + def tip(self, tip: CallBack) -> Self: + check_once(self, "_tip") + self._tip = tip + return self + + def parse(self) -> Parsed: + ... + + def to_doc(self) -> str: + ... + + +def builder(node: Literal) -> Literal: + ... \ No newline at end of file diff --git a/lib_not_dr/nuitka/compile.py b/lib_not_dr/nuitka/compile.py index 69d8ff6..339dae5 100644 --- a/lib_not_dr/nuitka/compile.py +++ b/lib_not_dr/nuitka/compile.py @@ -4,10 +4,8 @@ # All rights reserved # ------------------------------- -# 用于使用 nuitka 构建 DR import platform import warnings -import traceback from pathlib import Path from typing import List, Tuple, Optional diff --git a/pyproject.toml b/pyproject.toml index 6d83367..45b221d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,3 +22,15 @@ Homepage = "https://github.com/shenjackyuanjie/lib-not-dr" Repository = "https://github.com/shenjackyuanjie/lib-not-dr" Changelog = "https://github.com/shenjackyuanjie/lib-not-dr/blob/main/docs/change_log.md" + +[tool.ruff] + +target-version = "py38" + +line-length = 150 + +src = [ + "lib_not_dr" +] + +format = "grouped" \ No newline at end of file