4 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/24d0a5d5a75e/ Changeset: 24d0a5d5a75e User: hpk42 Date: 2013-12-09 07:07:47 Summary: backout allowing @pytest.fixture in front of pytest_funcarg__NAME functions. It was introduced because of pylint warnings and it's probably better to go for a pylint-pytest plugin that avoids also other warnings/issues. Affected #: 3 files
diff -r cb8469dd75ddbd0556e0b5454e81cef9b77bb47b -r 24d0a5d5a75eed225817178fb48fde78f9537854 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -122,9 +122,6 @@ - fix verbose reporting for @mock'd test functions -- allow @pytest.fixture marked pytest_funcarg__foo functions - so that pylint errors can be avoided. - Changes between 2.4.1 and 2.4.2 ----------------------------------- diff -r cb8469dd75ddbd0556e0b5454e81cef9b77bb47b -r 24d0a5d5a75eed225817178fb48fde78f9537854 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1654,9 +1654,8 @@ # magic globals with __getattr__ might have got us a wrong # fixture attribute continue - elif name.startswith(self._argprefix): - # let's allso fixture-marked pytest_funcarg__ prefixed functions - name = name[len(self._argprefix):] + else: + assert not name.startswith(self._argprefix) fixturedef = FixtureDef(self, nodeid, name, obj, marker.scope, marker.params, yieldctx=marker.yieldctx, diff -r cb8469dd75ddbd0556e0b5454e81cef9b77bb47b -r 24d0a5d5a75eed225817178fb48fde78f9537854 testing/python/integration.py --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -195,16 +195,3 @@ def test_pytestconfig_is_session_scoped(): from _pytest.python import pytestconfig assert pytestconfig._pytestfixturefunction.scope == "session" - -def test_funcarg_prefix_and_marker(testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture - def pytest_funcarg__foo(): - return 1 - - def test_hello(foo): - assert foo == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) https://bitbucket.org/hpk42/pytest/commits/b164af9ab582/ Changeset: b164af9ab582 User: hpk42 Date: 2013-12-09 08:14:39 Summary: speed up a test Affected #: 1 file diff -r 24d0a5d5a75eed225817178fb48fde78f9537854 -r b164af9ab582b7db2884d7edf9520ccfc4cc0d37 testing/test_core.py --- a/testing/test_core.py +++ b/testing/test_core.py @@ -340,10 +340,8 @@ assert hello == "world" assert 'hello' in py.test.__all__ """) - result = testdir.runpytest(p) - result.stdout.fnmatch_lines([ - "*1 passed*" - ]) + reprec = testdir.inline_run(p) + reprec.assertoutcome(passed=1) def test_do_option_postinitialize(self, testdir): config = testdir.parseconfigure() https://bitbucket.org/hpk42/pytest/commits/f5b569604b07/ Changeset: f5b569604b07 User: hpk42 Date: 2013-12-09 08:14:58 Summary: make bench.py accept an optional script name and add a slow "manyparam" test Affected #: 2 files diff -r b164af9ab582b7db2884d7edf9520ccfc4cc0d37 -r f5b569604b076759be36b9a57a623d1a9080178d bench/bench.py --- a/bench/bench.py +++ b/bench/bench.py @@ -1,9 +1,11 @@ +import sys if __name__ == '__main__': import cProfile import py import pstats - stats = cProfile.run('py.test.cmdline.main(["skip.py", ])', 'prof') + script = sys.argv[1] if len(sys.argv) > 1 else "empty.py" + stats = cProfile.run('py.test.cmdline.main([%r])' % script, 'prof') p = pstats.Stats("prof") p.strip_dirs() p.sort_stats('cumulative') diff -r b164af9ab582b7db2884d7edf9520ccfc4cc0d37 -r f5b569604b076759be36b9a57a623d1a9080178d bench/manyparam.py --- /dev/null +++ b/bench/manyparam.py @@ -0,0 +1,12 @@ + +import pytest + +@pytest.fixture(scope='module', params=range(966)) +def foo(request): + return request.param + +def test_it(foo): + pass +def test_it2(foo): + pass + https://bitbucket.org/hpk42/pytest/commits/0017064cd599/ Changeset: 0017064cd599 User: hpk42 Date: 2013-12-09 10:05:44 Summary: speed up reorder for large higher-than-function-scoped parametrizations Affected #: 1 file diff -r f5b569604b076759be36b9a57a623d1a9080178d -r 0017064cd59995049af1ea0b8ae166527cea9720 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1626,7 +1626,7 @@ def pytest_collection_modifyitems(self, items): # separate parametrized setups - items[:] = reorder_items(items, set(), 0) + items[:] = reorder_items(items) def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False): if nodeid is not NOTSET: @@ -1824,14 +1824,25 @@ # down to the lower scopes such as to minimize number of "high scope" # setups and teardowns -def reorder_items(items, ignore, scopenum): +def reorder_items(items): + argkeys_cache = {} + for scopenum in range(0, scopenum_function): + argkeys_cache[scopenum] = d = {} + for item in items: + keys = set(get_parametrized_fixture_keys(item, scopenum)) + if keys: + d[item] = keys + return reorder_items_atscope(items, set(), argkeys_cache, 0) + +def reorder_items_atscope(items, ignore, argkeys_cache, scopenum): if scopenum >= scopenum_function or len(items) < 3: return items items_done = [] while 1: items_before, items_same, items_other, newignore = \ - slice_items(items, ignore, scopenum) - items_before = reorder_items(items_before, ignore, scopenum+1) + slice_items(items, ignore, argkeys_cache[scopenum]) + items_before = reorder_items_atscope( + items_before, ignore, argkeys_cache,scopenum+1) if items_same is None: # nothing to reorder in this scope assert items_other is None @@ -1841,54 +1852,58 @@ ignore = newignore -def slice_items(items, ignore, scopenum): - # we pick the first item which uses a fixture instance in the requested scope - # and which we haven't seen yet. We slice the input items list into - # a list of items_nomatch, items_same and items_other - slicing_argkey = None - for i, item in enumerate(items): - argkeys = get_parametrized_fixture_keys(item, ignore, scopenum) - if slicing_argkey is None: - if argkeys: - slicing_argkey = argkeys.pop() - items_before = items[:i] - items_same = [item] - items_other = [] - continue - if slicing_argkey in argkeys: - items_same.append(item) - else: - items_other.append(item) - if slicing_argkey is None: - return items, None, None, None - newignore = ignore.copy() - newignore.add(slicing_argkey) - return (items_before, items_same, items_other, newignore) +def slice_items(items, ignore, scoped_argkeys_cache): + # we pick the first item which uses a fixture instance in the + # requested scope and which we haven't seen yet. We slice the input + # items list into a list of items_nomatch, items_same and + # items_other + if scoped_argkeys_cache: # do we need to do work at all? + it = iter(items) + # first find a slicing key + for i, item in enumerate(it): + argkeys = scoped_argkeys_cache.get(item) + if argkeys is not None: + argkeys = argkeys.difference(ignore) + if argkeys: # found a slicing key + slicing_argkey = argkeys.pop() + items_before = items[:i] + items_same = [item] + items_other = [] + # now slice the remainder of the list + for item in it: + argkeys = scoped_argkeys_cache.get(item) + if argkeys and slicing_argkey in argkeys and \ + slicing_argkey not in ignore: + items_same.append(item) + else: + items_other.append(item) + newignore = ignore.copy() + newignore.add(slicing_argkey) + return (items_before, items_same, items_other, newignore) + return items, None, None, None -def get_parametrized_fixture_keys(item, ignore, scopenum): +def get_parametrized_fixture_keys(item, scopenum): """ return list of keys for all parametrized arguments which match the specified scope. """ assert scopenum < scopenum_function # function - keys = set() try: cs = item.callspec except AttributeError: - return keys # no parametrization on this item - # cs.indictes.items() is random order of argnames but - # then again different functions (items) can change order of - # arguments so it doesn't matter much probably - for argname, param_index in cs.indices.items(): - if cs._arg2scopenum[argname] != scopenum: - continue - if scopenum == 0: # session - key = (argname, param_index) - elif scopenum == 1: # module - key = (argname, param_index, item.fspath) - elif scopenum == 2: # class - key = (argname, param_index, item.fspath, item.cls) - if key not in ignore: - keys.add(key) - return keys + pass + else: + # cs.indictes.items() is random order of argnames but + # then again different functions (items) can change order of + # arguments so it doesn't matter much probably + for argname, param_index in cs.indices.items(): + if cs._arg2scopenum[argname] != scopenum: + continue + if scopenum == 0: # session + key = (argname, param_index) + elif scopenum == 1: # module + key = (argname, param_index, item.fspath) + elif scopenum == 2: # class + key = (argname, param_index, item.fspath, item.cls) + yield key def xunitsetup(obj, name): 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