From 79927428d1c962eacc2adbe8097ded23fea2ddf4 Mon Sep 17 00:00:00 2001 From: palaviv Date: Mon, 25 Apr 2016 17:11:47 +0300 Subject: [PATCH] Added pytest_make_parametrize_id hook --- _pytest/hookspec.py | 6 ++++++ _pytest/python.py | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index 60e9b47d262..5d70ea1c378 100644 --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -133,6 +133,12 @@ def pytest_deselected(items): def pytest_make_collect_report(collector): """ perform ``collector.collect()`` and return a CollectReport. """ +@hookspec(firstresult=True) +def pytest_make_parametrize_id(val): + """Return a user-friendly string representation of the given ``val`` that will be used + by @pytest.mark.parametrize calls. Return None if the hook doesn't know about ``val``. + """ + # ------------------------------------------------------------------------- # Python test function related hooks # ------------------------------------------------------------------------- diff --git a/_pytest/python.py b/_pytest/python.py index 6785892d974..20c6a4de6b4 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -342,6 +342,9 @@ def pytest_pycollect_makeitem(collector, name, obj): res = list(collector._genfunctions(name, obj)) outcome.force_result(res) +def pytest_make_parametrize_id(val): + return None + def is_generator(func): try: return _pytest._code.getrawcode(func).co_flags & 32 # generator function @@ -1030,7 +1033,7 @@ def parametrize(self, argnames, argvalues, indirect=False, ids=None, if ids and len(ids) != len(argvalues): raise ValueError('%d tests specified with %d ids' %( len(argvalues), len(ids))) - ids = idmaker(argnames, argvalues, idfn, ids) + ids = idmaker(argnames, argvalues, idfn, ids, self.config) newcalls = [] for callspec in self._calls or [CallSpec2(self)]: for param_index, valset in enumerate(argvalues): @@ -1130,7 +1133,7 @@ def _escape_strings(val): return val.encode('unicode-escape') -def _idval(val, argname, idx, idfn): +def _idval(val, argname, idx, idfn, config): if idfn: try: s = idfn(val) @@ -1139,6 +1142,11 @@ def _idval(val, argname, idx, idfn): except Exception: pass + if config: + hook_id = config.hook.pytest_make_parametrize_id(val=val) + if hook_id: + return hook_id + if isinstance(val, (bytes, str)) or (_PY2 and isinstance(val, unicode)): return _escape_strings(val) elif isinstance(val, (float, int, bool, NoneType)): @@ -1151,16 +1159,16 @@ def _idval(val, argname, idx, idfn): return val.__name__ return str(argname)+str(idx) -def _idvalset(idx, valset, argnames, idfn, ids): +def _idvalset(idx, valset, argnames, idfn, ids, config): if ids is None or ids[idx] is None: - this_id = [_idval(val, argname, idx, idfn) + this_id = [_idval(val, argname, idx, idfn, config) for val, argname in zip(valset, argnames)] return "-".join(this_id) else: return _escape_strings(ids[idx]) -def idmaker(argnames, argvalues, idfn=None, ids=None): - ids = [_idvalset(valindex, valset, argnames, idfn, ids) +def idmaker(argnames, argvalues, idfn=None, ids=None, config=None): + ids = [_idvalset(valindex, valset, argnames, idfn, ids, config) for valindex, valset in enumerate(argvalues)] if len(set(ids)) != len(ids): # The ids are not unique