Skip to content

Commit

Permalink
WIP: store _param_ids_from/_param_ids_generated with Marks
Browse files Browse the repository at this point in the history
  • Loading branch information
blueyed committed Nov 19, 2019
1 parent 0da413f commit 167d5fb
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
23 changes: 21 additions & 2 deletions src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import warnings
from collections import namedtuple
from collections.abc import MutableMapping
from typing import List
from typing import Optional
from typing import Set

import attr
Expand Down Expand Up @@ -144,7 +146,13 @@ class Mark:
#: keyword arguments of the mark decorator
kwargs = attr.ib() # Dict[str, object]

def combined_with(self, other):
_param_ids_from = attr.ib(type=Optional["Mark"], default=None)
_param_ids_generated = attr.ib(type=Optional[List[str]], default=None)

def _has_param_ids(self):
return "ids" in self.kwargs or len(self.args) >= 4

def combined_with(self, other: "Mark") -> "Mark":
"""
:param other: the mark to combine with
:type other: Mark
Expand All @@ -153,8 +161,19 @@ def combined_with(self, other):
combines by appending args and merging the mappings
"""
assert self.name == other.name

param_ids_from = None # type: Optional[Mark]
if self.name == "parametrize":
if other._has_param_ids():
param_ids_from = other
elif self._has_param_ids():
param_ids_from = self

return Mark(
self.name, self.args + other.args, dict(self.kwargs, **other.kwargs)
self.name,
self.args + other.args,
dict(self.kwargs, **other.kwargs),
param_ids_from=param_ids_from,
)


Expand Down
21 changes: 20 additions & 1 deletion src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,25 @@ def pytest_generate_tests(metafunc):
_validate_parametrize_spelling(metafunc)

for marker in metafunc.definition.iter_markers(name="parametrize"):
metafunc.parametrize(*marker.args, **marker.kwargs)
args, kwargs = marker.args, marker.kwargs
if marker._param_ids_from:
ids = marker._param_ids_from._param_ids_generated
if ids is None:
save_ids = True
else:
save_ids = False
if len(args) > 3:
args = args.copy()
args[3] = ids
else:
assert "ids" in kwargs
kwargs = kwargs.copy()
kwargs["ids"] = ids

new_ids = metafunc.parametrize(*args, **kwargs)

if marker._param_ids_from and save_ids:
object.__setattr__(marker._param_ids_from, "_param_ids_generated", new_ids)


def pytest_configure(config):
Expand Down Expand Up @@ -1024,6 +1042,7 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None, scope=None)
)
newcalls.append(newcallspec)
self._calls = newcalls
return ids

def _resolve_arg_ids(self, argnames, ids, parameters, item):
"""Resolves the actual ids for the given argnames, based on the ``ids`` parameter given
Expand Down
6 changes: 3 additions & 3 deletions testing/python/metafunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1849,12 +1849,12 @@ def test_converted_to_str(a, b):
"""
)
result = testdir.runpytest("-vv", "-s")
result.stdout.fnmatch_lines_random( # random for py35.
result.stdout.fnmatch_lines(
[
"test_parametrize_iterator.py::test1[param0] PASSED",
"test_parametrize_iterator.py::test1[param1] PASSED",
"test_parametrize_iterator.py::test2[param2] PASSED",
"test_parametrize_iterator.py::test2[param3] PASSED",
"test_parametrize_iterator.py::test2[param0] PASSED",
"test_parametrize_iterator.py::test2[param1] PASSED",
"test_parametrize_iterator.py::test_converted_to_str[0] PASSED",
"test_parametrize_iterator.py::test_converted_to_str[1] PASSED",
"*= 6 passed in *",
Expand Down

0 comments on commit 167d5fb

Please sign in to comment.