2 from setuptools import setup as _setup
4 py3_args = ['use_2to3', 'convert_2to3_doctests', 'use_2to3_fixers', 'test_dirs', 'test_build_dir', 'doctest_exts', 'pyversion_patching']
6 if sys.version_info < (3,):
7 # Remove any Python-3.x-only arguments (so they don't generate complaints
8 # from 2.x setuptools) and then just pass through to the regular setup
10 def setup(*args, **kwargs):
14 return _setup(*args, **kwargs)
20 from setuptools import Distribution as _Distribution
21 from distutils.core import Command
22 from setuptools.command.build_py import Mixin2to3
23 from distutils import dir_util, file_util, log
24 import setuptools.command.test
25 from pkg_resources import normalize_path, Environment
28 patch.logger.setLevel(logging.WARN)
32 patchfile_re = re.compile(r'(.*)\.py([0-9.]+)\.patch$')
34 def pyversion_patch(filename):
35 '''Find the best pyversion-fixup patch for a given filename and apply
38 dir, file = os.path.split(filename)
41 for dirfile in os.listdir(dir):
42 m = patchfile_re.match(dirfile)
45 base, ver = m.groups()
48 ver = tuple([int(v) for v in ver.split('.')])
49 if sys.version_info >= ver and ver > best_ver:
54 log.info("Applying %s to %s..." % (patchfile, filename))
58 p = patch.fromfile(patchfile)
64 class Distribution (_Distribution):
65 def __init__(self, attrs=None):
67 self.test_build_dir = None
68 self.doctest_exts = ['.py', '.rst']
69 self.pyversion_patching = False
70 _Distribution.__init__(self, attrs)
72 class BuildTestsCommand (Command, Mixin2to3):
73 # Create mirror copy of tests, convert all .py files using 2to3
76 def initialize_options(self):
79 def finalize_options(self):
80 test_base = self.distribution.test_build_dir
82 bcmd = self.get_finalized_command('build')
83 test_base = bcmd.build_base
84 self.test_base = test_base
87 use_2to3 = getattr(self.distribution, 'use_2to3', False)
88 test_dirs = getattr(self.distribution, 'test_dirs', [])
89 test_base = self.test_base
90 bpy_cmd = self.get_finalized_command("build_py")
91 lib_base = normalize_path(bpy_cmd.build_lib)
95 dir_util.mkpath(test_base)
96 for testdir in test_dirs:
97 for srcdir, dirnames, filenames in os.walk(testdir):
98 destdir = os.path.join(test_base, srcdir)
99 dir_util.mkpath(destdir)
101 if fn.startswith("."):
102 # Skip .svn folders and such
104 dstfile, copied = file_util.copy_file(
105 os.path.join(srcdir, fn),
106 os.path.join(destdir, fn),
109 modified.append(dstfile)
110 if fn.endswith('.py'):
111 py_modified.append(dstfile)
112 for ext in self.distribution.doctest_exts:
114 doc_modified.append(dstfile)
117 self.run_2to3(py_modified)
118 self.run_2to3(doc_modified, True)
119 if self.distribution.pyversion_patching:
120 if patch is not None:
121 for file in modified:
122 pyversion_patch(file)
124 log.warn("Warning: pyversion_patching specified in setup config but patch module not found. Patching will not be performed.")
126 dir_util.mkpath(lib_base)
127 self.reinitialize_command('egg_info', egg_base=lib_base)
128 self.run_command('egg_info')
130 class TestCommand (setuptools.command.test.test):
131 # Override 'test' command to make sure 'build_tests' gets run first.
133 self.run_command('build_tests')
134 this_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))
135 lib_dirs = glob.glob(os.path.join(this_dir, 'build', 'lib*'))
136 test_dir = os.path.join(this_dir, 'build', 'tests')
137 env = Environment(search_path=lib_dirs)
138 distributions = env["nose"]
139 assert len(distributions) == 1, (
140 "Incorrect number of distributions found")
141 dist = distributions[0]
143 sys.path.insert(0, test_dir)
144 setuptools.command.test.test.run(self)
146 def setup(*args, **kwargs):
147 kwargs.setdefault('distclass', Distribution)
148 cmdclass = kwargs.setdefault('cmdclass', {})
149 cmdclass.setdefault('build_tests', BuildTestsCommand)
150 cmdclass.setdefault('test', TestCommand)
151 return _setup(*args, **kwargs)