Skip to content

pytest.mark.parametrize string-based parameter list doesn't handle single element tuples #719

Description

@pytestbot

Originally reported by: David Haney (BitBucket: david_haney, GitHub: david_haney)


When specifying a @pytest.mark.parametrize element composed of a one-element tuple, I'm unable to use the string-based argument list, for example:

@pytest.mark.parametrize("arg", scenarios)
def test(arg):
    print(arg)
    assert(arg == "a") # this assert always fails

arg ends up being the tuple instead of the first item in the tuple (as I would expected based on tuples with more than one item. I also tried:

@pytest.mark.parametrize("arg,", scenarios)

but that also associated the entire tuple with arg instead of the first element. I reverted back to the older model of specifying the arguments as a tuple:

@pytest.mark.parametrize("arg,", scenarios)

Finally I switched back to the older style of using a tuple to specify the parameter list:

@pytest.mark.parametrize(("arg",), scenarios)

This version worked. This seems to imply that there is either a bug/limitation in the new string-based parameter specification, or that there is still a use-case for the tuple-based parameter specification. It would be helpful if either the string-based implementation could be updated to handle this situation, or if the documentation could be updated to note when the tuple-based parameter specification is still needed.


Activity

  1. pytestbot commented on Apr 14, 2015

    @pytestbot
    ContributorAuthor

    Original comment by Brianna Laugher (BitBucket: pfctdayelise, GitHub: pfctdayelise):


    This looks closely related to #638.

  2. self-assigned this
    on Jul 10, 2015
  3. RonnyPfannschmidt commented on Jul 25, 2015

    @RonnyPfannschmidt
    Member

    @pfctdayelise is that one easy, its hard to tell off hand

  4. untitaker commented on Aug 8, 2015

    @untitaker
    Contributor

    The current state:

    • Single-arg parametrization means a list of values must be passed.
    • Multi-arg parametrization means a list of value-tuples must be passed.

    Unless I'm missing something, fixing this would create an ambiguity, as single-arg parametrization would take either values or tuples with one value each. It'd be no longer possible to pass tuples as parametrization values, i.e. it'd be no longer possible to replicate the current behavior of scenarios = [("a",)] in the future.

    I think this issue should be closed -- the fix is to use scenarios = ['a'].

  5. nicoddemus commented on Aug 8, 2015

    @nicoddemus
    Member

    I think the OP means that these two tests should be equivalent:

    import pytest
    
    scenarios = [('a',)]
    
    @pytest.mark.parametrize(("arg",), scenarios)
    def test_foo_1(arg):
        assert arg == 'a'
    
    @pytest.mark.parametrize("arg", scenarios)
    def test_foo_2(arg):
        assert arg == 'a'  
    test_foo.py::test_foo_1[a] FAILED
    test_foo.py::test_foo_2[arg0] PASSED
    
    ================================== FAILURES ===================================
    ________________________________ test_foo_1[a] ________________________________
    
    arg = 'a'
    
        @pytest.mark.parametrize(("arg",), scenarios)
        def test_foo_1(arg):
    >       assert arg == ('a',)
    E       assert 'a' == ('a',)
    
    test_foo.py:7: AssertionError
    ===================== 1 failed, 1 passed in 0.02 seconds ======================
    

    When you use more than one argument, both tests work as expected:

    import pytest
    
    scenarios = [('a', 'b')]
    
    @pytest.mark.parametrize(("arg","arg2"), scenarios)
    def test_bar_1(arg, arg2):
        assert arg == 'a'
        assert arg2 == 'b'
    
    @pytest.mark.parametrize("arg,arg2", scenarios)
    def test_bar_2(arg, arg2):
        assert arg == 'a'
        assert arg2 == 'b'  
    test_foo.py::test_bar_1[a-b] PASSED
    test_foo.py::test_bar_2[a-b] PASSED
    

    I would expect both forms to work even if used with a single argument, so this seems like a bug to me... 😅

  6. untitaker commented on Aug 8, 2015

    @untitaker
    Contributor

    I see, I misread the OP.

  7. RonnyPfannschmidt commented on Aug 8, 2015

    @RonnyPfannschmidt
    Member

    I would expect tuples for single arg string without the comma

  8. nicoddemus commented on Aug 8, 2015

    @nicoddemus
    Member

    I would expect tuples for single arg string without the comma

    Could you elaborate your reasoning?

    From the docs, it seems that passing "arg" or ("arg",) should be the same thing, that's why I feel it is a bug.

  9. RonnyPfannschmidt commented on Aug 8, 2015

    @RonnyPfannschmidt
    Member

    think about a use-cases where you want to pass tuples of different arty to a single argument,

    wouldn't it unpack them in a bad way ? - imho the structure of the definition should match the structure of the expression

    the ',' writing is just a shortcut for the tuples - and just like tuples without a comma, its not a tuple

  10. nicoddemus commented on Aug 8, 2015

    @nicoddemus
    Member

    Could you post a code example of what you mean? I think it would be better to illustrate your point.

  11. RonnyPfannschmidt commented on Aug 8, 2015

    @RonnyPfannschmidt
    Member
    paramerize('a', [(1,), (1,2), (2,), ]) # a should never be 1 and never be 2
    
  12. untitaker commented on Aug 8, 2015

    @untitaker
    Contributor

    I thought this issue was about passing tuples for the parameter NAMES, not the VALUES.

    On 8 August 2015 18:44:46 CEST, Ronny Pfannschmidt notifications@github.com wrote:

    paramerize('a', [(1,), (1,2), (2,), ]) # a should never be 1 and never
    be 2
    

    Reply to this email directly or view it on GitHub:
    #719 (comment)

    Sent from my phone. Please excuse my brevity.

  13. RonnyPfannschmidt commented on Aug 8, 2015

    @RonnyPfannschmidt
    Member

    @untitaker there is some detail logic involved wrt interaction between names and values, it'd take a while to dig this out properly, i cant promise it for this weekend

  14. 17 remaining items

  15. added a commit that references this issue on Jul 21, 2026
    398581a
  16. added 2 commits that reference this issue on Jul 22, 2026
    4bb429b
    1417d18
  17. added a commit that references this issue on Jul 29, 2026
  18. added a commit that references this issue on Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

topic: parametrizerelated to @pytest.mark.parametrizetype: bugproblem that needs to be addressed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions