Skip to content

Use pip from specified python cmd#2115

Open
heewa wants to merge 1 commit into
saltstack:developfrom
heewa:use-same-pip-as-python
Open

Use pip from specified python cmd#2115
heewa wants to merge 1 commit into
saltstack:developfrom
heewa:use-same-pip-as-python

Conversation

@heewa

@heewa heewa commented Jun 2, 2026

Copy link
Copy Markdown

What does this PR do?

Tries to use a pip that's matched to the specified python cmd, either:

  1. <python_cmd> -m pip (eg python3.14 -m pip)
  2. pip<py_version> (eg pip3.14)
    • tries to retain some of the old "try to find a pip" behavior, but restricted to a version match

What issues does this PR fix or reference?

When a version of python is specified (eg with -x python3.14 arg to the bootstrap script), but a corresponding pip command isn't available, the old behavior was to try using a pip of the major version (eg pip3), but this is problematic if that version of pip does exist, but doesn't match the python version used to build packages. That results in:

  • packages being successfully built
  • successfully installed, but into a different python version
  • therefore salt doesn't run with the given python cmd

@twangboy twangboy self-assigned this Jun 26, 2026
Comment thread bootstrap-salt.sh
echodebug "The pip binary '${_pip_cmd}' was not found in PATH"
_pip_cmd="pip$(echo "${_py_version}" | cut -c -1)"
_pip_cmd="${_py_exe} -m pip"
_pip_version="$(${_pip_cmd} --version)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If pip is not installed, running ${_pip_cmd} --version will dump a No module named pip traceback or command error to stderr. We should silence stderr here so the terminal output stays clean for the user during the check.

_pip_version="$( ${_pip_cmd} --version 2>/dev/null )"

Comment thread bootstrap-salt.sh
_pip_cmd="pip$(echo "${_py_version}" | cut -c -1)"
_pip_cmd="${_py_exe} -m pip"
_pip_version="$(${_pip_cmd} --version)"
if [ -z "${_pip_version}" ]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on string length of the output can occasionally be brittle depending on the shell environment or if python outputs unexpected warnings to stdout. A more robust and idiomatic way to check if the module works is to evaluate the exit code of the command directly.

if ! ${_pip_cmd} --version >/dev/null 2>&1; then

Comment thread bootstrap-salt.sh
if [ -z "${_pip_version}" ]; then
echodebug "Pip is not installed for Python '${_py_exe}' (version ${_py_version})"
_pip_cmd="pip${_py_version}"
if ! __check_command_exists "${_pip_cmd}"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocker:
This is where the logic breaks completely. If the code falls through to this check (or if the previous block set _pip_cmd="pip${_py_version}"), passing ${_pip_cmd} to __check_command_exists will fail if it contains spaces (like "/usr/bin/python3 -m pip").

__check_command_exists utilizes utilities like which or command -v, which expect a standalone binary executable, not a command string with flags. Passing -m pip will make the function look for a literal binary with spaces/arguments in its name and fail every time.

Since we've already successfully verified the command works if it hits the fallback logic, we should bypass __check_command_exists entirely when using the -m pip syntax, or handle the check explicitly.

Suggested Change:
Instead of trying to mix the two syntax styles in a single variable and routing them through __check_command_exists, refactor the block to separate the python module execution path from the legacy binary fallback path:

    _pip_cmd="${_py_exe} -m pip"
    if ${_pip_cmd} --version >/dev/null 2>&1; then
        _pip_version="$( ${_pip_cmd} --version 2>/dev/null )"
    else
        echodebug "Pip is not installed for Python '${_py_exe}' (version ${_py_version})"
        # Fallback to looking for standard standalone binaries
        _pip_cmd="pip${_py_version}"
        if ! __check_command_exists "${_pip_cmd}"; then
            echodebug "The pip binary '${_pip_cmd}' was not found in PATH"
            echoerror "Unable to find a pip binary"
            return 1
        fi
        _pip_version="$( ${_pip_cmd} --version 2>/dev/null )"
    fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants