diff --git a/src/rez/cli/pip.py b/src/rez/cli/pip.py index 40386bc25..8bb0fb390 100644 --- a/src/rez/cli/pip.py +++ b/src/rez/cli/pip.py @@ -2,6 +2,7 @@ Install a pip-compatible python package, and its dependencies, as rez packages. """ from __future__ import print_function +from argparse import REMAINDER def setup_parser(parser, completions=False): @@ -30,7 +31,10 @@ def setup_parser(parser, completions=False): parser.add_argument( "PACKAGE", help="package to install or archive/url to install from") - + parser.add_argument( + "-e", "--extra", nargs=REMAINDER, + help="extra args passthrough to pip install (overrides pre-configured args if specified)" + ) def command(opts, parser, extra_arg_groups=None): from rez.pip import pip_install_package, run_pip_command @@ -59,7 +63,8 @@ def command(opts, parser, extra_arg_groups=None): pip_version=opts.pip_ver, python_version=opts.py_ver, release=opts.release, - prefix=opts.prefix) + prefix=opts.prefix, + extra_args=opts.extra) # print summary # diff --git a/src/rez/config.py b/src/rez/config.py index 0a61c7874..cdb7bcd45 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -308,6 +308,7 @@ def _parse_env_var(self, value): "implicit_styles": OptionalStrList, "alias_styles": OptionalStrList, "memcached_uri": OptionalStrList, + "pip_extra_args": OptionalStrList, "local_packages_path": Str, "release_packages_path": Str, "dot_image_format": Str, diff --git a/src/rez/pip.py b/src/rez/pip.py index a0db31756..85879c15c 100644 --- a/src/rez/pip.py +++ b/src/rez/pip.py @@ -198,7 +198,8 @@ def find_pip_from_context(python_version, pip_version=None): def pip_install_package(source_name, pip_version=None, python_version=None, - mode=InstallMode.min_deps, release=False, prefix=None): + mode=InstallMode.min_deps, release=False, prefix=None, + extra_args=None): """Install a pip-compatible python package as a rez package. Args: source_name (str): Name of package or archive/url containing the pip @@ -212,6 +213,7 @@ def pip_install_package(source_name, pip_version=None, python_version=None, managed. release (bool): If True, install as a released package; otherwise, it will be installed as a local package. + extra_args (List[str]): Additional options to the pip install command. Returns: 2-tuple: @@ -249,13 +251,30 @@ def pip_install_package(source_name, pip_version=None, python_version=None, context.print_info(buf) _log(buf.getvalue()) + # preconfigured options + pre_configured = ["--use-pep517", "--target=%s" % destpath] + + # gather additional pip install options + pip_extra_opts = extra_args if extra_args else config.pip_extra_args + + # make sure that the target option is overridden if supplied + if any("--target=" in opt for opt in pip_extra_opts): + # extra args redefines the target option so ignore pre-configured one + pre_configured = pre_configured[0:1] + # disable pep517 if forced + if "--no-use-pep517" in pip_extra_opts: + pre_configured = [] + + # keep unique opts + opts = list(set(pre_configured + pip_extra_opts)) + # Build pip commandline cmd = [ - py_exe, "-m", "pip", "install", - "--use-pep517", - "--target=%s" % destpath + py_exe, "-m", "pip", "install" ] + cmd.extend(opts) + if mode == InstallMode.no_deps: cmd.append("--no-deps") cmd.append(source_name) diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index f9f10a31e..0f7fda7be 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -694,6 +694,15 @@ # launched without extension from windows and other systems. create_executable_script_mode = "single" +# Configurable pip extra arguments passed to the rez-pip install command. +# Since the rez-pip install command already includes some pre-configured +# arguments (target, use-pep517) this setting can potentially override the +# default configuration in a way which can cause package installation issues. +# It is recommended to refrain from overriding the default arguments and only +# use this setting for additional arguments that might be needed. +# https://pip.pypa.io/en/stable/reference/pip_install/#options +pip_extra_args = [] + ############################################################################### # Rez-1 Compatibility