Pytest: An ergonomics suggestion - accept format strings as `ids` in mark.parametrize()

Created on 11 Dec 2019  路  4Comments  路  Source: pytest-dev/pytest

I couldn't find this in previously opened tickets, so here goes: why don't we allow ids passed to pytest.mark.parametrize to be treated as format strings? It doesn't make much sense for those ids to be strings anyway as they would typically be either lists/iterables or callables.

E.g.:

# current
@pytest.mark.parametrize('foo', [1, 2, 3], ids=lambda x: f'foo:{x}')  # either this
@pytest.mark.parametrize('bar', [0.1, 0.2, 0.3], ids='bar:{:.2%}'.format)  # or this
# proposed
@pytest.mark.parametrize('foo', [1, 2, 3], ids='foo:{}')
@pytest.mark.parametrize('bar', [0.1, 0.2, 0.3], ids='bar:{:.2%}')

In the end, if ids is a callable, it's function that takes a single argument and converts it to a string.

One of the best built-in ways to do it in Python is via format strings, so why not provide direct ergonomic support for it?

proposal

Most helpful comment

oh I see what you're proposing -- I'm still -1 on what you're proposing, the type for the ids function is already complicated enough to understand as it is -- plus you can accomplish this by passing the .format function directly

while it would be possible, it would increase the complexity of parametrize further than it already is and (imo) with not much benefit.

open to hear what the other maintainers say but my leaning is that implementing and explaining this nuance of ids in docs would be pretty difficult and the small benefit in this one case would not out weigh the maintenance

All 4 comments

I believe you're looking for idfn http://doc.pytest.org/en/latest/example/parametrize.html#different-options-for-test-ids

@asottile Nope, not really...

as they would typically be either lists/iterables or callables

The idfn you've pointed out is the "callable" case I've mentioned.

My point being, most of the time, there will be some string formatting going on, so why not also accept format strings directly (as in the example above)?

oh I see what you're proposing -- I'm still -1 on what you're proposing, the type for the ids function is already complicated enough to understand as it is -- plus you can accomplish this by passing the .format function directly

while it would be possible, it would increase the complexity of parametrize further than it already is and (imo) with not much benefit.

open to hear what the other maintainers say but my leaning is that implementing and explaining this nuance of ids in docs would be pretty difficult and the small benefit in this one case would not out weigh the maintenance

plus it would potentially break this which works today:

CASES = (1, 23, 2, 4)

@pytest.mark.parametrize('x', CASES, ids=string.ascii_letters[:len(CASES)])
def test(x):
    pass
$ pytest t.py -v
============================= test session starts ==============================
platform linux -- Python 3.6.8, pytest-5.3.1, py-1.8.0, pluggy-0.13.1 -- /tmp/x/venv/bin/python3
cachedir: .pytest_cache
rootdir: /tmp/x
collected 4 items                                                              

t.py::test[a] PASSED                                                     [ 25%]
t.py::test[b] PASSED                                                     [ 50%]
t.py::test[c] PASSED                                                     [ 75%]
t.py::test[d] PASSED                                                     [100%]

============================== 4 passed in 0.01s ===============================
Was this page helpful?
0 / 5 - 0 ratings