better function subclasses

This commit is contained in:
Jesse Bannon 2023-11-18 00:40:54 -08:00
parent f4cd0fc781
commit 879c070194
4 changed files with 14 additions and 12 deletions

View file

@ -16,8 +16,9 @@ from ytdl_sub.script.types.resolvable import AnyTypeReturnable
from ytdl_sub.script.types.resolvable import AnyTypeReturnableA from ytdl_sub.script.types.resolvable import AnyTypeReturnableA
from ytdl_sub.script.types.resolvable import AnyTypeReturnableB from ytdl_sub.script.types.resolvable import AnyTypeReturnableB
from ytdl_sub.script.types.resolvable import ArgumentType from ytdl_sub.script.types.resolvable import ArgumentType
from ytdl_sub.script.types.resolvable import FunctionLike from ytdl_sub.script.types.resolvable import FunctionType
from ytdl_sub.script.types.resolvable import Resolvable from ytdl_sub.script.types.resolvable import Resolvable
from ytdl_sub.script.types.resolvable import TypeHintedFunctionType
from ytdl_sub.script.types.variable import FunctionArgument from ytdl_sub.script.types.variable import FunctionArgument
from ytdl_sub.script.types.variable import Variable from ytdl_sub.script.types.variable import Variable
from ytdl_sub.script.types.variable_dependency import VariableDependency from ytdl_sub.script.types.variable_dependency import VariableDependency
@ -28,10 +29,7 @@ from ytdl_sub.utils.exceptions import StringFormattingException
@dataclass(frozen=True) @dataclass(frozen=True)
class Function(VariableDependency, ArgumentType, ABC): class Function(FunctionType, VariableDependency, ABC):
name: str
args: List[ArgumentType]
@property @property
def variables(self) -> Set[Variable]: def variables(self) -> Set[Variable]:
""" """
@ -104,7 +102,7 @@ class CustomFunction(Function):
raise StringFormattingException(f"Custom function {self.name} does not exist") raise StringFormattingException(f"Custom function {self.name} does not exist")
class BuiltInFunction(Function, FunctionLike): class BuiltInFunction(Function, TypeHintedFunctionType):
def validate_args(self) -> "BuiltInFunction": def validate_args(self) -> "BuiltInFunction":
if not self.input_spec.is_compatible(input_args=self.args): if not self.input_spec.is_compatible(input_args=self.args):
raise FunctionArgumentsExceptionFormatter( raise FunctionArgumentsExceptionFormatter(

View file

@ -116,10 +116,14 @@ class String(ResolvableT[str], Hashable, ArgumentType):
pass pass
class FunctionLike(NamedType): @dataclass(frozen=True)
class FunctionType(ArgumentType, ABC):
name: str name: str
args: List[ArgumentType] args: List[ArgumentType]
@dataclass(frozen=True)
class TypeHintedFunctionType(FunctionType, ABC):
@abstractmethod @abstractmethod
def output_type(self) -> Type[Resolvable]: def output_type(self) -> Type[Resolvable]:
pass pass

View file

@ -4,8 +4,8 @@ from typing import Type
from typing import TypeVar from typing import TypeVar
from typing import Union from typing import Union
from ytdl_sub.script.types.resolvable import FunctionLike
from ytdl_sub.script.types.resolvable import NamedType from ytdl_sub.script.types.resolvable import NamedType
from ytdl_sub.script.types.resolvable import TypeHintedFunctionType
from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
from ytdl_sub.script.utils.exceptions import UserException from ytdl_sub.script.utils.exceptions import UserException
from ytdl_sub.script.utils.type_checking import FunctionInputSpec from ytdl_sub.script.utils.type_checking import FunctionInputSpec
@ -90,7 +90,7 @@ class FunctionArgumentsExceptionFormatter:
def __init__( def __init__(
self, self,
input_spec: FunctionInputSpec, input_spec: FunctionInputSpec,
function_instance: FunctionLike, function_instance: TypeHintedFunctionType,
): ):
self._args = input_spec.args self._args = input_spec.args
self._varargs = input_spec.varargs self._varargs = input_spec.varargs
@ -115,7 +115,7 @@ class FunctionArgumentsExceptionFormatter:
def highlight(self) -> IncompatibleFunctionArguments: def highlight(self) -> IncompatibleFunctionArguments:
received_type_names: List[str] = [] received_type_names: List[str] = []
for arg in self._input_args: for arg in self._input_args:
if isinstance(arg, FunctionLike): if isinstance(arg, TypeHintedFunctionType):
if is_union(arg.output_type()): if is_union(arg.output_type()):
# TODO: Move naming to separate function, deal with Union input naming # TODO: Move naming to separate function, deal with Union input naming
received_type_names.append( received_type_names.append(

View file

@ -6,7 +6,7 @@ from typing import Union
from typing import get_origin from typing import get_origin
from ytdl_sub.script.types.resolvable import ArgumentType from ytdl_sub.script.types.resolvable import ArgumentType
from ytdl_sub.script.types.resolvable import FunctionLike from ytdl_sub.script.types.resolvable import FunctionType
from ytdl_sub.script.types.resolvable import NamedType from ytdl_sub.script.types.resolvable import NamedType
from ytdl_sub.script.types.resolvable import Resolvable from ytdl_sub.script.types.resolvable import Resolvable
from ytdl_sub.script.types.variable import Variable from ytdl_sub.script.types.variable import Variable
@ -30,7 +30,7 @@ def is_type_compatible(
expected_arg_type: Type[Resolvable | Optional[Resolvable]], expected_arg_type: Type[Resolvable | Optional[Resolvable]],
) -> bool: ) -> bool:
arg_type: Type[NamedType] = arg.__class__ arg_type: Type[NamedType] = arg.__class__
if isinstance(arg, FunctionLike): if isinstance(arg, FunctionType):
arg_type = arg.output_type() arg_type = arg.output_type()
elif isinstance(arg, Variable): elif isinstance(arg, Variable):
return True # unresolved variables can be anything, so pass for now return True # unresolved variables can be anything, so pass for now