Discussion:
[PEAK] Conflict between PEAK and coverage.py
Bobby Impollonia
2011-03-13 00:20:23 UTC
Permalink
Hi.
I am trying to measure code coverage for a project using coverage.py.
The project relies on DecoratorTools and PEAK-Rules via Turbogears.

With DecoratorTools 1.8, the coverage report always comes back as 0%
due to a known problem where DecoratorTools removes coverage's tracing
function. This is fixed in the development version of DecoratorTools
which uses sys.gettrace() on Python 2.6+ to find and restore existing
tracing functions.

However, with the current development versions of DecoratorTools and
PEAK-Rules, I now receive an error importing PEAK-Rules when (and only
when) running under coverage.py.

The error is:
TypeError: unbound method make_decorator() must be called with Method
instance as first argument (got str instance instead)

It originates from line 296 of peak.rules.core:
when = Method.make_decorator(
"when", "Extend a generic function with a new action"
)

You can reproduce the problem with the following steps using Python 2.6:
virtualenv --no-site-packages myenv
cd myenv
. bin/activate
pip install ez_setup coverage distribute==0.6.14
pip install http://svn.eby-sarna.com/DecoratorTools.tar.gz?view=tar
pip install http://svn.eby-sarna.com/PEAK-Rules.tar.gz?view=tar
echo '#!/usr/bin/env python' > mytest.py
echo 'import peak.rules' >> mytest.py
chmod +x mytest.py
./mytest.py # this succeeds
coverage run ./mytest.py # this throws the exception
P.J. Eby
2011-03-18 19:59:58 UTC
Permalink
Post by Bobby Impollonia
TypeError: unbound method make_decorator() must be called with Method
instance as first argument (got str instance instead)
when = Method.make_decorator(
"when", "Extend a generic function with a new action"
)
The real error here is occurring earlier, when make_decorator isn't
getting made into a classmethod. So, it would appear that something
in coverage's trace function is disabling DecoratorTools' trace
function, or at any rate stopping it from getting called.
Post by Bobby Impollonia
coverage run ./mytest.py # this throws the exception
Have you tried the --timid option? Coverage's internal docs suggest
that this is required when working with DecoratorTools.
Bobby Impollonia
2011-03-22 22:14:07 UTC
Permalink
The real error here is occurring earlier, when make_decorator isn't getting
made into a classmethod.
Thanks for explanation. You are right as I can recreate the problem
without Peak Rules using the following test program:
from peak.util.decorators import decorate

class MyClass(object):
decorate(classmethod)
def myclassmethod(cls):
return cls.__name__

if __name__ == '__main__':
print MyClass().myclassmethod() # throws exception under coverage
So, it would appear that something in coverage's
trace function is disabling DecoratorTools' trace function, or at any rate
stopping it from getting called.
So is this likely a bug in coverage?
Have you tried the --timid option? ?Coverage's internal docs suggest that
this is required when working with DecoratorTools.
It works correctly with --timid. It's somewhat inconvenient because it
makes the tests run several times slower and nose's coverage plugin
doesn't expose that option.
P.J. Eby
2011-03-22 23:18:55 UTC
Permalink
Post by Bobby Impollonia
It works correctly with --timid. It's somewhat inconvenient because it
makes the tests run several times slower and nose's coverage plugin
doesn't expose that option.
If you can get the coverage developers to tell me what DecoratorTools
is doing wrong, exactly, I can try to fix it.

At the moment, DecoratorTools does use sys.get_trace() if available,
and some of the problems it had (in previous versions) have been
fixed (where it was assuming global/local functions were the
same). But, without the "--timid" option, coverage is using a
C-level trace function, and I have no idea how those interact with
the Python-level tracing support.
Bobby Impollonia
2011-03-23 00:21:22 UTC
Permalink
Post by Bobby Impollonia
It works correctly with --timid. It's somewhat inconvenient because it
makes the tests run several times slower and nose's coverage plugin
doesn't expose that option.
If you can get the coverage developers to tell me what DecoratorTools is
doing wrong, exactly, I can try to fix it.
I added a coverage bug to track the issue and maybe get some eyes on
it from that side:
https://bitbucket.org/ned/coveragepy/issue/125/coverage-removes-decoratortoolss-tracing
Loading...