From 15328c04eb8f6456e7a8162c2b324cfa7976711f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 15 Apr 2015 19:31:22 -0300 Subject: [PATCH 1/2] Handle inspect.getsourcelines failures in FixtureLookupError Fixes #553 --HG-- branch : getsourcelines-error-issue-553-pytest2.7 --- CHANGELOG | 5 +++++ _pytest/python.py | 19 ++++++++++++------- testing/acceptance_test.py | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 11445503c..03dcd2655 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ 2.7.1.dev (compared to 2.7.0) ----------------------------- +- fix issue553: properly handling inspect.getsourcelines failures in + FixtureLookupError which would lead to to an internal error, + obfuscating the original problem. Thanks talljosh for initial + diagnose/patch and Bruno Oliveira for final patch. + - fix issue660: properly report scope-mismatch-access errors independently from ordering of fixture arguments. Also avoid the pytest internal traceback which does not provide diff --git a/_pytest/python.py b/_pytest/python.py index 292054a0c..e0346a7aa 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1537,13 +1537,18 @@ class FixtureLookupError(LookupError): # it at the requesting side for function in stack: fspath, lineno = getfslineno(function) - lines, _ = inspect.getsourcelines(function) - addline("file %s, line %s" % (fspath, lineno+1)) - for i, line in enumerate(lines): - line = line.rstrip() - addline(" " + line) - if line.lstrip().startswith('def'): - break + try: + lines, _ = inspect.getsourcelines(function) + except IOError: + error_msg = "file %s, line %s: source code not available" + addline(error_msg % (fspath, lineno+1)) + else: + addline("file %s, line %s" % (fspath, lineno+1)) + for i, line in enumerate(lines): + line = line.rstrip() + addline(" " + line) + if line.lstrip().startswith('def'): + break if msg is None: fm = self.request._fixturemanager diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index f6bdf610a..614af6a3a 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -353,6 +353,23 @@ class TestGeneralUsage: *unrecognized* """) + def test_getsourcelines_error_issue553(self, testdir): + p = testdir.makepyfile(""" + def raise_error(obj): + raise IOError('source code not available') + + import inspect + inspect.getsourcelines = raise_error + + def test_foo(invalid_fixture): + pass + """) + res = testdir.runpytest(p) + res.stdout.fnmatch_lines([ + "*source code not available*", + "*fixture 'invalid_fixture' not found", + ]) + class TestInvocationVariants: def test_earlyinit(self, testdir):