예제 #1
0
 def _pyenv_scheme_path(self, path):
     pyenv = self.pypmenv.pyenv
     fullpath = pyenv.get_install_scheme_path(path)
     assert fullpath.startswith(pyenv.base_dir), \
         "'%s' is not based on '%s' (%s)" % (
         fullpath, pyenv.base_dir, pyenv.root_dir)
     p = os.path.relpath(fullpath, pyenv.base_dir)
     if PLATNAME.startswith('win'):
         p = p.replace('\\', '/')
     return p
예제 #2
0
 def _pyenv_scheme_path(self, path):
     pyenv = self.pypmenv.pyenv
     fullpath = pyenv.get_install_scheme_path(path)
     assert fullpath.startswith(pyenv.base_dir), \
         "'%s' is not based on '%s' (%s)" % (
         fullpath, pyenv.base_dir, pyenv.root_dir)
     p = os.path.relpath(fullpath, pyenv.base_dir)
     if PLATNAME.startswith('win'):
         p = p.replace('\\', '/')
     return p
예제 #3
0
    def get_install_scheme_path(self, path, usersite=False):
        if self.pyversion_info[:2] not in ((2, 6), (3, 1)):
            # use the `sysconfig` module that was introduced in Python 2.7

            # Find the desired scheme; alas, there is no standard function for
            # this in the stdlib. See http://bugs.python.org/issue8772
            # The following should work on default ActivePython installation.
            scheme = os.name
            if usersite:
                if PLATNAME.startswith('mac'):
                    scheme = 'osx_framework_user'
                else:
                    scheme += '_user'
            elif scheme == 'posix':
                scheme = 'posix_prefix'

            return self.eval("sysconfig.get_paths('%s')['%s']" %
                             (scheme, path),
                             with_modules=['sysconfig']).strip()
        else:
            # backward compat: use the limited `distutils.sysconfig` module on
            # 2.6. Unlike 2.7's sysconfig, this does not have the convenient
            # `get_paths` function ... forcing us to do the template
            # substitution ourselves, which may be error prone. :-/

            # HACK: 2.6 does not have a path named 'stdlib'; let's just use
            # purelib, which is usually site-packages/ and go one-level up to
            # get the intended stdlib.
            if path == 'stdlib':
                joinwith = '..'
                path = 'purelib'
            else:
                joinwith = None

            if PLATNAME.startswith('win'):
                scheme = 'nt'
            else:
                scheme = 'unix'
            scheme += ('_user' if usersite else
                       ('_prefix' if scheme == 'unix' else ''))

            template = self.eval(
                "INSTALL_SCHEMES['%s']['%s']" % (scheme, path),
                preimport_stmts=[
                    "import os",
                    "from distutils.command.install import INSTALL_SCHEMES",
                ]).strip()

            # hardcoded template substitution (distutils API does not provide
            # this)
            template = template.replace('$base', self.base_dir)
            template = template.replace('$py_version_short', self.pyver)
            if '$user' in template:
                assert isinstance(self, UserLocalPythonEnvironment)
                template = template.replace('$usersite', self.user_site_dir)
                template = template.replace('$userbase', self.user_base_dir)
            assert '$' not in template, \
                    'Unsubstituded variables left in "%s"' % template

            if joinwith:
                template = os.path.join(template, joinwith)

            return template
예제 #4
0
    def get_install_scheme_path(self, path, usersite=False):
        if self.pyversion_info[:2] not in  ((2,6), (3,1)):
            # use the `sysconfig` module that was introduced in Python 2.7

            # Find the desired scheme; alas, there is no standard function for
            # this in the stdlib. See http://bugs.python.org/issue8772 
            # The following should work on default ActivePython installation.
            scheme = os.name
            if usersite:
                if PLATNAME.startswith('mac'):
                    scheme = 'osx_framework_user'
                else:
                    scheme += '_user'
            elif scheme == 'posix':
                scheme = 'posix_prefix'

            return self.eval(
                "sysconfig.get_paths('%s')['%s']" % (scheme, path),
                with_modules=['sysconfig']
            ).strip()
        else:
            # backward compat: use the limited `distutils.sysconfig` module on
            # 2.6. Unlike 2.7's sysconfig, this does not have the convenient
            # `get_paths` function ... forcing us to do the template
            # substitution ourselves, which may be error prone. :-/
            
            # HACK: 2.6 does not have a path named 'stdlib'; let's just use
            # purelib, which is usually site-packages/ and go one-level up to
            # get the intended stdlib.
            if path == 'stdlib':
                joinwith = '..'
                path = 'purelib'
            else:
                joinwith = None

            if PLATNAME.startswith('win'):
                scheme = 'nt'
            else:
                scheme = 'unix'
            scheme += ('_user' if usersite else (
                '_prefix' if scheme == 'unix' else ''))

            template = self.eval(
                "INSTALL_SCHEMES['%s']['%s']" % (scheme, path), 
                preimport_stmts=[
                    "import os",
                    "from distutils.command.install import INSTALL_SCHEMES",
            ]).strip()

            # hardcoded template substitution (distutils API does not provide
            # this)
            template = template.replace('$base', self.base_dir)
            template = template.replace('$py_version_short', self.pyver)
            if '$user' in template:
                assert isinstance(self, UserLocalPythonEnvironment)
                template = template.replace('$usersite', self.user_site_dir)
                template = template.replace('$userbase', self.user_base_dir)
            assert '$' not in template, \
                    'Unsubstituded variables left in "%s"' % template

            if joinwith:
                template = os.path.join(template, joinwith)
                
            return template
예제 #5
0
    def _extract_to_install_scheme(self, bpkgfile, name):
        pyenv = self.pypmenv.pyenv
        # Install scheme used by the build environment (i.e., pyenv used by
        # pypm-builder on our build machines).
        as_build_scheme = {
            'win': {
                'purelib': 'lib/site-packages',
                'stdlib': 'lib',
                'scripts': 'scripts',
            },
            'unix': {
                'purelib': 'lib/python{0}/site-packages'.format(pyenv.pyver),
                'stdlib': 'lib/python{0}'.format(pyenv.pyver),
                'scripts': 'bin',
            },
        }
        plat = PLATNAME.startswith('win') and 'win' or 'unix'

        # Scheme used by pyenv
        pyenv_scheme = {
            'purelib': self._pyenv_scheme_path('purelib'),
            'stdlib': self._pyenv_scheme_path('stdlib'),
            'scripts': self._pyenv_scheme_path('scripts'),
        }

        files_to_overwrite = []
        force_overwrite = self.pypmenv.options['force']
        # Hack #1: Don't check for distribute and pip, as virtualenvs usually
        # already have a copy of them installed.
        if name in ('distribute', 'setuptools', 'pip'):
            force_overwrite = True

        with bpkgfile.extract_over2(pyenv.base_dir) as tf:
            for tinfo in tf.getmembers():
                # Replace AS build virtualenv scheme with the user's scheme
                # Eg: lib/site-packages/XYZ -> %APPDATA%/Python/Python26/XYZ
                for name, prefix in as_build_scheme[plat].items():
                    if tinfo.name.lower().startswith(prefix):
                        old = tinfo.name
                        new = pyenv_scheme[name] + old[len(prefix):]
                        if new != old:
                            LOG.debug('fs:extract: transforming "%s" to "%s"',
                                      old, new)
                            tinfo.name = new

                # Check for overwrites
                if os.path.lexists(
                        tinfo.name) and not os.path.isdir(tinfo.name):
                    # Hack #2: allow overwriting of *.pth files (setuptools
                    # hackishness) eg: [...]/site-packages/setuptools.pth
                    if not tinfo.name.endswith('.pth'):
                        files_to_overwrite.append(tinfo.name)

            if files_to_overwrite:

                LOG.debug(
                    'install requires overwriting of %d files:\n%s',
                    len(files_to_overwrite), '\n'.join([
                        os.path.join(pyenv.base_dir, f)
                        for f in files_to_overwrite
                    ]))
                if force_overwrite:
                    LOG.warn('overwriting %d files' % len(files_to_overwrite))
                else:
                    errmsg = [
                        'cannot overwrite "%s"' % concise_path(
                            os.path.join(pyenv.base_dir,
                                         files_to_overwrite[0]))
                    ]
                    if len(files_to_overwrite) > 1:
                        errmsg.append(' (and %d other files)' %
                                      (len(files_to_overwrite) - 1, ))
                    errmsg.append(
                        '; run pypm as "pypm --force ..." to overwrite anyway')
                    if len(files_to_overwrite) > 1:
                        errmsg.append(
                            '; run "pypm log" to see the full list of files to be overwritten'
                        )
                    raise IOError(wrapped(''.join(errmsg)))

            return tf.getnames()
예제 #6
0
    def _extract_to_install_scheme(self, bpkgfile, name):
        pyenv = self.pypmenv.pyenv
        # Install scheme used by the build environment (i.e., pyenv used by
        # pypm-builder on our build machines).
        as_build_scheme = {
            'win': {
                'purelib': 'lib/site-packages',
                'stdlib':  'lib',
                'scripts': 'scripts',
            },
            'unix': {
                'purelib': 'lib/python{0}/site-packages'.format(pyenv.pyver),
                'stdlib':  'lib/python{0}'.format(pyenv.pyver),
                'scripts': 'bin',
            },
        }
        plat = PLATNAME.startswith('win') and 'win' or 'unix'

        # Scheme used by pyenv
        pyenv_scheme = {
            'purelib': self._pyenv_scheme_path('purelib'),
            'stdlib':  self._pyenv_scheme_path('stdlib'),
            'scripts': self._pyenv_scheme_path('scripts'),
        }
        
        files_to_overwrite = []
        force_overwrite = self.pypmenv.options['force']
        # Hack #1: Don't check for distribute and pip, as virtualenvs usually
        # already have a copy of them installed.
        if name in ('distribute', 'setuptools', 'pip'):
            force_overwrite = True

        with bpkgfile.extract_over2(pyenv.base_dir) as tf:
            for tinfo in tf.getmembers():
                # Replace AS build virtualenv scheme with the user's scheme
                # Eg: lib/site-packages/XYZ -> %APPDATA%/Python/Python26/XYZ
                for name, prefix in as_build_scheme[plat].items():
                    if tinfo.name.lower().startswith(prefix):
                        old = tinfo.name
                        new = pyenv_scheme[name] + old[len(prefix):]
                        if new != old:
                            LOG.debug('fs:extract: transforming "%s" to "%s"',
                                      old, new)
                            tinfo.name = new
                            
                # Check for overwrites
                if os.path.exists(tinfo.name) and not os.path.isdir(tinfo.name):
                    # Hack #2: allow overwriting of *.pth files (setuptools
                    # hackishness) eg: [...]/site-packages/setuptools.pth
                    if not tinfo.name.endswith('.pth'):
                        files_to_overwrite.append(tinfo.name)
                    
            if files_to_overwrite:
                
                LOG.debug(
                    'install requires overwriting of %d files:\n%s',
                    len(files_to_overwrite),
                   '\n'.join([os.path.join(pyenv.base_dir, f)
                              for f in files_to_overwrite]))
                if force_overwrite:
                    LOG.warn('overwriting %d files' % len(files_to_overwrite))
                else:
                    errmsg = ['cannot overwrite "%s"' % concise_path(os.path.join(
                        pyenv.base_dir, files_to_overwrite[0]))]
                    if len(files_to_overwrite) > 1:
                        errmsg.append(' (and %d other files)' % (len(files_to_overwrite)-1,))
                    errmsg.append('; run pypm as "pypm --force ..." to overwrite anyway')
                    if len(files_to_overwrite) > 1:
                        errmsg.append('; run "pypm log" to see the full list of files to be overwritten')
                    raise IOError(wrapped(''.join(errmsg)))

            return tf.getnames()