Imported Upstream version 1.2.1
[platform/upstream/python-nose.git] / setup3lib.py
1 import sys
2 from setuptools import setup as _setup
3
4 py3_args = ['use_2to3', 'convert_2to3_doctests', 'use_2to3_fixers', 'test_dirs', 'test_build_dir', 'doctest_exts', 'pyversion_patching']
5
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
9     # routine.
10     def setup(*args, **kwargs):
11         for a in py3_args:
12             if a in kwargs:
13                 del kwargs[a]
14         return _setup(*args, **kwargs)
15 else:
16     import glob
17     import os
18     import re
19     import logging
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
26     try:
27         import patch
28         patch.logger.setLevel(logging.WARN)
29     except ImportError:
30         patch = None
31
32     patchfile_re = re.compile(r'(.*)\.py([0-9.]+)\.patch$')
33
34     def pyversion_patch(filename):
35         '''Find the best pyversion-fixup patch for a given filename and apply
36            it.
37         '''
38         dir, file = os.path.split(filename)
39         best_ver = (0,)
40         patchfile = None
41         for dirfile in os.listdir(dir):
42             m = patchfile_re.match(dirfile)
43             if not m:
44                 continue
45             base, ver = m.groups()
46             if base != file:
47                 continue
48             ver = tuple([int(v) for v in ver.split('.')])
49             if sys.version_info >= ver and ver > best_ver:
50                 best_ver = ver
51                 patchfile = dirfile
52         if not patchfile:
53             return False
54         log.info("Applying %s to %s..." % (patchfile, filename))
55         cwd = os.getcwd()
56         os.chdir(dir)
57         try:
58             p = patch.fromfile(patchfile)
59             p.apply()
60         finally:
61             os.chdir(cwd)
62         return True
63
64     class Distribution (_Distribution):
65         def __init__(self, attrs=None):
66             self.test_dirs = []
67             self.test_build_dir = None
68             self.doctest_exts = ['.py', '.rst']
69             self.pyversion_patching = False
70             _Distribution.__init__(self, attrs)
71
72     class BuildTestsCommand (Command, Mixin2to3):
73         # Create mirror copy of tests, convert all .py files using 2to3
74         user_options = []
75
76         def initialize_options(self):
77             self.test_base = None
78
79         def finalize_options(self):
80             test_base = self.distribution.test_build_dir
81             if not test_base:
82                 bcmd = self.get_finalized_command('build')
83                 test_base = bcmd.build_base
84             self.test_base = test_base
85
86         def run(self):
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)
92             modified = []
93             py_modified = []
94             doc_modified = []
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)
100                 for fn in filenames:
101                     if fn.startswith("."):
102                         # Skip .svn folders and such
103                         continue
104                     dstfile, copied = file_util.copy_file(
105                                           os.path.join(srcdir, fn),
106                                           os.path.join(destdir, fn),
107                                           update=True)
108                     if copied:
109                         modified.append(dstfile)
110                         if fn.endswith('.py'):
111                             py_modified.append(dstfile)
112                         for ext in self.distribution.doctest_exts:
113                             if fn.endswith(ext):
114                                 doc_modified.append(dstfile)
115                                 break
116             if use_2to3:
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)
123                 else:
124                     log.warn("Warning: pyversion_patching specified in setup config but patch module not found.  Patching will not be performed.")
125
126             dir_util.mkpath(lib_base)
127             self.reinitialize_command('egg_info', egg_base=lib_base)
128             self.run_command('egg_info')
129
130     class TestCommand (setuptools.command.test.test):
131         # Override 'test' command to make sure 'build_tests' gets run first.
132         def run(self):
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]
142             dist.activate()
143             sys.path.insert(0, test_dir)
144             setuptools.command.test.test.run(self)
145
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)