Skip to content

Commit

Permalink
CI pep8, flake8, mypy, py27
Browse files Browse the repository at this point in the history
  • Loading branch information
bmartinn committed May 9, 2020
1 parent 9eb6111 commit cede64d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 31 deletions.
8 changes: 5 additions & 3 deletions news/8187.feature
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Run the wheel install in a multiprocessing Pool, this has x1.5 speedup factor when installing cached packages.
Packages that could not be installed (exception raised), will be installed serially once the Pool is done.
If multiprocessing.Pool is not supported by the platform, fall-back to serial installation.
Run the wheel install in a multiprocessing Pool, this has x1.5 speedup factor
when installing cached packages. Packages that could not be installed
(exception raised), will be installed serially once the Pool is done.
If multiprocessing.Pool is not supported by the platform,
fall-back to serial installation.
64 changes: 36 additions & 28 deletions src/pip/_internal/req/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import absolute_import

import logging
from functools import partial

from pip._internal.utils.logging import indent_log
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
Expand All @@ -13,12 +14,12 @@
from .req_set import RequirementSet

try:
from multiprocessing.pool import Pool
from multiprocessing.pool import Pool # noqa
except ImportError: # Platform-specific: No multiprocessing available
Pool = None
Pool = None # type: ignore

if MYPY_CHECK_RUNNING:
from typing import Any, List, Sequence
from typing import Any, List, Sequence, Optional

__all__ = [
"RequirementSet", "InstallRequirement",
Expand Down Expand Up @@ -59,64 +60,71 @@ def install_given_reqs(
)

# pre allocate installed package names
installed = [None] * len(to_install)
installed = \
[None] * len(to_install) # type: List[Optional[InstallationResult]]

install_args = [install_options, global_options, args, kwargs]

if Pool is not None:
if to_install and Pool is not None:
# first let's try to install in parallel, if we fail we do it by order.
pool = Pool()
try:
pool_result = pool.starmap_async(__single_install, [(install_args, r) for r in to_install])
pool_result = pool.map_async(
partial(__single_install, install_args), to_install)
# python 2.7 timeout=None will not catch KeyboardInterrupt
installed = pool_result.get(timeout=999999)
except (KeyboardInterrupt, SystemExit):
pool.terminate()
raise
except Exception:
# we will reinstall sequentially
pass
pool.close()
pool.join()

with indent_log():
for i, requirement in enumerate(to_install):
if installed[i] is None:
installed[i] = __single_install(install_args, requirement, allow_raise=True)
installed[i] = __single_install(
install_args, requirement, allow_raise=True)

return [i for i in installed if i is not None]


def __single_install(args, a_requirement, allow_raise=False):
if a_requirement.should_reinstall:
logger.info('Attempting uninstall: %s', a_requirement.name)
def __single_install(
install_args, # type: List[Any]
requirement, # type: InstallRequirement
allow_raise=False # type: bool
):
# type: (...) -> Optional[InstallationResult]
"""
Install a single requirement, returns InstallationResult
(to be called per requirement, either in parallel or serially)
"""
if requirement.should_reinstall:
logger.info('Attempting uninstall: %s', requirement.name)
with indent_log():
uninstalled_pathset = a_requirement.uninstall(
uninstalled_pathset = requirement.uninstall(
auto_confirm=True
)
try:
a_requirement.install(
args[0], # install_options,
args[1], # global_options,
*args[2], # *args,
**args[3] # **kwargs
requirement.install(
install_args[0], # install_options,
install_args[1], # global_options,
*install_args[2], # *args,
**install_args[3] # **kwargs
)
except Exception:
should_rollback = (
a_requirement.should_reinstall and
not a_requirement.install_succeeded
)
should_rollback = (requirement.should_reinstall and
not requirement.install_succeeded)
# if install did not succeed, rollback previous uninstall
if should_rollback:
uninstalled_pathset.rollback()
if allow_raise:
raise
else:
should_commit = (
a_requirement.should_reinstall and
a_requirement.install_succeeded
)
should_commit = (requirement.should_reinstall and
requirement.install_succeeded)
if should_commit:
uninstalled_pathset.commit()
return InstallationResult(a_requirement.name)
return InstallationResult(requirement.name)

return None

0 comments on commit cede64d

Please sign in to comment.