commit python-coverage for openSUSE:Factory
![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package python-coverage for openSUSE:Factory checked in at 2012-11-28 14:32:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-coverage (Old) and /work/SRC/openSUSE:Factory/.python-coverage.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-coverage", Maintainer is "CThiel@suse.com" Changes: -------- --- /work/SRC/openSUSE:Factory/python-coverage/python-coverage.changes 2012-05-29 10:35:15.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-coverage.new/python-coverage.changes 2012-11-28 14:32:52.000000000 +0100 @@ -1,0 +2,48 @@ +Tue Nov 20 18:15:53 UTC 2012 - saschpe@suse.de + +- Update to version 3.5.3: + + Line numbers in the HTML report line up better with the source lines, fixing + issue 197 + + When specifying a directory as the source= option, the directory itself no + longer needs to have a __init__.py file, though its subdirectories do, to + be considered as source files. + + Files encoded as UTF-8 with a BOM are now properly handled, fixing + issue 179_. + + Fixed more cases of non-Python files being reported as Python source, and + then not being able to parse them as Python. Closes issue 82 (again). + + Fixed memory leaks under Python 3, thanks, Brett Cannon. Closes issue 147_. + + Optimized .pyo files may not have been handled correctly, issue 195_. + + Certain unusually named file paths could have been mangled during reporting, + issue 194_. + + Try to do a better job of the impossible task of detecting when we can't + build the C extension, fixing issue 183_. + + Testing is now done with tox +- Changes from version 3.5.2: + + No changes since 3.5.2.b1 +- Changes from version 3.5.2b1 + + The HTML report has slightly tweaked controls: the buttons at the top of + the page are color-coded to the source lines they affect. + + Custom CSS can be applied to the HTML report by specifying a CSS file as + the extra_css configuration value in the [html] section. + + Source files with custom encodings declared in a comment at the top are now + properly handled during reporting on Python 2. Python 3 always handled them + properly. This fixes issue 157_. + + Backup files left behind by editors are no longer collected by the source= + option, fixing issue 168_. + + If a file doesn't parse properly as Python, we don't report it as an error + if the filename seems like maybe it wasn't meant to be Python. This is a + pragmatic fix for issue 82_. + + The -m switch on coverage report, which includes missing line numbers + in the summary report, can now be specifed as show_missing in the + config file. Closes issue 173_. + + When running a module with coverage run -m <modulename>, certain details + of the execution environment weren't the same as for + python -m <modulename>. This had the unfortunate side-effect of making + coverage run -m unittest discover not work if you had tests in a + directory named "test". This fixes issue 155_. + + Now the exit status of your product code is properly used as the process + status when running python -m coverage run .... Thanks, JT Olds. + + When installing into pypy, we no longer attempt (and fail) to compile + the C tracer function, closing issue 166_. + +------------------------------------------------------------------- --- /work/SRC/openSUSE:Factory/python-coverage/python3-coverage.changes 2012-09-11 09:15:35.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-coverage.new/python3-coverage.changes 2012-11-28 14:32:52.000000000 +0100 @@ -1,0 +2,50 @@ +Tue Nov 20 18:18:25 UTC 2012 - saschpe@suse.de + +- Update to version 3.5.3: + + Line numbers in the HTML report line up better with the source lines, fixing + issue 197 + + When specifying a directory as the source= option, the directory itself no + longer needs to have a __init__.py file, though its subdirectories do, to + be considered as source files. + + Files encoded as UTF-8 with a BOM are now properly handled, fixing + issue 179_. + + Fixed more cases of non-Python files being reported as Python source, and + then not being able to parse them as Python. Closes issue 82 (again). + + Fixed memory leaks under Python 3, thanks, Brett Cannon. Closes issue 147_. + + Optimized .pyo files may not have been handled correctly, issue 195_. + + Certain unusually named file paths could have been mangled during reporting, + issue 194_. + + Try to do a better job of the impossible task of detecting when we can't + build the C extension, fixing issue 183_. + + Testing is now done with tox +- Changes from version 3.5.2: + + No changes since 3.5.2.b1 +- Changes from version 3.5.2b1 + + The HTML report has slightly tweaked controls: the buttons at the top of + the page are color-coded to the source lines they affect. + + Custom CSS can be applied to the HTML report by specifying a CSS file as + the extra_css configuration value in the [html] section. + + Source files with custom encodings declared in a comment at the top are now + properly handled during reporting on Python 2. Python 3 always handled them + properly. This fixes issue 157_. + + Backup files left behind by editors are no longer collected by the source= + option, fixing issue 168_. + + If a file doesn't parse properly as Python, we don't report it as an error + if the filename seems like maybe it wasn't meant to be Python. This is a + pragmatic fix for issue 82_. + + The -m switch on coverage report, which includes missing line numbers + in the summary report, can now be specifed as show_missing in the + config file. Closes issue 173_. + + When running a module with coverage run -m <modulename>, certain details + of the execution environment weren't the same as for + python -m <modulename>. This had the unfortunate side-effect of making + coverage run -m unittest discover not work if you had tests in a + directory named "test". This fixes issue 155_. + + Now the exit status of your product code is properly used as the process + status when running python -m coverage run .... Thanks, JT Olds. + + When installing into pypy, we no longer attempt (and fail) to compile + the C tracer function, closing issue 166_. +- Name Python3 binaries consistently: + + Fix in setup.py to have correct egg-info data + +------------------------------------------------------------------- Old: ---- coverage-3.5.1.tar.gz New: ---- coverage-3.5.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-coverage.spec ++++++ --- /var/tmp/diff_new_pack.VrjxtW/_old 2012-11-28 14:32:53.000000000 +0100 +++ /var/tmp/diff_new_pack.VrjxtW/_new 2012-11-28 14:32:53.000000000 +0100 @@ -17,7 +17,7 @@ Name: python-coverage -Version: 3.5.1 +Version: 3.5.3 Release: 0 Url: http://nedbatchelder.com/code/coverage/%{version} Summary: Code coverage measurement for Python ++++++ python3-coverage.spec ++++++ --- /var/tmp/diff_new_pack.VrjxtW/_old 2012-11-28 14:32:53.000000000 +0100 +++ /var/tmp/diff_new_pack.VrjxtW/_new 2012-11-28 14:32:53.000000000 +0100 @@ -17,7 +17,7 @@ Name: python3-coverage -Version: 3.5.1 +Version: 3.5.3 Release: 0 Url: http://nedbatchelder.com/code/coverage/%{version} Summary: Code coverage measurement for Python @@ -26,19 +26,13 @@ Source: http://pypi.python.org/packages/source/c/coverage/coverage-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: python3 +BuildRequires: python3-2to3 BuildRequires: python3-devel BuildRequires: python3-distribute BuildRequires: python3-xml -BuildRequires: python3-2to3 Requires: python3-distribute Requires: python3-xml -%if 0%{?suse_version} <= 1140 -%{!?python3_sitearch: %global python3_sitearch %(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} -%{!?py3_ver: %global py3_ver %(python3 -c "import sys; version=str(sys.version_info[0]) + '.' + str(sys.version_info[1]); print(version)")} -%endif -Requires: python(abi) = %{py3_ver} - %description Coverage.py measures code coverage, typically during test execution. It uses the code analysis tools and tracing hooks provided in the Python standard @@ -46,6 +40,7 @@ %prep %setup -q -n coverage-%{version} +sed -i "s|coverage =|coverage-%{py3_ver} =|" setup.py # Add Python version suffix to binaries %build 2to3 --nobackups --write . @@ -53,12 +48,11 @@ %install python3 setup.py install --prefix=%{_prefix} --root=%{buildroot} -mv %{buildroot}%{_bindir}/coverage %{buildroot}%{_bindir}/coverage-python%{py3_ver} %files %defattr(-,root,root,-) %doc AUTHORS.txt CHANGES.txt README.txt -%{_bindir}/coverage-python%{py3_ver} +%{_bindir}/coverage-%{py3_ver} %{python3_sitearch}/coverage %{python3_sitearch}/coverage-%{version}-py%{py3_ver}.egg-info ++++++ coverage-3.5.1.tar.gz -> coverage-3.5.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/AUTHORS.txt new/coverage-3.5.3/AUTHORS.txt --- old/coverage-3.5.1/AUTHORS.txt 2011-04-27 16:20:35.000000000 +0200 +++ new/coverage-3.5.3/AUTHORS.txt 2012-08-08 03:29:29.000000000 +0200 @@ -3,10 +3,13 @@ Other contributions have been made by: +Marc Abramowitz Chris Adams Geoff Bache +Julian Berman Titus Brown Brett Cannon +Pablo Carballo Guillaume Chazarain David Christian Danek Duvall @@ -22,6 +25,8 @@ Patrick Mezard Noel O'Boyle Detlev Offenbach +JT Olds +George Paci Catherine Proulx Brandon Rhodes Adi Roiban diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/CHANGES.txt new/coverage-3.5.3/CHANGES.txt --- old/coverage-3.5.1/CHANGES.txt 2011-09-23 14:12:53.000000000 +0200 +++ new/coverage-3.5.3/CHANGES.txt 2012-09-29 15:34:37.000000000 +0200 @@ -2,6 +2,96 @@ Change history for Coverage.py ------------------------------ +Version 3.5.3 --- 29 September 2012 +----------------------------------- + +- Line numbers in the HTML report line up better with the source lines, fixing + `issue 197`, thanks Marius Gedminas. + +- When specifying a directory as the source= option, the directory itself no + longer needs to have a ``__init__.py`` file, though its subdirectories do, to + be considered as source files. + +- Files encoded as UTF-8 with a BOM are now properly handled, fixing + `issue 179`_. Thanks, Pablo Carballo. + +- Fixed more cases of non-Python files being reported as Python source, and + then not being able to parse them as Python. Closes `issue 82` (again). + Thanks, Julian Berman. + +- Fixed memory leaks under Python 3, thanks, Brett Cannon. Closes `issue 147`_. + +- Optimized .pyo files may not have been handled correctly, `issue 195`_. + Thanks, Marius Gedminas. + +- Certain unusually named file paths could have been mangled during reporting, + `issue 194`_. Thanks, Marius Gedminas. + +- Try to do a better job of the impossible task of detecting when we can't + build the C extension, fixing `issue 183`_. + +- Testing is now done with `tox`_, thanks, Marc Abramowitz. + +.. _issue 82: https://bitbucket.org/ned/coveragepy/issue/82/tokenerror-when-generating-htm... +.. _issue 147: https://bitbucket.org/ned/coveragepy/issue/147/massive-memory-usage-by-ctrac... +.. _issue 179: https://bitbucket.org/ned/coveragepy/issue/179/htmlreporter-fails-when-sourc... +.. _issue 183: https://bitbucket.org/ned/coveragepy/issue/183/install-fails-for-python-23 +.. _issue 194: https://bitbucket.org/ned/coveragepy/issue/194/filelocatorrelative_filename-... +.. _issue 195: https://bitbucket.org/ned/coveragepy/issue/195/pyo-file-handling-in-codeunit +.. _issue 197: https://bitbucket.org/ned/coveragepy/issue/197/line-numbers-in-html-report-d... +.. _tox: http://tox.readthedocs.org/ + + + +Version 3.5.2 --- 4 May 2012 +---------------------------- + +No changes since 3.5.2.b1 + + +Version 3.5.2b1 --- 29 April 2012 +--------------------------------- + +- The HTML report has slightly tweaked controls: the buttons at the top of + the page are color-coded to the source lines they affect. + +- Custom CSS can be applied to the HTML report by specifying a CSS file as + the extra_css configuration value in the [html] section. + +- Source files with custom encodings declared in a comment at the top are now + properly handled during reporting on Python 2. Python 3 always handled them + properly. This fixes `issue 157`_. + +- Backup files left behind by editors are no longer collected by the source= + option, fixing `issue 168`_. + +- If a file doesn't parse properly as Python, we don't report it as an error + if the filename seems like maybe it wasn't meant to be Python. This is a + pragmatic fix for `issue 82`_. + +- The ``-m`` switch on ``coverage report``, which includes missing line numbers + in the summary report, can now be specifed as ``show_missing`` in the + config file. Closes `issue 173`_. + +- When running a module with ``coverage run -m <modulename>``, certain details + of the execution environment weren't the same as for + ``python -m <modulename>``. This had the unfortunate side-effect of making + ``coverage run -m unittest discover`` not work if you had tests in a + directory named "test". This fixes `issue 155`_. + +- Now the exit status of your product code is properly used as the process + status when running ``python -m coverage run ...``. Thanks, JT Olds. + +- When installing into pypy, we no longer attempt (and fail) to compile + the C tracer function, closing `issue 166`_. + +.. _issue 82: https://bitbucket.org/ned/coveragepy/issue/82/tokenerror-when-generating-htm... +.. _issue 155: https://bitbucket.org/ned/coveragepy/issue/155/cant-use-coverage-run-m-unitt... +.. _issue 157: https://bitbucket.org/ned/coveragepy/issue/157/chokes-on-source-files-with-n... +.. _issue 166: https://bitbucket.org/ned/coveragepy/issue/166/dont-try-to-compile-c-extensi... +.. _issue 168: https://bitbucket.org/ned/coveragepy/issue/168/dont-be-alarmed-by-emacs-drop... +.. _issue 173: https://bitbucket.org/ned/coveragepy/issue/173/theres-no-way-to-specify-show... + Version 3.5.1 --- 23 September 2011 ----------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/PKG-INFO new/coverage-3.5.3/PKG-INFO --- old/coverage-3.5.1/PKG-INFO 2011-09-23 14:26:51.000000000 +0200 +++ new/coverage-3.5.3/PKG-INFO 2012-09-30 04:31:20.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: coverage -Version: 3.5.1 +Version: 3.5.3 Summary: Code coverage measurement for Python Home-page: http://nedbatchelder.com/code/coverage Author: Ned Batchelder and others @@ -10,7 +10,7 @@ the code analysis tools and tracing hooks provided in the Python standard library to determine which lines are executable, and which have been executed. - Coverage.py runs on Pythons 2.3 through 3.2. + Coverage.py runs on Pythons 2.3 through 3.3, and PyPy 1.8. Documentation is at `nedbatchelder.com <http://nedbatchelder.com/code/coverage>`_. Code repository and issue tracker are at `bitbucket.org <http://bitbucket.org/ned/coveragepy>`_. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/__init__.py new/coverage-3.5.3/coverage/__init__.py --- old/coverage-3.5.1/coverage/__init__.py 2011-09-23 14:12:13.000000000 +0200 +++ new/coverage-3.5.3/coverage/__init__.py 2012-09-29 15:29:38.000000000 +0200 @@ -5,7 +5,7 @@ """ -__version__ = "3.5.1" # see detailed history in CHANGES.txt +__version__ = "3.5.3" # see detailed history in CHANGES.txt __url__ = "http://nedbatchelder.com/code/coverage" if max(__version__).isalpha(): @@ -60,7 +60,7 @@ # COPYRIGHT AND LICENSE # # Copyright 2001 Gareth Rees. All rights reserved. -# Copyright 2004-2010 Ned Batchelder. All rights reserved. +# Copyright 2004-2012 Ned Batchelder. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/__main__.py new/coverage-3.5.3/coverage/__main__.py --- old/coverage-3.5.1/coverage/__main__.py 2010-09-02 04:14:33.000000000 +0200 +++ new/coverage-3.5.3/coverage/__main__.py 2012-02-16 04:52:00.000000000 +0100 @@ -1,3 +1,4 @@ """Coverage.py's main entrypoint.""" +import sys from coverage.cmdline import main -main() +sys.exit(main()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/annotate.py new/coverage-3.5.3/coverage/annotate.py --- old/coverage-3.5.1/coverage/annotate.py 2010-09-03 02:47:10.000000000 +0200 +++ new/coverage-3.5.3/coverage/annotate.py 2012-04-20 19:26:17.000000000 +0200 @@ -26,20 +26,20 @@ """ - def __init__(self, coverage, ignore_errors=False): - super(AnnotateReporter, self).__init__(coverage, ignore_errors) + def __init__(self, coverage, config): + super(AnnotateReporter, self).__init__(coverage, config) self.directory = None blank_re = re.compile(r"\s*(#|$)") else_re = re.compile(r"\s*else\s*:\s*(#|$)") - def report(self, morfs, config, directory=None): + def report(self, morfs, directory=None): """Run the report. See `coverage.report()` for arguments. """ - self.report_files(self.annotate_file, morfs, config, directory) + self.report_files(self.annotate_file, morfs, directory) def annotate_file(self, cu, analysis): """Annotate a single file. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/backward.py new/coverage-3.5.3/coverage/backward.py --- old/coverage-3.5.1/coverage/backward.py 2011-08-28 21:09:56.000000000 +0200 +++ new/coverage-3.5.3/coverage/backward.py 2012-04-14 00:29:54.000000000 +0200 @@ -6,7 +6,7 @@ # W0611: Unused import blah # W0622: Redefining built-in blah -import os, sys +import os, re, sys # Python 2.3 doesn't have `set` try: @@ -72,19 +72,15 @@ except ImportError: import ConfigParser as configparser -# Python 3.2 provides `tokenize.open`, the best way to open source files. -import tokenize -try: - open_source = tokenize.open # pylint: disable=E1101 -except AttributeError: +# Reading Python source and interpreting the coding comment is a big deal. +if sys.version_info >= (3, 0): + # Python 3.2 provides `tokenize.open`, the best way to open source files. + import tokenize try: - detect_encoding = tokenize.detect_encoding # pylint: disable=E1101 + open_source = tokenize.open # pylint: disable=E1101 except AttributeError: - def open_source(fname): - """Open a source file the best way.""" - return open(fname, "rU") - else: from io import TextIOWrapper + detect_encoding = tokenize.detect_encoding # pylint: disable=E1101 # Copied from the 3.2 stdlib: def open_source(fname): """Open a file in read only mode using the encoding detected by @@ -96,6 +92,11 @@ text = TextIOWrapper(buffer, encoding, line_buffering=True) text.mode = 'r' return text +else: + def open_source(fname): + """Open a source file the best way.""" + return open(fname, "rU") + # Python 3.x is picky about bytes and strings, so provide methods to # get them right, and make them no-ops in 2.x @@ -117,27 +118,6 @@ """Convert bytes `b` to a string (no-op in 2.x).""" return b -# A few details about writing encoded text are different in 2.x and 3.x. -if sys.version_info >= (3, 0): - def write_encoded(fname, text, encoding='utf8', errors='strict'): - '''Write string `text` to file names `fname`, with encoding.''' - # Don't use "with", so that this file is still good for old 2.x. - f = open(fname, 'w', encoding=encoding, errors=errors) - try: - f.write(text) - finally: - f.close() -else: - # It's not clear that using utf8 strings in 2.x is the right thing to do. - def write_encoded(fname, text, encoding='utf8', errors='strict'): - '''Write utf8 string `text` to file names `fname`, with encoding.''' - import codecs - f = codecs.open(fname, 'w', encoding=encoding, errors=errors) - try: - f.write(text.decode('utf8')) - finally: - f.close() - # Md5 is available in different places. try: import hashlib diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/codeunit.py new/coverage-3.5.3/coverage/codeunit.py --- old/coverage-3.5.1/coverage/codeunit.py 2011-02-05 05:20:13.000000000 +0100 +++ new/coverage-3.5.3/coverage/codeunit.py 2012-09-10 02:05:08.000000000 +0200 @@ -52,7 +52,7 @@ else: f = morf # .pyc files should always refer to a .py instead. - if f.endswith('.pyc'): + if f.endswith('.pyc') or f.endswith('.pyo'): f = f[:-1] self.filename = self.file_locator.canonical_filename(f) @@ -115,3 +115,23 @@ raise CoverageException( "No source for code %r." % self.filename ) + + def should_be_python(self): + """Does it seem like this file should contain Python? + + This is used to decide if a file reported as part of the exection of + a program was really likely to have contained Python in the first + place. + + """ + # Get the file extension. + _, ext = os.path.splitext(self.filename) + + # Anything named *.py* should be Python. + if ext.startswith('.py'): + return True + # A file with no extension should be Python. + if not ext: + return True + # Everything else is probably not Python. + return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/collector.py new/coverage-3.5.3/coverage/collector.py --- old/coverage-3.5.1/coverage/collector.py 2011-09-04 03:33:45.000000000 +0200 +++ new/coverage-3.5.3/coverage/collector.py 2012-08-31 05:21:08.000000000 +0200 @@ -1,12 +1,23 @@ """Raw data collector for Coverage.""" -import sys, threading +import os, sys, threading try: # Use the C extension code when we can, for speed. from coverage.tracer import CTracer except ImportError: # Couldn't import the C extension, maybe it isn't built. + if os.getenv('COVERAGE_TEST_TRACER') == 'c': + # During testing, we use the COVERAGE_TEST_TRACER env var to indicate + # that we've fiddled with the environment to test this fallback code. + # If we thought we had a C tracer, but couldn't import it, then exit + # quickly and clearly instead of dribbling confusing errors. I'm using + # sys.exit here instead of an exception because an exception here + # causes all sorts of other noise in unittest. + sys.stderr.write( + "*** COVERAGE_TEST_TRACER is 'c' but can't import CTracer!\n" + ) + sys.exit(1) CTracer = None @@ -45,7 +56,8 @@ """The trace function passed to sys.settrace.""" #print("trace event: %s %r @%d" % ( - # event, frame.f_code.co_filename, frame.f_lineno)) + # event, frame.f_code.co_filename, frame.f_lineno), + # file=sys.stderr) if self.last_exc_back: if frame == self.last_exc_back: @@ -232,10 +244,10 @@ if self._collectors: self._collectors[-1].pause() self._collectors.append(self) - #print >>sys.stderr, "Started: %r" % self._collectors + #print("Started: %r" % self._collectors, file=sys.stderr) # Check to see whether we had a fullcoverage tracer installed. - traces0 = None + traces0 = [] if hasattr(sys, "gettrace"): fn0 = sys.gettrace() if fn0: @@ -246,10 +258,14 @@ # Install the tracer on this thread. fn = self._start_tracer() - if traces0: - for args in traces0: - (frame, event, arg), lineno = args + for args in traces0: + (frame, event, arg), lineno = args + try: fn(frame, event, arg, lineno=lineno) + except TypeError: + raise Exception( + "fullcoverage must be run with the C trace function." + ) # Install our installation tracer in threading, to jump start other # threads. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/config.py new/coverage-3.5.3/coverage/config.py --- old/coverage-3.5.1/coverage/config.py 2011-08-24 04:52:07.000000000 +0200 +++ new/coverage-3.5.3/coverage/config.py 2012-07-06 03:31:18.000000000 +0200 @@ -48,9 +48,11 @@ self.partial_list = DEFAULT_PARTIAL[:] self.partial_always_list = DEFAULT_PARTIAL_ALWAYS[:] self.precision = 0 + self.show_missing = False # Defaults for [html] self.html_dir = "htmlcov" + self.extra_css = None # Defaults for [xml] self.xml_output = "coverage.xml" @@ -118,10 +120,14 @@ self.get_line_list(cp, 'report', 'partial_branches_always') if cp.has_option('report', 'precision'): self.precision = cp.getint('report', 'precision') + if cp.has_option('report', 'show_missing'): + self.show_missing = cp.getboolean('report', 'show_missing') # [html] if cp.has_option('html', 'directory'): self.html_dir = cp.get('html', 'directory') + if cp.has_option('html', 'extra_css'): + self.extra_css = cp.get('html', 'extra_css') # [xml] if cp.has_option('xml', 'output'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/control.py new/coverage-3.5.3/coverage/control.py --- old/coverage-3.5.1/coverage/control.py 2011-09-07 17:48:02.000000000 +0200 +++ new/coverage-3.5.3/coverage/control.py 2012-04-28 16:05:39.000000000 +0200 @@ -222,14 +222,6 @@ # can't do anything with the data later anyway. return False - if filename.endswith(".html"): - # Jinja and maybe other templating systems compile templates into - # Python code, but use the template filename as the filename in - # the compiled code. Of course, those filenames are useless later - # so don't bother collecting. TODO: How should we really separate - # out good file extensions from bad? - return False - self._check_for_packages() # Compiled Python files have two filenames: frame.f_code.co_filename is @@ -327,7 +319,7 @@ try: pkg_file = mod.__file__ except AttributeError: - self._warn("Module %s has no Python source." % pkg) + pkg_file = None else: d, f = os.path.split(pkg_file) if f.startswith('__init__.'): @@ -336,8 +328,14 @@ else: pkg_file = self._source_for_file(pkg_file) pkg_file = self.file_locator.canonical_filename(pkg_file) + if not os.path.exists(pkg_file): + pkg_file = None + + if pkg_file: self.source.append(pkg_file) self.source_match.add(pkg_file) + else: + self._warn("Module %s has no Python source." % pkg) for pkg in found: self.source_pkgs.remove(pkg) @@ -559,12 +557,11 @@ """ self.config.from_args( - ignore_errors=ignore_errors, omit=omit, include=include - ) - reporter = SummaryReporter( - self, show_missing, self.config.ignore_errors + ignore_errors=ignore_errors, omit=omit, include=include, + show_missing=show_missing, ) - reporter.report(morfs, outfile=file, config=self.config) + reporter = SummaryReporter(self, self.config) + reporter.report(morfs, outfile=file) def annotate(self, morfs=None, directory=None, ignore_errors=None, omit=None, include=None): @@ -581,22 +578,29 @@ self.config.from_args( ignore_errors=ignore_errors, omit=omit, include=include ) - reporter = AnnotateReporter(self, self.config.ignore_errors) - reporter.report(morfs, config=self.config, directory=directory) + reporter = AnnotateReporter(self, self.config) + reporter.report(morfs, directory=directory) def html_report(self, morfs=None, directory=None, ignore_errors=None, - omit=None, include=None): + omit=None, include=None, extra_css=None): """Generate an HTML report. + The HTML is written to `directory`. The file "index.html" is the + overview starting point, with links to more detailed pages for + individual modules. + + `extra_css` is a path to a file of other CSS to apply on the page. + It will be copied into the HTML directory. + See `coverage.report()` for other arguments. """ self.config.from_args( ignore_errors=ignore_errors, omit=omit, include=include, - html_dir=directory, + html_dir=directory, extra_css=extra_css, ) - reporter = HtmlReporter(self, self.config.ignore_errors) - reporter.report(morfs, config=self.config) + reporter = HtmlReporter(self, self.config) + reporter.report(morfs) def xml_report(self, morfs=None, outfile=None, ignore_errors=None, omit=None, include=None): @@ -622,8 +626,8 @@ outfile = open(self.config.xml_output, "w") file_to_close = outfile try: - reporter = XmlReporter(self, self.config.ignore_errors) - reporter.report(morfs, outfile=outfile, config=self.config) + reporter = XmlReporter(self, self.config) + reporter.report(morfs, outfile=outfile) finally: if file_to_close: file_to_close.close() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/execfile.py new/coverage-3.5.3/coverage/execfile.py --- old/coverage-3.5.1/coverage/execfile.py 2011-05-22 04:12:58.000000000 +0200 +++ new/coverage-3.5.3/coverage/execfile.py 2011-10-31 04:09:58.000000000 +0100 @@ -65,6 +65,7 @@ openfile.close() # Finally, hand the file off to run_python_file for execution. + args[0] = pathname run_python_file(pathname, args, package=packagename) @@ -82,14 +83,18 @@ main_mod = imp.new_module('__main__') sys.modules['__main__'] = main_mod main_mod.__file__ = filename - main_mod.__package__ = package + if package: + main_mod.__package__ = package main_mod.__builtins__ = BUILTINS # Set sys.argv and the first path element properly. old_argv = sys.argv old_path0 = sys.path[0] sys.argv = args - sys.path[0] = os.path.abspath(os.path.dirname(filename)) + if package: + sys.path[0] = '' + else: + sys.path[0] = os.path.abspath(os.path.dirname(filename)) try: # Open the source file. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/files.py new/coverage-3.5.3/coverage/files.py --- old/coverage-3.5.1/coverage/files.py 2011-09-03 22:31:28.000000000 +0200 +++ new/coverage-3.5.3/coverage/files.py 2012-09-29 20:35:55.000000000 +0200 @@ -27,7 +27,7 @@ """ if filename.startswith(self.relative_dir): - filename = filename.replace(self.relative_dir, "") + filename = filename.replace(self.relative_dir, "", 1) return filename def canonical_filename(self, filename): @@ -207,13 +207,24 @@ def find_python_files(dirname): - """Yield all of the importable Python files in `dirname`, recursively.""" - for dirpath, dirnames, filenames in os.walk(dirname, topdown=True): - if '__init__.py' not in filenames: + """Yield all of the importable Python files in `dirname`, recursively. + + To be importable, the files have to be in a directory with a __init__.py, + except for `dirname` itself, which isn't required to have one. The + assumption is that `dirname` was specified directly, so the user knows + best, but subdirectories are checked for a __init__.py to be sure we only + find the importable files. + + """ + for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)): + if i > 0 and '__init__.py' not in filenames: # If a directory doesn't have __init__.py, then it isn't # importable and neither are its files del dirnames[:] continue for filename in filenames: - if fnmatch.fnmatch(filename, "*.py"): + # We're only interested in files that look like reasonable Python + # files: Must end with .py, and must not have certain funny + # characters that probably mean they are editor junk. + if re.match(r"^[^.#~!$@%^&*()+=,]+\.py$", filename): yield os.path.join(dirpath, filename) Files old/coverage-3.5.1/coverage/fullcoverage/__pycache__/encodings.cpython-32.pyc and new/coverage-3.5.3/coverage/fullcoverage/__pycache__/encodings.cpython-32.pyc differ Files old/coverage-3.5.1/coverage/fullcoverage/__pycache__/encodings.cpython-33.pyc and new/coverage-3.5.3/coverage/fullcoverage/__pycache__/encodings.cpython-33.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/fullcoverage/encodings.py new/coverage-3.5.3/coverage/fullcoverage/encodings.py --- old/coverage-3.5.1/coverage/fullcoverage/encodings.py 2011-08-11 14:18:58.000000000 +0200 +++ new/coverage-3.5.3/coverage/fullcoverage/encodings.py 2012-08-31 05:21:08.000000000 +0200 @@ -43,8 +43,7 @@ # happen last, since all of the symbols in this module will become None # at that exact moment, including "sys". -parentdirs = [ d for d in sys.path if __file__.startswith(d) ] -parentdirs.sort(key=len) -sys.path.remove(parentdirs[-1]) +parentdir = max(filter(__file__.startswith, sys.path), key=len) +sys.path.remove(parentdir) del sys.modules['encodings'] import encodings Files old/coverage-3.5.1/coverage/fullcoverage/encodings.pyc and new/coverage-3.5.3/coverage/fullcoverage/encodings.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/html.py new/coverage-3.5.3/coverage/html.py --- old/coverage-3.5.1/coverage/html.py 2011-08-17 15:42:47.000000000 +0200 +++ new/coverage-3.5.3/coverage/html.py 2012-05-15 03:20:21.000000000 +0200 @@ -1,11 +1,11 @@ """HTML reporting for Coverage.""" -import os, re, shutil +import os, re, shutil, sys import coverage -from coverage.backward import pickle, write_encoded +from coverage.backward import pickle from coverage.misc import CoverageException, Hasher -from coverage.phystokens import source_token_lines +from coverage.phystokens import source_token_lines, source_encoding from coverage.report import Reporter from coverage.templite import Templite @@ -41,8 +41,8 @@ "keybd_open.png", ] - def __init__(self, cov, ignore_errors=False): - super(HtmlReporter, self).__init__(cov, ignore_errors) + def __init__(self, cov, config): + super(HtmlReporter, self).__init__(cov, config) self.directory = None self.template_globals = { 'escape': escape, @@ -58,29 +58,33 @@ self.files = [] self.arcs = self.coverage.data.has_arcs() self.status = HtmlStatus() + self.extra_css = None - def report(self, morfs, config=None): + def report(self, morfs): """Generate an HTML report for `morfs`. - `morfs` is a list of modules or filenames. `config` is a - CoverageConfig instance. + `morfs` is a list of modules or filenames. """ - assert config.html_dir, "must provide a directory for html reporting" + assert self.config.html_dir, "must give a directory for html reporting" # Read the status data. - self.status.read(config.html_dir) + self.status.read(self.config.html_dir) # Check that this run used the same settings as the last run. m = Hasher() - m.update(config) + m.update(self.config) these_settings = m.digest() if self.status.settings_hash() != these_settings: self.status.reset() self.status.set_settings_hash(these_settings) + # The user may have extra CSS they want copied. + if self.config.extra_css: + self.extra_css = os.path.basename(self.config.extra_css) + # Process all the files. - self.report_files(self.html_file, morfs, config, config.html_dir) + self.report_files(self.html_file, morfs, self.config.html_dir) if not self.files: raise CoverageException("No data to report.") @@ -92,15 +96,27 @@ def make_local_static_report_files(self): """Make local instances of static files for HTML report.""" + # The files we provide must always be copied. for static in self.STATIC_FILES: shutil.copyfile( data_filename("htmlfiles/" + static), os.path.join(self.directory, static) ) + # The user may have extra CSS they want copied. + if self.extra_css: + shutil.copyfile( + self.config.extra_css, + os.path.join(self.directory, self.extra_css) + ) + def write_html(self, fname, html): """Write `html` to `fname`, properly encoded.""" - write_encoded(fname, html, 'ascii', 'xmlcharrefreplace') + fout = open(fname, "wb") + try: + fout.write(html.encode('ascii', 'xmlcharrefreplace')) + finally: + fout.close() def file_hash(self, source, cu): """Compute a hash that changes if the file needs to be re-reported.""" @@ -128,6 +144,16 @@ self.status.set_file_hash(flat_rootname, this_hash) + # If need be, determine the encoding of the source file. We use it + # later to properly write the HTML. + if sys.version_info < (3, 0): + encoding = source_encoding(source) + # Some UTF8 files have the dreaded UTF8 BOM. If so, junk it. + if encoding.startswith("utf-8") and source[:3] == "\xef\xbb\xbf": + source = source[3:] + encoding = "utf-8" + + # Get the numbers for this file. nums = analysis.numbers missing_branch_arcs = analysis.missing_branch_arcs() @@ -193,8 +219,11 @@ # Write the HTML page for this file. html_filename = flat_rootname + ".html" html_path = os.path.join(self.directory, html_filename) + extra_css = self.extra_css html = spaceless(self.source_tmpl.render(locals())) + if sys.version_info < (3, 0): + html = html.decode(encoding) self.write_html(html_path, html) # Save this file's information for the index file. @@ -217,6 +246,7 @@ arcs = self.arcs totals = sum([f['nums'] for f in files]) + extra_css = self.extra_css self.write_html( os.path.join(self.directory, "index.html"), @@ -246,7 +276,11 @@ usable = False try: status_file = os.path.join(directory, self.STATUS_FILE) - status = pickle.load(open(status_file, "rb")) + fstatus = open(status_file, "rb") + try: + status = pickle.load(fstatus) + finally: + fstatus.close() except IOError: usable = False else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/htmlfiles/coverage_html.js new/coverage-3.5.3/coverage/htmlfiles/coverage_html.js --- old/coverage-3.5.1/coverage/htmlfiles/coverage_html.js 2011-06-27 04:47:28.000000000 +0200 +++ new/coverage-3.5.3/coverage/htmlfiles/coverage_html.js 2012-04-28 23:09:43.000000000 +0200 @@ -122,6 +122,11 @@ .bind('keydown', '1', coverage.to_first_chunk) ; + $(".button_toggle_run").click(function (evt) {coverage.toggle_lines(evt.target, "run");}); + $(".button_toggle_exc").click(function (evt) {coverage.toggle_lines(evt.target, "exc");}); + $(".button_toggle_mis").click(function (evt) {coverage.toggle_lines(evt.target, "mis");}); + $(".button_toggle_par").click(function (evt) {coverage.toggle_lines(evt.target, "par");}); + coverage.assign_shortkeys(); coverage.wire_up_help_panel(); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/htmlfiles/index.html new/coverage-3.5.3/coverage/htmlfiles/index.html --- old/coverage-3.5.1/coverage/htmlfiles/index.html 2011-06-06 02:45:08.000000000 +0200 +++ new/coverage-3.5.3/coverage/htmlfiles/index.html 2012-04-28 16:05:39.000000000 +0200 @@ -4,6 +4,9 @@ <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> <title>Coverage report</title> <link rel='stylesheet' href='style.css' type='text/css'> + {% if extra_css %} + <link rel='stylesheet' href='{{ extra_css }}' type='text/css'> + {% endif %} <script type='text/javascript' src='jquery-1.4.3.min.js'></script> <script type='text/javascript' src='jquery.tablesorter.min.js'></script> <script type='text/javascript' src='jquery.hotkeys.js'></script> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/htmlfiles/pyfile.html new/coverage-3.5.3/coverage/htmlfiles/pyfile.html --- old/coverage-3.5.1/coverage/htmlfiles/pyfile.html 2011-04-27 14:30:17.000000000 +0200 +++ new/coverage-3.5.3/coverage/htmlfiles/pyfile.html 2012-04-28 23:53:33.000000000 +0200 @@ -7,6 +7,9 @@ <meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /> <title>Coverage for {{cu.name|escape}}: {{nums.pc_covered_str}}%</title> <link rel='stylesheet' href='style.css' type='text/css'> + {% if extra_css %} + <link rel='stylesheet' href='{{ extra_css }}' type='text/css'> + {% endif %} <script type='text/javascript' src='jquery-1.4.3.min.js'></script> <script type='text/javascript' src='jquery.hotkeys.js'></script> <script type='text/javascript' src='jquery.isonscreen.js'></script> @@ -24,12 +27,12 @@ </h1> <img id='keyboard_icon' src='keybd_closed.png'> <h2 class='stats'> - {{nums.n_statements}} statements - <span class='{{c_run}} shortkey_r' onclick='coverage.toggle_lines(this, "run")'>{{nums.n_executed}} run</span> - <span class='{{c_mis}} shortkey_m' onclick='coverage.toggle_lines(this, "mis")'>{{nums.n_missing}} missing</span> - <span class='{{c_exc}} shortkey_x' onclick='coverage.toggle_lines(this, "exc")'>{{nums.n_excluded}} excluded</span> + {{nums.n_statements}} statements + <span class='{{c_run}} shortkey_r button_toggle_run'>{{nums.n_executed}} run</span> + <span class='{{c_mis}} shortkey_m button_toggle_mis'>{{nums.n_missing}} missing</span> + <span class='{{c_exc}} shortkey_x button_toggle_exc'>{{nums.n_excluded}} excluded</span> {% if arcs %} - <span class='{{c_par}} shortkey_p' onclick='coverage.toggle_lines(this, "par")'>{{n_par}} partial</span> + <span class='{{c_par}} shortkey_p button_toggle_par'>{{n_par}} partial</span> {% endif %} </h2> </div> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/htmlfiles/style.css new/coverage-3.5.3/coverage/htmlfiles/style.css --- old/coverage-3.5.1/coverage/htmlfiles/style.css 2011-06-05 16:20:48.000000000 +0200 +++ new/coverage-3.5.3/coverage/htmlfiles/style.css 2012-09-26 15:27:55.000000000 +0200 @@ -24,8 +24,8 @@ /* Set base font size to 12/16 */ p { - font-size: .75em; /* 12/16 */ - line-height: 1.3333em; /* 16/12 */ + font-size: .75em; /* 12/16 */ + line-height: 1.33333333em; /* 16/12 */ } table { @@ -102,6 +102,31 @@ border-color: #999 #ccc #ccc #999; } +.stats span.run { + background: #ddffdd; +} +.stats span.exc { + background: #eeeeee; +} +.stats span.mis { + background: #ffdddd; +} +.stats span.hide_run { + background: #eeffee; +} +.stats span.hide_exc { + background: #f5f5f5; +} +.stats span.hide_mis { + background: #ffeeee; +} +.stats span.par { + background: #ffffaa; +} +.stats span.hide_par { + background: #ffffcc; +} + /* Help panel */ #keyboard_icon { float: right; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/parser.py new/coverage-3.5.3/coverage/parser.py --- old/coverage-3.5.1/coverage/parser.py 2011-08-10 14:01:33.000000000 +0200 +++ new/coverage-3.5.3/coverage/parser.py 2012-08-08 03:29:29.000000000 +0200 @@ -35,6 +35,10 @@ "No source for code: %r: %s" % (self.filename, err) ) + # Scrap the BOM if it exists. + if self.text and ord(self.text[0]) == 0xfeff: + self.text = self.text[1:] + self.exclude = exclude self.show_tokens = False @@ -199,7 +203,15 @@ statements. """ - self._raw_parse() + try: + self._raw_parse() + except tokenize.TokenError: + _, tokerr, _ = sys.exc_info() + msg, lineno = tokerr.args + raise NotPython( + "Couldn't parse '%s' as Python source: '%s' at %s" % + (self.filename, msg, lineno) + ) excluded_lines = self.first_lines(self.excluded) ignore = excluded_lines + list(self.docstrings) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/phystokens.py new/coverage-3.5.3/coverage/phystokens.py --- old/coverage-3.5.1/coverage/phystokens.py 2011-02-05 05:20:13.000000000 +0100 +++ new/coverage-3.5.3/coverage/phystokens.py 2012-03-29 23:42:45.000000000 +0200 @@ -1,6 +1,6 @@ """Better tokenizing for coverage.py.""" -import keyword, re, token, tokenize +import codecs, keyword, re, sys, token, tokenize from coverage.backward import StringIO # pylint: disable=W0622 def phys_tokens(toks): @@ -106,3 +106,101 @@ if line: yield line + +def source_encoding(source): + """Determine the encoding for `source` (a string), according to PEP 263. + + Returns a string, the name of the encoding. + + """ + # Note: this function should never be called on Python 3, since py3 has + # built-in tools to do this. + assert sys.version_info < (3, 0) + + # This is mostly code adapted from Py3.2's tokenize module. + + cookie_re = re.compile("coding[:=]\s*([-\w.]+)") + + # Do this so the detect_encode code we copied will work. + readline = iter(source.splitlines()).next + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if re.match(r"^utf-8($|-)", enc): + return "utf-8" + if re.match(r"^(latin-1|iso-8859-1|iso-latin-1)($|-)", enc): + return "iso-8859-1" + return orig_enc + + # From detect_encode(): + # It detects the encoding from the presence of a utf-8 bom or an encoding + # cookie as specified in pep-0263. If both a bom and a cookie are present, + # but disagree, a SyntaxError will be raised. If the encoding cookie is an + # invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + # 'utf-8-sig' is returned. + + # If no encoding is specified, then the default will be returned. The + # default varied with version. + + if sys.version_info <= (2, 4): + default = 'iso-8859-1' + else: + default = 'ascii' + + bom_found = False + encoding = None + + def read_or_stop(): + """Get the next source line, or ''.""" + try: + return readline() + except StopIteration: + return '' + + def find_cookie(line): + """Find an encoding cookie in `line`.""" + try: + line_string = line.decode('ascii') + except UnicodeDecodeError: + return None + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = codecs.lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + raise SyntaxError("unknown encoding: " + encoding) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(codecs.BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default + + encoding = find_cookie(first) + if encoding: + return encoding + + second = read_or_stop() + if not second: + return default + + encoding = find_cookie(second) + if encoding: + return encoding + + return default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/report.py new/coverage-3.5.3/coverage/report.py --- old/coverage-3.5.1/coverage/report.py 2011-08-03 03:58:59.000000000 +0200 +++ new/coverage-3.5.3/coverage/report.py 2012-04-20 19:26:17.000000000 +0200 @@ -7,15 +7,15 @@ class Reporter(object): """A base class for all reporters.""" - def __init__(self, coverage, ignore_errors=False): + def __init__(self, coverage, config): """Create a reporter. - `coverage` is the coverage instance. `ignore_errors` controls how - skittish the reporter will be during file processing. + `coverage` is the coverage instance. `config` is an instance of + CoverageConfig, for controlling all sorts of behavior. """ self.coverage = coverage - self.ignore_errors = ignore_errors + self.config = config # The code units to report on. Set by find_code_units. self.code_units = [] @@ -24,19 +24,18 @@ # classes. self.directory = None - def find_code_units(self, morfs, config): + def find_code_units(self, morfs): """Find the code units we'll report on. - `morfs` is a list of modules or filenames. `config` is a - CoverageConfig instance. + `morfs` is a list of modules or filenames. """ morfs = morfs or self.coverage.data.measured_files() file_locator = self.coverage.file_locator self.code_units = code_unit_factory(morfs, file_locator) - if config.include: - patterns = [file_locator.abs_file(p) for p in config.include] + if self.config.include: + patterns = [file_locator.abs_file(p) for p in self.config.include] filtered = [] for cu in self.code_units: for pattern in patterns: @@ -45,8 +44,8 @@ break self.code_units = filtered - if config.omit: - patterns = [file_locator.abs_file(p) for p in config.omit] + if self.config.omit: + patterns = [file_locator.abs_file(p) for p in self.config.omit] filtered = [] for cu in self.code_units: for pattern in patterns: @@ -58,7 +57,7 @@ self.code_units.sort() - def report_files(self, report_fn, morfs, config, directory=None): + def report_files(self, report_fn, morfs, directory=None): """Run a reporting function on a number of morfs. `report_fn` is called for each relative morf in `morfs`. It is called @@ -69,10 +68,8 @@ where `code_unit` is the `CodeUnit` for the morf, and `analysis` is the `Analysis` for the morf. - `config` is a CoverageConfig instance. - """ - self.find_code_units(morfs, config) + self.find_code_units(morfs) if not self.code_units: raise CoverageException("No data to report.") @@ -84,6 +81,11 @@ for cu in self.code_units: try: report_fn(cu, self.coverage._analyze(cu)) - except (NoSource, NotPython): - if not self.ignore_errors: + except NoSource: + if not self.config.ignore_errors: + raise + except NotPython: + # Only report errors for .py files, and only if we didn't + # explicitly suppress those errors. + if cu.should_be_python() and not self.config.ignore_errors: raise diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/summary.py new/coverage-3.5.3/coverage/summary.py --- old/coverage-3.5.1/coverage/summary.py 2010-09-03 03:40:49.000000000 +0200 +++ new/coverage-3.5.3/coverage/summary.py 2012-04-20 19:26:17.000000000 +0200 @@ -4,24 +4,23 @@ from coverage.report import Reporter from coverage.results import Numbers +from coverage.misc import NotPython class SummaryReporter(Reporter): """A reporter for writing the summary report.""" - def __init__(self, coverage, show_missing=True, ignore_errors=False): - super(SummaryReporter, self).__init__(coverage, ignore_errors) - self.show_missing = show_missing + def __init__(self, coverage, config): + super(SummaryReporter, self).__init__(coverage, config) self.branches = coverage.data.has_arcs() - def report(self, morfs, outfile=None, config=None): + def report(self, morfs, outfile=None): """Writes a report summarizing coverage statistics per module. - `outfile` is a file object to write the summary to. `config` is a - CoverageConfig instance. + `outfile` is a file object to write the summary to. """ - self.find_code_units(morfs, config) + self.find_code_units(morfs) # Prepare the formatting strings max_name = max([len(cu.name) for cu in self.code_units] + [5]) @@ -35,7 +34,7 @@ width100 = Numbers.pc_str_width() header += "%*s" % (width100+4, "Cover") fmt_coverage += "%%%ds%%%%" % (width100+3,) - if self.show_missing: + if self.config.show_missing: header += " Missing" fmt_coverage += " %s" rule = "-" * len(header) + "\n" @@ -59,15 +58,19 @@ if self.branches: args += (nums.n_branches, nums.n_missing_branches) args += (nums.pc_covered_str,) - if self.show_missing: + if self.config.show_missing: args += (analysis.missing_formatted(),) outfile.write(fmt_coverage % args) total += nums except KeyboardInterrupt: # pragma: no cover raise except: - if not self.ignore_errors: + report_it = not self.config.ignore_errors + if report_it: typ, msg = sys.exc_info()[:2] + if typ is NotPython and not cu.should_be_python(): + report_it = False + if report_it: outfile.write(fmt_err % (cu.name, typ.__name__, msg)) if total.n_files > 1: @@ -76,6 +79,6 @@ if self.branches: args += (total.n_branches, total.n_missing_branches) args += (total.pc_covered_str,) - if self.show_missing: + if self.config.show_missing: args += ("",) outfile.write(fmt_coverage % args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/tracer.c new/coverage-3.5.3/coverage/tracer.c --- old/coverage-3.5.1/coverage/tracer.c 2011-09-04 03:33:45.000000000 +0200 +++ new/coverage-3.5.3/coverage/tracer.c 2012-09-02 13:45:47.000000000 +0200 @@ -27,7 +27,8 @@ #define MyText_Type PyUnicode_Type #define MyText_Check(o) PyUnicode_Check(o) -#define MyText_AS_STRING(o) PyBytes_AS_STRING(PyUnicode_AsASCIIString(o)) +#define MyText_AS_BYTES(o) PyUnicode_AsASCIIString(o) +#define MyText_AS_STRING(o) PyBytes_AS_STRING(o) #define MyInt_FromLong(l) PyLong_FromLong(l) #define MyType_HEAD_INIT PyVarObject_HEAD_INIT(NULL, 0) @@ -36,6 +37,7 @@ #define MyText_Type PyString_Type #define MyText_Check(o) PyString_Check(o) +#define MyText_AS_BYTES(o) (Py_INCREF(o), o) #define MyText_AS_STRING(o) PyString_AS_STRING(o) #define MyInt_FromLong(l) PyInt_FromLong(l) @@ -207,7 +209,9 @@ printf(" "); } if (filename) { - printf(" %s", MyText_AS_STRING(filename)); + PyObject *ascii = MyText_AS_BYTES(filename); + printf(" %s", MyText_AS_STRING(ascii)); + Py_DECREF(ascii); } if (msg) { printf(" %s", msg); @@ -257,17 +261,24 @@ int ret = RET_OK; PyObject * filename = NULL; PyObject * tracename = NULL; + #if WHAT_LOG || TRACE_LOG + PyObject * ascii = NULL; + #endif #if WHAT_LOG if (what <= sizeof(what_sym)/sizeof(const char *)) { - printf("trace: %s @ %s %d\n", what_sym[what], MyText_AS_STRING(frame->f_code->co_filename), frame->f_lineno); + ascii = MyText_AS_BYTES(frame->f_code->co_filename); + printf("trace: %s @ %s %d\n", what_sym[what], MyText_AS_STRING(ascii), frame->f_lineno); + Py_DECREF(ascii); } #endif #if TRACE_LOG - if (strstr(MyText_AS_STRING(frame->f_code->co_filename), start_file) && frame->f_lineno == start_line) { + ascii = MyText_AS_BYTES(frame->f_code->co_filename); + if (strstr(MyText_AS_STRING(ascii), start_file) && frame->f_lineno == start_line) { logging = 1; } + Py_DECREF(ascii); #endif /* See below for details on missing-return detection. */ @@ -508,7 +519,10 @@ /* In Python, the what argument is a string, we need to find an int for the C function. */ for (what = 0; what_names[what]; what++) { - if (!strcmp(MyText_AS_STRING(what_str), what_names[what])) { + PyObject *ascii = MyText_AS_BYTES(what_str); + int should_break = !strcmp(MyText_AS_STRING(ascii), what_names[what]); + Py_DECREF(ascii); + if (should_break) { break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage/xmlreport.py new/coverage-3.5.3/coverage/xmlreport.py --- old/coverage-3.5.1/coverage/xmlreport.py 2011-02-05 05:20:13.000000000 +0100 +++ new/coverage-3.5.3/coverage/xmlreport.py 2012-04-20 19:26:17.000000000 +0200 @@ -15,20 +15,19 @@ class XmlReporter(Reporter): """A reporter for writing Cobertura-style XML coverage results.""" - def __init__(self, coverage, ignore_errors=False): - super(XmlReporter, self).__init__(coverage, ignore_errors) + def __init__(self, coverage, config): + super(XmlReporter, self).__init__(coverage, config) self.packages = None self.xml_out = None self.arcs = coverage.data.has_arcs() - def report(self, morfs, outfile=None, config=None): + def report(self, morfs, outfile=None): """Generate a Cobertura-compatible XML report for `morfs`. `morfs` is a list of modules or filenames. - `outfile` is a file object to write the XML to. `config` is a - CoverageConfig instance. + `outfile` is a file object to write the XML to. """ # Initial setup. @@ -54,7 +53,7 @@ # Call xml_file for each file in the data. self.packages = {} - self.report_files(self.xml_file, morfs, config) + self.report_files(self.xml_file, morfs) lnum_tot, lhits_tot = 0, 0 bnum_tot, bhits_tot = 0, 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage.egg-info/PKG-INFO new/coverage-3.5.3/coverage.egg-info/PKG-INFO --- old/coverage-3.5.1/coverage.egg-info/PKG-INFO 2011-09-23 14:26:50.000000000 +0200 +++ new/coverage-3.5.3/coverage.egg-info/PKG-INFO 2012-09-30 04:31:18.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: coverage -Version: 3.5.1 +Version: 3.5.3 Summary: Code coverage measurement for Python Home-page: http://nedbatchelder.com/code/coverage Author: Ned Batchelder and others @@ -10,7 +10,7 @@ the code analysis tools and tracing hooks provided in the Python standard library to determine which lines are executable, and which have been executed. - Coverage.py runs on Pythons 2.3 through 3.2. + Coverage.py runs on Pythons 2.3 through 3.3, and PyPy 1.8. Documentation is at `nedbatchelder.com <http://nedbatchelder.com/code/coverage>`_. Code repository and issue tracker are at `bitbucket.org <http://bitbucket.org/ned/coveragepy>`_. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/coverage.egg-info/SOURCES.txt new/coverage-3.5.3/coverage.egg-info/SOURCES.txt --- old/coverage-3.5.1/coverage.egg-info/SOURCES.txt 2011-09-23 14:26:51.000000000 +0200 +++ new/coverage-3.5.3/coverage.egg-info/SOURCES.txt 2012-09-30 04:31:19.000000000 +0200 @@ -35,6 +35,9 @@ coverage.egg-info/not-zip-safe coverage.egg-info/top_level.txt coverage/fullcoverage/encodings.py +coverage/fullcoverage/encodings.pyc +coverage/fullcoverage/__pycache__/encodings.cpython-32.pyc +coverage/fullcoverage/__pycache__/encodings.cpython-33.pyc coverage/htmlfiles/coverage_html.js coverage/htmlfiles/index.html coverage/htmlfiles/jquery-1.4.3.min.js diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/distribute_setup.py new/coverage-3.5.3/distribute_setup.py --- old/coverage-3.5.1/distribute_setup.py 2011-09-04 03:33:45.000000000 +0200 +++ new/coverage-3.5.3/distribute_setup.py 2012-08-31 21:15:05.000000000 +0200 @@ -46,7 +46,7 @@ args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 -DEFAULT_VERSION = "0.6.21" +DEFAULT_VERSION = "0.6.27" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/coverage-3.5.1/setup.py new/coverage-3.5.3/setup.py --- old/coverage-3.5.1/setup.py 2011-06-29 14:22:52.000000000 +0200 +++ new/coverage-3.5.3/setup.py 2012-07-21 00:10:54.000000000 +0200 @@ -6,7 +6,7 @@ the code analysis tools and tracing hooks provided in the Python standard library to determine which lines are executable, and which have been executed. -Coverage.py runs on Pythons 2.3 through 3.2. +Coverage.py runs on Pythons 2.3 through 3.3, and PyPy 1.8. Documentation is at `nedbatchelder.com <%s>`_. Code repository and issue tracker are at `bitbucket.org <http://bitbucket.org/ned/coveragepy>`_. @@ -36,7 +36,7 @@ """ # Pull in the tools we need. -import sys, traceback +import sys # Distribute is a new fork of setuptools. It's supported on Py3.x, so we use # it there, but stick with classic setuptools on Py2.x until Distribute becomes @@ -102,8 +102,19 @@ url = __url__, ) -# Jython can't compile C extensions -if not sys.platform.startswith('java'): +# There are a few reasons we might not be able to compile the C extension. + +compile_extension = True + +if sys.platform.startswith('java'): + # Jython can't compile C extensions + compile_extension = False + +if '__pypy__' in sys.builtin_module_names: + # Pypy can't compile C extensions + compile_extension = False + +if compile_extension: setup_args.update(dict( ext_modules = [ Extension("coverage.tracer", sources=["coverage/tracer.c"]) @@ -120,10 +131,15 @@ try: setup(**setup_args) except: # pylint: disable=W0702 - if 'ext_modules' not in setup_args: + # When setup() can't compile, it tries to exit. We'll catch SystemExit + # here :-(, and try again. + if 'install' not in sys.argv or 'ext_modules' not in setup_args: + # We weren't trying to install an extension, so forget it. raise msg = "Couldn't install with extension module, trying without it..." - exc_msg = traceback.format_exc(0).split('\n')[-2] + exc = sys.exc_info()[1] + exc_msg = "%s: %s" % (exc.__class__.__name__, exc) print("**\n** %s\n** %s\n**" % (msg, exc_msg)) + del setup_args['ext_modules'] setup(**setup_args) -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de