more organize
This commit is contained in:
parent
6c1ce8b820
commit
6b2cd52313
10 changed files with 146 additions and 131 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
from ytdl_sub.script.types import String
|
from ytdl_sub.script.types.resolvable import String
|
||||||
|
|
||||||
|
|
||||||
class StringFunctions:
|
class StringFunctions:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from typing import Set
|
||||||
from ytdl_sub.script.functions import Resolvable
|
from ytdl_sub.script.functions import Resolvable
|
||||||
from ytdl_sub.script.parser import parse
|
from ytdl_sub.script.parser import parse
|
||||||
from ytdl_sub.script.syntax_tree import SyntaxTree
|
from ytdl_sub.script.syntax_tree import SyntaxTree
|
||||||
from ytdl_sub.script.syntax_tree import Variable
|
from ytdl_sub.script.types.variable import Variable
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from ytdl_sub.script.syntax_tree import ArgumentType
|
|
||||||
from ytdl_sub.script.syntax_tree import Function
|
|
||||||
from ytdl_sub.script.syntax_tree import SyntaxTree
|
from ytdl_sub.script.syntax_tree import SyntaxTree
|
||||||
from ytdl_sub.script.syntax_tree import Variable
|
from ytdl_sub.script.types.function import ArgumentType
|
||||||
from ytdl_sub.script.types import Boolean
|
from ytdl_sub.script.types.function import Function
|
||||||
from ytdl_sub.script.types import Float
|
from ytdl_sub.script.types.resolvable import Boolean
|
||||||
from ytdl_sub.script.types import Integer
|
from ytdl_sub.script.types.resolvable import Float
|
||||||
from ytdl_sub.script.types import String
|
from ytdl_sub.script.types.resolvable import Integer
|
||||||
|
from ytdl_sub.script.types.resolvable import String
|
||||||
|
from ytdl_sub.script.types.variable import Variable
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
from ytdl_sub.validators.string_formatter_validators import is_valid_source_variable_name
|
from ytdl_sub.validators.string_formatter_validators import is_valid_source_variable_name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,83 +1,17 @@
|
||||||
from abc import ABC
|
|
||||||
from abc import abstractmethod
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Union
|
|
||||||
from typing import final
|
|
||||||
|
|
||||||
from ytdl_sub.script.functions import Functions
|
from ytdl_sub.script.types.function import Function
|
||||||
from ytdl_sub.script.types import Boolean
|
from ytdl_sub.script.types.function import VariableDependency
|
||||||
from ytdl_sub.script.types import Float
|
from ytdl_sub.script.types.resolvable import Resolvable
|
||||||
from ytdl_sub.script.types import Integer
|
from ytdl_sub.script.types.resolvable import String
|
||||||
from ytdl_sub.script.types import Resolvable
|
from ytdl_sub.script.types.variable import Variable
|
||||||
from ytdl_sub.script.types import String
|
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Variable:
|
|
||||||
name: str
|
|
||||||
|
|
||||||
|
|
||||||
ArgumentType = Union[Integer, Float, String, Boolean, Variable, "Function"]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class VariableDependency(ABC):
|
|
||||||
@property
|
|
||||||
@abstractmethod
|
|
||||||
def variables(self) -> Set[Variable]:
|
|
||||||
raise NotImplemented()
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def resolve(self, resolved_variables: Dict[Variable, Resolvable]) -> str:
|
|
||||||
raise NotImplemented()
|
|
||||||
|
|
||||||
@final
|
|
||||||
def has_variable_dependency(self, resolved_variables: Dict[Variable, Resolvable]) -> bool:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
True if variable dependency. False otherwise.
|
|
||||||
"""
|
|
||||||
return self.variables.issubset(set(resolved_variables.keys()))
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Function(VariableDependency):
|
|
||||||
name: str
|
|
||||||
args: List[ArgumentType]
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
# TODO: Figure out resolution via introspecting args and outputs of function
|
|
||||||
try:
|
|
||||||
getattr(Functions, self.name)
|
|
||||||
except AttributeError:
|
|
||||||
raise StringFormattingException(f"Function name {self.name} does not exist")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def variables(self) -> Set[Variable]:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
All variables used within the function
|
|
||||||
"""
|
|
||||||
variables: Set[Variable] = set()
|
|
||||||
for arg in self.args:
|
|
||||||
if isinstance(arg, Variable):
|
|
||||||
variables.add(arg)
|
|
||||||
elif isinstance(arg, Function):
|
|
||||||
variables.update(arg.variables)
|
|
||||||
|
|
||||||
return variables
|
|
||||||
|
|
||||||
def resolve(self, resolved_variables: Dict[Variable, Resolvable]) -> Resolvable:
|
|
||||||
raise NotImplemented()
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SyntaxTree(VariableDependency):
|
class SyntaxTree(VariableDependency):
|
||||||
ast: List[String | Variable | Function]
|
ast: List[String | Variable | Function]
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,3 @@
|
||||||
from abc import ABC
|
|
||||||
from abc import abstractmethod
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from typing import Generic
|
|
||||||
from typing import TypeVar
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
|
||||||
NumericT = TypeVar("NumericT", bound=int | float)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Resolvable(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def resolve(self) -> str:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ResolvableT(Resolvable, Generic[T]):
|
|
||||||
value: T
|
|
||||||
|
|
||||||
def resolve(self) -> str:
|
|
||||||
return str(self.value)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Numeric(ResolvableT[NumericT], ABC, Generic[NumericT]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Integer(ResolvableT[int]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Float(ResolvableT[float]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Boolean(ResolvableT[bool]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class String(ResolvableT[str]):
|
|
||||||
pass
|
|
||||||
|
|
|
||||||
0
src/ytdl_sub/script/types/__init__.py
Normal file
0
src/ytdl_sub/script/types/__init__.py
Normal file
72
src/ytdl_sub/script/types/function.py
Normal file
72
src/ytdl_sub/script/types/function.py
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
from abc import ABC
|
||||||
|
from abc import abstractmethod
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Dict
|
||||||
|
from typing import List
|
||||||
|
from typing import Set
|
||||||
|
from typing import Union
|
||||||
|
from typing import final
|
||||||
|
|
||||||
|
from ytdl_sub.script.functions import Functions
|
||||||
|
from ytdl_sub.script.types.resolvable import Boolean
|
||||||
|
from ytdl_sub.script.types.resolvable import Float
|
||||||
|
from ytdl_sub.script.types.resolvable import Integer
|
||||||
|
from ytdl_sub.script.types.resolvable import Resolvable
|
||||||
|
from ytdl_sub.script.types.resolvable import String
|
||||||
|
from ytdl_sub.script.types.variable import Variable
|
||||||
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
|
|
||||||
|
ArgumentType = Union[Integer, Float, String, Boolean, Variable, "Function"]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class VariableDependency(ABC):
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def variables(self) -> Set[Variable]:
|
||||||
|
raise NotImplemented()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def resolve(self, resolved_variables: Dict[Variable, Resolvable]) -> str:
|
||||||
|
raise NotImplemented()
|
||||||
|
|
||||||
|
@final
|
||||||
|
def has_variable_dependency(self, resolved_variables: Dict[Variable, Resolvable]) -> bool:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if variable dependency. False otherwise.
|
||||||
|
"""
|
||||||
|
return self.variables.issubset(set(resolved_variables.keys()))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Function(VariableDependency):
|
||||||
|
name: str
|
||||||
|
args: List[ArgumentType]
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
# TODO: Figure out resolution via introspecting args and outputs of function
|
||||||
|
try:
|
||||||
|
getattr(Functions, self.name)
|
||||||
|
except AttributeError:
|
||||||
|
raise StringFormattingException(f"Function name {self.name} does not exist")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def variables(self) -> Set[Variable]:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
All variables used within the function
|
||||||
|
"""
|
||||||
|
variables: Set[Variable] = set()
|
||||||
|
for arg in self.args:
|
||||||
|
if isinstance(arg, Variable):
|
||||||
|
variables.add(arg)
|
||||||
|
elif isinstance(arg, Function):
|
||||||
|
variables.update(arg.variables)
|
||||||
|
|
||||||
|
return variables
|
||||||
|
|
||||||
|
def resolve(self, resolved_variables: Dict[Variable, Resolvable]) -> Resolvable:
|
||||||
|
raise NotImplemented()
|
||||||
48
src/ytdl_sub/script/types/resolvable.py
Normal file
48
src/ytdl_sub/script/types/resolvable.py
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
from abc import ABC
|
||||||
|
from abc import abstractmethod
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Generic
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
NumericT = TypeVar("NumericT", bound=int | float)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Resolvable(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def resolve(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ResolvableT(Resolvable, Generic[T]):
|
||||||
|
value: T
|
||||||
|
|
||||||
|
def resolve(self) -> str:
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Numeric(ResolvableT[NumericT], ABC, Generic[NumericT]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Integer(ResolvableT[int]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Float(ResolvableT[float]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Boolean(ResolvableT[bool]):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class String(ResolvableT[str]):
|
||||||
|
pass
|
||||||
6
src/ytdl_sub/script/types/variable.py
Normal file
6
src/ytdl_sub/script/types/variable.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Variable:
|
||||||
|
name: str
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ytdl_sub.script.parser import parse
|
from ytdl_sub.script.parser import parse
|
||||||
from ytdl_sub.script.syntax_tree import Function
|
|
||||||
from ytdl_sub.script.syntax_tree import SyntaxTree
|
from ytdl_sub.script.syntax_tree import SyntaxTree
|
||||||
from ytdl_sub.script.syntax_tree import Variable
|
from ytdl_sub.script.types.function import Function
|
||||||
from ytdl_sub.script.types import Boolean
|
from ytdl_sub.script.types.resolvable import Boolean
|
||||||
from ytdl_sub.script.types import Float
|
from ytdl_sub.script.types.resolvable import Float
|
||||||
from ytdl_sub.script.types import Integer
|
from ytdl_sub.script.types.resolvable import Integer
|
||||||
from ytdl_sub.script.types import String
|
from ytdl_sub.script.types.resolvable import String
|
||||||
|
from ytdl_sub.script.types.variable import Variable
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue