| | import os |
| | import sys |
| | from itertools import product, starmap |
| | import distutils.command.install_lib as orig |
| |
|
| |
|
| | class install_lib(orig.install_lib): |
| | """Don't add compiled flags to filenames of non-Python files""" |
| |
|
| | def initialize_options(self): |
| | orig.install_lib.initialize_options(self) |
| | self.multiarch = None |
| | self.install_layout = None |
| |
|
| | def finalize_options(self): |
| | orig.install_lib.finalize_options(self) |
| | self.set_undefined_options('install',('install_layout','install_layout')) |
| | if self.install_layout == 'deb' and sys.version_info[:2] >= (3, 3): |
| | import sysconfig |
| | self.multiarch = sysconfig.get_config_var('MULTIARCH') |
| |
|
| | def run(self): |
| | self.build() |
| | outfiles = self.install() |
| | if outfiles is not None: |
| | |
| | self.byte_compile(outfiles) |
| |
|
| | def get_exclusions(self): |
| | """ |
| | Return a collections.Sized collections.Container of paths to be |
| | excluded for single_version_externally_managed installations. |
| | """ |
| | all_packages = ( |
| | pkg |
| | for ns_pkg in self._get_SVEM_NSPs() |
| | for pkg in self._all_packages(ns_pkg) |
| | ) |
| |
|
| | excl_specs = product(all_packages, self._gen_exclusion_paths()) |
| | return set(starmap(self._exclude_pkg_path, excl_specs)) |
| |
|
| | def _exclude_pkg_path(self, pkg, exclusion_path): |
| | """ |
| | Given a package name and exclusion path within that package, |
| | compute the full exclusion path. |
| | """ |
| | parts = pkg.split('.') + [exclusion_path] |
| | return os.path.join(self.install_dir, *parts) |
| |
|
| | @staticmethod |
| | def _all_packages(pkg_name): |
| | """ |
| | >>> list(install_lib._all_packages('foo.bar.baz')) |
| | ['foo.bar.baz', 'foo.bar', 'foo'] |
| | """ |
| | while pkg_name: |
| | yield pkg_name |
| | pkg_name, sep, child = pkg_name.rpartition('.') |
| |
|
| | def _get_SVEM_NSPs(self): |
| | """ |
| | Get namespace packages (list) but only for |
| | single_version_externally_managed installations and empty otherwise. |
| | """ |
| | |
| | |
| | |
| | if not self.distribution.namespace_packages: |
| | return [] |
| |
|
| | install_cmd = self.get_finalized_command('install') |
| | svem = install_cmd.single_version_externally_managed |
| |
|
| | return self.distribution.namespace_packages if svem else [] |
| |
|
| | @staticmethod |
| | def _gen_exclusion_paths(): |
| | """ |
| | Generate file paths to be excluded for namespace packages (bytecode |
| | cache files). |
| | """ |
| | |
| | yield '__init__.py' |
| |
|
| | yield '__init__.pyc' |
| | yield '__init__.pyo' |
| |
|
| | if not hasattr(sys, 'implementation'): |
| | return |
| |
|
| | base = os.path.join( |
| | '__pycache__', '__init__.' + sys.implementation.cache_tag) |
| | yield base + '.pyc' |
| | yield base + '.pyo' |
| | yield base + '.opt-1.pyc' |
| | yield base + '.opt-2.pyc' |
| |
|
| | def copy_tree( |
| | self, infile, outfile, |
| | preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 |
| | ): |
| | assert preserve_mode and preserve_times and not preserve_symlinks |
| | exclude = self.get_exclusions() |
| |
|
| | if not exclude: |
| | import distutils.dir_util |
| | distutils.dir_util._multiarch = self.multiarch |
| | return orig.install_lib.copy_tree(self, infile, outfile) |
| |
|
| | |
| |
|
| | from setuptools.archive_util import unpack_directory |
| | from distutils import log |
| |
|
| | outfiles = [] |
| |
|
| | if self.multiarch: |
| | import sysconfig |
| | ext_suffix = sysconfig.get_config_var ('EXT_SUFFIX') |
| | if ext_suffix.endswith(self.multiarch + ext_suffix[-3:]): |
| | new_suffix = None |
| | else: |
| | new_suffix = "%s-%s%s" % (ext_suffix[:-3], self.multiarch, ext_suffix[-3:]) |
| |
|
| | def pf(src, dst): |
| | if dst in exclude: |
| | log.warn("Skipping installation of %s (namespace package)", |
| | dst) |
| | return False |
| |
|
| | if self.multiarch and new_suffix and dst.endswith(ext_suffix) and not dst.endswith(new_suffix): |
| | dst = dst.replace(ext_suffix, new_suffix) |
| | log.info("renaming extension to %s", os.path.basename(dst)) |
| |
|
| | log.info("copying %s -> %s", src, os.path.dirname(dst)) |
| | outfiles.append(dst) |
| | return dst |
| |
|
| | unpack_directory(infile, outfile, pf) |
| | return outfiles |
| |
|
| | def get_outputs(self): |
| | outputs = orig.install_lib.get_outputs(self) |
| | exclude = self.get_exclusions() |
| | if exclude: |
| | return [f for f in outputs if f not in exclude] |
| | return outputs |
| |
|