diff options
Diffstat (limited to 'setuptools')
| -rw-r--r-- | setuptools/__init__.py | 10 | ||||
| -rw-r--r-- | setuptools/command/build_py.py | 60 | ||||
| -rw-r--r-- | setuptools/dist.py | 5 |
3 files changed, 73 insertions, 2 deletions
diff --git a/setuptools/__init__.py b/setuptools/__init__.py index aaf634da..8c3eeb6d 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -24,6 +24,16 @@ _distribute = True bootstrap_install_from = None +# Should we run 2to3 on all Python files, in Python 3.x? +# Default: no; assume that a distribution installed for 3.x is already +# written in 3.x +run_2to3 = False +# If we run 2to3 on .py files, should we also convert docstrings? +# Default: yes; assume that we can detect doctests reliably +run_2to3_on_doctests = True +# Package names for fixer packages +lib2to3_fixer_packages = ['lib2to3.fixes'] + def find_packages(where='.', exclude=()): """Return a list all Python packages found within directory 'where' diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 3fce7693..2413b420 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -3,7 +3,47 @@ from distutils.command.build_py import build_py as _build_py from distutils.util import convert_path from glob import glob -class build_py(_build_py): +try: + from distutils.util import Mixin2to3 as _Mixin2to3 + # add support for converting doctests that is missing in 3.1 distutils + from distutils import log + from lib2to3.refactor import RefactoringTool, get_fixers_from_package + import setuptools + class DistutilsRefactoringTool(RefactoringTool): + def log_error(self, msg, *args, **kw): + log.error(msg, *args) + + def log_message(self, msg, *args): + log.info(msg, *args) + + def log_debug(self, msg, *args): + log.debug(msg, *args) + + class Mixin2to3(_Mixin2to3): + def run_2to3(self, files, doctests = False): + if not setuptools.run_2to3: + return + if not files: + return + log.info("Fixing "+" ".join(files)) + if not self.fixer_names: + self.fixer_names = [] + for p in setuptools.lib2to3_fixer_packages: + self.fixer_names.extend(get_fixers_from_package(p)) + if doctests: + if setuptools.run_2to3_on_doctests: + r = DistutilsRefactoringTool(self.fixer_names) + r.refactor(files, write=True, doctests_only=True) + else: + _Mixin2to3.run_2to3(self, files) + +except ImportError: + class Mixin2to3: + def run_2to3(self, files, doctests=True): + # Nothing done in 2.x + pass + +class build_py(_build_py, Mixin2to3): """Enhanced 'build_py' command that includes data files with packages The data files are specified via a 'package_data' argument to 'setup()'. @@ -17,6 +57,8 @@ class build_py(_build_py): self.package_data = self.distribution.package_data self.exclude_package_data = self.distribution.exclude_package_data or {} if 'data_files' in self.__dict__: del self.__dict__['data_files'] + self.__updated_files = [] + self.__doctests_2to3 = [] def run(self): """Build modules, packages, and copy data files to build directory""" @@ -30,6 +72,10 @@ class build_py(_build_py): self.build_packages() self.build_package_data() + self.run_2to3(self.__updated_files, False) + self.run_2to3(self.__updated_files, True) + self.run_2to3(self.__doctests_2to3, True) + # Only compile actual .py files, using our base class' idea of what our # output files are. self.byte_compile(_build_py.get_outputs(self, include_bytecode=0)) @@ -39,6 +85,12 @@ class build_py(_build_py): self.data_files = files = self._get_data_files(); return files return _build_py.__getattr__(self,attr) + def build_module(self, module, module_file, package): + outfile, copied = _build_py.build_module(self, module, module_file, package) + if copied: + self.__updated_files.append(outfile) + return outfile, copied + def _get_data_files(self): """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" self.analyze_manifest() @@ -77,7 +129,11 @@ class build_py(_build_py): for filename in filenames: target = os.path.join(build_dir, filename) self.mkpath(os.path.dirname(target)) - self.copy_file(os.path.join(src_dir, filename), target) + srcfile = os.path.join(src_dir, filename) + outf, copied = self.copy_file(srcfile, target) + srcfile = os.path.abspath(srcfile) + if copied and srcfile in self.distribution.convert_doctests_2to3: + self.__doctests_2to3.append(outf) def analyze_manifest(self): diff --git a/setuptools/dist.py b/setuptools/dist.py index c2e57f4b..fd23d9ba 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -255,6 +255,11 @@ class Distribution(_Distribution): if value is not None: ep.require(installer=self.fetch_build_egg) ep.load()(self, ep.name, value) + if getattr(self, 'convert_doctests_2to3', None): + # XXX may convert to set here when we can rely on set being builtin + self.convert_doctests_2to3 = [os.path.abspath(p) for p in self.convert_doctests_2to3] + else: + self.convert_doctests_2to3 = [] def fetch_build_egg(self, req): """Fetch an egg needed for building""" |
