python (3.11.7)
       1  import os
       2  import sys
       3  from itertools import product, starmap
       4  import distutils.command.install_lib as orig
       5  
       6  
       7  class ESC[4;38;5;81minstall_lib(ESC[4;38;5;149morigESC[4;38;5;149m.ESC[4;38;5;149minstall_lib):
       8      """Don't add compiled flags to filenames of non-Python files"""
       9  
      10      def run(self):
      11          self.build()
      12          outfiles = self.install()
      13          if outfiles is not None:
      14              # always compile, in case we have any extension stubs to deal with
      15              self.byte_compile(outfiles)
      16  
      17      def get_exclusions(self):
      18          """
      19          Return a collections.Sized collections.Container of paths to be
      20          excluded for single_version_externally_managed installations.
      21          """
      22          all_packages = (
      23              pkg
      24              for ns_pkg in self._get_SVEM_NSPs()
      25              for pkg in self._all_packages(ns_pkg)
      26          )
      27  
      28          excl_specs = product(all_packages, self._gen_exclusion_paths())
      29          return set(starmap(self._exclude_pkg_path, excl_specs))
      30  
      31      def _exclude_pkg_path(self, pkg, exclusion_path):
      32          """
      33          Given a package name and exclusion path within that package,
      34          compute the full exclusion path.
      35          """
      36          parts = pkg.split('.') + [exclusion_path]
      37          return os.path.join(self.install_dir, *parts)
      38  
      39      @staticmethod
      40      def _all_packages(pkg_name):
      41          """
      42          >>> list(install_lib._all_packages('foo.bar.baz'))
      43          ['foo.bar.baz', 'foo.bar', 'foo']
      44          """
      45          while pkg_name:
      46              yield pkg_name
      47              pkg_name, sep, child = pkg_name.rpartition('.')
      48  
      49      def _get_SVEM_NSPs(self):
      50          """
      51          Get namespace packages (list) but only for
      52          single_version_externally_managed installations and empty otherwise.
      53          """
      54          # TODO: is it necessary to short-circuit here? i.e. what's the cost
      55          # if get_finalized_command is called even when namespace_packages is
      56          # False?
      57          if not self.distribution.namespace_packages:
      58              return []
      59  
      60          install_cmd = self.get_finalized_command('install')
      61          svem = install_cmd.single_version_externally_managed
      62  
      63          return self.distribution.namespace_packages if svem else []
      64  
      65      @staticmethod
      66      def _gen_exclusion_paths():
      67          """
      68          Generate file paths to be excluded for namespace packages (bytecode
      69          cache files).
      70          """
      71          # always exclude the package module itself
      72          yield '__init__.py'
      73  
      74          yield '__init__.pyc'
      75          yield '__init__.pyo'
      76  
      77          if not hasattr(sys, 'implementation'):
      78              return
      79  
      80          base = os.path.join(
      81              '__pycache__', '__init__.' + sys.implementation.cache_tag)
      82          yield base + '.pyc'
      83          yield base + '.pyo'
      84          yield base + '.opt-1.pyc'
      85          yield base + '.opt-2.pyc'
      86  
      87      def copy_tree(
      88              self, infile, outfile,
      89              preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1
      90      ):
      91          assert preserve_mode and preserve_times and not preserve_symlinks
      92          exclude = self.get_exclusions()
      93  
      94          if not exclude:
      95              return orig.install_lib.copy_tree(self, infile, outfile)
      96  
      97          # Exclude namespace package __init__.py* files from the output
      98  
      99          from setuptools.archive_util import unpack_directory
     100          from distutils import log
     101  
     102          outfiles = []
     103  
     104          def pf(src, dst):
     105              if dst in exclude:
     106                  log.warn("Skipping installation of %s (namespace package)",
     107                           dst)
     108                  return False
     109  
     110              log.info("copying %s -> %s", src, os.path.dirname(dst))
     111              outfiles.append(dst)
     112              return dst
     113  
     114          unpack_directory(infile, outfile, pf)
     115          return outfiles
     116  
     117      def get_outputs(self):
     118          outputs = orig.install_lib.get_outputs(self)
     119          exclude = self.get_exclusions()
     120          if exclude:
     121              return [f for f in outputs if f not in exclude]
     122          return outputs