dev-petrov / pytest-lazy-fixtures

Allows you to use fixtures in @pytest.mark.parametrize.
MIT License
55 stars 2 forks source link

Issues with NamedTuple in parameter clause #7

Closed kasium closed 7 months ago

kasium commented 7 months ago

Given the below code, pytest fails

from typing import NamedTuple

import pytest

class Data(NamedTuple):
    a: int
    b: int

@pytest.mark.parametrize("data", [Data(a=1, b=2)])
def test(data):
    assert data.a == 1
    assert data.b == 2
value = Data(a=1, b=2), request = <SubRequest 'data' for <Function test[data0]>>

    def load_lazy_fixtures(value, request: pytest.FixtureRequest):
        if isinstance(value, LazyFixtureCallableWrapper):
            return value.get_func(request)(
                *load_lazy_fixtures(value.args, request),
                **load_lazy_fixtures(value.kwargs, request),
            )
        if isinstance(value, LazyFixtureWrapper):
            return value.load_fixture(request)
        if isinstance(value, dict):
            return {key: load_lazy_fixtures(value, request) for key, value in value.items()}
        elif isinstance(value, (list, tuple, set)):
>           return type(value)([load_lazy_fixtures(value, request) for value in value])
E           TypeError: Data.__new__() missing 1 required positional argument: 'b'

venv/lib/python3.12/site-packages/pytest_lazy_fixtures/loader.py:18: TypeError

Root cause is the instance check of tuple. pytest-lazy-fixture should only consider tuples, not NamedTuple. Note, that if all fields of the NamedTuple have a default value, the assertion statement will fail like assert [1, 2] == 1

dev-petrov commented 7 months ago

Fixed in 1.0.4