2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/4972758f9321/ Changeset: 4972758f9321 Branch: parametrize-hashable User: bubenkoff Date: 2013-12-03 21:05:19 Summary: implement index-based mechanizm for collection of parametrized tests Affected #: 3 files
diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r 4972758f932169015f6fe68168f26a8093357a70 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Unreleased ----------------------------------- +- fix issue244 by implementing special index for parameters to only use + indices for paramentrized test ids + - fix issue287 by running all finalizers but saving the exception from the first failing finalizer and re-raising it so teardown will still have failed. We reraise the first failing exception because diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r 4972758f932169015f6fe68168f26a8093357a70 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -594,12 +594,14 @@ self._globalparam = _notexists self._arg2scopenum = {} # used for sorting parametrized resources self.keywords = {} + self.indices = {} def copy(self, metafunc): cs = CallSpec2(self.metafunc) cs.funcargs.update(self.funcargs) cs.params.update(self.params) cs.keywords.update(self.keywords) + cs.indices.update(self.indices) cs._arg2scopenum.update(self._arg2scopenum) cs._idlist = list(self._idlist) cs._globalid = self._globalid @@ -623,7 +625,8 @@ def id(self): return "-".join(map(str, filter(None, self._idlist))) - def setmulti(self, valtype, argnames, valset, id, keywords, scopenum=0): + def setmulti(self, valtype, argnames, valset, id, keywords, scopenum, + param_index): for arg,val in zip(argnames, valset): self._checkargnotcontained(arg) getattr(self, valtype)[arg] = val @@ -631,6 +634,7 @@ # parametrize_sorted() which groups tests by params/scope if valtype == "funcargs": self.params[arg] = id + self.indices[arg] = param_index self._arg2scopenum[arg] = scopenum if val is _notexists: self._emptyparamspecified = True @@ -740,11 +744,12 @@ ids = idmaker(argnames, argvalues) newcalls = [] for callspec in self._calls or [CallSpec2(self)]: - for i, valset in enumerate(argvalues): + for param_index, valset in enumerate(argvalues): assert len(valset) == len(argnames) newcallspec = callspec.copy(self) - newcallspec.setmulti(valtype, argnames, valset, ids[i], - newkeywords.get(i, {}), scopenum) + newcallspec.setmulti(valtype, argnames, valset, ids[param_index], + newkeywords.get(param_index, {}), scopenum, + param_index) newcalls.append(newcallspec) self._calls = newcalls @@ -1862,19 +1867,19 @@ except AttributeError: return [] if scopenum == 0: - argparams = [x for x in cs.params.items() if x not in ignore + argparams = [x for x in cs.indices.items() if x not in ignore and cs._arg2scopenum[x[0]] == scopenum] elif scopenum == 1: # module argparams = [] - for argname, param in cs.params.items(): + for argname, valindex in cs.indices.items(): if cs._arg2scopenum[argname] == scopenum: - key = (argname, param, item.fspath) + key = (argname, valindex, item.fspath) if key in ignore: continue argparams.append(key) elif scopenum == 2: # class argparams = [] - for argname, param in cs.params.items(): + for argname, valindex in cs.indices.items(): if cs._arg2scopenum[argname] == scopenum: l = cache.setdefault(item.fspath, []) try: @@ -1882,13 +1887,13 @@ except ValueError: i = len(l) l.append(item.cls) - key = (argname, param, item.fspath, i) + key = (argname, valindex, item.fspath, i) if key in ignore: continue argparams.append(key) #elif scopenum == 3: # argparams = [] - # for argname, param in cs.params.items(): + # for argname, param in cs.indices.items(): # if cs._arg2scopenum[argname] == scopenum: # key = (argname, param, getfslineno(item.obj)) # if key in ignore: diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r 4972758f932169015f6fe68168f26a8093357a70 testing/python/collect.py --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -355,6 +355,35 @@ rec = testdir.inline_run() rec.assertoutcome(passed=2) + + def test_parametrize_with_non_hashable_values_indirect(self, testdir): + """Test parametrization with non-hashable values with indirect parametrization.""" + testdir.makepyfile(""" + archival_mapping = { + '1.0': {'tag': '1.0'}, + '1.2.2a1': {'tag': 'release-1.2.2a1'}, + } + + import pytest + + @pytest.fixture + def key(request): + return request.param + + @pytest.fixture + def value(request): + return request.param + + @pytest.mark.parametrize('key value'.split(), + archival_mapping.items(), indirect=True) + def test_archival_to_version(key, value): + assert key in archival_mapping + assert value == archival_mapping[key] + """) + rec = testdir.inline_run() + rec.assertoutcome(passed=2) + + def test_parametrize_with_mark(selfself, testdir): items = testdir.getitems(""" import pytest https://bitbucket.org/hpk42/pytest/commits/ef64b4405d0c/ Changeset: ef64b4405d0c User: hpk42 Date: 2013-12-03 21:07:15 Summary: Merged in paylogic/pytest/parametrize-hashable (pull request #89) implement index-based mechanizm for collection of parametrized tests Affected #: 3 files diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r ef64b4405d0caf4ba5bb390f591889b99be574a1 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Unreleased ----------------------------------- +- fix issue244 by implementing special index for parameters to only use + indices for paramentrized test ids + - fix issue287 by running all finalizers but saving the exception from the first failing finalizer and re-raising it so teardown will still have failed. We reraise the first failing exception because diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r ef64b4405d0caf4ba5bb390f591889b99be574a1 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -594,12 +594,14 @@ self._globalparam = _notexists self._arg2scopenum = {} # used for sorting parametrized resources self.keywords = {} + self.indices = {} def copy(self, metafunc): cs = CallSpec2(self.metafunc) cs.funcargs.update(self.funcargs) cs.params.update(self.params) cs.keywords.update(self.keywords) + cs.indices.update(self.indices) cs._arg2scopenum.update(self._arg2scopenum) cs._idlist = list(self._idlist) cs._globalid = self._globalid @@ -623,7 +625,8 @@ def id(self): return "-".join(map(str, filter(None, self._idlist))) - def setmulti(self, valtype, argnames, valset, id, keywords, scopenum=0): + def setmulti(self, valtype, argnames, valset, id, keywords, scopenum, + param_index): for arg,val in zip(argnames, valset): self._checkargnotcontained(arg) getattr(self, valtype)[arg] = val @@ -631,6 +634,7 @@ # parametrize_sorted() which groups tests by params/scope if valtype == "funcargs": self.params[arg] = id + self.indices[arg] = param_index self._arg2scopenum[arg] = scopenum if val is _notexists: self._emptyparamspecified = True @@ -740,11 +744,12 @@ ids = idmaker(argnames, argvalues) newcalls = [] for callspec in self._calls or [CallSpec2(self)]: - for i, valset in enumerate(argvalues): + for param_index, valset in enumerate(argvalues): assert len(valset) == len(argnames) newcallspec = callspec.copy(self) - newcallspec.setmulti(valtype, argnames, valset, ids[i], - newkeywords.get(i, {}), scopenum) + newcallspec.setmulti(valtype, argnames, valset, ids[param_index], + newkeywords.get(param_index, {}), scopenum, + param_index) newcalls.append(newcallspec) self._calls = newcalls @@ -1862,19 +1867,19 @@ except AttributeError: return [] if scopenum == 0: - argparams = [x for x in cs.params.items() if x not in ignore + argparams = [x for x in cs.indices.items() if x not in ignore and cs._arg2scopenum[x[0]] == scopenum] elif scopenum == 1: # module argparams = [] - for argname, param in cs.params.items(): + for argname, valindex in cs.indices.items(): if cs._arg2scopenum[argname] == scopenum: - key = (argname, param, item.fspath) + key = (argname, valindex, item.fspath) if key in ignore: continue argparams.append(key) elif scopenum == 2: # class argparams = [] - for argname, param in cs.params.items(): + for argname, valindex in cs.indices.items(): if cs._arg2scopenum[argname] == scopenum: l = cache.setdefault(item.fspath, []) try: @@ -1882,13 +1887,13 @@ except ValueError: i = len(l) l.append(item.cls) - key = (argname, param, item.fspath, i) + key = (argname, valindex, item.fspath, i) if key in ignore: continue argparams.append(key) #elif scopenum == 3: # argparams = [] - # for argname, param in cs.params.items(): + # for argname, param in cs.indices.items(): # if cs._arg2scopenum[argname] == scopenum: # key = (argname, param, getfslineno(item.obj)) # if key in ignore: diff -r a6837c60c2409e26e718c20a5e033842afe73a0f -r ef64b4405d0caf4ba5bb390f591889b99be574a1 testing/python/collect.py --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -355,6 +355,35 @@ rec = testdir.inline_run() rec.assertoutcome(passed=2) + + def test_parametrize_with_non_hashable_values_indirect(self, testdir): + """Test parametrization with non-hashable values with indirect parametrization.""" + testdir.makepyfile(""" + archival_mapping = { + '1.0': {'tag': '1.0'}, + '1.2.2a1': {'tag': 'release-1.2.2a1'}, + } + + import pytest + + @pytest.fixture + def key(request): + return request.param + + @pytest.fixture + def value(request): + return request.param + + @pytest.mark.parametrize('key value'.split(), + archival_mapping.items(), indirect=True) + def test_archival_to_version(key, value): + assert key in archival_mapping + assert value == archival_mapping[key] + """) + rec = testdir.inline_run() + rec.assertoutcome(passed=2) + + def test_parametrize_with_mark(selfself, testdir): items = testdir.getitems(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org https://mail.python.org/mailman/listinfo/pytest-commit