Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
InstallCommand Class Reference
Inheritance diagram for InstallCommand:
Collaboration diagram for InstallCommand:

Public Member Functions

None add_options (self)
 
int run (self, Values options, List[str] args)
 
- Public Member Functions inherited from RequirementCommand
None __init__ (self, *Any args, **Any kw)
 
RequirementPreparer make_requirement_preparer (cls, TempDirectory temp_build_dir, Values options, BuildTracker build_tracker, PipSession session, PackageFinder finder, bool use_user_site, Optional[str] download_dir=None, int verbosity=0)
 
BaseResolver make_resolver (cls, RequirementPreparer preparer, PackageFinder finder, Values options, Optional[WheelCache] wheel_cache=None, bool use_user_site=False, bool ignore_installed=True, bool ignore_requires_python=False, bool force_reinstall=False, str upgrade_strategy="to-satisfy-only", Optional[bool] use_pep517=None, Optional[Tuple[int,...]] py_version_info=None)
 
List[InstallRequirementget_requirements (self, List[str] args, Values options, PackageFinder finder, PipSession session)
 
- Public Member Functions inherited from IndexGroupCommand
None handle_pip_version_check (self, Values options)
 
- Public Member Functions inherited from Command
Tuple[Values, List[str]] parse_args (self, List[str] args)
 
int main (self, List[str] args)
 
- Public Member Functions inherited from CommandContextMixIn
Generator[None, None, Nonemain_context (self)
 
_T enter_context (self, ContextManager[_T] context_provider)
 
- Public Member Functions inherited from SessionCommandMixin
PipSession get_default_session (self, Values options)
 

Data Fields

 cmd_opts
 
 parser
 
- Data Fields inherited from Command
 name
 
 summary
 
 parser
 
 cmd_opts
 
 tempdir_registry
 
 verbosity
 

Static Public Attributes

str usage
 
- Static Public Attributes inherited from Command
str usage = ""
 
bool ignore_require_venv = False
 

Protected Member Functions

None _handle_target_dir (self, str target_dir, TempDirectory target_temp_dir, bool upgrade)
 
Optional[ConflictDetails] _determine_conflicts (self, List[InstallRequirement] to_install)
 
None _warn_about_conflicts (self, ConflictDetails conflict_details, str resolver_variant)
 
- Protected Member Functions inherited from RequirementCommand
PackageFinder _build_package_finder (self, Values options, PipSession session, Optional[TargetPython] target_python=None, Optional[bool] ignore_requires_python=None)
 
- Protected Member Functions inherited from Command
int _main (self, List[str] args)
 
- Protected Member Functions inherited from SessionCommandMixin
Optional[List[str]] _get_index_urls (cls, Values options)
 
PipSession _build_session (self, Values options, Optional[int] retries=None, Optional[int] timeout=None, bool fallback_to_certifi=False)
 

Additional Inherited Members

- Static Public Member Functions inherited from RequirementCommand
str determine_resolver_variant (Values options)
 
None trace_basic_info (PackageFinder finder)
 
- Protected Attributes inherited from CommandContextMixIn
 _in_main_context
 
 _main_context
 
- Protected Attributes inherited from SessionCommandMixin
 _session
 

Detailed Description

Install packages from:

- PyPI (and other indexes) using requirement specifiers.
- VCS project urls.
- Local project directories.
- Local or remote source archives.

pip also supports installing from "requirements files", which provide
an easy way to specify a whole environment to be installed.

Definition at line 52 of file install.py.

Member Function Documentation

◆ _determine_conflicts()

Optional[ConflictDetails] _determine_conflicts (   self,
List[InstallRequirement]   to_install 
)
protected

Definition at line 571 of file install.py.

573 ) -> Optional[ConflictDetails]:
574 try:
575 return check_install_conflicts(to_install)
576 except Exception:
578 "Error while checking for conflicts. Please file an issue on "
579 "pip's issue tracker: https://github.com/pypa/pip/issues/new"
580 )
581 return None
582
for i

References i.

Referenced by InstallCommand.run().

Here is the caller graph for this function:

◆ _handle_target_dir()

None _handle_target_dir (   self,
str  target_dir,
TempDirectory  target_temp_dir,
bool   upgrade 
)
protected

Definition at line 517 of file install.py.

519 ) -> None:
520 ensure_dir(target_dir)
521
522 # Checking both purelib and platlib directories for installed
523 # packages to be moved to target directory
524 lib_dir_list = []
525
526 # Checking both purelib and platlib directories for installed
527 # packages to be moved to target directory
528 scheme = get_scheme("", home=target_temp_dir.path)
529 purelib_dir = scheme.purelib
530 platlib_dir = scheme.platlib
531 data_dir = scheme.data
532
533 if os.path.exists(purelib_dir):
534 lib_dir_list.append(purelib_dir)
535 if os.path.exists(platlib_dir) and platlib_dir != purelib_dir:
536 lib_dir_list.append(platlib_dir)
537 if os.path.exists(data_dir):
538 lib_dir_list.append(data_dir)
539
540 for lib_dir in lib_dir_list:
541 for item in os.listdir(lib_dir):
542 if lib_dir == data_dir:
543 ddir = os.path.join(data_dir, item)
544 if any(s.startswith(ddir) for s in lib_dir_list[:-1]):
545 continue
546 target_item_dir = os.path.join(target_dir, item)
547 if os.path.exists(target_item_dir):
548 if not upgrade:
550 "Target directory %s already exists. Specify "
551 "--upgrade to force replacement.",
552 target_item_dir,
553 )
554 continue
555 if os.path.islink(target_item_dir):
557 "Target directory %s already exists and is "
558 "a link. pip will not automatically replace "
559 "links, please remove if replacement is "
560 "desired.",
561 target_item_dir,
562 )
563 continue
564 if os.path.isdir(target_item_dir):
565 shutil.rmtree(target_item_dir)
566 else:
567 os.remove(target_item_dir)
568
569 shutil.move(os.path.join(lib_dir, item), target_item_dir)
570

References i.

Referenced by InstallCommand.run().

Here is the caller graph for this function:

◆ _warn_about_conflicts()

None _warn_about_conflicts (   self,
ConflictDetails  conflict_details,
str   resolver_variant 
)
protected

Definition at line 583 of file install.py.

585 ) -> None:
586 package_set, (missing, conflicting) = conflict_details
587 if not missing and not conflicting:
588 return
589
590 parts: List[str] = []
591 if resolver_variant == "legacy":
593 "pip's legacy dependency resolver does not consider dependency "
594 "conflicts when selecting packages. This behaviour is the "
595 "source of the following dependency conflicts."
596 )
597 else:
598 assert resolver_variant == "2020-resolver"
600 "pip's dependency resolver does not currently take into account "
601 "all the packages that are installed. This behaviour is the "
602 "source of the following dependency conflicts."
603 )
604
605 # NOTE: There is some duplication here, with commands/check.py
606 for project_name in missing:
607 version = package_set[project_name][0]
608 for dependency in missing[project_name]:
609 message = (
610 "{name} {version} requires {requirement}, "
611 "which is not installed."
612 ).format(
613 name=project_name,
614 version=version,
615 requirement=dependency[1],
616 )
617 parts.append(message)
618
619 for project_name in conflicting:
620 version = package_set[project_name][0]
621 for dep_name, dep_version, req in conflicting[project_name]:
622 message = (
623 "{name} {version} requires {requirement}, but {you} have "
624 "{dep_name} {dep_version} which is incompatible."
625 ).format(
626 name=project_name,
627 version=version,
628 requirement=req,
629 dep_name=dep_name,
630 dep_version=dep_version,
631 you=("you" if resolver_variant == "2020-resolver" else "you'll"),
632 )
633 parts.append(message)
634
635 logger.critical("\n".join(parts))
636
637

References i.

Referenced by InstallCommand.run().

Here is the caller graph for this function:

◆ add_options()

None add_options (   self)

Reimplemented from Command.

Definition at line 72 of file install.py.

72 def add_options(self) -> None:
73 self.cmd_opts.add_option(cmdoptions.requirements())
74 self.cmd_opts.add_option(cmdoptions.constraints())
75 self.cmd_opts.add_option(cmdoptions.no_deps())
76 self.cmd_opts.add_option(cmdoptions.pre())
77
78 self.cmd_opts.add_option(cmdoptions.editable())
79 self.cmd_opts.add_option(
80 "--dry-run",
81 action="store_true",
82 dest="dry_run",
83 default=False,
84 help=(
85 "Don't actually install anything, just print what would be. "
86 "Can be used in combination with --ignore-installed "
87 "to 'resolve' the requirements."
88 ),
89 )
90 self.cmd_opts.add_option(
91 "-t",
92 "--target",
93 dest="target_dir",
94 metavar="dir",
95 default=None,
96 help=(
97 "Install packages into <dir>. "
98 "By default this will not replace existing files/folders in "
99 "<dir>. Use --upgrade to replace existing packages in <dir> "
100 "with new versions."
101 ),
102 )
104
105 self.cmd_opts.add_option(
106 "--user",
107 dest="use_user_site",
108 action="store_true",
109 help=(
110 "Install to the Python user install directory for your "
111 "platform. Typically ~/.local/, or %APPDATA%\\Python on "
112 "Windows. (See the Python documentation for site.USER_BASE "
113 "for full details.)"
114 ),
115 )
116 self.cmd_opts.add_option(
117 "--no-user",
118 dest="use_user_site",
119 action="store_false",
120 help=SUPPRESS_HELP,
121 )
122 self.cmd_opts.add_option(
123 "--root",
124 dest="root_path",
125 metavar="dir",
126 default=None,
127 help="Install everything relative to this alternate root directory.",
128 )
129 self.cmd_opts.add_option(
130 "--prefix",
131 dest="prefix_path",
132 metavar="dir",
133 default=None,
134 help=(
135 "Installation prefix where lib, bin and other top-level "
136 "folders are placed. Note that the resulting installation may "
137 "contain scripts and other resources which reference the "
138 "Python interpreter of pip, and not that of ``--prefix``. "
139 "See also the ``--python`` option if the intention is to "
140 "install packages into another (possibly pip-free) "
141 "environment."
142 ),
143 )
144
145 self.cmd_opts.add_option(cmdoptions.src())
146
147 self.cmd_opts.add_option(
148 "-U",
149 "--upgrade",
150 dest="upgrade",
151 action="store_true",
152 help=(
153 "Upgrade all specified packages to the newest available "
154 "version. The handling of dependencies depends on the "
155 "upgrade-strategy used."
156 ),
157 )
158
159 self.cmd_opts.add_option(
160 "--upgrade-strategy",
161 dest="upgrade_strategy",
162 default="only-if-needed",
163 choices=["only-if-needed", "eager"],
164 help=(
165 "Determines how dependency upgrading should be handled "
166 "[default: %default]. "
167 '"eager" - dependencies are upgraded regardless of '
168 "whether the currently installed version satisfies the "
169 "requirements of the upgraded package(s). "
170 '"only-if-needed" - are upgraded only when they do not '
171 "satisfy the requirements of the upgraded package(s)."
172 ),
173 )
174
175 self.cmd_opts.add_option(
176 "--force-reinstall",
177 dest="force_reinstall",
178 action="store_true",
179 help="Reinstall all packages even if they are already up-to-date.",
180 )
181
182 self.cmd_opts.add_option(
183 "-I",
184 "--ignore-installed",
185 dest="ignore_installed",
186 action="store_true",
187 help=(
188 "Ignore the installed packages, overwriting them. "
189 "This can break your system if the existing package "
190 "is of a different version or was installed "
191 "with a different package manager!"
192 ),
193 )
194
197 self.cmd_opts.add_option(cmdoptions.use_pep517())
198 self.cmd_opts.add_option(cmdoptions.no_use_pep517())
201
204
205 self.cmd_opts.add_option(
206 "--compile",
207 action="store_true",
208 dest="compile",
209 default=True,
210 help="Compile Python source files to bytecode",
211 )
212
213 self.cmd_opts.add_option(
214 "--no-compile",
215 action="store_false",
216 dest="compile",
217 help="Do not compile Python source files to bytecode",
218 )
219
220 self.cmd_opts.add_option(
221 "--no-warn-script-location",
222 action="store_false",
223 dest="warn_script_location",
224 default=True,
225 help="Do not warn when installing scripts outside PATH",
226 )
227 self.cmd_opts.add_option(
228 "--no-warn-conflicts",
229 action="store_false",
230 dest="warn_about_conflicts",
231 default=True,
232 help="Do not warn about broken dependencies",
233 )
234 self.cmd_opts.add_option(cmdoptions.no_binary())
235 self.cmd_opts.add_option(cmdoptions.only_binary())
236 self.cmd_opts.add_option(cmdoptions.prefer_binary())
238 self.cmd_opts.add_option(cmdoptions.progress_bar())
240
241 index_opts = cmdoptions.make_option_group(
243 self.parser,
244 )
245
246 self.parser.insert_option_group(0, index_opts)
247 self.parser.insert_option_group(0, self.cmd_opts)
248
249 self.cmd_opts.add_option(
250 "--report",
251 dest="json_report_file",
252 metavar="file",
253 default=None,
254 help=(
255 "Generate a JSON file describing what pip did to install "
256 "the provided requirements. "
257 "Can be used in combination with --dry-run and --ignore-installed "
258 "to 'resolve' the requirements. "
259 "When - is used as file name it writes to stdout. "
260 "When writing to stdout, please combine with the --quiet option "
261 "to avoid mixing pip logging output with JSON output."
262 ),
263 )
264

References Command.cmd_opts, CacheCommand.cmd_opts, CompletionCommand.cmd_opts, ConfigurationCommand.cmd_opts, DebugCommand.cmd_opts, DownloadCommand.cmd_opts, FreezeCommand.cmd_opts, HashCommand.cmd_opts, IndexCommand.cmd_opts, InspectCommand.cmd_opts, InstallCommand.cmd_opts, ListCommand.cmd_opts, SearchCommand.cmd_opts, ShowCommand.cmd_opts, UninstallCommand.cmd_opts, WheelCommand.cmd_opts, and i.

◆ run()

int run (   self,
Values  options,
List[str]  args 
)

Reimplemented from Command.

Definition at line 266 of file install.py.

266 def run(self, options: Values, args: List[str]) -> int:
267 if options.use_user_site and options.target_dir is not None:
268 raise CommandError("Can not combine '--user' and '--target'")
269
270 # Check whether the environment we're installing into is externally
271 # managed, as specified in PEP 668. Specifying --root, --target, or
272 # --prefix disables the check, since there's no reliable way to locate
273 # the EXTERNALLY-MANAGED file for those cases. An exception is also
274 # made specifically for "--dry-run --report" for convenience.
275 installing_into_current_environment = (
277 and options.root_path is None
278 and options.target_dir is None
279 and options.prefix_path is None
280 )
281 if (
282 installing_into_current_environment
284 ):
285 check_externally_managed()
286
287 upgrade_strategy = "to-satisfy-only"
289 upgrade_strategy = options.upgrade_strategy
290
291 cmdoptions.check_dist_restriction(options, check_target=True)
292
293 logger.verbose("Using %s", get_pip_version())
294 options.use_user_site = decide_user_install(
296 prefix_path=options.prefix_path,
297 target_dir=options.target_dir,
298 root_path=options.root_path,
299 isolated_mode=options.isolated_mode,
300 )
301
302 target_temp_dir: Optional[TempDirectory] = None
303 target_temp_dir_path: Optional[str] = None
307 if (
308 # fmt: off
311 # fmt: on
312 ):
313 raise CommandError(
314 "Target path exists but is not a directory, will not continue."
315 )
316
317 # Create a target directory for using with the target option
318 target_temp_dir = TempDirectory(kind="target")
319 target_temp_dir_path = target_temp_dir.path
320 self.enter_context(target_temp_dir)
321
322 global_options = options.global_options or []
323
324 session = self.get_default_session(options)
325
326 target_python = make_target_python(options)
327 finder = self._build_package_finder(
328 options=options,
329 session=session,
330 target_python=target_python,
331 ignore_requires_python=options.ignore_requires_python,
332 )
333 build_tracker = self.enter_context(get_build_tracker())
334
335 directory = TempDirectory(
336 delete=not options.no_clean,
337 kind="install",
338 globally_managed=True,
339 )
340
341 try:
342 reqs = self.get_requirements(args, options, finder, session)
343 check_legacy_setup_py_options(options, reqs)
344
345 wheel_cache = WheelCache(options.cache_dir)
346
347 # Only when installing is it permitted to use PEP 660.
348 # In other circumstances (pip wheel, pip download) we generate
349 # regular (i.e. non editable) metadata and wheels.
350 for req in reqs:
352
353 preparer = self.make_requirement_preparer(
354 temp_build_dir=directory,
355 options=options,
356 build_tracker=build_tracker,
357 session=session,
358 finder=finder,
359 use_user_site=options.use_user_site,
360 verbosity=self.verbosity,
361 )
362 resolver = self.make_resolver(
363 preparer=preparer,
364 finder=finder,
365 options=options,
366 wheel_cache=wheel_cache,
367 use_user_site=options.use_user_site,
368 ignore_installed=options.ignore_installed,
369 ignore_requires_python=options.ignore_requires_python,
370 force_reinstall=options.force_reinstall,
371 upgrade_strategy=upgrade_strategy,
372 use_pep517=options.use_pep517,
373 )
374
375 self.trace_basic_info(finder)
376
377 requirement_set = resolver.resolve(
378 reqs, check_supported_wheels=not options.target_dir
379 )
380
382 report = InstallationReport(requirement_set.requirements_to_install)
383 if options.json_report_file == "-":
384 print_json(data=report.to_dict())
385 else:
386 with open(options.json_report_file, "w", encoding="utf-8") as f:
387 json.dump(report.to_dict(), f, indent=2, ensure_ascii=False)
388
390 # In non dry-run mode, the legacy versions and specifiers check
391 # will be done as part of conflict detection.
393 would_install_items = sorted(
394 (r.metadata["name"], r.metadata["version"])
396 )
397 if would_install_items:
398 write_output(
399 "Would install %s",
400 " ".join("-".join(item) for item in would_install_items),
401 )
402 return SUCCESS
403
404 try:
405 pip_req = requirement_set.get_requirement("pip")
406 except KeyError:
407 modifying_pip = False
408 else:
409 # If we're not replacing an already installed pip,
410 # we're not modifying it.
411 modifying_pip = pip_req.satisfied_by is None
412 protect_pip_from_modification_on_windows(modifying_pip=modifying_pip)
413
414 reqs_to_build = [
415 r
417 if should_build_for_install_command(r)
418 ]
419
420 _, build_failures = build(
421 reqs_to_build,
422 wheel_cache=wheel_cache,
423 verify=True,
424 build_options=[],
425 global_options=global_options,
426 )
427
428 if build_failures:
429 raise InstallationError(
430 "Could not build wheels for {}, which is required to "
431 "install pyproject.toml-based projects".format(
432 ", ".join(r.name for r in build_failures) # type: ignore
433 )
434 )
435
436 to_install = resolver.get_installation_order(requirement_set)
437
438 # Check for conflicts in the package set we're installing.
439 conflicts: Optional[ConflictDetails] = None
440 should_warn_about_conflicts = (
442 )
443 if should_warn_about_conflicts:
444 conflicts = self._determine_conflicts(to_install)
445
446 # Don't warn about script install locations if
447 # --target or --prefix has been specified
448 warn_script_location = options.warn_script_location
450 warn_script_location = False
451
452 installed = install_given_reqs(
453 to_install,
454 global_options,
456 home=target_temp_dir_path,
457 prefix=options.prefix_path,
458 warn_script_location=warn_script_location,
459 use_user_site=options.use_user_site,
460 pycompile=options.compile,
461 )
462
463 lib_locations = get_lib_location_guesses(
465 home=target_temp_dir_path,
467 prefix=options.prefix_path,
468 isolated=options.isolated_mode,
469 )
470 env = get_environment(lib_locations)
471
473 items = []
474 for result in installed:
475 item = result.name
476 try:
477 installed_dist = env.get_distribution(item)
478 if installed_dist is not None:
479 item = f"{item}-{installed_dist.version}"
480 except Exception:
481 pass
482 items.append(item)
483
484 if conflicts is not None:
485 self._warn_about_conflicts(
486 conflicts,
487 resolver_variant=self.determine_resolver_variant(options),
488 )
489
490 installed_desc = " ".join(items)
491 if installed_desc:
492 write_output(
493 "Successfully installed %s",
494 installed_desc,
495 )
496 except OSError as error:
497 show_traceback = self.verbosity >= 1
498
499 message = create_os_error_message(
500 error,
501 show_traceback,
503 )
504 logger.error(message, exc_info=show_traceback) # noqa
505
506 return ERROR
507
509 assert target_temp_dir
510 self._handle_target_dir(
511 options.target_dir, target_temp_dir, options.upgrade
512 )
513 if options.root_user_action == "warn":
514 warn_if_run_as_root()
515 return SUCCESS
516

References ListCommand._build_package_finder(), RequirementCommand._build_package_finder(), IndexCommand._build_package_finder(), InstallCommand._determine_conflicts(), InstallCommand._handle_target_dir(), InstallCommand._warn_about_conflicts(), pip._internal.commands.install.create_os_error_message(), pip._internal.commands.install.decide_user_install(), RequirementCommand.determine_resolver_variant(), CommandContextMixIn.enter_context(), SessionCommandMixin.get_default_session(), pip._internal.commands.install.get_lib_location_guesses(), RequirementCommand.get_requirements(), Metadata.get_requirements(), i, RequirementCommand.make_requirement_preparer(), RequirementCommand.make_resolver(), RequirementCommand.trace_basic_info(), Command.verbosity, and RequirementPreparer.verbosity.

Here is the call graph for this function:

Field Documentation

◆ cmd_opts

◆ parser

◆ usage

str usage
static
Initial value:
= """
%prog [options] <requirement specifier> [package-index-options] ...
%prog [options] -r <requirements file> [package-index-options] ...
%prog [options] [-e] <vcs project url> ...
%prog [options] [-e] <local project path> ...
%prog [options] <archive url/path> ..."""

Definition at line 65 of file install.py.


The documentation for this class was generated from the following file: