Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions taskiq/receiver/params_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ def parse_params(
# trying to parse found value as in type annotation.
message.args[argnum] = parse_obj_as(annot, value)
except (ValueError, RuntimeError) as exc:
logger.debug(exc, exc_info=True)
logger.warning(
"Can't parse argument %d for task %s. Reason: %s",
argnum,
message.task_name,
exc,
exc_info=True,
)
else:
# We try to get this parameter from kwargs.
value = message.kwargs.get(param_name)
Expand All @@ -86,4 +92,10 @@ def parse_params(
# trying to parse found value as in type annotation.
message.kwargs[param_name] = parse_obj_as(annot, value)
except (ValueError, RuntimeError) as exc:
logger.debug(exc, exc_info=True)
logger.warning(
"Can't parse argument %s for task %s. Reason: %s",
param_name,
message.task_name,
exc,
exc_info=True,
)
263 changes: 263 additions & 0 deletions tests/receiver/test_params_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
import inspect
import logging
from dataclasses import dataclass
from typing import Any, Callable, get_type_hints

import pytest
from pydantic import BaseModel

from taskiq.message import TaskiqMessage
from taskiq.receiver.params_parser import parse_params


def _helper(f: Callable[..., Any], message: TaskiqMessage) -> None:
sign = inspect.signature(f)
hints = get_type_hints(f)
parse_params(sign, hints, message)


def test_primitive_args_success() -> None:
def func(a: int, b: int) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=["1", "2"],
kwargs={},
)
_helper(func, msg)
assert msg.args == [1, 2]
assert msg.kwargs == {}


def test_dataclasses_args_success() -> None:
@dataclass
class TestObj:
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[{"a": "10", "b": "20"}],
kwargs={},
)
_helper(func, msg)
assert msg.args == [TestObj(a=10, b=20)]
assert msg.kwargs == {}


def test_pydantic_args_success() -> None:
class TestObj(BaseModel):
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[{"a": "10", "b": "20"}],
kwargs={},
)
_helper(func, msg)
assert msg.args == [TestObj(a=10, b=20)]
assert msg.kwargs == {}


def test_primitive_args_failure(caplog: pytest.LogCaptureFixture) -> None:
def func(a: int, b: int) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=["f3", "2"],
kwargs={},
)
with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument 0" in caplog.text
assert msg.args == ["f3", 2]


def test_dataclasses_args_failure(caplog: pytest.LogCaptureFixture) -> None:
@dataclass
class TestObj:
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[{"a": "10", "b": "f3"}],
kwargs={},
)
with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument 0" in caplog.text
assert msg.args == [{"a": "10", "b": "f3"}]


def test_pyndantic_args_failure(caplog: pytest.LogCaptureFixture) -> None:
class TestObj(BaseModel):
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[{"a": "10", "b": "f3"}],
kwargs={},
)

with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument 0" in caplog.text
assert msg.args == [{"a": "10", "b": "f3"}]


def test_kwargs_primitives_success() -> None:
def func(a: int, b: int) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[1],
kwargs={"b": "2"},
)
_helper(func, msg)
assert msg.args == [1]
assert msg.kwargs == {"b": 2}


def test_kwargs_dataclasses_success() -> None:
@dataclass
class TestObj:
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[],
kwargs={"a": {"a": "10", "b": "20"}},
)
_helper(func, msg)
assert msg.args == []
assert msg.kwargs == {"a": TestObj(a=10, b=20)}


def test_kwargs_pyndantic_success() -> None:
class TestObj(BaseModel):
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[],
kwargs={"a": {"a": "10", "b": "20"}},
)
_helper(func, msg)
assert msg.args == []
assert msg.kwargs == {"a": TestObj(a=10, b=20)}


def test_kwargs_primitives_failure(caplog: pytest.LogCaptureFixture) -> None:
def func(a: int, b: int) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[],
kwargs={"a": "1", "b": "f3"},
)
with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument b" in caplog.text
assert msg.kwargs == {"a": 1, "b": "f3"}


def test_kwargs_dataclasses_failure(caplog: pytest.LogCaptureFixture) -> None:
@dataclass
class TestObj:
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[],
kwargs={"a": {"a": "10", "b": "f3"}},
)
with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument a" in caplog.text
assert msg.kwargs == {"a": {"a": "10", "b": "f3"}}


def test_kwargs_pyndantic_failure(caplog: pytest.LogCaptureFixture) -> None:
class TestObj(BaseModel):
a: int
b: int

def func(a: TestObj) -> None:
pass

msg = TaskiqMessage(
task_id="test",
task_name="test",
labels={},
labels_types={},
args=[],
kwargs={"a": {"a": "10", "b": "f3"}},
)
with caplog.at_level(logging.WARNING):
_helper(func, msg)
assert "Can't parse argument a" in caplog.text
assert msg.kwargs == {"a": {"a": "10", "b": "f3"}}
Loading