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?
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 ===============================
Most helpful comment
oh I see what you're proposing -- I'm still -1 on what you're proposing, the type for the
idsfunction is already complicated enough to understand as it is -- plus you can accomplish this by passing the.formatfunction directlywhile it would be possible, it would increase the complexity of
parametrizefurther 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
idsin docs would be pretty difficult and the small benefit in this one case would not out weigh the maintenance