Factor out code for handling the --user option & its default
@@ -292,30 +292,16 @@ class InstallCommand(RequirementCommand):
options.src_dir = os.path.abspath(options.src_dir)
install_options = options.install_options or []
- if options.use_user_site:
- if options.prefix_path:
- raise CommandError(
- "Can not combine '--user' and '--prefix' as they imply "
- "different installation locations"
- )
- if virtualenv_no_global():
- raise InstallationError(
- "Can not perform a '--user' install. User site-packages "
- "are not visible in this virtualenv."
+
+ options.use_user_site = decide_user_install(
+ options.use_user_site,
+ prefix_path=options.prefix_path,
+ target_dir=options.target_dir,
+ root_path=options.root_path,
+ isolated_mode=options.isolated_mode,
)
- install_options.append('--user')
- install_options.append('--prefix=')
- elif options.use_user_site is None:
- if options.prefix_path or options.target_dir:
- options.use_user_site = False
- elif site_packages_writable(
- root=options.root_path,
- isolated=options.isolated_mode
- ):
- options.use_user_site = False
- elif site.ENABLE_USER_SITE:
- options.use_user_site = True
+ if options.use_user_site:
install_options.append('--user')
install_options.append('--prefix=')
@@ -614,6 +600,44 @@ def site_packages_writable(**kwargs):
)
+def decide_user_install(
+ use_user_site,
+ prefix_path,
+ target_dir,
+ root_path,
+ isolated_mode,
+):
+ """Determine whether to do a user install based on the input options.
+
+ If use_user_site is True/False, that is checked for compatibility with
+ other options. If None, the default behaviour depends on other options
+ and the environment.
+ """
+ if use_user_site:
+ if prefix_path:
+ raise CommandError(
+ "Can not combine '--user' and '--prefix' as they imply "
+ "different installation locations"
+ )
+ if virtualenv_no_global():
+ raise InstallationError(
+ "Can not perform a '--user' install. User site-packages "
+ "are not visible in this virtualenv."
+ )
+ if use_user_site in (True, False):
+ return use_user_site
+
+ if prefix_path or target_dir:
+ return False # user install incompatible with --prefix/--target
+
+ # Default behaviour: prefer non-user installation if that looks possible.
+ # If we don't have permission for that and user site-packages are visible,
+ # choose a user install.
+ return site.ENABLE_USER_SITE and not site_packages_writable(
+ root=root_path, isolated=isolated_mode
+ )
+
+
def create_env_error_message(error, show_traceback, using_user_site):
"""Format an error message for an EnvironmentError
