[Python-checkins] devinabox: Update the README on how to generate a coverage report. Also negates

brett.cannon python-checkins at python.org
Wed Aug 7 16:15:01 CEST 2013


http://hg.python.org/devinabox/rev/cb783f26d952
changeset:   55:cb783f26d952
user:        Brett Cannon <brett at python.org>
date:        Wed Aug 07 10:14:47 2013 -0400
summary:
  Update the README on how to generate a coverage report. Also negates
the need for full_coverage.py.

files:
  README           |  103 +++++++++++++++-----------
  full_coverage.py |  134 -----------------------------------
  2 files changed, 59 insertions(+), 178 deletions(-)


diff --git a/README b/README
--- a/README
+++ b/README
@@ -21,7 +21,7 @@
 
 When you are done you should have in this directory everything
 someone needs to contribute. Simply copy the whole directory to some sort of
-media (USB 3 thumb drive and CD tend to work well) and then pass it around for
+media (USB 3 drive and a CD tend to work well) and then pass it around for
 people to copy somewhere on to their system. They can run ``hg pull -u`` to
 get updates, sparing the probably taxed internet connection at the sprint from
 doing complete repository cloning.
@@ -30,6 +30,11 @@
 clones is a handy way to ensure old build artifacts have been removed.
 You will need to enable the purge extension in ``~/.hgrc``.
 
+Also make sure to not simply copy your own repositories to the box! Otherwise
+the clones will most likely have paths which use SSH and the hg account on
+hg.python.org which only core developers can use. It's just easier to make the
+clones from scratch.
+
 
 Mercurial
 ---------
@@ -68,7 +73,7 @@
 CPython
 -------
 
-Clone the CPython repository and build it (you will be cleaning up your build
+Clone the `CPython repository`_ and build it (you will be cleaning up your build
 later, though as a final step).
 
 Also make sure to build the documentation. This not only alleviates the need for
@@ -78,55 +83,68 @@
 being built by a repository build of CPython (and thus Python 3) this may no
 longer hold true.
 
+.. _CPython repository: http://hg.python.org/cpython
+
 
 PEPs
 ----
 
-Clone the repository and build it. That way if people need to reference a PEP
-they can easily find itand will be able to use the easier-to-read HTML version.
+Clone the `PEP repository`_ and build it. That way if people need to reference a
+PEP they can easily find itand will be able to use the easier-to-read HTML
+version.
 
 No specific guidelines for building the PEPs are provided for new contributors
 since there is only a slim chance they will be editing a PEP, and if they are
 then they should be able to figure out how to get the PEPs to build on their
 own.
 
+.. _PEP repository: http://hg.python.org/peps
+
 
 Devguide
 --------
 
-Clone the repository and build it. This gives people a local copy to use
-rather than having to use the (probably slow) internet connection at the sprint.
+Clone the `devguide repository`_ and build it. This gives people a local copy to
+use rather than having to use the (probably slow) internet connection at the
+sprint.
 
 If a new contributor needs to be able to build the devguide, they should only
 need to set their ``PYTHONPATH`` to point at the ``cpython/Doc/tools`` directory
 in the CPython repository thanks to the requisite projects being pulled in when
 you built the CPython documentation.
 
+.. _devguide repository: http://hg.python.org/devguide
+
 
 Coverage.py
 -----------
 
-01. Build the CPython repository
-02. Clone the repository from https://bitbucket.org/ned/coveragepy
-03. Clone setuptools from https://bitbucket.org/pypa/setuptools/
-04. Run ``python3 setup.py build`` in the ``setuptools`` directory
-05. Run ``ln -s ../setuptools/build/lib/setuptools`` in the ``coveragepy``
-    directory
-06. Run ``ln -s ../setuptools/build/lib/pkg_resources.py`` in the
-    ``coveragepy`` directory
-07. Run ``./cpython/python full_coverage.py build``
-08. Run ``./cpython/python full_coverage.py run``
-09. Run ``./cpython/python full_coverage.py html original_coverage_report``
-10. Run ``hg purge --all`` in the CPython repository
+#. Download setuptools_
+#. Download coverage_
+#. Build CPython: ``./build_cpython.py``
+#. Create an venv: ``./cpython/python.exe -m venv venv``
+#. Extract setuptools and coverage: ``tar -x -f setuptools-*.tar.gz; tar -x -f coverage-*.tar.gz``
+#. Install setuptools in the venv: ``../venv/bin/python3 setup.py install``
+#. Install coverage in the venv
+#. Set PYTHONPATH to ``fullcoverage`` (will need to change the directory): ``export PYTHONPATH=../coverage-N.N/coverage/fullcoverage``
+#. Run coverage from the venv: ``./bin/python -m coverage run --pylib -m test``
+#. Unset PYTHONPATH: ``unset PYTHONPATH``
+#. Generate coverage report: ``./bin/python -m coverage html --directory=../coverage_report -i --include="../cpython/Lib/*" --title="CPython test coverage report"``
+#. Delete project directories (but not tar files!) for coverage and setuptools
+#. Delete venv
+#. Clean up the cpython clone: either ``make distclean`` or check it out again
 
+Do be aware that this step takes a few **hours**. If you find report generation
+is the bottleneck (typically because of memory pressure), you can generate the
+HTML reports in chunks at the cost of not having a comprehensive index. E.g. to
+report for every module/package starting with the letter 'a'::
 
-All these steps will generate a complete coverage report for the standard
-library and put it in the ``original_coverage_report`` directory. Do note that
-the  location is **not** the default one for the script to prevent users from
-accidentally overwriting the original copy (and thus needing to run the whole
-coverage again from scratch).
+  ./bin/python3 -m coverage html --directory ../coverage_report -i ../cpython/Lib/a*.py ../cpython/Lib/a*/*.py ../cpython/Lib/a*/*/*.py
 
-Do be aware that this step takes a few **hours**.
+You can then create an index using the textual report from coverage.py.
+
+.. _setuptools: https://pypi.python.org/pypi/setuptools
+.. _coverage: https://pypi.python.org/pypi/coverage
 
 
 Included files to help out
@@ -136,6 +154,23 @@
 both you and the new contributors.
 
 
+``index.html``
+--------------
+
+An HTML file with links to the various pieces of documentation you built
+previously and the helper scripts.
+
+
+``build_cpython.py``
+--------------------
+On UNIX-based OSs it builds the CPython repository. On all platforms it
+verifies that the expected CPython binary exists.
+
+While the devguide includes instructions on how to build under UNIX, the script
+just simplifies this by having a single command subsume both the configure and
+build steps. It also uses reasonable defaults (e.g. all cores on the CPU).
+
+
 ``full_coverage.py``
 ---------------------
 
@@ -144,23 +179,3 @@
 tests as an argument. The ``html`` directory can take an argument for a
 directory to write to, but the default should not conflict with the original
 coverage run you did earlier (if you followed the directions =) .
-
-
-``build_cpython.py``
---------------------
-On UNIX-based OSs, builds the CPython repository, and on all platforms it
-verifies that the expected CPython binary exists.
-
-While the devguide includes instructions on how to build under UNIX, the script
-just simplifies this by having a single command subsume both the configure and
-build steps. It also uses reasonable defaults (e.g. all cores on the CPU).
-
-(You may need to cd into the CPython directory and run ``make`` to get the
-extension modules to build)
-
-
-``index.html``
---------------
-
-An HTML file with links to the various pieces of documentation you built
-previously and the helper scripts.
diff --git a/full_coverage.py b/full_coverage.py
deleted file mode 100644
--- a/full_coverage.py
+++ /dev/null
@@ -1,134 +0,0 @@
-"""Use coverage.py on CPython's standard library.
-
-See the ``-h`` or ``help`` command of the script for instructions on use.
-
-"""
-import importlib.machinery
-import contextlib
-import os
-import shutil
-import subprocess
-import sys
-import webbrowser
-
-
-def path_from_here(path):
-    """Calculate the absolute path to 'path' from where this file is located."""
-    return os.path.abspath(os.path.join(os.path.dirname(__file__), path))
-
-COVERAGE = path_from_here('coveragepy')
-REPORT = path_from_here('coverage_report')
-CPYTHON = os.path.dirname(sys.executable)
-
-
- at contextlib.contextmanager
-def chdir(directory):
-    """Change the directory temporarily."""
-    original_directory = os.getcwd()
-    os.chdir(directory)
-    yield
-    os.chdir(original_directory)
-
-def make_setup_cmd(*args):
-    # Silence a spurious warning from setuptools
-    # See https://bitbucket.org/pypa/setuptools/issue/29/
-    cmd = [sys.executable, '-W', 'ignore::UserWarning:distutils.dist',
-           'setup.py']
-    cmd.extend(args)
-    return cmd
-
-def build(args):
-    """Build coverage.py's C-based tracer.
-
-    Make sure to delete any pre-existing build to make sure it uses the latest
-    source from CPython.
-    """
-    with chdir(COVERAGE):
-        for ext in importlib.machinery.EXTENSION_SUFFIXES:
-            tracer_path = os.path.join('coverage', 'tracer' + ext)
-            try:
-                os.unlink(tracer_path)
-            except FileNotFoundError:
-                pass
-        subprocess.check_call(make_setup_cmd('clean'))
-        env = os.environ.copy()
-        env['CPPFLAGS'] = '-I {} -I {}'.format(CPYTHON,
-                                               os.path.join(CPYTHON, 'Include'))
-        command = make_setup_cmd('build_ext', '--inplace')
-        process = subprocess.Popen(command, env=env)
-        process.wait()
-
-
-def run(args):
-    """Run coverage.py against Python's stdlib as best as possible.
-
-    If any specific tests are listed, then limit the run to those tests.
-    """
-    command = [sys.executable, COVERAGE, 'run', '--pylib', 'Lib/test/regrtest.py']
-    if args.tests:
-        command.extend(args.tests)
-    with chdir(CPYTHON):
-        try:
-            os.unlink(os.path.join(CPYTHON, '.coverage'))
-        except FileNotFoundError:
-            pass
-        pythonpath = os.path.join(COVERAGE, 'coverage', 'fullcoverage')
-        process = subprocess.Popen(command, env={'PYTHONPATH': pythonpath})
-        process.wait()
-
-
-def report(args):
-    """Generate the HTML-based coverage report.
-
-    Write the results to either REPORT or a user-specified location.
-    """
-    report = os.path.abspath(args.directory)
-    title = '{} {} test coverage'.format(sys.implementation.name,
-                           sys.version.partition(' \n')[0])
-    if os.path.exists(report):
-        shutil.rmtree(report)
-    with chdir(CPYTHON):
-        subprocess.check_call([sys.executable, COVERAGE, 'html', '-i',
-                               '-d', report, '--omit', 'Lib/test/*',
-                               '--title', title])
-    print(os.path.join(report, 'index.html'))
-
-
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser()
-    subparsers = parser.add_subparsers(dest='subparser_name',
-            help="use coverage.py on Python's standard library")
-
-    build_parser = subparsers.add_parser('build',
-            help='build coverage.py using {}'.format(sys.executable))
-    build_parser.set_defaults(func=build)
-
-    stdlib_path = os.path.join(CPYTHON, 'Lib')
-    run_parser = subparsers.add_parser('run',
-            help='run coverage.py over the standard library at {} '
-                 '(coverage.py must already be built)'.format(stdlib_path))
-    run_parser.add_argument('tests', action='store', nargs='*',
-            help='optional list of tests to run (default: all tests)')
-    run_parser.set_defaults(func=run)
-
-    report_parser = subparsers.add_parser('html',
-            help='generate an HTML coverage report')
-    report_parser.add_argument('directory',
-            help='where to save the report (default: {})'.format(REPORT),
-            nargs='?', action='store', default=REPORT)
-    report_parser.set_defaults(func=report)
-
-    help_parser = subparsers.add_parser('help',
-            help='show the help message for the specified command')
-    help_parser.add_argument('command', nargs='?',
-            help='for which command to show a help message')
-
-    args = parser.parse_args()
-    if args.subparser_name != 'help':
-        args.func(args)
-    else:
-        help_args = ['-h']
-        if args.command:
-            help_args.insert(0, args.command)
-        parser.parse_args(help_args)

-- 
Repository URL: http://hg.python.org/devinabox


More information about the Python-checkins mailing list