@@ -46,18 +46,6 @@ function prepare_python_and_pip() {
46
46
# Construct the version string (e.g., "python3.12")
47
47
python3_version_string=" python$python3_version_majorminor "
48
48
49
- # Check actual pip3 version
50
- # Note: we don't use "/usr/bin/pip3" at all, since it's commonly missing. instead "python -m pip"
51
- # The hostdep package python3-pip is still required, and other crazy might impact this.
52
- # We might need to install our own pip if it gets bad enough.
53
- declare pip3_version
54
- pip3_version=" $( " ${python3_binary_path} " -m pip --version) "
55
-
56
- # get the pip3 version number only (eg, "21.2.4" from "pip 21.2.4 from /usr/lib/python3/dist-packages/pip (python 3.9)")
57
- declare pip3_version_number
58
- pip3_version_number=" $( echo " ${pip3_version} " | cut -d' ' -f2) " # @TODO: brittle. how to do this better?
59
- display_alert " pip3 version" " ${pip3_version_number} : '${pip3_version} '" " info"
60
-
61
49
# Hash the contents of the dependencies array + the Python version + the release
62
50
declare python3_pip_dependencies_path
63
51
declare python3_pip_dependencies_hash
@@ -66,8 +54,15 @@ function prepare_python_and_pip() {
66
54
# Check for the existence of requirements.txt, fail if not found
67
55
[[ ! -f " ${python3_pip_dependencies_path} " ]] && exit_with_error " Python Pip requirements.txt file not found at path: ${python3_pip_dependencies_path} "
68
56
57
+ # We will install our own pip; we don't want to rely on the host's pip version, as that implies old setuptools etc.
58
+ # Parse the pip version from the requirements.txt file; use grep to find the line starting with "pip == "
59
+ # Example line: "pip == 25.0.1 # pip is the package installer for Python" so get rid of comments
60
+ declare pip3_version_number=" undetermined"
61
+ pip3_version_number=$( grep -E " ^pip[[:space:]]*==" " ${python3_pip_dependencies_path} " | cut -d' =' -f3 | cut -d' #' -f 1 | tr -d ' [:space:]' )
62
+ display_alert " pip3 version" " ${pip3_version_number} " " info"
63
+
69
64
# Calculate the hash for the Pip requirements
70
- python3_pip_dependencies_hash=" $( echo " ${HOSTRELEASE} " " ${python3_version} " " ${pip3_version } " " $( cat " ${python3_pip_dependencies_path} " ) " | sha256sum | cut -d' ' -f1) "
65
+ python3_pip_dependencies_hash=" $( echo " ${HOSTRELEASE} " " ${python3_version} " " ${pip3_version_number } " " $( cat " ${python3_pip_dependencies_path} " ) " | sha256sum | cut -d' ' -f1) "
71
66
72
67
declare non_cache_dir=" /armbian-pip"
73
68
declare python_pip_cache=" ${SRC} /cache/pip"
@@ -83,16 +78,8 @@ function prepare_python_and_pip() {
83
78
fi
84
79
fi
85
80
86
- declare -a pip3_extra_args=(" --no-warn-script-location" " --user" )
87
- # if pip 23+, add "--break-system-packages" to pip3 invocations.
88
- # See See PEP 668 -- System-wide package management with pip
89
- # but the fact is that we're _not_ managing system-wide, instead --user
90
- if linux-version compare " ${pip3_version_number} " ge " 23.0" ; then
91
- pip3_extra_args+=(" --break-system-packages" )
92
- fi
93
- if linux-version compare " ${pip3_version_number} " ge " 22.1" ; then
94
- pip3_extra_args+=(" --root-user-action=ignore" )
95
- fi
81
+ # we run as root, but with --user; --break-system-packages is required due to PEP 668 (no system packages are installed here anyway)
82
+ declare -a pip3_extra_args=(" --no-warn-script-location" " --user" " --root-user-action=ignore" " --break-system-packages" )
96
83
97
84
declare python_hash_base=" ${python_pip_cache} /pip_pkg_hash"
98
85
declare python_hash_file=" ${python_hash_base} _${python3_pip_dependencies_hash} "
@@ -110,11 +97,13 @@ function prepare_python_and_pip() {
110
97
[REQUIREMENTS_PATH]=" ${python3_pip_dependencies_path} "
111
98
[VERSION]=" ${python3_version} "
112
99
[VERSION_STRING]=" ${python3_version_string} "
113
- [PIP_VERSION]=" ${pip3_version} "
100
+ [PIP_VERSION]=" ${pip3_version_number} "
101
+ [GET_PIP_BIN]=" ${PYTHON3_INFO[USERBASE]} /bin/get-pip-${pip3_version_number} .py"
114
102
)
115
103
116
104
# declare a readonly global array for ENV vars to invoke python3 with
117
105
declare -r -g -a PYTHON3_VARS=(
106
+ " PYTHONPATH=/does/not/exist/armbian/uses/user/packages/only"
118
107
" PYTHONUSERBASE=${PYTHON3_INFO[USERBASE]} "
119
108
" PYTHONUNBUFFERED=yes"
120
109
" PYTHONPYCACHEPREFIX=${PYTHON3_INFO[PYCACHEPREFIX]} "
@@ -129,6 +118,18 @@ function prepare_python_and_pip() {
129
118
# remove the old hashes matching base, don't leave junk behind
130
119
run_host_command_logged rm -fv " ${python_hash_base} *"
131
120
121
+ # If get-pip.py is not present, download it, using curl.
122
+ if [[ ! -f " ${PYTHON3_INFO[GET_PIP_BIN]} " ]]; then
123
+ display_alert " Downloading get-pip.py" " from https://bootstrap.pypa.io/get-pip.py" " info"
124
+ run_host_command_logged curl -sSL -o " ${PYTHON3_INFO[GET_PIP_BIN]} " " https://bootstrap.pypa.io/get-pip.py"
125
+ fi
126
+
127
+ # Install pip, using get-pip.py; that bootstraps pip using an embedded, temporary, pip contained in get-pip.py
128
+ display_alert " Installing pip using get-pip.py" " ${pip3_version_number} " " info"
129
+ run_host_command_logged env -i " ${PYTHON3_VARS[@]@ Q} " " ${PYTHON3_INFO[BIN]} " " ${PYTHON3_INFO[GET_PIP_BIN]} " " ${pip3_extra_args[@]} " " pip==${pip3_version_number} "
130
+
131
+ # Install the dependencies
132
+ display_alert " Installing Python dependencies" " from ${python3_pip_dependencies_path} " " info"
132
133
run_host_command_logged env -i " ${PYTHON3_VARS[@]@ Q} " " ${PYTHON3_INFO[BIN]} " -m pip install " ${pip3_extra_args[@]} " -r " ${python3_pip_dependencies_path} "
133
134
134
135
# Create the hash file
0 commit comments