Skip to content

When missing the method argument of teardown_method, getting INTERNALERROR  #1604

Closed
@guyzmo

Description

@guyzmo

Context: I'm using pytest 2.9.2, on Python 3.5, with a bunch of plugins (see outputs).

I have setup a tests module in my project with a test class similar to:

tests/test_project.py:

class TestProject:
    def setup_method(self, method): pass
    def teardown_method(self): pass # oops I forgot the method arg!

    def test_project(self):
        assert True

I ran it, and obtained the following traceback:

Test session starts (platform: linux, Python 3.5.1, pytest 2.9.2, pytest-sugar 0.7.1)
cachedir: .cache
rootdir: …, inifile:
plugins: cov-2.2.1, xdist-1.14, sugar-0.7.1, catchlog-1.2.2, datadir-ng-1.1.0

INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/main.py", line 94, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/main.py", line 125, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 724, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 338, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 333, in <lambda>
INTERNALERROR>     _MultiCall(methods, kwargs, hook.spec_opts).execute()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 596, in execute
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/main.py", line 150, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 724, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 338, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 333, in <lambda>
INTERNALERROR>     _MultiCall(methods, kwargs, hook.spec_opts).execute()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 595, in execute
INTERNALERROR>     return _wrapped_call(hook_impl.function(*args), self.execute)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 253, in _wrapped_call
INTERNALERROR>     return call_outcome.get_result()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 278, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 264, in __init__
INTERNALERROR>     self.result = func()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 596, in execute
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/runner.py", line 66, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/runner.py", line 78, in runtestprotocol
INTERNALERROR>     nextitem=nextitem))
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/runner.py", line 122, in call_and_report
INTERNALERROR>     report = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 724, in __call__
INTERNALERROR>     return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 338, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 333, in <lambda>
INTERNALERROR>     _MultiCall(methods, kwargs, hook.spec_opts).execute()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 595, in execute
INTERNALERROR>     return _wrapped_call(hook_impl.function(*args), self.execute)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 249, in _wrapped_call
INTERNALERROR>     wrap_controller.send(call_outcome)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/skipping.py", line 226, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 278, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 264, in __init__
INTERNALERROR>     self.result = func()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/vendored_packages/pluggy.py", line 596, in execute
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/runner.py", line 232, in pytest_runtest_makereport
INTERNALERROR>     style=item.config.option.tbstyle)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/python.py", line 745, in _repr_failure_py
INTERNALERROR>     style=style)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/main.py", line 408, in _repr_failure_py
INTERNALERROR>     style=style, tbfilter=tbfilter)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/_code/code.py", line 418, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/_code/code.py", line 599, in repr_excinfo
INTERNALERROR>     reprcrash = excinfo._getreprcrash()
INTERNALERROR>   File …/pytest-2.9.2-py3.5.egg/_pytest/_code/code.py", line 395, in _getreprcrash
INTERNALERROR>     entry = self.traceback.getcrashentry()
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/_code/code.py", line 314, in getcrashentry
INTERNALERROR>     return self[-1]
INTERNALERROR>   File "…/pytest-2.9.2-py3.5.egg/_pytest/_code/code.py", line 289, in __getitem__
INTERNALERROR>     val = super(Traceback, self).__getitem__(key)
INTERNALERROR> IndexError: list index out of range


Results (0.18s):
       1 passed

I ran the test again with --fulltraceback and had the traceback telling me that I'm wrong, with no issue (cf that gist).

After some discussion on #pylib with @RonnyPfannschmidt, we figured out it's definitely the traceback pruning that's at fault: the exception is thrown within pytest, so when pruning all pytest stuff, there's nothing left.

So as a solution we could do the following to avoid pruning if the last stack entry is from a file in the pytest lib:

at line 387 of _pytest/main.py:

    if self.config.option.fulltrace:
        style="long"
    else:
        if not 'pytest' in excinfo.tb.tb_frame.f_code.co_filename:
            self._prunetraceback(excinfo)
        tbfilter = False  # prunetraceback already does it
        if style == "auto":
            style = "long"

which will return the full stacktrace, as we're avoiding pruning it altogether. It's ok, but I'm not found of the test itself… it's a bit too Q&D.

or we could do the following version that prunes everything, showing only the last item of the stack, where there's useful information to debug:

at line 387 of _pytest/main.py:

    if self.config.option.fulltrace:
        style="long"
    else:
        from ._code.code import Traceback
        tb = Traceback([excinfo.traceback[-1]])
        self._prunetraceback(excinfo)
        if len(excinfo.traceback) == 0:
            excinfo.traceback = tb
        tbfilter = False  # prunetraceback already does it
        if style == "auto":
            style = "long"

which gives:

―――――――――――――――――――――――――――――――――――――――――――――――― ERROR at teardown of TestProject.test_project ―――――――――――――――――――――――――――――――――――――――――――――――――

>   self.addfinalizer(lambda: fin(self.obj))
E   TypeError: teardown_method() takes 1 positional argument but 2 were given

var/eggs/pytest-2.9.2-py3.5.egg/_pytest/python.py:716: TypeError
 tests/test_project.py   

I'd be happy to submit a PR for solving this… But I guess it needs some discussion on whether either of my suggestions are good to solve the issue or not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions