map funcs
This commit is contained in:
parent
d35c8e9965
commit
689dfe8673
4 changed files with 84 additions and 19 deletions
|
|
@ -3,6 +3,7 @@ from typing import Optional
|
|||
from ytdl_sub.script.types.map import Map
|
||||
from ytdl_sub.script.types.resolvable import AnyArgument
|
||||
from ytdl_sub.script.types.resolvable import Hashable
|
||||
from ytdl_sub.script.utils.exceptions import KeyDoesNotExistRuntimeException
|
||||
|
||||
|
||||
class MapFunctions:
|
||||
|
|
@ -12,6 +13,11 @@ class MapFunctions:
|
|||
Return ``key``'s value within the Map. If ``key`` does not exist, and ``default`` is
|
||||
provided, it will return ``default``. Otherwise, will error.
|
||||
"""
|
||||
if default is not None:
|
||||
return mapping.value.get(key, default=default)
|
||||
if key not in mapping.value:
|
||||
if default is not None:
|
||||
return default
|
||||
|
||||
raise KeyDoesNotExistRuntimeException(
|
||||
f"Tried to call %map_get with key {key.value}, but it does not exist"
|
||||
)
|
||||
return mapping.value[key]
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from ytdl_sub.script.types.variable_dependency import VariableDependency
|
|||
from ytdl_sub.script.utils.exception_formatters import FunctionArgumentsExceptionFormatter
|
||||
from ytdl_sub.script.utils.exceptions import UNREACHABLE
|
||||
from ytdl_sub.script.utils.exceptions import FunctionRuntimeException
|
||||
from ytdl_sub.script.utils.exceptions import RuntimeException
|
||||
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
|
||||
from ytdl_sub.script.utils.type_checking import FunctionSpec
|
||||
from ytdl_sub.script.utils.type_checking import is_union
|
||||
|
|
@ -189,7 +190,7 @@ class BuiltInFunction(Function, BuiltInFunctionType):
|
|||
|
||||
try:
|
||||
return self.callable(*resolved_arguments)
|
||||
except UserThrownRuntimeError:
|
||||
except (UserThrownRuntimeError, RuntimeException):
|
||||
raise
|
||||
except Exception as exc:
|
||||
raise FunctionRuntimeException(
|
||||
|
|
|
|||
|
|
@ -2,15 +2,14 @@ from abc import ABC
|
|||
|
||||
from ytdl_sub.utils.exceptions import ValidationException
|
||||
|
||||
###################################################################################################
|
||||
# USER EXCEPTIONS
|
||||
|
||||
|
||||
class UserException(ValidationException, ABC):
|
||||
"""It's the user's fault!"""
|
||||
|
||||
|
||||
class RuntimeException(ValueError, ABC):
|
||||
"""Exception thrown at runtime during resolution"""
|
||||
|
||||
|
||||
class InvalidSyntaxException(UserException):
|
||||
"""Syntax is incorrect"""
|
||||
|
||||
|
|
@ -47,18 +46,6 @@ class CycleDetected(UserException):
|
|||
"""A cycle exists within a user's script"""
|
||||
|
||||
|
||||
class FunctionRuntimeException(RuntimeException):
|
||||
"""Exception thrown when a ytdl-sub function has an error occur at runtime"""
|
||||
|
||||
|
||||
class KeyNotHashableRuntimeException(RuntimeException):
|
||||
"""Map tried to use a non-hashable key at runtime"""
|
||||
|
||||
|
||||
class FunctionDoesNotExistRuntimeException(RuntimeException):
|
||||
"""Tried to get a function that does not exist"""
|
||||
|
||||
|
||||
class UserThrownRuntimeError(ValidationException):
|
||||
"""An error explicitly thrown by the user via a function"""
|
||||
|
||||
|
|
@ -72,3 +59,26 @@ UNREACHABLE = _UnreachableSyntaxException(
|
|||
"Please upload your config/subscription file(s) to and make a GitHub issue at "
|
||||
"https://github.com/jmbannon/ytdl-sub/issues"
|
||||
)
|
||||
|
||||
###################################################################################################
|
||||
# RUNTIME EXCEPTIONS
|
||||
|
||||
|
||||
class RuntimeException(ValueError, ABC):
|
||||
"""Exception thrown at runtime during resolution"""
|
||||
|
||||
|
||||
class FunctionRuntimeException(RuntimeException):
|
||||
"""Exception thrown when a ytdl-sub function has an error occur at runtime"""
|
||||
|
||||
|
||||
class KeyNotHashableRuntimeException(RuntimeException):
|
||||
"""Map tried to use a non-hashable key at runtime"""
|
||||
|
||||
|
||||
class FunctionDoesNotExistRuntimeException(RuntimeException):
|
||||
"""Tried to get a function that does not exist"""
|
||||
|
||||
|
||||
class KeyDoesNotExistRuntimeException(RuntimeException):
|
||||
"""Tried to access a key on a map that does not exist, with no default"""
|
||||
|
|
|
|||
48
tests/unit/script/functions/test_map_functions.py
Normal file
48
tests/unit/script/functions/test_map_functions.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.script.script import Script
|
||||
from ytdl_sub.script.utils.exceptions import KeyDoesNotExistRuntimeException
|
||||
|
||||
|
||||
class TestMapFunctions:
|
||||
def test_map_get(self):
|
||||
output = (
|
||||
Script(
|
||||
{
|
||||
"input_map": "{{'key': 'value'}}",
|
||||
"output": "{%map_get(input_map, 'key')}",
|
||||
}
|
||||
)
|
||||
.resolve(update=True)
|
||||
.get("output")
|
||||
.native
|
||||
)
|
||||
assert output == "value"
|
||||
|
||||
def test_map_get_optional(self):
|
||||
output = (
|
||||
Script(
|
||||
{
|
||||
"input_map": "{{'key': 'value'}}",
|
||||
"output": "{%map_get(input_map, 'dne', 'optional_value')}",
|
||||
}
|
||||
)
|
||||
.resolve(update=True)
|
||||
.get("output")
|
||||
.native
|
||||
)
|
||||
assert output == "optional_value"
|
||||
|
||||
def test_map_get_errors_missing_key(self):
|
||||
with pytest.raises(
|
||||
KeyDoesNotExistRuntimeException,
|
||||
match=re.escape("Tried to call %map_get with key dne, but it does not exist"),
|
||||
):
|
||||
Script(
|
||||
{
|
||||
"input_map": "{{'key': 'value'}}",
|
||||
"output": "{%map_get(input_map, 'dne')}",
|
||||
}
|
||||
).resolve()
|
||||
Loading…
Reference in a new issue