26
26
# Parameters:
27
27
# "$1": The name or path of the python binary to test.
28
28
#
29
- # Return 0 (true) if the given argument "$1" is a Python 3 binary.
29
+ # Return 0 (true) if the given argument "$1" is a viable Python 3 binary.
30
30
# Return a non-zero value (false) otherwise.
31
31
#
32
32
# Diagnostic messages may be printed to stderr (pipe 2). Redirect to /dev/null
@@ -35,41 +35,17 @@ is_python3() (
35
35
set -o errexit
36
36
set -o pipefail
37
37
38
+ HERE=" $( dirname " ${BASH_SOURCE[0]} " ) "
39
+
38
40
# Binary to use, e.g. "python".
39
41
local -r bin=" ${1:? ' is_python3 requires a name or path of a python binary to test' } "
40
42
41
43
# Binary must be executable.
42
44
command -V " $bin " & > /dev/null || return
43
45
44
- # Reject binaries that do not support argument "-V".
45
- " $bin " -V & > /dev/null || return
46
-
47
- # Expect an output of the form: "Python x.y.z".
48
- # Note: Python 2 binaries output to stderr rather than stdout.
49
- local -r version_output=" $( " $bin " -V 2>&1 | tr -d ' \n' ) "
50
-
51
- # For diagnostic purposes.
52
- echo " - $bin : $version_output "
53
-
54
- # shellcheck disable=SC2091
55
- if ! $( " $bin " -c " import sys; exit('free-threading' in sys.version)" ) ; then
56
- echo " Skipping free-threaded version of Python ${version} "
57
- return 1
58
- fi
59
-
60
- # The minimum version we support is Python 3.9. All other versions are EOL.
61
- # shellcheck disable=SC2091
62
- if ! $( " $bin " -c " import sys; exit(sys.version_info[0] == 3 and sys.version_info[1] < 9)" ) ; then
63
- version=$( $bin --version)
64
- echo " Detected EOL Python ${version} , skipping."
65
- return 1
66
- fi
46
+ echo " - ${bin} "
67
47
68
- # Evaluate result of this function.
69
- # Note: Python True (1) and False (0) is treated as fail (1) and success (0)
70
- # by Bash; therefore `is_python3` returns "true" when `v < 3` is false.
71
- # Skip prerelease versions of python.
72
- " $bin " -c " import sys; exit(sys.version_info[0] < 3 or sys.version_info.releaselevel != 'final')"
48
+ " $bin " " ${HERE:? } /is_python3.py" || return
73
49
) 1>&2
74
50
75
51
# is_venv_capable
@@ -209,15 +185,26 @@ find_python3() (
209
185
set -o errexit
210
186
set -o pipefail
211
187
212
- local -a bins=()
213
- local bin=" "
214
-
215
- # The list of Python binaries to test for venv or virtualenv support.
216
- # The binaries are tested in the order of their position in the array.
217
- {
218
- echo " Finding python3 binaries to test..."
188
+ # Prefer Python Toolchain Current version.
189
+ declare python_binary=" "
190
+ case " ${OSTYPE:? } " in
191
+ cygwin)
192
+ python_binary=" /cygdrive/c/Python/Current/python.exe"
193
+ ;;
194
+ darwin* )
195
+ python_binary=" /Library/Frameworks/Python.Framework/Versions/Current/bin/python3"
196
+ ;;
197
+ * )
198
+ python_binary=" /opt/python/Current/bin/python3"
199
+ ;;
200
+ esac
201
+ if is_python3 " ${python_binary:? } " ; then
202
+ echo " Using Python binary ${python_binary:? } " >&2
203
+ echo " ${python_binary:? } "
204
+ return
205
+ fi
219
206
220
- append_bins () {
207
+ test_bins () {
221
208
local -r bin_path=" ${1:? ' missing path' } "
222
209
shift
223
210
local -r pattern=" ${1:? ' missing pattern' } "
@@ -227,78 +214,50 @@ find_python3() (
227
214
for dir in $( find " $bin_path " -maxdepth 1 -name " $pattern " -type d 2> /dev/null | sort -rV) ; do
228
215
for bin in " ${suffixes[@]} " ; do
229
216
if is_python3 " $dir /$bin " ; then
230
- bins+=(" $dir /$bin " )
217
+ echo " $dir /$bin "
218
+ return
231
219
fi
232
220
done
233
221
done
234
222
}
235
223
236
- # C:/python/Python3X/bin/python
237
- append_bins " C:/python" " Python3[0-9]*" " python3.exe" " python.exe"
238
-
239
- # /opt/python/3.X/bin/python
240
- append_bins " /opt/python" " 3.[0-9]*" " bin/python3" " bin/python"
241
-
242
- # /opt/mongodbtoolchain/vX/bin/python
243
- append_bins " /opt/mongodbtoolchain" " v[0-9]*" " bin/python3" " bin/python"
244
-
245
- # /Library/Frameworks/Python.Framework/Versions/XXX/bin/python3 (used by AWS Mac Fleet)
246
- append_bins " /Library/Frameworks/Python.Framework/Versions/" " [0-9]*" " bin/python3"
247
-
248
- bin=" python3"
249
- if is_python3 " $bin " ; then bins+=(" $bin " ); fi
250
-
251
- bin=" python"
252
- if is_python3 " $bin " ; then bins+=(" $bin " ); fi
253
- } 1>&2
254
-
255
- {
256
- # Some environments trigger an unbound variable error if "${bins[@]}" is empty when used below.
257
- if (( "${# bins[@]} " == 0 )) ; then
258
- echo " Could not find any python3 binaries!"
259
- return 1
224
+ # Look in other standard locations.
225
+ case " ${OSTYPE:? } " in
226
+ cygwin)
227
+ # Python toolchain: C:/python/Python3X/bin/python
228
+ python_binary=" $( test_bins " C:/python" " Python3[0-9]*" " python3.exe" " python.exe" ) "
229
+ ;;
230
+ darwin* )
231
+ # Standard location: /Library/Frameworks/Python.Framework/Versions/XXX/bin/python3
232
+ python_binary=" $( test_bins " /Library/Frameworks/Python.Framework/Versions/" " [0-9]*" " bin/python3" ) "
233
+ ;;
234
+ * )
235
+ # MongoDB toolchain: /opt/mongodbtoolchain/vX/bin/python
236
+ python_binary=" $( test_bins " /opt/mongodbtoolchain" " v[0-9]*" " bin/python3" " bin/python" ) "
237
+ if [ -z " $python_binary " ]; then
238
+ # Python toolchain: /opt/python/3.X/bin/python
239
+ python_binary=$( test_bins " /opt/python" " 3.[0-9]*" " bin/python3" " bin/python" )
260
240
fi
241
+ ;;
242
+ esac
261
243
262
- # For diagnostic purposes.
263
- echo " List of python3 binaries to test:"
264
- for bin in " ${bins[@]} " ; do
265
- echo " - $bin "
266
- done
267
- } 1>&2
268
-
269
- # Find a binary that is capable of venv or virtualenv and set it as `res`.
270
- local res=" "
271
- {
272
- echo " Testing python3 binaries..."
273
- for bin in " ${bins[@]} " ; do
274
- {
275
- if ! is_venv_capable " $bin " ; then
276
- echo " - $bin is not capable of venv"
277
-
278
- if ! is_virtualenv_capable " $bin " ; then
279
- echo " - $bin is not capable of virtualenv"
280
- continue
281
- else
282
- echo " - $bin is capable of virtualenv"
283
- fi
284
- else
285
- echo " - $bin is capable of venv"
286
- fi
287
- } 1>&2
288
-
289
- res=" $bin "
290
- break
291
- done
292
-
293
- if [[ -z " $res " ]]; then
294
- echo " Could not find a python3 binary capable of creating a virtual environment!"
295
- return 1
244
+ # Fall back to looking for a system python.
245
+ if [ -z " ${python_binary} " ]; then
246
+ if is_python3 " python3" ; then
247
+ python_binary=" python3"
248
+ elif is_python3 " python" ; then
249
+ python_binary=" python"
296
250
fi
297
- } 1>&2
298
-
299
- echo " $res "
251
+ fi
300
252
301
- return 0
253
+ # Handle success.
254
+ if [ -n " ${python_binary} " ]; then
255
+ echo " Using Python binary ${python_binary:? } " >&2
256
+ echo " ${python_binary:? } "
257
+ return
258
+ else
259
+ echo " No valid pythons found!" >&2
260
+ fi
302
261
)
303
262
304
263
#
@@ -314,7 +273,6 @@ find_python3() (
314
273
# with `2>/dev/null` to silence these messages.
315
274
#
316
275
# If DRIVERS_TOOLS_PYTHON is set, it will return that value. Otherwise
317
- # it will look for the "Current" python in the python toolchain. Finally,
318
276
# it will fall back to using find_python3 to return a suitable value.
319
277
#
320
278
ensure_python3 () {
@@ -325,30 +283,12 @@ ensure_python3() {
325
283
return
326
284
fi
327
285
328
- # Use Python Toolchain.
329
- declare python_binary=" "
330
- case " ${OSTYPE:? } " in
331
- cygwin)
332
- python_binary=" /cygdrive/c/Python/Current/python.exe"
333
- ;;
334
- darwin* )
335
- python_binary=" /Library/Frameworks/Python.Framework/Versions/Current/bin/python3"
336
- ;;
337
- * )
338
- python_binary=" /opt/python/Current/bin/python3"
339
- ;;
340
- esac
341
- if command -v " ${python_binary:? } " > /dev/null; then
342
- echo " Using Python binary ${python_binary:? } " >&2
343
- echo " ${python_binary:? } "
344
- return
345
- fi
346
-
347
286
# Use find_python3.
287
+ declare python_binary=" "
348
288
{
349
289
echo " Finding Python3 binary..."
350
- python_binary=" $( find_python3 2> /dev/null) " || return
290
+ python_binary=" $( find_python3 2> /dev/null) "
351
291
echo " Finding Python3 binary... done."
352
292
} 1>&2
353
- echo " ${python_binary:? } "
293
+ echo " ${python_binary} "
354
294
}
0 commit comments