linting
This commit is contained in:
parent
96182af2c1
commit
acceb50377
6 changed files with 48 additions and 25 deletions
|
|
@ -222,13 +222,13 @@ class _Parser:
|
|||
self._set_highlight_position()
|
||||
raise NUMERICS_INVALID_CHAR
|
||||
|
||||
if numeric_string == "." or numeric_string == "-":
|
||||
if numeric_string in (".", "-"):
|
||||
raise NUMERICS_INVALID_CHAR
|
||||
|
||||
try:
|
||||
numeric_float = float(numeric_string)
|
||||
except ValueError:
|
||||
raise UNREACHABLE
|
||||
except ValueError as exc:
|
||||
raise UNREACHABLE from exc
|
||||
|
||||
if (numeric_int := int(numeric_float)) == numeric_float:
|
||||
return Integer(value=numeric_int)
|
||||
|
|
@ -351,10 +351,10 @@ class _Parser:
|
|||
if ch == "]":
|
||||
self._pos += 1
|
||||
return UnresolvedArray(value=function_args)
|
||||
else:
|
||||
function_args = self._parse_args(
|
||||
argument_parser=ArgumentParser.ARRAY, breaking_chars="]"
|
||||
)
|
||||
|
||||
function_args = self._parse_args(
|
||||
argument_parser=ArgumentParser.ARRAY, breaking_chars="]"
|
||||
)
|
||||
|
||||
raise UNREACHABLE
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class Array(NonHashable):
|
|||
value: List[Resolvable]
|
||||
|
||||
@classmethod
|
||||
def human_readable_name(cls) -> str:
|
||||
def type_name(cls) -> str:
|
||||
return "Array"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from ytdl_sub.script.types.resolvable import AnyType_0
|
|||
from ytdl_sub.script.types.resolvable import AnyType_1
|
||||
from ytdl_sub.script.types.resolvable import AnyType_2
|
||||
from ytdl_sub.script.types.resolvable import ArgumentType
|
||||
from ytdl_sub.script.types.resolvable import NamedType
|
||||
from ytdl_sub.script.types.resolvable import Resolvable
|
||||
from ytdl_sub.script.types.variable import FunctionArgument
|
||||
from ytdl_sub.script.types.variable import Variable
|
||||
|
|
@ -30,6 +31,14 @@ def is_union(arg_type: Type) -> bool:
|
|||
return get_origin(arg_type) is Union
|
||||
|
||||
|
||||
def is_optional(arg_type: Type) -> bool:
|
||||
return is_union(arg_type) and type(None) in arg_type.__args__
|
||||
|
||||
|
||||
def get_optional_type(optional_type: Type) -> Type[NamedType]:
|
||||
return [arg for arg in optional_type.__args__ if arg != type(None)][0]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FunctionInputSpec:
|
||||
args: Optional[List[Type[Resolvable | Optional[Resolvable]]]] = None
|
||||
|
|
@ -110,10 +119,17 @@ class FunctionInputSpec:
|
|||
assert False, "should never reach here"
|
||||
|
||||
def expected_args_str(self) -> str:
|
||||
def to_human_readable_name(python_type: Type[NamedType] | Type[Union[NamedType]]) -> str:
|
||||
if is_optional(python_type):
|
||||
return f"Optional[{to_human_readable_name(get_optional_type(python_type))}]"
|
||||
if is_union(python_type):
|
||||
return ", ".join(to_human_readable_name(arg) for arg in python_type.__args__)
|
||||
return python_type.type_name()
|
||||
|
||||
if self.args is not None:
|
||||
return f"({', '.join([type_.__name__ for type_ in self.args])})"
|
||||
return f"({', '.join([to_human_readable_name(type_) for type_ in self.args])})"
|
||||
elif self.varargs is not None:
|
||||
return f"({self.varargs.__name__}, ...)"
|
||||
return f"({to_human_readable_name(self.varargs.__name__)}, ...)"
|
||||
|
||||
@classmethod
|
||||
def from_function(cls, func: "BuiltInFunction") -> "FunctionInputSpec":
|
||||
|
|
@ -210,12 +226,12 @@ class BuiltInFunction(Function):
|
|||
if is_union(arg.output_type):
|
||||
# TODO: Move naming to separate function, deal with Union input naming
|
||||
received_type_names.append(
|
||||
f"%{arg.name}(...)->Union[{', '.join(arg_type.human_readable_name() for arg_type in arg.output_type.__args__)}]"
|
||||
f"%{arg.name}(...)->Union[{', '.join(arg_type.type_name() for arg_type in arg.output_type.__args__)}]"
|
||||
)
|
||||
else:
|
||||
received_type_names.append(f"%{arg.name}(...)->{arg.output_type.__name__}")
|
||||
received_type_names.append(f"%{arg.name}(...)->{arg.output_type.type_name()}")
|
||||
else:
|
||||
received_type_names.append(arg.__class__.__name__)
|
||||
received_type_names.append(arg.type_name())
|
||||
|
||||
received_args_str = f"({', '.join([name for name in received_type_names])})"
|
||||
|
||||
|
|
@ -224,7 +240,7 @@ class BuiltInFunction(Function):
|
|||
def validate_args(self) -> "BuiltInFunction":
|
||||
if not self.input_spec.is_compatible(input_args=self.args):
|
||||
raise IncompatibleFunctionArguments(
|
||||
f"Invalid arguments passed to function {self.name}.\n"
|
||||
f"Incompatible arguments passed to function {self.name}.\n"
|
||||
f"{self._expected_received_error_msg()}"
|
||||
)
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class Map(NonHashable):
|
|||
value: Dict[Hashable, Resolvable]
|
||||
|
||||
@classmethod
|
||||
def human_readable_name(cls) -> str:
|
||||
def type_name(cls) -> str:
|
||||
return "Map"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,25 +10,27 @@ T = TypeVar("T")
|
|||
NumericT = TypeVar("NumericT", bound=int | float)
|
||||
|
||||
|
||||
class ArgumentType(ABC):
|
||||
class NamedType(ABC):
|
||||
@classmethod
|
||||
def type_name(cls) -> str:
|
||||
return cls.__name__
|
||||
|
||||
|
||||
class ArgumentType(NamedType, ABC):
|
||||
"""
|
||||
Any possible argument type that has not been resolved yet
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def human_readable_name(cls) -> str:
|
||||
return cls.__name__
|
||||
|
||||
|
||||
class AnyType_0(ABC):
|
||||
class AnyType_0(NamedType, ABC):
|
||||
pass
|
||||
|
||||
|
||||
class AnyType_1(ABC):
|
||||
class AnyType_1(NamedType, ABC):
|
||||
pass
|
||||
|
||||
|
||||
class AnyType_2(ABC):
|
||||
class AnyType_2(NamedType, ABC):
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ class TestFunction:
|
|||
with pytest.raises(
|
||||
IncompatibleFunctionArguments,
|
||||
match=_incompatible_arguments_match(
|
||||
expected="Map, Hashable, Optional", recieved="%if(...)->Union[Map, Array], String"
|
||||
expected="Map, Hashable, Optional[AnyType]",
|
||||
recieved="%if(...)->Union[Map, Array], String",
|
||||
),
|
||||
):
|
||||
Script({"func": function_str}).resolve()
|
||||
|
|
@ -83,4 +84,8 @@ class TestFunction:
|
|||
"function_str", ["{%array_at({'a': 'dict?'}, 1)}" "{%array_extend('not', 'array')}"]
|
||||
)
|
||||
def test_incompatible_types(self, function_str):
|
||||
assert Script({"func": function_str}).resolve()
|
||||
with pytest.raises(
|
||||
IncompatibleFunctionArguments,
|
||||
match=_incompatible_arguments_match(expected="Array, Integer", recieved="Map, Integer"),
|
||||
):
|
||||
Script({"func": function_str}).resolve()
|
||||
|
|
|
|||
Loading…
Reference in a new issue