|
4 | 4 | from __future__ import absolute_import
|
5 | 5 |
|
6 | 6 | import logging
|
| 7 | +from functools import partial |
7 | 8 |
|
8 | 9 | from pip._internal.utils.logging import indent_log
|
9 | 10 | from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
|
13 | 14 | from .req_set import RequirementSet
|
14 | 15 |
|
15 | 16 | try:
|
16 |
| - from multiprocessing.pool import Pool |
| 17 | + from multiprocessing.pool import Pool # noqa |
17 | 18 | except ImportError: # Platform-specific: No multiprocessing available
|
18 |
| - Pool = None |
| 19 | + Pool = None # type: ignore |
19 | 20 |
|
20 | 21 | if MYPY_CHECK_RUNNING:
|
21 |
| - from typing import Any, List, Sequence |
| 22 | + from typing import Any, List, Sequence, Optional |
22 | 23 |
|
23 | 24 | __all__ = [
|
24 | 25 | "RequirementSet", "InstallRequirement",
|
@@ -59,64 +60,71 @@ def install_given_reqs(
|
59 | 60 | )
|
60 | 61 |
|
61 | 62 | # pre allocate installed package names
|
62 |
| - installed = [None] * len(to_install) |
| 63 | + installed = \ |
| 64 | + [None] * len(to_install) # type: List[Optional[InstallationResult]] |
| 65 | + |
63 | 66 | install_args = [install_options, global_options, args, kwargs]
|
64 | 67 |
|
65 |
| - if Pool is not None: |
| 68 | + if to_install and Pool is not None: |
66 | 69 | # first let's try to install in parallel, if we fail we do it by order.
|
67 | 70 | pool = Pool()
|
68 | 71 | try:
|
69 |
| - pool_result = pool.starmap_async(__single_install, [(install_args, r) for r in to_install]) |
| 72 | + pool_result = pool.map_async( |
| 73 | + partial(__single_install, install_args), to_install) |
70 | 74 | # python 2.7 timeout=None will not catch KeyboardInterrupt
|
71 | 75 | installed = pool_result.get(timeout=999999)
|
72 | 76 | except (KeyboardInterrupt, SystemExit):
|
73 | 77 | pool.terminate()
|
74 | 78 | raise
|
75 |
| - except Exception: |
76 |
| - # we will reinstall sequentially |
77 |
| - pass |
78 | 79 | pool.close()
|
79 | 80 | pool.join()
|
80 | 81 |
|
81 | 82 | with indent_log():
|
82 | 83 | for i, requirement in enumerate(to_install):
|
83 | 84 | if installed[i] is None:
|
84 |
| - installed[i] = __single_install(install_args, requirement, allow_raise=True) |
| 85 | + installed[i] = __single_install( |
| 86 | + install_args, requirement, allow_raise=True) |
85 | 87 |
|
86 | 88 | return [i for i in installed if i is not None]
|
87 | 89 |
|
88 | 90 |
|
89 |
| -def __single_install(args, a_requirement, allow_raise=False): |
90 |
| - if a_requirement.should_reinstall: |
91 |
| - logger.info('Attempting uninstall: %s', a_requirement.name) |
| 91 | +def __single_install( |
| 92 | + install_args, # type: List[Any] |
| 93 | + requirement, # type: InstallRequirement |
| 94 | + allow_raise=False # type: bool |
| 95 | +): |
| 96 | + # type: (...) -> Optional[InstallationResult] |
| 97 | + """ |
| 98 | + Install a single requirement, returns InstallationResult |
| 99 | +
|
| 100 | + (to be called per requirement, either in parallel or serially) |
| 101 | + """ |
| 102 | + if requirement.should_reinstall: |
| 103 | + logger.info('Attempting uninstall: %s', requirement.name) |
92 | 104 | with indent_log():
|
93 |
| - uninstalled_pathset = a_requirement.uninstall( |
| 105 | + uninstalled_pathset = requirement.uninstall( |
94 | 106 | auto_confirm=True
|
95 | 107 | )
|
96 | 108 | try:
|
97 |
| - a_requirement.install( |
98 |
| - args[0], # install_options, |
99 |
| - args[1], # global_options, |
100 |
| - *args[2], # *args, |
101 |
| - **args[3] # **kwargs |
| 109 | + requirement.install( |
| 110 | + install_args[0], # install_options, |
| 111 | + install_args[1], # global_options, |
| 112 | + *install_args[2], # *args, |
| 113 | + **install_args[3] # **kwargs |
102 | 114 | )
|
103 | 115 | except Exception:
|
104 |
| - should_rollback = ( |
105 |
| - a_requirement.should_reinstall and |
106 |
| - not a_requirement.install_succeeded |
107 |
| - ) |
| 116 | + should_rollback = (requirement.should_reinstall and |
| 117 | + not requirement.install_succeeded) |
108 | 118 | # if install did not succeed, rollback previous uninstall
|
109 | 119 | if should_rollback:
|
110 | 120 | uninstalled_pathset.rollback()
|
111 | 121 | if allow_raise:
|
112 | 122 | raise
|
113 | 123 | else:
|
114 |
| - should_commit = ( |
115 |
| - a_requirement.should_reinstall and |
116 |
| - a_requirement.install_succeeded |
117 |
| - ) |
| 124 | + should_commit = (requirement.should_reinstall and |
| 125 | + requirement.install_succeeded) |
118 | 126 | if should_commit:
|
119 | 127 | uninstalled_pathset.commit()
|
120 |
| - return InstallationResult(a_requirement.name) |
| 128 | + return InstallationResult(requirement.name) |
121 | 129 |
|
122 | 130 | return None
|
0 commit comments