Skip to content

Commit

Permalink
🏷️ version 0.5.14
Browse files Browse the repository at this point in the history
update typing
  • Loading branch information
RF-Tar-Railt committed Sep 8, 2023
1 parent 00fd944 commit 7c97d36
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 130 deletions.
1 change: 1 addition & 0 deletions nepattern/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .main import IP as IP
from .main import NUMBER as NUMBER
from .main import URL as URL
from .main import STRING as STRING
from .main import AnyOne as AnyOne
from .main import AnyString as AnyString
from .main import Bind as Bind
Expand Down
31 changes: 16 additions & 15 deletions nepattern/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ class DirectPattern(BasePattern):
"""直接判断"""
def __init__(self, target: Any, alias: str | None = None):
self.target = target
super().__init__("", MatchMode.TYPE_CONVERT, type(target), alias=alias or str(target))
super().__init__(model=MatchMode.TYPE_CONVERT, origin=type(target), alias=alias or str(target))

def prefixed(self):
if isinstance(self.target, str):
return BasePattern(self.target, alias=self.alias).prefixed()
return BasePattern(self.target, MatchMode.REGEX_MATCH, alias=self.alias).prefixed()
return self

def suffixed(self):
if isinstance(self.target, str):
return BasePattern(self.target, alias=self.alias).suffixed()
return BasePattern(self.target, MatchMode.REGEX_MATCH, alias=self.alias).suffixed()
return self

def match(self, input_: Any):
Expand All @@ -36,7 +36,7 @@ def match(self, input_: Any):

def validate(self, input_: Any, default: Any = None):
if input_ == self.target:
return ValidateResult(input_, ResultFlag.VALID)
return ValidateResult(input_, flag=ResultFlag.VALID)
e = MatchFailed(
lang.require("nepattern", "content_error").format(target=input_)
)
Expand Down Expand Up @@ -64,8 +64,9 @@ class RegexPattern(BasePattern[Match[str]]):
def __init__(self, pattern: str | TPattern, alias: str | None = None):
super().__init__("", origin=Match[str], alias=alias or "regex[:group]") # type: ignore
self.regex_pattern = re.compile(pattern)
self.pattern = self.regex_pattern.pattern

def match(self, input_: str | Any) -> Match[str]:
def match(self, input_: Any) -> Match[str]:
if not isinstance(input_, str):
raise MatchFailed(
lang.require("nepattern", "type_error").format(target=input_)
Expand Down Expand Up @@ -102,9 +103,9 @@ def __init__(self, base: Iterable[BasePattern | object | str], anti: bool = Fals
alias_content = "|".join(
[repr(a) for a in self.for_validate] + [repr(a) for a in self.for_equal]
)
super().__init__(r"(.+?)", MatchMode.KEEP, str, alias=alias_content, anti=anti)
super().__init__(model=MatchMode.KEEP, origin=str, alias=alias_content, anti=anti)

def match(self, text: str | Any):
def match(self, text: Any):
if not text:
text = None
if text not in self.for_equal:
Expand Down Expand Up @@ -160,15 +161,15 @@ def __init__(self, form: type[TSeq], base: BasePattern):
self._mode = "all"
if form is list:
super().__init__(
r"\[(.+?)\]", MatchMode.REGEX_CONVERT, form, lambda _, x: x, f"list[{base}]"
r"\[(.+?)\]", MatchMode.REGEX_CONVERT, form, alias=f"list[{base}]"
)
elif form is tuple:
super().__init__(
r"\((.+?)\)", MatchMode.REGEX_CONVERT, form, lambda _, x: x, f"tuple[{base}]"
r"\((.+?)\)", MatchMode.REGEX_CONVERT, form, alias=f"tuple[{base}]"
)
elif form is set:
super().__init__(
r"\{(.+?)\}", MatchMode.REGEX_CONVERT, form, lambda _, x: x, f"set[{base}]"
r"\{(.+?)\}", MatchMode.REGEX_CONVERT, form, alias=f"set[{base}]"
)
else:
raise ValueError(
Expand All @@ -177,7 +178,7 @@ def __init__(self, form: type[TSeq], base: BasePattern):
)
)

def match(self, text: str | Any):
def match(self, text: Any):
_res = super().match(text)
_max = 0
success: list[tuple[int, Any]] = []
Expand Down Expand Up @@ -233,11 +234,11 @@ def __init__(self, arg_key: BasePattern[TKey], arg_value: BasePattern[TVal]):
r"\{(.+?)\}",
MatchMode.REGEX_CONVERT,
dict,
lambda _, x: x,
f"dict[{self.key}, {self.value}]",
alias=f"dict[{self.key}, {self.value}]",
)
self.converter = lambda _, x: x[1]

def match(self, text: str | Any):
def match(self, text: Any):
_res = super().match(text)
success: list[tuple[int, Any, Any]] = []
fail: list[tuple[int, MatchFailed]] = []
Expand Down Expand Up @@ -295,7 +296,7 @@ class SwitchPattern(BasePattern[_TCase]):

def __init__(self, data: dict[Any | ellipsis, _TCase]):
self.switch = data
super().__init__("", MatchMode.TYPE_CONVERT, type(list(data.values())[0]))
super().__init__(model=MatchMode.TYPE_CONVERT, origin=type(list(data.values())[0]))

def __calc_repr__(self):
return "|".join(f"{k}" for k in self.switch if k != Ellipsis)
Expand Down
131 changes: 94 additions & 37 deletions nepattern/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
import re
from copy import deepcopy
from enum import Enum, IntEnum
from typing import Any, Callable, Generic, TypeVar, overload
from typing import Any, Callable, Generic, TypeVar, Literal, overload, TYPE_CHECKING

from tarina import Empty, generic_isinstance
from tarina.lang import lang

try:
from typing import Annotated, Self, get_origin # type: ignore
except ImportError:
from typing_extensions import Annotated, Self, get_origin
from typing_extensions import Annotated, Self, get_origin

from .exception import MatchFailed
from .util import TPattern
Expand Down Expand Up @@ -86,15 +82,19 @@ def or_default(self) -> bool:
return self.flag == ResultFlag.DEFAULT

@overload
def step(self, other: type[T] | T) -> T:
def step(self, other: BasePattern[T]) -> ValidateResult[T]:
...

@overload
def step(self, other: Callable[[TVOrigin], T]) -> T | Self:
def step(self, other: type[T]) -> T:
...

@overload
def step(self, other: BasePattern[T]) -> ValidateResult[T]:
def step(self, other: Callable[[TVOrigin], T]) -> T:
...

@overload
def step(self, other: Any) -> Self:
...

def step(
Expand All @@ -104,22 +104,22 @@ def step(
return self.success # type: ignore
if callable(other) and self.success:
return other(self.value)
if isinstance(other, BasePattern):
return other.exec(self.value)
if self.success and hasattr(self.value, "__rshift__"):
return self.value | other # type: ignore
return self
return other.exec(self.value) if isinstance(other, BasePattern) else self

@overload
def __rshift__(self, other: type[T] | T) -> T:
def __rshift__(self, other: BasePattern[T]) -> ValidateResult[T]:
...

@overload
def __rshift__(self, other: Callable[[TVOrigin], T]) -> T | Self:
def __rshift__(self, other: type[T]) -> T:
...

@overload
def __rshift__(self, other: BasePattern[T]) -> ValidateResult[T]:
def __rshift__(self, other: Callable[[TVOrigin], T]) -> T:
...

@overload
def __rshift__(self, other: Any) -> Self:
...

def __rshift__(
Expand All @@ -144,7 +144,7 @@ class BasePattern(Generic[TOrigin]):
regex_pattern: TPattern # type: ignore
pattern: str
mode: MatchMode
converter: Callable[[BasePattern[TOrigin], str | Any], TOrigin | None]
converter: Callable[[BasePattern[TOrigin], Any], TOrigin | None]
validators: list[Callable[[TOrigin], bool]]

anti: bool
Expand All @@ -171,12 +171,71 @@ class BasePattern(Generic[TOrigin]):
"_accept"
)

@overload
def __init__(
self,
*,
model: Literal[MatchMode.KEEP],
origin: type[TOrigin] = Any,
alias: str | None = None,
previous: BasePattern | None = None,
accepts: list[type | BasePattern] | None = None,
validators: list[Callable[[TOrigin], bool]] | None = None,
anti: bool = False,
):
...

@overload
def __init__(
self,
pattern: str,
model: Literal[MatchMode.REGEX_MATCH],
origin: type[TOrigin] = str,
converter: Callable[[BasePattern[TOrigin], str], TOrigin | None] | None = None,
alias: str | None = None,
previous: BasePattern | None = None,
accepts: list[type | BasePattern] | None = None,
validators: list[Callable[[TOrigin], bool]] | None = None,
anti: bool = False,
):
...

@overload
def __init__(
self,
pattern: str,
model: Literal[MatchMode.REGEX_CONVERT],
origin: type[TOrigin],
converter: Callable[[BasePattern[TOrigin], re.Match[str]], TOrigin | None] | None = None,
alias: str | None = None,
previous: BasePattern | None = None,
accepts: list[type | BasePattern] | None = None,
validators: list[Callable[[TOrigin], bool]] | None = None,
anti: bool = False,
):
...

@overload
def __init__(
self,
*,
model: Literal[MatchMode.TYPE_CONVERT],
origin: type[TOrigin],
converter: Callable[[BasePattern[TOrigin], Any], TOrigin | None] | None = None,
alias: str | None = None,
previous: BasePattern | None = None,
accepts: list[type | BasePattern] | None = None,
validators: list[Callable[[TOrigin], bool]] | None = None,
anti: bool = False,
):
...

def __init__(
self,
pattern: str = ".+",
model: int | MatchMode = MatchMode.REGEX_MATCH,
model: MatchMode = MatchMode.REGEX_MATCH,
origin: type[TOrigin] = str,
converter: Callable[[BasePattern[TOrigin], str | Any], TOrigin] | None = None,
converter: Callable[[BasePattern[TOrigin], Any], TOrigin | None] | None = None,
alias: str | None = None,
previous: BasePattern | None = None,
accepts: list[type | BasePattern] | None = None,
Expand Down Expand Up @@ -208,7 +267,7 @@ def __init__(
self.converter = converter or (
lambda _, x: (get_origin(origin) or origin)(x)
if model == MatchMode.TYPE_CONVERT
else eval(x)
else eval(x[0])
)
self.validators = validators or []
self.anti = anti
Expand Down Expand Up @@ -278,7 +337,7 @@ def __eq__(self, other):
def of(unit: type[TOrigin]) -> BasePattern[TOrigin]:
"""提供 Type[DataUnit] 类型的构造方法"""
return BasePattern(
"", MatchMode.KEEP, unit, alias=unit.__name__, accepts=[unit]
model=MatchMode.KEEP, origin=unit, alias=unit.__name__, accepts=[unit]
)

@staticmethod
Expand All @@ -289,12 +348,12 @@ def on(obj: TOrigin) -> BasePattern[TOrigin]:
return DirectPattern(obj)

@staticmethod
def to(content: Any) -> BasePattern | None:
def to(content: Any) -> BasePattern:
"""便捷的使用 type_parser 的方法"""
from .main import type_parser

if isinstance(res := type_parser(content, "allow"), BasePattern):
return res
res = type_parser(content, "allow")
return res if isinstance(res, BasePattern) else type_parser(Any)

def reverse(self) -> Self:
"""改变 pattern 的 anti 值"""
Expand All @@ -314,10 +373,10 @@ def suffixed(self):
"""让表达式能在某些场景下实现后缀匹配; 返回自身的拷贝"""
cp_self = deepcopy(self)
if self.mode in (MatchMode.REGEX_MATCH, MatchMode.REGEX_CONVERT):
cp_self.regex_pattern = re.compile(f".*?({self.pattern})$")
cp_self.regex_pattern = re.compile(f"{self.pattern}$")
return cp_self

def match(self, input_: str | Any) -> TOrigin:
def match(self, input_: Any) -> TOrigin:
"""
对传入的参数进行匹配, 如果匹配成功, 则返回转换后的值, 否则返回None
"""
Expand Down Expand Up @@ -350,21 +409,19 @@ def match(self, input_: str | Any) -> TOrigin:
raise MatchFailed(
lang.require("nepattern", "content_error").format(target=input_)
)
if TYPE_CHECKING:
assert res is not None
return res
if input_.__class__ is not str:
if not self.previous or not isinstance(input_ := self.previous.match(input_), str):
raise MatchFailed(
lang.require("nepattern", "type_error").format(target=type(input_))
)
if mat := self.regex_pattern.match(input_):
emp = not mat.groups()
return (
self.converter(self, mat[0] if emp else mat[1])
if self.mode == 3
else mat[0]
if emp
else mat[1]
)
if mat := (self.regex_pattern.match(input_) or self.regex_pattern.search(input_)):
if self.mode == 1:
return mat[0] # type: ignore
if (res := self.converter(self, mat)) is not None:
return res
raise MatchFailed(
lang.require("nepattern", "content_error").format(target=input_)
)
Expand All @@ -389,7 +446,7 @@ def validate( # type: ignore
"""
try:
res = self.match(input_)
if self.validators and not all([i(res) for i in self.validators]):
if self.validators and not all(i(res) for i in self.validators):
raise MatchFailed(
lang.require("nepattern", "content_error").format(target=input_)
)
Expand Down
Loading

0 comments on commit 7c97d36

Please sign in to comment.