nedbat/coveragepy

who-tests-what issues with old style classes in PY2

fersarr opened this issue · 1 comments

who-tests-what seems to have issues with old-style classes when running under Python 2.7. Not sure if this still matters to many people but it does produce issues for us.

Given the following dummy test file test_file_1.py:


class TestClass():

    def test_basic(self):
        print('bla')

I get failures when running under PY2 when the class does not inherit from object (making it old-style). As soon as I make it inherit from object, it works. It also works if I use Python 3.6.5.

$ py.test --cov=. test_file_1.py
...

=============================================================================================================================================================================== FAILURES ================================================================================================================================================================================
_________________________________________________________________________________________________________________________________________________________________________ TestClass.test_basic __________________________________________________________________________________________________________________________________________________________________________

frame = <frame object at 0x7f8cf0a95050>

    def should_start_context_test_function(frame):
        """Is this frame calling a test_* function?"""
        if frame.f_code.co_name.startswith("test"):
>           return qualname_from_frame(frame)

../../../path/coverage-5.0a4-py2.7-linux-x86_64.egg/coverage/context.py:9:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

frame = <frame object at 0x7f8cf0a95050>

    def qualname_from_frame(frame):
        """Get a qualified name for the code running in `frame`."""
        co = frame.f_code
        fname = co.co_name
        if not co.co_varnames:
            return fname

        first_arg = co.co_varnames[0]
        if co.co_argcount and first_arg == "self":
            self = frame.f_locals["self"]
        else:
            return fname

        method = getattr(self, fname, None)
        if method is None:
            return fname

        func = getattr(method, '__func__', None)
        if func is None:
            return fname

        if hasattr(func, '__qualname__'):
            qname = func.__qualname__
        else:
>           for cls in self.__class__.__mro__:
E           AttributeError: class TestClass has no attribute '__mro__'

../../../path/coverage-5.0a4-py2.7-linux-x86_64.egg/coverage/context.py:37: AttributeError

========================================================================================================================================================================== 0 tests deselected ===========================================================================================================================================================================
================================================================================================================================================================= 1 failed, 1 warnings in 0.35 seconds =

My .coveragerc is:

[run]
dynamic_context = test_function

Environment:

Python 2.7.13
coverage 5.0a4

This is fixed in 792e2fc, though only the function name (not the defining class) is reported, since we don't have an MRO to look through.