-
Notifications
You must be signed in to change notification settings - Fork 354
Description
Describe the bug here.
Environment
- win 10
- Rez version:3.30
- Rez python version:Python 3.11.9
To Reproduce
- rez-pip -i PyYAML
Actual behavior
warning: NO packages were installed.
My Debug
...\rez\windows\python3\rez-3.3.0-py3.11.9\Lib\site-packages\rez\pip.py
When installing pip packages using rez pip, such as PyYAML, there will be a warning of “NO packages were installed”, and YAML did not install successfully. After debugging, it was found that the main issue is that in the pip_install_package function of {rez_installed-dir} \ Lib \ site-packages \ rez \ pip-py, the _cmd (context=context, command=cmd) function is mainly used to execute the installation of the pip command. When the context is not empty (which is indeed not empty during debugging), the _cmd function will call p=context.execute_shell (command=command, block=False), and this line of code will open a new cmd window to run the download and installation of the YAML package, and save it in tempDir; Then at the same time, in the main window of Rez pip, the code after pip_install_package will continue to run. When it reaches distributions=list (distribution-path.get-distributes()), a problem occurs: the YAML file that should have been saved in {tempDir} is not retrieved until it reaches printw_learning ("NO packages were installed."). After in-depth disassembly, it is obvious that the execution of calling the _cmd function in the pip_install_package function and subsequently obtaining the distribution code runs at the same time in actual debugging (when the context is not empty), so the subsequent code runs out before the installed yaml package is downloaded to tempDir, resulting in always unsuccessful installation.
Finally, I can only use p=Popen (command) in the _cmd function to perform the download and installation successfully, but the question I want to ask is: what is the difference between context.execute_shell and p=Popen (command)? What impact will my solution have on the installed pip package?
`def pip_install_package(source_name, pip_version=None, python_version=None,
mode=InstallMode.min_deps, release=False, prefix=None,
extra_args=None):
...
...
if context and config.debug("package_release"):
buf = StringIO()
print("\n\npackage download environment:", file=buf)
context.print_info(buf)
_log(buf.getvalue())
# Build pip commandline
cmd = [py_exe, "-m", "pip", "install"]
_extra_args = extra_args or config.pip_extra_args or []
if "--no-use-pep517" not in _extra_args:
cmd.append("--use-pep517")
if not _option_present(_extra_args, "-t", "--target"):
cmd.append("--target=%s" % targetpath)
if mode == InstallMode.no_deps and "--no-deps" not in _extra_args:
cmd.append("--no-deps")
cmd.extend(_extra_args)
cmd.append(source_name)
# run pip
#
# Note: https://github.com/pypa/pip/pull/3934. If/when this PR is merged,
# it will allow explicit control of where to put bin files.
#
**_cmd(context=context, command=cmd)**
# determine version of python in use
if context is None:
# since we had to use system pip, we have to assume system python version
py_ver_str = '.'.join(map(str, sys.version_info))
py_ver = Version(py_ver_str)
else:
python_variant = context.get_resolved_package("python")
py_ver = python_variant.version
# Collect resulting python packages using distlib
distribution_path = DistributionPath([targetpath])
distributions = list(distribution_path.get_distributions())
print("distributions:",distributions)
dist_names = [x.name for x in distributions]
...
...
shutil.rmtree(targetpath)
# print summary
#
if installed_variants:
print_info("%d packages were installed.", len(installed_variants))
else:
print_warning("NO packages were installed.")
if skipped_variants:
print_warning(
"%d packages were already installed.",
len(skipped_variants),
)
return installed_variants, skipped_variants
def _cmd(context, command):
cmd_str = ' '.join(quote(x) for x in command)
_log("running: %s" % cmd_str)
#p = Popen(command)
if context is None:
p = Popen(command)
else:
p = context.execute_shell(command=command, block=False)
with p:
p.wait()
if p.returncode:
raise BuildError("Failed to download source with pip: %s" % cmd_str)
`