Skip to content

Commit 35181cd

Browse files
authored
Merge pull request #7775 from chrahunt/refactor/better-handle-build-dir
Globally manage temp build dir in requirement commands
2 parents ea47be5 + 60a2fa4 commit 35181cd

File tree

3 files changed

+242
-230
lines changed

3 files changed

+242
-230
lines changed

src/pip/_internal/commands/download.py

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -100,45 +100,49 @@ def run(self, options, args):
100100

101101
req_tracker = self.enter_context(get_requirement_tracker())
102102

103-
with TempDirectory(
104-
options.build_dir, delete=build_delete, kind="download"
105-
) as directory:
106-
reqs = self.get_requirements(
107-
args,
108-
options,
109-
finder,
110-
session,
111-
None
112-
)
113-
114-
preparer = self.make_requirement_preparer(
115-
temp_build_dir=directory,
116-
options=options,
117-
req_tracker=req_tracker,
118-
session=session,
119-
finder=finder,
120-
download_dir=options.download_dir,
121-
use_user_site=False,
122-
)
123-
124-
resolver = self.make_resolver(
125-
preparer=preparer,
126-
finder=finder,
127-
options=options,
128-
py_version_info=options.python_version,
129-
)
130-
131-
self.trace_basic_info(finder)
132-
133-
requirement_set = resolver.resolve(
134-
reqs, check_supported_wheels=True
135-
)
136-
137-
downloaded = ' '.join([
138-
req.name for req in requirement_set.requirements.values()
139-
if req.successfully_downloaded
140-
])
141-
if downloaded:
142-
write_output('Successfully downloaded %s', downloaded)
103+
directory = TempDirectory(
104+
options.build_dir,
105+
delete=build_delete,
106+
kind="download",
107+
globally_managed=True,
108+
)
109+
110+
reqs = self.get_requirements(
111+
args,
112+
options,
113+
finder,
114+
session,
115+
None
116+
)
117+
118+
preparer = self.make_requirement_preparer(
119+
temp_build_dir=directory,
120+
options=options,
121+
req_tracker=req_tracker,
122+
session=session,
123+
finder=finder,
124+
download_dir=options.download_dir,
125+
use_user_site=False,
126+
)
127+
128+
resolver = self.make_resolver(
129+
preparer=preparer,
130+
finder=finder,
131+
options=options,
132+
py_version_info=options.python_version,
133+
)
134+
135+
self.trace_basic_info(finder)
136+
137+
requirement_set = resolver.resolve(
138+
reqs, check_supported_wheels=True
139+
)
140+
141+
downloaded = ' '.join([
142+
req.name for req in requirement_set.requirements.values()
143+
if req.successfully_downloaded
144+
])
145+
if downloaded:
146+
write_output('Successfully downloaded %s', downloaded)
143147

144148
return requirement_set

src/pip/_internal/commands/install.py

Lines changed: 139 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -286,156 +286,160 @@ def run(self, options, args):
286286

287287
req_tracker = self.enter_context(get_requirement_tracker())
288288

289-
with TempDirectory(
290-
options.build_dir, delete=build_delete, kind="install"
291-
) as directory:
292-
try:
293-
reqs = self.get_requirements(
294-
args, options, finder, session,
295-
wheel_cache, check_supported_wheels=not options.target_dir,
296-
)
289+
directory = TempDirectory(
290+
options.build_dir,
291+
delete=build_delete,
292+
kind="install",
293+
globally_managed=True,
294+
)
297295

298-
warn_deprecated_install_options(
299-
reqs, options.install_options
300-
)
296+
try:
297+
reqs = self.get_requirements(
298+
args, options, finder, session,
299+
wheel_cache, check_supported_wheels=not options.target_dir,
300+
)
301301

302-
preparer = self.make_requirement_preparer(
303-
temp_build_dir=directory,
304-
options=options,
305-
req_tracker=req_tracker,
306-
session=session,
307-
finder=finder,
308-
use_user_site=options.use_user_site,
309-
)
310-
resolver = self.make_resolver(
311-
preparer=preparer,
312-
finder=finder,
313-
options=options,
314-
wheel_cache=wheel_cache,
315-
use_user_site=options.use_user_site,
316-
ignore_installed=options.ignore_installed,
317-
ignore_requires_python=options.ignore_requires_python,
318-
force_reinstall=options.force_reinstall,
319-
upgrade_strategy=upgrade_strategy,
320-
use_pep517=options.use_pep517,
321-
)
302+
warn_deprecated_install_options(
303+
reqs, options.install_options
304+
)
322305

323-
self.trace_basic_info(finder)
306+
preparer = self.make_requirement_preparer(
307+
temp_build_dir=directory,
308+
options=options,
309+
req_tracker=req_tracker,
310+
session=session,
311+
finder=finder,
312+
use_user_site=options.use_user_site,
313+
)
314+
resolver = self.make_resolver(
315+
preparer=preparer,
316+
finder=finder,
317+
options=options,
318+
wheel_cache=wheel_cache,
319+
use_user_site=options.use_user_site,
320+
ignore_installed=options.ignore_installed,
321+
ignore_requires_python=options.ignore_requires_python,
322+
force_reinstall=options.force_reinstall,
323+
upgrade_strategy=upgrade_strategy,
324+
use_pep517=options.use_pep517,
325+
)
324326

325-
requirement_set = resolver.resolve(
326-
reqs, check_supported_wheels=not options.target_dir
327-
)
327+
self.trace_basic_info(finder)
328328

329-
try:
330-
pip_req = requirement_set.get_requirement("pip")
331-
except KeyError:
332-
modifying_pip = None
333-
else:
334-
# If we're not replacing an already installed pip,
335-
# we're not modifying it.
336-
modifying_pip = pip_req.satisfied_by is None
337-
protect_pip_from_modification_on_windows(
338-
modifying_pip=modifying_pip
339-
)
329+
requirement_set = resolver.resolve(
330+
reqs, check_supported_wheels=not options.target_dir
331+
)
340332

341-
check_binary_allowed = get_check_binary_allowed(
342-
finder.format_control
343-
)
333+
try:
334+
pip_req = requirement_set.get_requirement("pip")
335+
except KeyError:
336+
modifying_pip = None
337+
else:
338+
# If we're not replacing an already installed pip,
339+
# we're not modifying it.
340+
modifying_pip = pip_req.satisfied_by is None
341+
protect_pip_from_modification_on_windows(
342+
modifying_pip=modifying_pip
343+
)
344344

345-
reqs_to_build = [
346-
r for r in requirement_set.requirements.values()
347-
if should_build_for_install_command(
348-
r, check_binary_allowed
349-
)
350-
]
345+
check_binary_allowed = get_check_binary_allowed(
346+
finder.format_control
347+
)
351348

352-
_, build_failures = build(
353-
reqs_to_build,
354-
wheel_cache=wheel_cache,
355-
build_options=[],
356-
global_options=[],
349+
reqs_to_build = [
350+
r for r in requirement_set.requirements.values()
351+
if should_build_for_install_command(
352+
r, check_binary_allowed
357353
)
354+
]
358355

359-
# If we're using PEP 517, we cannot do a direct install
360-
# so we fail here.
361-
# We don't care about failures building legacy
362-
# requirements, as we'll fall through to a direct
363-
# install for those.
364-
pep517_build_failures = [
365-
r for r in build_failures if r.use_pep517
366-
]
367-
if pep517_build_failures:
368-
raise InstallationError(
369-
"Could not build wheels for {} which use"
370-
" PEP 517 and cannot be installed directly".format(
371-
", ".join(r.name for r in pep517_build_failures)))
372-
373-
to_install = resolver.get_installation_order(
374-
requirement_set
375-
)
356+
_, build_failures = build(
357+
reqs_to_build,
358+
wheel_cache=wheel_cache,
359+
build_options=[],
360+
global_options=[],
361+
)
376362

377-
# Consistency Checking of the package set we're installing.
378-
should_warn_about_conflicts = (
379-
not options.ignore_dependencies and
380-
options.warn_about_conflicts
381-
)
382-
if should_warn_about_conflicts:
383-
self._warn_about_conflicts(to_install)
384-
385-
# Don't warn about script install locations if
386-
# --target has been specified
387-
warn_script_location = options.warn_script_location
388-
if options.target_dir:
389-
warn_script_location = False
390-
391-
installed = install_given_reqs(
392-
to_install,
393-
install_options,
394-
global_options,
395-
root=options.root_path,
396-
home=target_temp_dir_path,
397-
prefix=options.prefix_path,
398-
pycompile=options.compile,
399-
warn_script_location=warn_script_location,
400-
use_user_site=options.use_user_site,
401-
)
363+
# If we're using PEP 517, we cannot do a direct install
364+
# so we fail here.
365+
# We don't care about failures building legacy
366+
# requirements, as we'll fall through to a direct
367+
# install for those.
368+
pep517_build_failures = [
369+
r for r in build_failures if r.use_pep517
370+
]
371+
if pep517_build_failures:
372+
raise InstallationError(
373+
"Could not build wheels for {} which use"
374+
" PEP 517 and cannot be installed directly".format(
375+
", ".join(r.name for r in pep517_build_failures)))
376+
377+
to_install = resolver.get_installation_order(
378+
requirement_set
379+
)
402380

403-
lib_locations = get_lib_location_guesses(
404-
user=options.use_user_site,
405-
home=target_temp_dir_path,
406-
root=options.root_path,
407-
prefix=options.prefix_path,
408-
isolated=options.isolated_mode,
409-
)
410-
working_set = pkg_resources.WorkingSet(lib_locations)
411-
412-
installed.sort(key=operator.attrgetter('name'))
413-
items = []
414-
for result in installed:
415-
item = result.name
416-
try:
417-
installed_version = get_installed_version(
418-
result.name, working_set=working_set
419-
)
420-
if installed_version:
421-
item += '-' + installed_version
422-
except Exception:
423-
pass
424-
items.append(item)
425-
installed_desc = ' '.join(items)
426-
if installed_desc:
427-
write_output(
428-
'Successfully installed %s', installed_desc,
429-
)
430-
except EnvironmentError as error:
431-
show_traceback = (self.verbosity >= 1)
381+
# Consistency Checking of the package set we're installing.
382+
should_warn_about_conflicts = (
383+
not options.ignore_dependencies and
384+
options.warn_about_conflicts
385+
)
386+
if should_warn_about_conflicts:
387+
self._warn_about_conflicts(to_install)
388+
389+
# Don't warn about script install locations if
390+
# --target has been specified
391+
warn_script_location = options.warn_script_location
392+
if options.target_dir:
393+
warn_script_location = False
394+
395+
installed = install_given_reqs(
396+
to_install,
397+
install_options,
398+
global_options,
399+
root=options.root_path,
400+
home=target_temp_dir_path,
401+
prefix=options.prefix_path,
402+
pycompile=options.compile,
403+
warn_script_location=warn_script_location,
404+
use_user_site=options.use_user_site,
405+
)
406+
407+
lib_locations = get_lib_location_guesses(
408+
user=options.use_user_site,
409+
home=target_temp_dir_path,
410+
root=options.root_path,
411+
prefix=options.prefix_path,
412+
isolated=options.isolated_mode,
413+
)
414+
working_set = pkg_resources.WorkingSet(lib_locations)
432415

433-
message = create_env_error_message(
434-
error, show_traceback, options.use_user_site,
416+
installed.sort(key=operator.attrgetter('name'))
417+
items = []
418+
for result in installed:
419+
item = result.name
420+
try:
421+
installed_version = get_installed_version(
422+
result.name, working_set=working_set
423+
)
424+
if installed_version:
425+
item += '-' + installed_version
426+
except Exception:
427+
pass
428+
items.append(item)
429+
installed_desc = ' '.join(items)
430+
if installed_desc:
431+
write_output(
432+
'Successfully installed %s', installed_desc,
435433
)
436-
logger.error(message, exc_info=show_traceback)
434+
except EnvironmentError as error:
435+
show_traceback = (self.verbosity >= 1)
436+
437+
message = create_env_error_message(
438+
error, show_traceback, options.use_user_site,
439+
)
440+
logger.error(message, exc_info=show_traceback)
437441

438-
return ERROR
442+
return ERROR
439443

440444
if options.target_dir:
441445
self._handle_target_dir(

0 commit comments

Comments
 (0)