pytest-dev / pytest-dev/pytest

parametrizing a fixture with indirect=True does not handle dicts correctly

Open
#11,632 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: parametrize type: enhancement
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

When using @pytest.mark.parametrize(..., indirect=True) a dict param is handled like a list of its keys, instead of a single param - I have to explicitly wrap it in a list or single-element tuple. Besides making the code less pleasant to read, it also kind of breaks the ruff PT007 linting rule (I set it to always prefer tuples for parametrization), because now I have to use a single-element tuple (which looks even worse than the list)...

Maybe a dict should always be handled as a single element?

import pytest


@pytest.fixture
def fixture_with_param(request):
    print(f'param: {request.param}')
    return request.param['foo'].upper()


@pytest.mark.parametrize('fixture_with_param', {'foo': 'bar', 'hello': 'world'}, indirect=True)
def test_bad_param(fixture_with_param):
    assert fixture_with_param == 'BAR'


@pytest.mark.parametrize('fixture_with_param', [{'foo': 'bar', 'hello': 'world'}], indirect=True)
def test_good_param(fixture_with_param):
    assert fixture_with_param == 'BAR'
$ pytest
================================================= test session starts ==================================================
platform linux -- Python 3.11.6, pytest-7.4.3, pluggy-1.3.0
rootdir: /tmp/empty
collected 3 items

test_indirect_param.py EE.                                                                                       [100%]

======================================================== ERRORS ========================================================
________________________________________ ERROR at setup of test_bad_param[foo] _________________________________________

request = <SubRequest 'fixture_with_param' for <Function test_bad_param[foo]>>

    @pytest.fixture
    def fixture_with_param(request):
        print(f'param: {request.param} ({type(request.param)})')
>       return request.param['foo'].upper()
E       TypeError: string indices must be integers, not 'str'

test_indirect_param.py:7: TypeError
------------------------------------------------ Captured stdout setup -------------------------------------------------
param: foo (<class 'str'>)
_______________________________________ ERROR at setup of test_bad_param[hello] ________________________________________

request = <SubRequest 'fixture_with_param' for <Function test_bad_param[hello]>>

    @pytest.fixture
    def fixture_with_param(request):
        print(f'param: {request.param} ({type(request.param)})')
>       return request.param['foo'].upper()
E       TypeError: string indices must be integers, not 'str'

test_indirect_param.py:7: TypeError
------------------------------------------------ Captured stdout setup -------------------------------------------------
param: hello (<class 'str'>)
=============================================== short test summary info ================================================
ERROR test_indirect_param.py::test_bad_param[foo] - TypeError: string indices must be integers, not 'str'
ERROR test_indirect_param.py::test_bad_param[hello] - TypeError: string indices must be integers, not 'str'
============================================= 1 passed, 2 errors in 0.02s ==============================================
$ python --version
Python 3.11.6

$ pip list
Package    Version
---------- -------
iniconfig  2.0.0
packaging  23.2
pip        23.3.1
pluggy     1.3.0
pytest     7.4.3
setuptools 65.5.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the indirect=True examples from the issue with pytest 7.4.3, then trace how parametrization converts the dict into individual parameters. Determine the intended handling for dict values and add regression coverage; done means the dict reaches the fixture as one parameter while existing parametrization behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.