| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import sys
- from setuptools import setup as _setup
- py3_args = ['use_2to3', 'convert_2to3_doctests', 'use_2to3_fixers', 'test_dirs', 'test_build_dir', 'doctest_exts', 'pyversion_patching']
- if sys.version_info < (3,):
- # Remove any Python-3.x-only arguments (so they don't generate complaints
- # from 2.x setuptools) and then just pass through to the regular setup
- # routine.
- def setup(*args, **kwargs):
- for a in py3_args:
- if a in kwargs:
- del kwargs[a]
- return _setup(*args, **kwargs)
- else:
- import os
- import re
- import logging
- from setuptools import Distribution as _Distribution
- from distutils.core import Command
- from setuptools.command.build_py import Mixin2to3
- from distutils import dir_util, file_util, log
- import setuptools.command.test
- from pkg_resources import normalize_path
- try:
- import patch
- patch.logger.setLevel(logging.WARN)
- except ImportError:
- patch = None
- patchfile_re = re.compile(r'(.*)\.py([0-9.]+)\.patch$')
- def pyversion_patch(filename):
- '''Find the best pyversion-fixup patch for a given filename and apply
- it.
- '''
- dir, file = os.path.split(filename)
- best_ver = (0,)
- patchfile = None
- for dirfile in os.listdir(dir):
- m = patchfile_re.match(dirfile)
- if not m:
- continue
- base, ver = m.groups()
- if base != file:
- continue
- ver = tuple([int(v) for v in ver.split('.')])
- if sys.version_info >= ver and ver > best_ver:
- best_ver = ver
- patchfile = dirfile
- if not patchfile:
- return False
- log.info("Applying %s to %s..." % (patchfile, filename))
- cwd = os.getcwd()
- os.chdir(dir)
- try:
- p = patch.fromfile(patchfile)
- p.apply()
- finally:
- os.chdir(cwd)
- return True
- class Distribution (_Distribution):
- def __init__(self, attrs=None):
- self.test_dirs = []
- self.test_build_dir = None
- self.doctest_exts = ['.py', '.rst']
- self.pyversion_patching = False
- _Distribution.__init__(self, attrs)
- class BuildTestsCommand (Command, Mixin2to3):
- # Create mirror copy of tests, convert all .py files using 2to3
- user_options = []
- def initialize_options(self):
- self.test_base = None
- def finalize_options(self):
- test_base = self.distribution.test_build_dir
- if not test_base:
- bcmd = self.get_finalized_command('build')
- test_base = bcmd.build_base
- self.test_base = test_base
- def run(self):
- use_2to3 = getattr(self.distribution, 'use_2to3', False)
- test_dirs = getattr(self.distribution, 'test_dirs', [])
- test_base = self.test_base
- bpy_cmd = self.get_finalized_command("build_py")
- lib_base = normalize_path(bpy_cmd.build_lib)
- modified = []
- py_modified = []
- doc_modified = []
- dir_util.mkpath(test_base)
- for testdir in test_dirs:
- for srcdir, dirnames, filenames in os.walk(testdir):
- destdir = os.path.join(test_base, srcdir)
- dir_util.mkpath(destdir)
- for fn in filenames:
- if fn.startswith("."):
- # Skip .svn folders and such
- continue
- dstfile, copied = file_util.copy_file(
- os.path.join(srcdir, fn),
- os.path.join(destdir, fn),
- update=True)
- if copied:
- modified.append(dstfile)
- if fn.endswith('.py'):
- py_modified.append(dstfile)
- for ext in self.distribution.doctest_exts:
- if fn.endswith(ext):
- doc_modified.append(dstfile)
- break
- if use_2to3:
- self.run_2to3(py_modified)
- self.run_2to3(doc_modified, True)
- if self.distribution.pyversion_patching:
- if patch is not None:
- for file in modified:
- pyversion_patch(file)
- else:
- log.warn("Warning: pyversion_patching specified in setup config but patch module not found. Patching will not be performed.")
- dir_util.mkpath(lib_base)
- self.reinitialize_command('egg_info', egg_base=lib_base)
- self.run_command('egg_info')
- class TestCommand (setuptools.command.test.test):
- # Override 'test' command to make sure 'build_tests' gets run first.
- def run(self):
- self.run_command('build_tests')
- setuptools.command.test.test.run(self)
- def setup(*args, **kwargs):
- kwargs.setdefault('distclass', Distribution)
- cmdclass = kwargs.setdefault('cmdclass', {})
- cmdclass.setdefault('build_tests', BuildTestsCommand)
- cmdclass.setdefault('test', TestCommand)
- return _setup(*args, **kwargs)
|