pytest-dev / pytest-dev/pytest
parametrizing a fixture with indirect=True does not handle dicts correctly
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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