|
9 | 9 | import os
|
10 | 10 | from functools import partial
|
11 | 11 |
|
| 12 | +from pip._internal.cli import cmdoptions |
12 | 13 | from pip._internal.cli.base_command import Command
|
13 | 14 | from pip._internal.cli.command_context import CommandContextMixIn
|
14 |
| -from pip._internal.exceptions import CommandError |
| 15 | +from pip._internal.exceptions import CommandError, PreviousBuildDirError |
15 | 16 | from pip._internal.index.package_finder import PackageFinder
|
16 | 17 | from pip._internal.legacy_resolve import Resolver
|
17 | 18 | from pip._internal.models.selection_prefs import SelectionPreferences
|
|
28 | 29 | make_link_collector,
|
29 | 30 | pip_self_version_check,
|
30 | 31 | )
|
| 32 | +from pip._internal.utils.temp_dir import tempdir_kinds |
31 | 33 | from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
32 | 34 |
|
33 | 35 | if MYPY_CHECK_RUNNING:
|
34 | 36 | from optparse import Values
|
35 |
| - from typing import List, Optional, Tuple |
| 37 | + from typing import Any, List, Optional, Tuple |
| 38 | + |
36 | 39 | from pip._internal.cache import WheelCache
|
37 | 40 | from pip._internal.models.target_python import TargetPython
|
38 | 41 | from pip._internal.req.req_set import RequirementSet
|
39 | 42 | from pip._internal.req.req_tracker import RequirementTracker
|
40 |
| - from pip._internal.utils.temp_dir import TempDirectory |
| 43 | + from pip._internal.utils.temp_dir import ( |
| 44 | + TempDirectory, |
| 45 | + TempDirectoryTypeRegistry, |
| 46 | + ) |
| 47 | + |
41 | 48 |
|
42 | 49 | logger = logging.getLogger(__name__)
|
43 | 50 |
|
@@ -149,8 +156,45 @@ def handle_pip_version_check(self, options):
|
149 | 156 | pip_self_version_check(session, options)
|
150 | 157 |
|
151 | 158 |
|
| 159 | +KEEPABLE_TEMPDIR_TYPES = [tempdir_kinds.BUILD_ENV, tempdir_kinds.REQ_BUILD] |
| 160 | + |
| 161 | + |
| 162 | +def with_cleanup(func): |
| 163 | + # type: (Any) -> Any |
| 164 | + """Decorator for common logic related to managing temporary |
| 165 | + directories. |
| 166 | + """ |
| 167 | + def configure_tempdir_registry(registry): |
| 168 | + # type: (TempDirectoryTypeRegistry) -> None |
| 169 | + for t in KEEPABLE_TEMPDIR_TYPES: |
| 170 | + registry.set_delete(t, False) |
| 171 | + |
| 172 | + def wrapper(self, options, args): |
| 173 | + # type: (RequirementCommand, Values, List[Any]) -> Optional[int] |
| 174 | + assert self.tempdir_registry is not None |
| 175 | + if options.no_clean: |
| 176 | + configure_tempdir_registry(self.tempdir_registry) |
| 177 | + |
| 178 | + try: |
| 179 | + return func(self, options, args) |
| 180 | + except PreviousBuildDirError: |
| 181 | + # This kind of conflict can occur when the user passes an explicit |
| 182 | + # build directory with a pre-existing folder. In that case we do |
| 183 | + # not want to accidentally remove it. |
| 184 | + configure_tempdir_registry(self.tempdir_registry) |
| 185 | + raise |
| 186 | + |
| 187 | + return wrapper |
| 188 | + |
| 189 | + |
152 | 190 | class RequirementCommand(IndexGroupCommand):
|
153 | 191 |
|
| 192 | + def __init__(self, *args, **kw): |
| 193 | + # type: (Any, Any) -> None |
| 194 | + super(RequirementCommand, self).__init__(*args, **kw) |
| 195 | + |
| 196 | + self.cmd_opts.add_option(cmdoptions.no_clean()) |
| 197 | + |
154 | 198 | @staticmethod
|
155 | 199 | def make_requirement_preparer(
|
156 | 200 | temp_build_dir, # type: TempDirectory
|
|
0 commit comments