runtime map hash error

This commit is contained in:
Jesse Bannon 2023-11-22 15:06:13 -08:00
parent 1d953a8270
commit c5baa7c2b3
4 changed files with 39 additions and 5 deletions

View file

@ -11,7 +11,7 @@ from ytdl_sub.script.types.resolvable import Resolvable
from ytdl_sub.script.types.resolvable import ResolvableToJson
from ytdl_sub.script.types.variable import Variable
from ytdl_sub.script.types.variable_dependency import VariableDependency
from ytdl_sub.utils.exceptions import StringFormattingException
from ytdl_sub.script.utils.exceptions import KeyNotHashableRuntimeException
@dataclass(frozen=True)
@ -42,7 +42,9 @@ class UnresolvedMap(Map, VariableDependency, AnyArgument):
arg=key, resolved_variables=resolved_variables, custom_functions=custom_functions
)
if not isinstance(resolved_key, Hashable):
raise StringFormattingException("key is not hashable")
raise KeyNotHashableRuntimeException(
f"Tried to use {resolved_key.type_name()} as a Map key, but it is not hashable."
)
output[resolved_key] = self._resolve_argument_type(
arg=value, resolved_variables=resolved_variables, custom_functions=custom_functions

View file

@ -12,7 +12,6 @@ from ytdl_sub.script.types.resolvable import Resolvable
from ytdl_sub.script.types.variable import FunctionArgument
from ytdl_sub.script.types.variable import Variable
from ytdl_sub.script.utils.exceptions import UNREACHABLE
from ytdl_sub.utils.exceptions import StringFormattingException
@dataclass(frozen=True)
@ -78,7 +77,8 @@ class VariableDependency(ABC):
return arg
if isinstance(arg, Variable):
if arg not in resolved_variables:
raise StringFormattingException("should never reach@")
# All variables should exist and be resolved at this point
raise UNREACHABLE
return resolved_variables[arg]
if isinstance(arg, VariableDependency):
return arg.resolve(

View file

@ -43,10 +43,18 @@ class CycleDetected(UserException):
"""A cycle exists within a user's script"""
class FunctionRuntimeException(ValueError):
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 UserThrownRuntimeError(ValidationException):
"""An error explicitly thrown by the user via a function"""

View file

@ -15,6 +15,7 @@ from ytdl_sub.script.types.resolvable import Boolean
from ytdl_sub.script.types.resolvable import Float
from ytdl_sub.script.types.resolvable import String
from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
from ytdl_sub.script.utils.exceptions import KeyNotHashableRuntimeException
class TestMap:
@ -159,3 +160,26 @@ class TestMap:
def test_map_key_not_hashable(self, value: str):
with pytest.raises(InvalidSyntaxException, match=re.escape(str(MAP_KEY_NOT_HASHABLE))):
Script({"map": value}).resolve()
def test_map_key_is_hashable_variable(self):
assert Script(
{
"map": "{{key_variable : 'value' }}",
"key_variable": "hashable",
}
).resolve() == {
"key_variable": String("hashable"),
"map": ResolvedMap({String("hashable"): String("value")}),
}
def test_map_key_is_non_hashable_variable(self):
with pytest.raises(
KeyNotHashableRuntimeException,
match=re.escape("Tried to use Array as a Map key, but it is not hashable."),
):
Script(
{
"map": "{{key_variable : 'value' }}",
"key_variable": "{['non-hashable']}",
}
).resolve()