1 # setup.py for coverage.py
3 """Code coverage measurement for Python
5 Coverage.py measures code coverage, typically during test execution. It uses
6 the code analysis tools and tracing hooks provided in the Python standard
7 library to determine which lines are executable, and which have been executed.
9 Coverage.py runs on Pythons 2.3 through 3.3, and PyPy 1.9.
11 Documentation is at `nedbatchelder.com <%s>`_. Code repository and issue
12 tracker are on `Bitbucket <http://bitbucket.org/ned/coveragepy>`_, with a
13 mirrored repo on `Github <https://github.com/nedbat/coveragepy>`_.
15 New in 3.7: ``--debug``, and 12 bugs closed.
17 New in 3.6: ``--fail-under``, and >20 bugs closed.
19 New in 3.5: Branch coverage exclusions, keyboard shortcuts in HTML report.
21 New in 3.4: Better control over source to measure, and unexecuted files
24 New in 3.3: .coveragerc files.
26 New in 3.2: Branch coverage!
29 # This file is used unchanged under all versions of Python, 2.x and 3.x.
32 Environment :: Console
33 Intended Audience :: Developers
34 License :: OSI Approved :: BSD License
35 Operating System :: OS Independent
36 Programming Language :: Python :: 2
37 Programming Language :: Python :: 3
38 Topic :: Software Development :: Quality Assurance
39 Topic :: Software Development :: Testing
42 # Pull in the tools we need.
45 from setuptools
import setup
46 from distutils
.core
import Extension
# pylint: disable=E0611,F0401
47 from distutils
.command
.build_ext
import build_ext
# pylint: disable=E0611,F0401,C0301
48 from distutils
import errors
# pylint: disable=E0611,F0401
50 # Get or massage our metadata. We exec coverage/version.py so we can avoid
51 # importing the product code into setup.py.
53 doc
= __doc__
# __doc__ will be overwritten by version.py.
54 __version__
= __url__
= "" # Keep pylint happy.
56 cov_ver_py
= os
.path
.join(os
.path
.split(__file__
)[0], "coverage/version.py")
57 version_file
= open(cov_ver_py
)
59 exec(compile(version_file
.read(), cov_ver_py
, 'exec'))
63 doclines
= (doc
% __url__
).splitlines()
64 classifier_list
= classifiers
.splitlines()
66 if 'a' in __version__
:
68 elif 'b' in __version__
:
71 devstat
= "5 - Production/Stable"
72 classifier_list
.append("Development Status :: " + devstat
)
74 # Install a script as "coverage", and as "coverage[23]", and as
75 # "coverage-2.7" (or whatever).
77 'coverage = coverage:main',
78 'coverage%d = coverage:main' % sys
.version_info
[:1],
79 'coverage-%d.%d = coverage:main' % sys
.version_info
[:2],
82 # Create the keyword arguments for setup()
86 version
= __version__
,
98 entry_points
= {'console_scripts': scripts
},
100 # We need to get HTML assets from our htmlfiles dir.
103 author
= 'Ned Batchelder and others',
104 author_email
= 'ned@nedbatchelder.com',
105 description
= doclines
[0],
106 long_description
= '\n'.join(doclines
[2:]),
107 keywords
= 'code coverage testing',
109 classifiers
= classifier_list
,
113 # A replacement for the build_ext command which raises a single exception
114 # if the build fails, so we can fallback nicely.
117 errors
.CCompilerError
,
118 errors
.DistutilsExecError
,
119 errors
.DistutilsPlatformError
,
121 if sys
.platform
== 'win32' and sys
.version_info
> (2, 6):
122 # 2.6's distutils.msvc9compiler can raise an IOError when failing to
124 ext_errors
+= (IOError,)
126 class BuildFailed(Exception):
127 """Raise this to indicate the C extension wouldn't build."""
129 Exception.__init
__(self
)
130 self
.cause
= sys
.exc_info()[1] # work around py 2/3 different syntax
132 class ve_build_ext(build_ext
):
133 """Build C extensions, but fail with a straightforward exception."""
136 """Wrap `run` with `BuildFailed`."""
139 except errors
.DistutilsPlatformError
:
142 def build_extension(self
, ext
):
143 """Wrap `build_extension` with `BuildFailed`."""
145 # Uncomment to test compile failures:
146 # raise errors.CCompilerError("OOPS")
147 build_ext
.build_extension(self
, ext
)
151 # this can happen on Windows 64 bit, see Python issue 7511
152 if "'path'" in str(sys
.exc_info()[1]): # works with both py 2/3
156 # There are a few reasons we might not be able to compile the C extension.
157 # Figure out if we should attempt the C extension or not.
159 compile_extension
= True
161 if sys
.platform
.startswith('java'):
162 # Jython can't compile C extensions
163 compile_extension
= False
165 if '__pypy__' in sys
.builtin_module_names
:
166 # Pypy can't compile C extensions
167 compile_extension
= False
169 if compile_extension
:
170 setup_args
.update(dict(
172 Extension("coverage.tracer", sources
=["coverage/tracer.c"])
175 'build_ext': ve_build_ext
,
179 # Py3.x-specific details.
181 if sys
.version_info
>= (3, 0):
182 setup_args
.update(dict(
187 """Actually invoke setup() with the arguments we built above."""
188 # For a variety of reasons, it might not be possible to install the C
189 # extension. Try it with, and if it fails, try it without.
193 msg
= "Couldn't install with extension module, trying without it..."
194 exc
= sys
.exc_info()[1]
195 exc_msg
= "%s: %s" % (exc
.__class
__.__name
__, exc
.cause
)
196 print("**\n** %s\n** %s\n**" % (msg
, exc_msg
))
198 del setup_args
['ext_modules']
201 if __name__
== '__main__':