![]() | Ned Batchelder : Blog | Code | Text | Site Coverage.py v3.0b1 » Home : Blog : March 2009 |
Coverage.py v3.0b1Saturday 7 March 2009 I'm undertaking a significant overhaul of coverage.py, my Python code coverage measurement tool. The first release of it is ready: coverage.py v3.0b1. Changes include:
As you can see, very little has changed functionally since v2.85. So far this is a refactoring, reimplementation, and repackaging effort. The new code will be a much better foundation for more interesting changes in the future. This beta 1 release is so I can find out if I've screwed up anything so far or not. You can download the kit in one of two ways:
If you find a problem, you can file a bug on bitbucket.org, or send me an email. Discussion is welcome on the Testing In Python mailing list. | |
Comments
Hi Ned,
If you want, you can let Bitbucket take care of hosting the archives as well. It accepts tag/branch names, so this will work:
http://bitbucket.org/ned/coveragepy/get/coverage-3.0b1.tar.gz
You can also link to snapshots by entering 'tip.zip', etc.
Hi Ned, and many thanks for 'coverage'.
to be reported as uncovered, if you 'exclude' it usingI'm not very experienced in Python, but found two remarks to tell you:
1) The exclude configuration command excludes everything under a statement, in the tree sense. This is clearly stated in the docs, but say you don't want a line like
coverage.exclude('class')this class is then not analysed, which is not what I want.I found a slow workaround (which is enough for my needs):
tested_pth, stmts, _stmts_excl, stmts_not, coales = \ coverage.analysis2(sys.modules[testmod2mod(mod_name)]) # # This is my exclusion algo, because excluding statements with # coverage.exclude('my_regex') # excludes the whole code branch under it, not only the line. # stmts_not_cleaned = [] try: tested_file = open(tested_pth) except IOError: pass else: for line_idx, line in enumerate(tested_file): if line_idx + 1 in stmts_not: interesting = True for pattern in ['^ *class ', '^ *def ', '^ *import ', '^ *from ']: match = re.search(pattern, line) if match is not None: interesting = False break if interesting: stmts_not_cleaned.append(line_idx + 1) tested_file.close() stmts_not = stmts_not_cleaned coales = coverage.the_coverage.format_lines(stmts, stmts_not)So what do you think of excluding lines only instead of branches?2) My workaround needed to repack the not covered lines in the coalesced form. I found it could be nice to be able to access your function in an easier way than what I had to write:Thanks again!
@Grahack, it sounds like you want to define the class, then start coverage. Under this execution, the def Class line will be reported as unexecuted (as will the method definitions), but the contents will be reported as executed. I can see this would be awkward, but I'd rather not change the behavior of the exclude pragma. I find it much more useful in its present form.
Can you start coverage before importing the class definitions?
Oh, I didn't want you to change anything, and of course I didn't want you to break backward compatibility. Just maybe add an 'exclude_line' thing if you thought it could be useful (well, if so, it would have been already there I guess).
Ok, I understand now. I indeed thought it was weird that those lines were not marked as executed. In fact I build the test suite, then pass it to the test runner that starts/stops coverage for each tested module. Gonna see if I can start coverage before importing my modules without too much work, else I'll stick with my hacky hack until other problems arise (like speed of execution).
Thanks.
Add a comment: