From 45693c28470f5a0e2c93d5ca6db130e2c27fdfaa Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sun, 19 Aug 2012 14:57:07 +0200 Subject: [PATCH 1/6] exchange the rawcode factory marker check with a more robust and specific instance check as advised by holger --- _pytest/python.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index 7dd356001..6e1841605 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1308,16 +1308,14 @@ class FuncargManager: obj = getattr(holderobj, name) if not callable(obj): continue - # to avoid breaking on magic global callables - # we explicitly check if we get a sane code object - # else having mock.call in the globals fails for example - code = py.code.getrawcode(obj) - if not inspect.iscode(code): - continue # resource factories either have a pytest_funcarg__ prefix # or are "funcarg" marked marker = getattr(obj, "_pytestfactory", None) if marker is not None: + if not isinstance(marker, FactoryMarker): + # magic globals with __getattr__ + # give us something thats wrong for that case + continue assert not name.startswith(self._argprefix) argname = name scope = marker.scope From 1318df4f5bc3f8118ed6a173e3d008bad4cb29f4 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Wed, 22 Aug 2012 19:49:50 +0200 Subject: [PATCH 2/6] add xfailing test for issue 179 --- testing/test_python.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/testing/test_python.py b/testing/test_python.py index c3cd5dfb1..3e949865e 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1664,6 +1664,24 @@ class TestFuncargFactory: "*2 passed*" ]) + @pytest.mark.xfail(reason="factorydef passed to tw.line") + def test_factory_uses_unknown_funcarg_error(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.factory(scope='session') + def arg1(missing): + return + + def test_missing(arg1): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*LookupError: no factory found for argument 'missing'" + ]) + + class TestResourceIntegrationFunctional: def test_parametrize_with_ids(self, testdir): From 503addbf09441677539c1c77914a94ab394c502a Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Wed, 22 Aug 2012 21:20:18 +0200 Subject: [PATCH 3/6] correctly have the test for issue #[C179 actually fail --- testing/test_python.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/testing/test_python.py b/testing/test_python.py index 3e949865e..a34a74191 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1668,12 +1668,16 @@ class TestFuncargFactory: def test_factory_uses_unknown_funcarg_error(self, testdir): testdir.makepyfile(""" import pytest - - @pytest.factory(scope='session') - def arg1(missing): + + @pytest.factory() + def fail(missing): return - def test_missing(arg1): + @pytest.factory() + def call_fail(fail): + return + + def test_missing(call_fail): pass """) result = testdir.runpytest() From e876ad9abd880086aab15d4ed1c877fdfa67dcf8 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Wed, 22 Aug 2012 21:43:42 +0200 Subject: [PATCH 4/6] fix issue 179 - propperly show the dependency chain of factories on setup failure --- CHANGELOG | 2 ++ _pytest/python.py | 10 ++++++++-- testing/test_python.py | 8 +++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 78c7e4f25..629e99199 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -35,6 +35,8 @@ Changes between 2.2.4 and 2.3.0.dev - fix issue128: show captured output when capsys/capfd are used +- fix issue179: propperly show the dependency chain of factories + - pluginmanager.register(...) now raises ValueError if the plugin has been already registered or the name is taken diff --git a/_pytest/python.py b/_pytest/python.py index 6e1841605..c67cafbdf 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1211,8 +1211,14 @@ class FuncargLookupErrorRepr(TerminalRepr): def toterminal(self, tw): tw.line() - for line in self.factblines or []: - tw.line(line) + if self.factblines: + tw.line(' dependency of:') + for factorydef in self.factblines: + tw.line(' %s in %s' % ( + factorydef.argname, + factorydef.baseid, + )) + tw.line() for line in self.deflines: tw.line(" " + line.strip()) for line in self.errorstring.split("\n"): diff --git a/testing/test_python.py b/testing/test_python.py index a34a74191..c97810514 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1664,8 +1664,7 @@ class TestFuncargFactory: "*2 passed*" ]) - @pytest.mark.xfail(reason="factorydef passed to tw.line") - def test_factory_uses_unknown_funcarg_error(self, testdir): + def test_factory_uses_unknown_funcarg_as_dependency_error(self, testdir): testdir.makepyfile(""" import pytest @@ -1682,7 +1681,10 @@ class TestFuncargFactory: """) result = testdir.runpytest() result.stdout.fnmatch_lines([ - "*LookupError: no factory found for argument 'missing'" + "*dependency of:*", + "*call_fail*", + "*def fail(*", + "*LookupError: no factory found for argument 'missing'", ]) From 7f36649763bec2cbfec3d27043f67e03f3a261fe Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 28 Aug 2012 16:35:06 -0400 Subject: [PATCH 5/6] remove usage of exception module, which is gone in py3.3 --- _pytest/python.py | 2 +- testing/test_python.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index c67cafbdf..edb61a457 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -781,7 +781,7 @@ def raises(ExpectedException, *args, **kwargs): # we want to catch a AssertionError # replace our subclass with the builtin one # see https://bitbucket.org/hpk42/pytest/issue/176/pytestraises - from exceptions import AssertionError as ExpectedException + from _pytest.assertion.util import BuiltinAssertionError as ExpectedException if not args: return RaisesContext(ExpectedException) diff --git a/testing/test_python.py b/testing/test_python.py index c97810514..9960fe700 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1422,9 +1422,9 @@ class TestRaises: def test_raises_flip_builtin_AssertionError(self): # we replace AssertionError on python level # however c code might still raise the builtin one - import exceptions + from _pytest.assertion.util import BuiltinAssertionError pytest.raises(AssertionError,""" - raise exceptions.AssertionError + raise BuiltinAssertionError """) @pytest.mark.skipif('sys.version < "2.5"') From a6060dfb6d40e1727ba040acf591233a2c88df54 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 28 Aug 2012 16:37:43 -0400 Subject: [PATCH 6/6] use py3 compatible print syntax --- testing/test_junitxml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 5c30487d0..0e12b74d6 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -162,7 +162,7 @@ class TestPython: import pytest @pytest.mark.parametrize('arg1', "<&'", ids="<&'") def test_func(arg1): - print arg1 + print(arg1) assert 0 """) result, dom = runandparse(testdir)