resolvable types

This commit is contained in:
Jesse Bannon 2023-07-17 23:14:44 -07:00
parent 63be17e920
commit b16f6262ec
5 changed files with 86 additions and 38 deletions

View file

@ -1,27 +1,67 @@
from abc import ABC
from dataclasses import dataclass
from typing import Generic
from typing import TypeVar
T = TypeVar("T")
@dataclass(frozen=True)
class Resolvable(ABC, Generic[T]):
value: T
def resolve(self) -> str:
return str(self.value)
@dataclass(frozen=True)
class Integer(Resolvable[int]):
pass
@dataclass(frozen=True)
class Float(Resolvable[float]):
pass
@dataclass(frozen=True)
class Boolean(Resolvable[bool]):
pass
@dataclass(frozen=True)
class String(Resolvable[str]):
pass
class Functions:
@staticmethod
def lower(string: str) -> str:
def lower(string: String) -> String:
"""
Returns
-------
Lower-cased string
"""
return string.lower()
return String(string.value.lower())
@staticmethod
def upper(string: str) -> str:
def upper(string: String) -> String:
"""
Returns
-------
Upper-cased string
"""
return string.upper()
return String(string.value.upper())
@staticmethod
def capitalize(string: str) -> str:
def capitalize(string: String) -> String:
"""
Returns
-------
Capitalized string
"""
return string.capitalize()
return String(string.value.capitalize())
@staticmethod
def concat(l_string: String, r_string: String) -> String:
return String(f"{l_string}{r_string}")

View file

@ -1,14 +1,14 @@
from typing import List
from typing import Optional
from ytdl_sub.script.functions import Boolean
from ytdl_sub.script.functions import Float
from ytdl_sub.script.functions import Integer
from ytdl_sub.script.functions import String
from ytdl_sub.script.types import ArgumentType
from ytdl_sub.script.types import Boolean
from ytdl_sub.script.types import Float
from ytdl_sub.script.types import Function
from ytdl_sub.script.types import Integer
from ytdl_sub.script.types import LiteralString
from ytdl_sub.script.types import NumericType
from ytdl_sub.script.types import String
from ytdl_sub.script.types import SyntaxTree
from ytdl_sub.script.types import Variable
from ytdl_sub.utils.exceptions import StringFormattingException

View file

@ -1,31 +1,18 @@
from dataclasses import dataclass
from typing import List, Dict, Optional
from typing import Dict
from typing import List
from typing import Optional
from typing import Set
from typing import Union
from ytdl_sub.script.functions import Boolean
from ytdl_sub.script.functions import Float
from ytdl_sub.script.functions import Functions
from ytdl_sub.script.functions import Integer
from ytdl_sub.script.functions import String
from ytdl_sub.utils.exceptions import StringFormattingException
@dataclass(frozen=True)
class Integer:
value: int
@dataclass(frozen=True)
class Float:
value: float
@dataclass(frozen=True)
class Boolean:
value: bool
@dataclass(frozen=True)
class String:
value: str
@dataclass(frozen=True)
class Variable:
name: str
@ -40,6 +27,12 @@ class Function:
name: str
args: List[ArgumentType]
def __post_init__(self):
try:
getattr(Functions, self.name)
except AttributeError:
raise StringFormattingException(f"Function name {self.name} does not exist")
@property
def variables(self) -> Set[Variable]:
"""
@ -68,6 +61,11 @@ class SyntaxTree:
@property
def variables(self) -> Set[Variable]:
"""
Returns
-------
All variables used within the SyntaxTree
"""
variables: Set[Variable] = set()
for token in self.ast:
if isinstance(token, Variable):
@ -79,11 +77,19 @@ class SyntaxTree:
@classmethod
def detect_cycles(cls, parsed_overrides: Dict[str, "SyntaxTree"]) -> None:
"""
Parameters
----------
parsed_overrides
``overrides`` in a subscription, parsed into a SyntaxTree
"""
variable_dependencies: Dict[Variable, Set[Variable]] = {
Variable(name): ast.variables for name, ast in parsed_overrides.items()
}
def _traverse(to_variable: Variable, visited_variables: Optional[List[Variable]] = None) -> None:
def _traverse(
to_variable: Variable, visited_variables: Optional[List[Variable]] = None
) -> None:
if visited_variables is None:
visited_variables = []
@ -97,4 +103,6 @@ class SyntaxTree:
for variable in variable_dependencies.keys():
_traverse(variable)
@classmethod
def resolve(cls, parsed_overrides: Dict[str, "SyntaxTree"]) -> Dict[str, str]:
raise NotImplemented()

View file

@ -75,7 +75,7 @@ def download_and_convert_url_thumbnail(
# timeout after 8 seconds
with urlopen(thumbnail_url, timeout=1.0) as file:
with tempfile.NamedTemporaryFile(delete=False) as thumbnail:
thumbnail.write(file._read())
thumbnail.write(file.read())
try:
os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True)

View file

@ -1,12 +1,12 @@
import pytest
from ytdl_sub.script.functions import Boolean
from ytdl_sub.script.functions import Float
from ytdl_sub.script.functions import Integer
from ytdl_sub.script.functions import String
from ytdl_sub.script.parser import parse
from ytdl_sub.script.types import Boolean
from ytdl_sub.script.types import Float
from ytdl_sub.script.types import Function
from ytdl_sub.script.types import Integer
from ytdl_sub.script.types import LiteralString
from ytdl_sub.script.types import String
from ytdl_sub.script.types import SyntaxTree
from ytdl_sub.script.types import Variable
from ytdl_sub.utils.exceptions import StringFormattingException