def test_invalid_get_no_subject_args() -> None: async def rule(): Get( STR, ) with pytest.raises(GetParseError): collect_awaitables(rule)
def wrapper(func): if not inspect.isfunction(func): raise ValueError( "The @rule decorator must be applied innermost of all decorators." ) awaitables = FrozenOrderedSet(collect_awaitables(func)) validate_requirements(func_id, parameter_types, awaitables, cacheable) # Set our own custom `__line_number__` dunder so that the engine may visualize the line number. func.__line_number__ = func.__code__.co_firstlineno func.rule = TaskRule( return_type, parameter_types, func, input_gets=awaitables, canonical_name=canonical_name, desc=desc, level=level, cacheable=cacheable, ) return func
def assert_awaitables(func, awaitable_types: Iterable[Tuple[type, type]]): gets = collect_awaitables(func) get_types = tuple((get.input_type, get.output_type) for get in gets) assert get_types == tuple(awaitable_types)
def test_invalid_get_invalid_product_type_not_a_type_name() -> None: async def rule(): Get(call(), STR("bob")) # noqa: F821 with pytest.raises(GetParseError): collect_awaitables(rule)
def test_invalid_get_invalid_subject_arg_no_constructor_call() -> None: async def rule(): Get(STR, "bob") with pytest.raises(GetParseError): collect_awaitables(rule)
def test_invalid_get_too_many_subject_args() -> None: async def rule(): Get(STR, INT, "bob", 3) with pytest.raises(GetParseError): collect_awaitables(rule)
def test_valid_get_unresolvable_subject_declared_type() -> None: async def rule(): Get(int, DNE, "bob") # noqa: F821 with pytest.raises(ValueError): collect_awaitables(rule)
def test_valid_get_unresolvable_product_type() -> None: async def rule(): Get(DNE, STR(42)) # noqa: F821 with pytest.raises(ValueError): collect_awaitables(rule)