1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
4 """Code coverage measurement for Python"""
6 # Distutils setup for coverage.py
7 # This file is used unchanged under all versions of Python, 2.x and 3.x.
12 from setuptools
import setup
13 from distutils
.core
import Extension
# pylint: disable=no-name-in-module, import-error
14 from distutils
.command
.build_ext
import build_ext
# pylint: disable=no-name-in-module, import-error
15 from distutils
import errors
# pylint: disable=no-name-in-module
17 # Get or massage our metadata. We exec coverage/version.py so we can avoid
18 # importing the product code into setup.py.
21 Environment :: Console
22 Intended Audience :: Developers
23 License :: OSI Approved :: Apache Software License
24 Operating System :: OS Independent
25 Programming Language :: Python :: 2.6
26 Programming Language :: Python :: 2.7
27 Programming Language :: Python :: 3.3
28 Programming Language :: Python :: 3.4
29 Programming Language :: Python :: 3.5
30 Programming Language :: Python :: 3.6
31 Programming Language :: Python :: Implementation :: CPython
32 Programming Language :: Python :: Implementation :: PyPy
33 Topic :: Software Development :: Quality Assurance
34 Topic :: Software Development :: Testing
37 cov_ver_py
= os
.path
.join(os
.path
.split(__file__
)[0], "coverage/version.py")
38 with
open(cov_ver_py
) as version_file
:
39 # __doc__ will be overwritten by version.py.
42 __version__
= __url__
= version_info
= ""
43 # Execute the code in version.py.
44 exec(compile(version_file
.read(), cov_ver_py
, 'exec'))
46 with
open("README.rst") as readme
:
47 long_description
= readme
.read().replace("http://coverage.readthedocs.io", __url__
)
49 classifier_list
= classifiers
.splitlines()
51 if version_info
[3] == 'alpha':
53 elif version_info
[3] in ['beta', 'candidate']:
56 assert version_info
[3] == 'final'
57 devstat
= "5 - Production/Stable"
58 classifier_list
.append("Development Status :: " + devstat
)
60 # Create the keyword arguments for setup()
77 # Install a script as "coverage", and as "coverage[23]", and as
78 # "coverage-2.7" (or whatever).
80 'coverage = coverage.cmdline:main',
81 'coverage%d = coverage.cmdline:main' % sys
.version_info
[:1],
82 'coverage-%d.%d = coverage.cmdline:main' % sys
.version_info
[:2],
86 # We need to get HTML assets from our htmlfiles directory.
89 author
='Ned Batchelder and others',
90 author_email
='ned@nedbatchelder.com',
92 long_description
=long_description
,
93 keywords
='code coverage testing',
95 classifiers
=classifier_list
,
99 # A replacement for the build_ext command which raises a single exception
100 # if the build fails, so we can fallback nicely.
103 errors
.CCompilerError
,
104 errors
.DistutilsExecError
,
105 errors
.DistutilsPlatformError
,
107 if sys
.platform
== 'win32':
108 # distutils.msvc9compiler can raise an IOError when failing to
110 ext_errors
+= (IOError,)
113 class BuildFailed(Exception):
114 """Raise this to indicate the C extension wouldn't build."""
116 Exception.__init
__(self
)
117 self
.cause
= sys
.exc_info()[1] # work around py 2/3 different syntax
120 class ve_build_ext(build_ext
):
121 """Build C extensions, but fail with a straightforward exception."""
124 """Wrap `run` with `BuildFailed`."""
127 except errors
.DistutilsPlatformError
:
130 def build_extension(self
, ext
):
131 """Wrap `build_extension` with `BuildFailed`."""
133 # Uncomment to test compile failure handling:
134 # raise errors.CCompilerError("OOPS")
135 build_ext
.build_extension(self
, ext
)
138 except ValueError as err
:
139 # this can happen on Windows 64 bit, see Python issue 7511
140 if "'path'" in str(err
): # works with both py 2/3
144 # There are a few reasons we might not be able to compile the C extension.
145 # Figure out if we should attempt the C extension or not.
147 compile_extension
= True
149 if sys
.platform
.startswith('java'):
150 # Jython can't compile C extensions
151 compile_extension
= False
153 if '__pypy__' in sys
.builtin_module_names
:
154 # Pypy can't compile C extensions
155 compile_extension
= False
157 if compile_extension
:
158 setup_args
.update(dict(
163 "coverage/ctracer/datastack.c",
164 "coverage/ctracer/filedisp.c",
165 "coverage/ctracer/module.c",
166 "coverage/ctracer/tracer.c",
171 'build_ext': ve_build_ext
,
175 # Py3.x-specific details.
177 if sys
.version_info
>= (3, 0):
178 setup_args
.update(dict(
184 """Actually invoke setup() with the arguments we built above."""
185 # For a variety of reasons, it might not be possible to install the C
186 # extension. Try it with, and if it fails, try it without.
189 except BuildFailed
as exc
:
190 msg
= "Couldn't install with extension module, trying without it..."
191 exc_msg
= "%s: %s" % (exc
.__class
__.__name
__, exc
.cause
)
192 print("**\n** %s\n** %s\n**" % (msg
, exc_msg
))
194 del setup_args
['ext_modules']
197 if __name__
== '__main__':