Ejemplo n.º 1
0
 def install_requirements(self, finder, requirements, message):
     args = [
         sys.executable, '-m', 'pip', 'install', '--ignore-installed',
         '--no-user', '--prefix', self.path, '--no-warn-script-location',
     ]
     if logger.getEffectiveLevel() <= logging.DEBUG:
         args.append('-v')
     for format_control in ('no_binary', 'only_binary'):
         formats = getattr(finder.format_control, format_control)
         args.extend(('--' + format_control.replace('_', '-'),
                      ','.join(sorted(formats or {':none:'}))))
     if finder.index_urls:
         args.extend(['-i', finder.index_urls[0]])
         for extra_index in finder.index_urls[1:]:
             args.extend(['--extra-index-url', extra_index])
     else:
         args.append('--no-index')
     for link in finder.find_links:
         args.extend(['--find-links', link])
     for _, host, _ in finder.secure_origins:
         args.extend(['--trusted-host', host])
     if finder.allow_all_prereleases:
         args.append('--pre')
     if finder.process_dependency_links:
         args.append('--process-dependency-links')
     args.append('--')
     args.extend(requirements)
     with open_spinner(message) as spinner:
         call_subprocess(args, show_stdout=False, spinner=spinner)
Ejemplo n.º 2
0
    def test_spinner_finish(
        self, exit_status, show_stdout, extra_ok_returncodes, log_level,
        caplog, expected,
    ):
        """
        Test that the spinner finishes correctly.
        """
        expected_exc_type = expected[0]
        expected_final_status = expected[1]
        expected_spin_count = expected[2]

        command = (
            'print("Hello"); print("world"); exit({})'.format(exit_status)
        )
        args, spinner = self.prepare_call(caplog, log_level, command=command)
        try:
            call_subprocess(
                args,
                show_stdout=show_stdout,
                extra_ok_returncodes=extra_ok_returncodes,
                spinner=spinner,
            )
        except Exception as exc:
            exc_type = type(exc)
        else:
            exc_type = None

        assert exc_type == expected_exc_type
        assert spinner.final_status == expected_final_status
        assert spinner.spin_count == expected_spin_count
Ejemplo n.º 3
0
 def run_egg_info(self):
     # type: () -> None
     if self.name:
         logger.debug(
             'Running setup.py (path:%s) egg_info for package %s',
             self.setup_py, self.name,
         )
     else:
         logger.debug(
             'Running setup.py (path:%s) egg_info for package from %s',
             self.setup_py, self.link,
         )
     script = SETUPTOOLS_SHIM % self.setup_py
     base_cmd = [sys.executable, '-c', script]
     if self.isolated:
         base_cmd += ["--no-user-cfg"]
     egg_info_cmd = base_cmd + ['egg_info']
     # We can't put the .egg-info files at the root, because then the
     # source code will be mistaken for an installed egg, causing
     # problems
     if self.editable:
         egg_base_option = []  # type: List[str]
     else:
         egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info')
         ensure_dir(egg_info_dir)
         egg_base_option = ['--egg-base', 'pip-egg-info']
     with self.build_env:
         call_subprocess(
             egg_info_cmd + egg_base_option,
             cwd=self.setup_py_dir,
             command_desc='python setup.py egg_info')
Ejemplo n.º 4
0
def _copy_dist_from_dir(link_path, location):
    """Copy distribution files in `link_path` to `location`.

    Invoked when user requests to install a local directory. E.g.:

        pip install .
        pip install ~/dev/git-repos/python-prompt-toolkit

    """

    # Note: This is currently VERY SLOW if you have a lot of data in the
    # directory, because it copies everything with `shutil.copytree`.
    # What it should really do is build an sdist and install that.
    # See https://github.com/pypa/pip/issues/2195

    if os.path.isdir(location):
        rmtree(location)

    # build an sdist
    setup_py = 'setup.py'
    sdist_args = [sys.executable]
    sdist_args.append('-c')
    sdist_args.append(SETUPTOOLS_SHIM % setup_py)
    sdist_args.append('sdist')
    sdist_args += ['--dist-dir', location]
    logger.info('Running setup.py sdist for %s', link_path)

    with indent_log():
        call_subprocess(sdist_args, cwd=link_path, show_stdout=False)

    # unpack sdist into `location`
    sdist = os.path.join(location, os.listdir(location)[0])
    logger.info('Unpacking sdist %s into %s', sdist, location)
    unpack_file(sdist, location, content_type=None, link=None)
Ejemplo n.º 5
0
    def install_editable(
        self,
        install_options,  # type: List[str]
        global_options=(),  # type: Sequence[str]
        prefix=None  # type: Optional[str]
    ):
        # type: (...) -> None
        logger.info('Running setup.py develop for %s', self.name)

        if self.isolated:
            global_options = list(global_options) + ["--no-user-cfg"]

        if prefix:
            prefix_param = ['--prefix={}'.format(prefix)]
            install_options = list(install_options) + prefix_param

        with indent_log():
            # FIXME: should we do --install-headers here too?
            with self.build_env:
                call_subprocess(
                    [
                        sys.executable,
                        '-c',
                        SETUPTOOLS_SHIM % self.setup_py
                    ] +
                    list(global_options) +
                    ['develop', '--no-deps'] +
                    list(install_options),

                    cwd=self.setup_py_dir,
                )

        self.install_succeeded = True
Ejemplo n.º 6
0
Archivo: wheel.py Proyecto: oz123/pip
    def __build_one(self, req, tempd, python_tag=None, isolate=False):
        base_args = self._base_setup_args(req, isolate=isolate)

        spin_message = 'Running setup.py bdist_wheel for %s' % (req.name,)
        with open_spinner(spin_message) as spinner:
            logger.debug('Destination directory: %s', tempd)
            wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
                + self.build_options

            if python_tag is not None:
                wheel_args += ["--python-tag", python_tag]

            env = {}
            if isolate:
                env['PYTHONNOUSERSITE'] = '1'

            try:
                call_subprocess(wheel_args, cwd=req.setup_py_dir,
                                extra_environ=env,
                                show_stdout=False, spinner=spinner)
                return True
            except:
                spinner.finish("error")
                logger.error('Failed building wheel for %s', req.name)
                return False
Ejemplo n.º 7
0
    def _build_one_legacy(self, req, tempd, python_tag=None):
        """Build one InstallRequirement using the "legacy" build process.

        Returns path to wheel if successfully built. Otherwise, returns None.
        """
        base_args = self._base_setup_args(req)

        spin_message = 'Building wheel for %s (setup.py)' % (req.name,)
        with open_spinner(spin_message) as spinner:
            logger.debug('Destination directory: %s', tempd)
            wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
                + self.build_options

            if python_tag is not None:
                wheel_args += ["--python-tag", python_tag]

            try:
                call_subprocess(wheel_args, cwd=req.setup_py_dir,
                                show_stdout=False, spinner=spinner)
            except Exception:
                spinner.finish("error")
                logger.error('Failed building wheel for %s', req.name)
                return None
            # listdir's return value is sorted to be deterministic
            return os.path.join(tempd, sorted(os.listdir(tempd))[0])
Ejemplo n.º 8
0
    def install_editable(self, install_options,
                         global_options=(), prefix=None):
        logger.info('Running setup.py develop for %s', self.name)

        if self.isolated:
            global_options = list(global_options) + ["--no-user-cfg"]

        if prefix:
            prefix_param = ['--prefix={0}'.format(prefix)]
            install_options = list(install_options) + prefix_param

        with indent_log():
            # FIXME: should we do --install-headers here too?
            call_subprocess(
                [
                    sys.executable,
                    '-c',
                    SETUPTOOLS_SHIM % self.setup_py
                ] +
                list(global_options) +
                ['develop', '--no-deps'] +
                list(install_options),

                cwd=self.setup_py_dir,
                show_stdout=False)

        self.install_succeeded = True
Ejemplo n.º 9
0
    def run_egg_info(self):
        assert self.source_dir
        if self.name:
            logger.debug(
                'Running setup.py (path:%s) egg_info for package %s',
                self.setup_py, self.name,
            )
        else:
            logger.debug(
                'Running setup.py (path:%s) egg_info for package from %s',
                self.setup_py, self.link,
            )

        with indent_log():
            script = SETUPTOOLS_SHIM % self.setup_py
            base_cmd = [sys.executable, '-c', script]
            if self.isolated:
                base_cmd += ["--no-user-cfg"]
            egg_info_cmd = base_cmd + ['egg_info']
            # We can't put the .egg-info files at the root, because then the
            # source code will be mistaken for an installed egg, causing
            # problems
            if self.editable:
                egg_base_option = []
            else:
                egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info')
                ensure_dir(egg_info_dir)
                egg_base_option = ['--egg-base', 'pip-egg-info']
            with self.build_env:
                call_subprocess(
                    egg_info_cmd + egg_base_option,
                    cwd=self.setup_py_dir,
                    show_stdout=False,
                    command_desc='python setup.py egg_info')

        if not self.req:
            if isinstance(parse_version(self.pkg_info()["Version"]), Version):
                op = "=="
            else:
                op = "==="
            self.req = Requirement(
                "".join([
                    self.pkg_info()["Name"],
                    op,
                    self.pkg_info()["Version"],
                ])
            )
            self._correct_build_location()
        else:
            metadata_name = canonicalize_name(self.pkg_info()["Name"])
            if canonicalize_name(self.req.name) != metadata_name:
                logger.warning(
                    'Running setup.py (path:%s) egg_info for package %s '
                    'produced metadata for project name %s. Fix your '
                    '#egg=%s fragments.',
                    self.setup_py, self.name, metadata_name, self.name
                )
                self.req = Requirement(metadata_name)
Ejemplo n.º 10
0
 def runner(cmd, cwd=None, extra_environ=None):
     with open_spinner(self.spin_message) as spinner:
         call_subprocess(
             cmd,
             cwd=cwd,
             extra_environ=extra_environ,
             spinner=spinner
         )
     self.spin_message = ""
Ejemplo n.º 11
0
    def _clean_one(self, req):
        base_args = self._base_setup_args(req)

        logger.info('Running setup.py clean for %s', req.name)
        clean_args = base_args + ['clean', '--all']
        try:
            call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False)
            return True
        except:
            logger.error('Failed cleaning build dir for %s', req.name)
            return False
Ejemplo n.º 12
0
 def runner(
     cmd,  # type: List[str]
     cwd=None,  # type: Optional[str]
     extra_environ=None  # type: Optional[Mapping[str, Any]]
 ):
     # type: (...) -> None
     with open_spinner(self.spin_message) as spinner:
         call_subprocess(
             cmd,
             cwd=cwd,
             extra_environ=extra_environ,
             spinner=spinner
         )
     self.spin_message = ""
Ejemplo n.º 13
0
    def _build_one_legacy(self, req, tempd, python_tag=None):
        """Build one InstallRequirement using the "legacy" build process.

        Returns path to wheel if successfully built. Otherwise, returns None.
        """
        base_args = self._base_setup_args(req)

        spin_message = 'Building wheel for %s (setup.py)' % (req.name,)
        with open_spinner(spin_message) as spinner:
            logger.debug('Destination directory: %s', tempd)
            wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
                + self.build_options

            if python_tag is not None:
                wheel_args += ["--python-tag", python_tag]

            try:
                output = call_subprocess(wheel_args, cwd=req.setup_py_dir,
                                         show_stdout=False, spinner=spinner)
            except Exception:
                spinner.finish("error")
                logger.error('Failed building wheel for %s', req.name)
                return None
            names = os.listdir(tempd)
            wheel_path = get_legacy_build_wheel_path(
                names=names,
                temp_dir=tempd,
                req=req,
                command_args=wheel_args,
                command_output=output,
            )
            return wheel_path
Ejemplo n.º 14
0
Archivo: wheel.py Proyecto: oz123/pip
    def _install_build_reqs(self, reqs, prefix):
        # Local import to avoid circular import (wheel <-> req_install)
        from pip._internal.req.req_install import InstallRequirement
        from pip._internal.index import FormatControl
        # Ignore the --no-binary option when installing the build system, so
        # we don't recurse trying to build a self-hosting build system.
        finder = copy.copy(self.finder)
        finder.format_control = FormatControl(set(), set())
        urls = [finder.find_requirement(InstallRequirement.from_line(r),
                                        upgrade=False).url
                for r in reqs]

        args = [sys.executable, '-m', 'pip', 'install', '--ignore-installed',
                '--prefix', prefix] + list(urls)
        with open_spinner("Installing build dependencies") as spinner:
            call_subprocess(args, show_stdout=False, spinner=spinner)
Ejemplo n.º 15
0
    def setup_py(self):
        assert self.source_dir, "No source dir for %s" % self
        cmd = [sys.executable, '-c', 'import setuptools']
        output = call_subprocess(
            cmd,
            show_stdout=False,
            command_desc='python -c "import setuptools"',
            on_returncode='ignore',
        )

        if output:
            if get_installed_version('setuptools') is None:
                add_msg = "Please install setuptools."
            else:
                add_msg = output
            # Setuptools is not available
            raise InstallationError(
                "Could not import setuptools which is required to "
                "install from a source distribution.\n%s" % add_msg
            )

        setup_py = os.path.join(self.setup_py_dir, 'setup.py')

        # Python2 __file__ should not be unicode
        if six.PY2 and isinstance(setup_py, six.text_type):
            setup_py = setup_py.encode(sys.getfilesystemencoding())

        return setup_py
Ejemplo n.º 16
0
 def run_command(self, cmd, show_stdout=True, cwd=None,
                 on_returncode='raise',
                 command_desc=None,
                 extra_environ=None, spinner=None):
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = [self.name] + cmd
     try:
         return call_subprocess(cmd, show_stdout, cwd,
                                on_returncode,
                                command_desc, extra_environ,
                                unset_environ=self.unset_environ,
                                spinner=spinner)
     except OSError as e:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         if e.errno == errno.ENOENT:
             raise BadCommand(
                 'Cannot find command %r - do you have '
                 '%r installed and in your '
                 'PATH?' % (self.name, self.name))
         else:
             raise  # re-raise exception if a different error occurred
Ejemplo n.º 17
0
def _install_build_reqs(finder, prefix, build_requirements):
    # NOTE: What follows is not a very good thing.
    #       Eventually, this should move into the BuildEnvironment class and
    #       that should handle all the isolation and sub-process invocation.
    finder = copy(finder)
    finder.format_control = FormatControl(set(), set([":all:"]))
    urls = [
        finder.find_requirement(
            InstallRequirement.from_line(r), upgrade=False).url
        for r in build_requirements
    ]
    args = [
        sys.executable, '-m', 'pip', 'install', '--ignore-installed',
        '--no-user', '--prefix', prefix,
    ] + list(urls)

    with open_spinner("Installing build dependencies") as spinner:
        call_subprocess(args, show_stdout=False, spinner=spinner)
Ejemplo n.º 18
0
 def install_requirements(
     self,
     finder,  # type: PackageFinder
     requirements,  # type: Iterable[str]
     prefix_as_string,  # type: str
     message  # type: Optional[str]
 ):
     # type: (...) -> None
     prefix = self._prefixes[prefix_as_string]
     assert not prefix.setup
     prefix.setup = True
     if not requirements:
         return
     args = [
         sys.executable, os.path.dirname(pip_location), 'install',
         '--ignore-installed', '--no-user', '--prefix', prefix.path,
         '--no-warn-script-location',
     ]  # type: List[str]
     if logger.getEffectiveLevel() <= logging.DEBUG:
         args.append('-v')
     for format_control in ('no_binary', 'only_binary'):
         formats = getattr(finder.format_control, format_control)
         args.extend(('--' + format_control.replace('_', '-'),
                      ','.join(sorted(formats or {':none:'}))))
     if finder.index_urls:
         args.extend(['-i', finder.index_urls[0]])
         for extra_index in finder.index_urls[1:]:
             args.extend(['--extra-index-url', extra_index])
     else:
         args.append('--no-index')
     for link in finder.find_links:
         args.extend(['--find-links', link])
     for _, host, _ in finder.secure_origins:
         args.extend(['--trusted-host', host])
     if finder.allow_all_prereleases:
         args.append('--pre')
     if finder.process_dependency_links:
         args.append('--process-dependency-links')
     args.append('--')
     args.extend(requirements)
     with open_spinner(message) as spinner:
         call_subprocess(args, show_stdout=False, spinner=spinner)
Ejemplo n.º 19
0
    def _build_one_legacy(self, req, tempd, python_tag=None):
        base_args = self._base_setup_args(req)

        spin_message = 'Building wheel for %s (setup.py)' % (req.name,)
        with open_spinner(spin_message) as spinner:
            logger.debug('Destination directory: %s', tempd)
            wheel_args = base_args + ['bdist_wheel', '-d', tempd] \
                + self.build_options

            if python_tag is not None:
                wheel_args += ["--python-tag", python_tag]

            try:
                call_subprocess(wheel_args, cwd=req.setup_py_dir,
                                show_stdout=False, spinner=spinner)
                return True
            except Exception:
                spinner.finish("error")
                logger.error('Failed building wheel for %s', req.name)
                return False
Ejemplo n.º 20
0
    def test_info_logging__subprocess_error(self, capfd, caplog):
        """
        Test INFO logging of a subprocess with an error (and without passing
        show_stdout=True).
        """
        log_level = INFO
        command = 'print("Hello"); print("world"); exit("fail")'
        args, spinner = self.prepare_call(caplog, log_level, command=command)

        with pytest.raises(InstallationError):
            call_subprocess(args, spinner=spinner)
        result = None

        expected = (None, [
            ('pip.subprocessor', ERROR, 'Complete output from command '),
            # The "failed" portion is later on in this "Hello" string.
            ('pip.subprocessor', ERROR, 'Hello'),
        ])
        # The spinner should spin three times in this case since the
        # subprocess output isn't being written to the console.
        self.check_result(
            capfd, caplog, log_level, spinner, result, expected,
            expected_spinner=(3, 'error'),
        )

        # Do some further checking on the captured log records to confirm
        # that the subprocess output was logged.
        last_record = caplog.record_tuples[-1]
        last_message = last_record[2]
        lines = last_message.splitlines()

        # We have to sort before comparing the lines because we can't
        # guarantee the order in which stdout and stderr will appear.
        # For example, we observed the stderr lines coming before stdout
        # in CI for PyPy 2.7 even though stdout happens first chronologically.
        assert sorted(lines) == [
            '----------------------------------------',
            'Hello',
            'fail',
            'world',
        ], 'lines: {}'.format(lines)  # Show the full output on failure.
Ejemplo n.º 21
0
    def test_info_logging_with_show_stdout_true(self, capfd, caplog):
        """
        Test INFO logging with show_stdout=True.
        """
        log_level = logging.INFO
        args, spinner = self.prepare_call(caplog, log_level)
        result = call_subprocess(args, spinner=spinner, show_stdout=True)

        expected = (None, ['Hello', 'world'], [])
        # The spinner shouldn't spin in this case since the subprocess
        # output is already being written to the console.
        self.check_result(
            capfd, caplog, log_level, spinner, result, expected,
            expected_spinner=(0, None),
        )
Ejemplo n.º 22
0
    def test_info_logging(self, capfd, caplog):
        """
        Test INFO logging (and without passing show_stdout=True).
        """
        log_level = INFO
        args, spinner = self.prepare_call(caplog, log_level)
        result = call_subprocess(args, spinner=spinner)

        expected = (['Hello', 'world'], [])
        # The spinner should spin twice in this case since the subprocess
        # output isn't being written to the console.
        self.check_result(
            capfd, caplog, log_level, spinner, result, expected,
            expected_spinner=(2, 'done'),
        )
Ejemplo n.º 23
0
    def test_debug_logging(self, capfd, caplog):
        """
        Test DEBUG logging (and without passing show_stdout=True).
        """
        log_level = DEBUG
        args, spinner = self.prepare_call(caplog, log_level)
        result = call_subprocess(args, spinner=spinner)

        expected = (['Hello', 'world'], [
            ('pip.subprocessor', DEBUG, 'Running command '),
            ('pip.subprocessor', DEBUG, 'Hello'),
            ('pip.subprocessor', DEBUG, 'world'),
        ])
        # The spinner shouldn't spin in this case since the subprocess
        # output is already being logged to the console.
        self.check_result(
            capfd, caplog, log_level, spinner, result, expected,
            expected_spinner=(0, None),
        )
Ejemplo n.º 24
0
 def run_command(
     self,
     cmd,  # type: List[str]
     show_stdout=True,  # type: bool
     cwd=None,  # type: Optional[str]
     on_returncode='raise',  # type: str
     extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
     command_desc=None,  # type: Optional[str]
     extra_environ=None,  # type: Optional[Mapping[str, Any]]
     spinner=None  # type: Optional[SpinnerInterface]
 ):
     # type: (...) -> Optional[Text]
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = [self.name] + cmd
     try:
         return call_subprocess(cmd, show_stdout, cwd,
                                on_returncode=on_returncode,
                                extra_ok_returncodes=extra_ok_returncodes,
                                command_desc=command_desc,
                                extra_environ=extra_environ,
                                unset_environ=self.unset_environ,
                                spinner=spinner)
     except OSError as e:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         if e.errno == errno.ENOENT:
             raise BadCommand(
                 'Cannot find command %r - do you have '
                 '%r installed and in your '
                 'PATH?' % (self.name, self.name))
         else:
             raise  # re-raise exception if a different error occurred
Ejemplo n.º 25
0
 def test_closes_stdin(self):
     with pytest.raises(InstallationError):
         call_subprocess(
             [sys.executable, '-c', 'input()'],
             show_stdout=True,
         )
Ejemplo n.º 26
0
    def install(self,
                install_options,
                global_options=None,
                root=None,
                home=None,
                prefix=None,
                warn_script_location=True,
                use_user_site=False,
                pycompile=True):
        global_options = global_options if global_options is not None else []
        if self.editable:
            self.install_editable(
                install_options,
                global_options,
                prefix=prefix,
            )
            return
        if self.is_wheel:
            version = wheel.wheel_version(self.source_dir)
            wheel.check_compatibility(version, self.name)

            self.move_wheel_files(
                self.source_dir,
                root=root,
                prefix=prefix,
                home=home,
                warn_script_location=warn_script_location,
                use_user_site=use_user_site,
                pycompile=pycompile,
            )
            self.install_succeeded = True
            return

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + \
            self.options.get('global_options', [])
        install_options = list(install_options) + \
            self.options.get('install_options', [])

        if self.isolated:
            global_options = global_options + ["--no-user-cfg"]

        with TempDirectory(kind="record") as temp_dir:
            record_filename = os.path.join(temp_dir.path, 'install-record.txt')
            install_args = self.get_install_args(
                global_options,
                record_filename,
                root,
                prefix,
                pycompile,
            )
            msg = 'Running setup.py install for %s' % (self.name, )
            with open_spinner(msg) as spinner:
                with indent_log():
                    call_subprocess(
                        install_args + install_options,
                        cwd=self.setup_py_dir,
                        show_stdout=False,
                        spinner=spinner,
                    )

            if not os.path.exists(record_filename):
                logger.debug('Record file %s not found', record_filename)
                return
            self.install_succeeded = True

            def prepend_root(path):
                if root is None or not os.path.isabs(path):
                    return path
                else:
                    return change_root(root, path)

            with open(record_filename) as f:
                for line in f:
                    directory = os.path.dirname(line)
                    if directory.endswith('.egg-info'):
                        egg_info_dir = prepend_root(directory)
                        break
                else:
                    logger.warning(
                        'Could not find .egg-info directory in install record'
                        ' for %s',
                        self,
                    )
                    # FIXME: put the record somewhere
                    # FIXME: should this be an error?
                    return
            new_lines = []
            with open(record_filename) as f:
                for line in f:
                    filename = line.strip()
                    if os.path.isdir(filename):
                        filename += os.path.sep
                    new_lines.append(
                        os.path.relpath(prepend_root(filename), egg_info_dir))
            new_lines.sort()
            ensure_dir(egg_info_dir)
            inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt')
            with open(inst_files_path, 'w') as f:
                f.write('\n'.join(new_lines) + '\n')
Ejemplo n.º 27
0
    def install(
            self,
            install_options,  # type: List[str]
            global_options=None,  # type: Optional[Sequence[str]]
            root=None,  # type: Optional[str]
            home=None,  # type: Optional[str]
            prefix=None,  # type: Optional[str]
            warn_script_location=True,  # type: bool
            use_user_site=False,  # type: bool
            pycompile=True,  # type: bool
    ):
        # type: (...) -> None
        global_options = global_options if global_options is not None else []
        if self.editable:
            self.install_editable(
                install_options,
                global_options,
                prefix=prefix,
            )
            return
        if self.is_wheel:
            version = wheel.wheel_version(self.source_dir)
            wheel.check_compatibility(version, self.name)

            self.move_wheel_files(
                self.source_dir,
                root=root,
                prefix=prefix,
                home=home,
                warn_script_location=warn_script_location,
                use_user_site=use_user_site,
                pycompile=pycompile,
            )
            self.install_succeeded = True
            return

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + self.options.get(
            "global_options", [])
        install_options = list(install_options) + self.options.get(
            "install_options", [])

        if self.isolated:
            # https://github.com/python/mypy/issues/1174
            global_options = global_options + ["--no-user-cfg"]  # type: ignore

        with TempDirectory(kind="record") as temp_dir:
            record_filename = os.path.join(temp_dir.path, "install-record.txt")
            install_args = self.get_install_args(
                global_options,
                record_filename,
                root,
                prefix,
                pycompile,
            )
            msg = "Running setup.py install for %s" % (self.name, )
            with open_spinner(msg) as spinner:
                with indent_log():
                    with self.build_env:
                        call_subprocess(
                            install_args + install_options,
                            cwd=self.setup_py_dir,
                            spinner=spinner,
                        )

            if not os.path.exists(record_filename):
                logger.debug("Record file %s not found", record_filename)
                return
            self.install_succeeded = True

            def prepend_root(path):
                # type: (str) -> str
                if root is None or not os.path.isabs(path):
                    return path
                else:
                    return change_root(root, path)

            with open(record_filename) as f:
                for line in f:
                    directory = os.path.dirname(line)
                    if directory.endswith(".egg-info"):
                        egg_info_dir = prepend_root(directory)
                        break
                else:
                    logger.warning(
                        "Could not find .egg-info directory in install record"
                        " for %s",
                        self,
                    )
                    # FIXME: put the record somewhere
                    # FIXME: should this be an error?
                    return
            new_lines = []
            with open(record_filename) as f:
                for line in f:
                    filename = line.strip()
                    if os.path.isdir(filename):
                        filename += os.path.sep
                    new_lines.append(
                        os.path.relpath(prepend_root(filename), egg_info_dir))
            new_lines.sort()
            ensure_dir(egg_info_dir)
            inst_files_path = os.path.join(egg_info_dir, "installed-files.txt")
            with open(inst_files_path, "w") as f:
                f.write("\n".join(new_lines) + "\n")
Ejemplo n.º 28
0
    def install(
        self,
        install_options,  # type: List[str]
        global_options=None,  # type: Optional[Sequence[str]]
        root=None,  # type: Optional[str]
        home=None,  # type: Optional[str]
        prefix=None,  # type: Optional[str]
        warn_script_location=True,  # type: bool
        use_user_site=False,  # type: bool
        pycompile=True  # type: bool
    ):
        # type: (...) -> None
        global_options = global_options if global_options is not None else []
        if self.editable:
            self.install_editable(
                install_options, global_options, prefix=prefix,
            )
            return
        if self.is_wheel:
            version = wheel.wheel_version(self.source_dir)
            wheel.check_compatibility(version, self.name)

            self.move_wheel_files(
                self.source_dir, root=root, prefix=prefix, home=home,
                warn_script_location=warn_script_location,
                use_user_site=use_user_site, pycompile=pycompile,
            )
            self.install_succeeded = True
            return

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + \
            self.options.get('global_options', [])
        install_options = list(install_options) + \
            self.options.get('install_options', [])

        if self.isolated:
            # https://github.com/python/mypy/issues/1174
            global_options = global_options + ["--no-user-cfg"]  # type: ignore

        with TempDirectory(kind="record") as temp_dir:
            record_filename = os.path.join(temp_dir.path, 'install-record.txt')
            install_args = self.get_install_args(
                global_options, record_filename, root, prefix, pycompile,
            )
            msg = 'Running setup.py install for %s' % (self.name,)
            with open_spinner(msg) as spinner:
                with indent_log():
                    with self.build_env:
                        call_subprocess(
                            install_args + install_options,
                            cwd=self.setup_py_dir,
                            spinner=spinner,
                        )

            if not os.path.exists(record_filename):
                logger.debug('Record file %s not found', record_filename)
                return
            self.install_succeeded = True

            def prepend_root(path):
                if root is None or not os.path.isabs(path):
                    return path
                else:
                    return change_root(root, path)

            with open(record_filename) as f:
                for line in f:
                    directory = os.path.dirname(line)
                    if directory.endswith('.egg-info'):
                        egg_info_dir = prepend_root(directory)
                        break
                else:
                    logger.warning(
                        'Could not find .egg-info directory in install record'
                        ' for %s',
                        self,
                    )
                    # FIXME: put the record somewhere
                    # FIXME: should this be an error?
                    return
            new_lines = []
            with open(record_filename) as f:
                for line in f:
                    filename = line.strip()
                    if os.path.isdir(filename):
                        filename += os.path.sep
                    new_lines.append(
                        os.path.relpath(prepend_root(filename), egg_info_dir)
                    )
            new_lines.sort()
            ensure_dir(egg_info_dir)
            inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt')
            with open(inst_files_path, 'w') as f:
                f.write('\n'.join(new_lines) + '\n')
Ejemplo n.º 29
0
def test_call_subprocess_works_okay_when_just_given_nothing():
    try:
        call_subprocess([sys.executable, '-c', 'print("Hello")'])
    except Exception:
        assert False, "Expected subprocess call to succeed"
Ejemplo n.º 30
0
 def test_closes_stdin(self):
     with pytest.raises(InstallationError):
         call_subprocess(
             [sys.executable, '-c', 'input()'],
             show_stdout=True,
         )
Ejemplo n.º 31
0
def test_call_subprocess_closes_stdin():
    with pytest.raises(InstallationError):
        call_subprocess([sys.executable, '-c', 'input()'])
Ejemplo n.º 32
0
def test_call_subprocess_closes_stdin():
    with pytest.raises(InstallationError):
        call_subprocess([sys.executable, '-c', 'input()'])
Ejemplo n.º 33
0
    def run_egg_info(self):
        assert self.source_dir
        if self.name:
            logger.debug(
                "Running setup.py (path:%s) egg_info for package %s",
                self.setup_py,
                self.name,
            )
        else:
            logger.debug(
                "Running setup.py (path:%s) egg_info for package from %s",
                self.setup_py,
                self.link,
            )

        with indent_log():
            script = SETUPTOOLS_SHIM % self.setup_py
            base_cmd = [sys.executable, "-c", script]
            if self.isolated:
                base_cmd += ["--no-user-cfg"]
            egg_info_cmd = base_cmd + ["egg_info"]
            # We can't put the .egg-info files at the root, because then the
            # source code will be mistaken for an installed egg, causing
            # problems
            if self.editable:
                egg_base_option = []
            else:
                egg_info_dir = os.path.join(self.setup_py_dir, "pip-egg-info")
                ensure_dir(egg_info_dir)
                egg_base_option = ["--egg-base", "pip-egg-info"]
            with self.build_env:
                call_subprocess(
                    egg_info_cmd + egg_base_option,
                    cwd=self.setup_py_dir,
                    show_stdout=False,
                    command_desc="python setup.py egg_info",
                )

        if not self.req:
            if isinstance(parse_version(self.pkg_info()["Version"]), Version):
                op = "=="
            else:
                op = "==="
            self.req = Requirement("".join([
                self.pkg_info()["Name"],
                op,
                self.pkg_info()["Version"],
            ]))
            self._correct_build_location()
        else:
            metadata_name = canonicalize_name(self.pkg_info()["Name"])
            if canonicalize_name(self.req.name) != metadata_name:
                logger.warning(
                    "Running setup.py (path:%s) egg_info for package %s "
                    "produced metadata for project name %s. Fix your "
                    "#egg=%s fragments.",
                    self.setup_py,
                    self.name,
                    metadata_name,
                    self.name,
                )
                self.req = Requirement(metadata_name)
Ejemplo n.º 34
0
def test_call_subprocess_works_okay_when_just_given_nothing():
    try:
        call_subprocess([sys.executable, '-c', 'print("Hello")'])
    except Exception:
        assert False, "Expected subprocess call to succeed"