json friendly array output
This commit is contained in:
parent
d50c0c6559
commit
1e68a99cdd
9 changed files with 41 additions and 33 deletions
|
|
@ -51,6 +51,7 @@ STRINGS_ONLY_ARGS = InvalidSyntaxException(
|
|||
"Strings can only be used as arguments to functions, maps, or arrays"
|
||||
)
|
||||
|
||||
|
||||
def UNEXPECTED_CHAR_ARGUMENT(parser: ArgumentParser):
|
||||
return InvalidSyntaxException(f"Unexpected character when parsing {parser.value} arguments")
|
||||
|
||||
|
|
@ -76,9 +77,11 @@ def _is_variable_start(char: str) -> bool:
|
|||
def _is_numeric_start(char: str) -> bool:
|
||||
return char.isnumeric() or char == "-"
|
||||
|
||||
|
||||
def _is_string_start(char: str) -> bool:
|
||||
return char in ["'", '"']
|
||||
|
||||
|
||||
def _is_breakable(char: str) -> bool:
|
||||
return char in ["}", ",", ")", "]"] or char.isspace()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
|
|
@ -6,6 +7,7 @@ from typing import Set
|
|||
from ytdl_sub.script.types.resolvable import ArgumentType
|
||||
from ytdl_sub.script.types.resolvable import NonHashable
|
||||
from ytdl_sub.script.types.resolvable import Resolvable
|
||||
from ytdl_sub.script.types.resolvable import ResolvableToJson
|
||||
from ytdl_sub.script.types.variable import FunctionArgument
|
||||
from ytdl_sub.script.types.variable import Variable
|
||||
from ytdl_sub.script.types.variable_dependency import VariableDependency
|
||||
|
|
@ -15,9 +17,6 @@ from ytdl_sub.script.types.variable_dependency import VariableDependency
|
|||
class Array(NonHashable):
|
||||
value: List[Resolvable]
|
||||
|
||||
def __str__(self):
|
||||
return f"[{', '.join([str(val.value) for val in self.value])}]"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class UnresolvedArray(Array, VariableDependency, ArgumentType):
|
||||
|
|
@ -63,5 +62,5 @@ class UnresolvedArray(Array, VariableDependency, ArgumentType):
|
|||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ResolvedArray(Array, Resolvable):
|
||||
class ResolvedArray(Array, ResolvableToJson):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from ytdl_sub.script.types.resolvable import ArgumentType
|
|||
from ytdl_sub.script.types.resolvable import Hashable
|
||||
from ytdl_sub.script.types.resolvable import NonHashable
|
||||
from ytdl_sub.script.types.resolvable import Resolvable
|
||||
from ytdl_sub.script.types.resolvable import ResolvableToJson
|
||||
from ytdl_sub.script.types.variable import FunctionArgument
|
||||
from ytdl_sub.script.types.variable import Variable
|
||||
from ytdl_sub.script.types.variable_dependency import VariableDependency
|
||||
|
|
@ -18,22 +19,6 @@ from ytdl_sub.utils.exceptions import StringFormattingException
|
|||
class Map(NonHashable):
|
||||
value: Dict[Hashable, Resolvable]
|
||||
|
||||
def to_native(self) -> Dict:
|
||||
output = {}
|
||||
for key, value in self.value.items():
|
||||
native_key = key.value
|
||||
if isinstance(value, Map):
|
||||
native_value = value.to_native()
|
||||
else:
|
||||
native_value = value.value
|
||||
|
||||
output[native_key] = native_value
|
||||
|
||||
return output
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self.to_native())
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class UnresolvedMap(Map, VariableDependency, ArgumentType):
|
||||
|
|
@ -92,5 +77,5 @@ class UnresolvedMap(Map, VariableDependency, ArgumentType):
|
|||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ResolvedMap(Map, Resolvable):
|
||||
class ResolvedMap(Map, ResolvableToJson):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import json
|
||||
from abc import ABC
|
||||
from abc import abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import Generic
|
||||
|
|
@ -40,6 +42,22 @@ class NonHashable(ABC):
|
|||
pass
|
||||
|
||||
|
||||
class ResolvableToJson(Resolvable, ABC):
|
||||
@classmethod
|
||||
def _to_native(cls, to_convert: Resolvable) -> Any:
|
||||
if isinstance(to_convert.value, list):
|
||||
return [cls._to_native(val) for val in to_convert.value]
|
||||
if isinstance(to_convert.value, dict):
|
||||
return {
|
||||
cls._to_native(key): cls._to_native(value)
|
||||
for key, value in to_convert.value.items()
|
||||
}
|
||||
return to_convert.value
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self._to_native(self))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ResolvableT(Hashable, ABC, Generic[T]):
|
||||
value: T
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class TestSyntaxTree:
|
|||
"bb": "b",
|
||||
"cc": "{%custom_func(aa, bb)}",
|
||||
}
|
||||
).resolve() == {"aa": String("a"), "bb": String("b"), "cc": String("return [a, b]")}
|
||||
).resolve() == {"aa": String("a"), "bb": String("b"), "cc": String('return ["a", "b"]')}
|
||||
|
||||
def test_simple(self):
|
||||
assert Script({"a": "a", "b": "{b_}", "b_": "b"}).resolve() == {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class TestArray:
|
|||
|
||||
def test_return_as_str(self):
|
||||
assert Script({"array": "str: {['a', 3.14]}"}).resolve() == {
|
||||
"array": String("str: [a, 3.14]")
|
||||
"array": String('str: ["a", 3.14]')
|
||||
}
|
||||
|
||||
def test_nested_array(self):
|
||||
|
|
@ -111,4 +111,4 @@ class TestArray:
|
|||
"bb": "b",
|
||||
"cc": "{%custom_func(aa, bb)}",
|
||||
}
|
||||
).resolve() == {"aa": String("a"), "bb": String("b"), "cc": String("return [a, b]")}
|
||||
).resolve() == {"aa": String("a"), "bb": String("b"), "cc": String('return ["a", "b"]')}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ from typing import Tuple
|
|||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
|
||||
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT
|
||||
from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT
|
||||
from ytdl_sub.script.parser import ArgumentParser
|
||||
|
|
@ -17,4 +18,4 @@ from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
|
|||
|
||||
|
||||
class TestBool:
|
||||
pass
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ from typing import Tuple
|
|||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
|
||||
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT
|
||||
from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT
|
||||
from ytdl_sub.script.parser import ArgumentParser
|
||||
|
|
@ -17,4 +18,4 @@ from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
|
|||
|
||||
|
||||
class TestFunction:
|
||||
pass
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ from typing import Tuple
|
|||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
|
||||
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import STRINGS_ONLY_ARGS
|
||||
from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT
|
||||
from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT
|
||||
from ytdl_sub.script.parser import ArgumentParser
|
||||
|
|
@ -21,10 +22,10 @@ class TestString:
|
|||
"string",
|
||||
[
|
||||
"{'323'}",
|
||||
"{ \"4253\" }",
|
||||
"{\"hi\"}",
|
||||
"{ \"asfsd\" }",
|
||||
"{\"sdfasf\"}",
|
||||
'{ "4253" }',
|
||||
'{"hi"}',
|
||||
'{ "asfsd" }',
|
||||
'{"sdfasf"}',
|
||||
"{ '3fsdf' }",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue