flake8-pytest-style icon indicating copy to clipboard operation
flake8-pytest-style copied to clipboard

Does not recognize size 1 tuples for names in @pytest.mark.parametrize().

Open cansjt opened this issue 4 years ago • 1 comments
trafficstars

Bug report

What's wrong

$ flake8 --pytest-parametrize-names-type tuple simple_test.py 
simple_test.py:21:2: PT006 wrong name(s) type in @pytest.mark.parametrize, expected string

If I asked for tuples, why am I bothered with strings ?

How it should work

If I ask for tuples as parameter names, there should not be any interpretation on the flake8-pytest-style side, it should only check that what I asked for is what it finds in the code:

# Assume this file is named simple_test.py
import pytest


# A string
@pytest.mark.parametrize('single_param', (
    pytest.param('hello'),
))
def test1(single_param):
    pass


# ``('single_param')`` is not a tuple, it is a parenthesized str, hence a str.
@pytest.mark.parametrize(('single_param'), (
    pytest.param('hello'),
))
def test2(single_param):
    pass


# A 1 str tuple
@pytest.mark.parametrize(('single_param', ), (
    pytest.param('hello'),
))
def test3(single_param):
    pass


# A 2 str tuple (to show that tuple length seem to be the matter)
@pytest.mark.parametrize(('single_param', 'two value'), (
    pytest.param('hello'),
))
def test4(single_param):
    pass

Then run:

$ flake8 --pytest-parametrize-names-type tuple simple_test.py 
simple_test.py:21:2: PT006 wrong name(s) type in @pytest.mark.parametrize, expected string

An issue is reported only for the one valid syntax. More over the error is confusing: I ask for tuples, I am told I should have strings.

System information

  • Operating system:
  • Python version:
  • flake8 version:
  • flake8-pytest-style version:

cansjt avatar Jun 12 '21 08:06 cansjt

Hi @cansjt,

Thank you for your report!

This is currently working the way I intended: when there is a single name, the plugin always expects it to be a plain string. Here is my rationale.

When there are multiple parameters, pytest needs a nested structure of parameter values:

@pytest.mark.parametrize(('param1', 'param2'), [(1, 2), (3, 4)])
def test_foo(param1):
    ...

When there is a single parameter, pytest needs a flat list/tuple of parameter values:

@pytest.mark.parametrize('param', [1, 2, 3])
def test_foo(param):
    ...

The way I see it, the names structure is "parallel" to the values. In the first example the values are wrapped in tuples ((1, 2) etc), and the names are correspondingly wrapped in a tuple. In the second example the individual values are not wrapped, so the name is also a plain string not wrapped in a list/tuple.

All things said, I could be open to introducing a new config option which would force single names to conform to the same style as multiple names. Unfortunately I am not sure when I will have time to implement it myself, but pull requests are always welcome.

m-burst avatar Jun 16 '21 21:06 m-burst