diff mbox series

[05/10] configure: Look for auxiliary Python installations

Message ID 20230222143752.466090-6-pbonzini@redhat.com
State New
Headers show
Series improvement to Python detection, preparation for dropping 3.6 | expand

Commit Message

Paolo Bonzini Feb. 22, 2023, 2:37 p.m. UTC
From: John Snow <jsnow@redhat.com>

At the moment, we look for just "python3" and "python", which is good
enough almost all of the time. But ... if you are on a platform that
uses an older Python by default and only offers a newer Python as an
option, you'll have to specify --python=/usr/bin/foo every time.

We can be kind and instead make a cursory attempt to locate a suitable
Python binary ourselves, looking for the remaining well-known binaries.

This configure loop will use whatever is specified in $PYTHON or, if
empty, will try the following in order:

1. python3
2. python
3. python3.11 down through python3.6

Notes:

- Python virtual environment provides binaries for "python3", "python",
  and whichever version you used to create the venv,
  e.g. "python3.8". If configure is invoked from inside of a venv, this
  configure loop will not "break out" of that venv unless that venv is
  created using an explicitly non-suitable version of Python that we
  cannot use.

- In the event that no suitable python is found, the first python found
  is the version used to generate the human-readable error message.

- The error message isn't printed right away to allow later
  configuration code to pick up an explicitly configured python.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure | 63 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 46 insertions(+), 17 deletions(-)

Comments

Daniel P. Berrangé Feb. 22, 2023, 3:19 p.m. UTC | #1
On Wed, Feb 22, 2023 at 03:37:47PM +0100, Paolo Bonzini wrote:
> From: John Snow <jsnow@redhat.com>
> 
> At the moment, we look for just "python3" and "python", which is good
> enough almost all of the time. But ... if you are on a platform that
> uses an older Python by default and only offers a newer Python as an
> option, you'll have to specify --python=/usr/bin/foo every time.
> 
> We can be kind and instead make a cursory attempt to locate a suitable
> Python binary ourselves, looking for the remaining well-known binaries.
> 
> This configure loop will use whatever is specified in $PYTHON or, if
> empty, will try the following in order:
> 
> 1. python3
> 2. python
> 3. python3.11 down through python3.6
> 
> Notes:
> 
> - Python virtual environment provides binaries for "python3", "python",
>   and whichever version you used to create the venv,
>   e.g. "python3.8". If configure is invoked from inside of a venv, this
>   configure loop will not "break out" of that venv unless that venv is
>   created using an explicitly non-suitable version of Python that we
>   cannot use.
> 
> - In the event that no suitable python is found, the first python found
>   is the version used to generate the human-readable error message.
> 
> - The error message isn't printed right away to allow later
>   configuration code to pick up an explicitly configured python.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  configure | 63 ++++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 46 insertions(+), 17 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
diff mbox series

Patch

diff --git a/configure b/configure
index 4d66a958023e..762b8397a7b7 100755
--- a/configure
+++ b/configure
@@ -592,20 +592,43 @@  esac
 
 : ${make=${MAKE-make}}
 
-# We prefer python 3.x. A bare 'python' is traditionally
-# python 2.x, but some distros have it as python 3.x, so
-# we check that too
-python=
-explicit_python=no
-for binary in "${PYTHON-python3}" python
-do
-    if has "$binary"
-    then
-        python=$(command -v "$binary")
-        break
-    fi
-done
 
+check_py_version() {
+    # We require python >= 3.6.
+    # NB: a True python conditional creates a non-zero return code (Failure)
+    "$1" -c 'import sys; sys.exit(sys.version_info < (3,6))'
+}
+
+python=
+first_python=
+if test -z "${PYTHON}"; then
+    explicit_python=no
+    # A bare 'python' is traditionally python 2.x, but some distros
+    # have it as python 3.x, so check in both places.
+    for binary in python3 python python3.11 python3.10 python3.9 python3.8 python3.7 python3.6; do
+        if has "$binary"; then
+            python=$(command -v "$binary")
+            if check_py_version "$python"; then
+                # This one is good.
+                first_python=
+                break
+            else
+                first_python=$python
+            fi
+        fi
+    done
+else
+    # Same as above, but only check the environment variable.
+    has "${PYTHON}" || error_exit "The PYTHON environment variable does not point to an executable"
+    python=$(command -v "$PYTHON")
+    explicit_python=yes
+    if check_py_version "$python"; then
+        # This one is good.
+        first_python=
+    else
+        first_python=$first_python
+    fi
+fi
 
 # Check for ancillary tools used in testing
 genisoimage=
@@ -1030,16 +1053,22 @@  rm -f ./*/config-devices.mak.d
 
 if test -z "$python"
 then
-    error_exit "Python not found. Use --python=/path/to/python"
+    # If first_python is set, there was a binary somewhere even though
+    # it was not suitable.  Use it for the error message.
+    if test -n "$first_python"; then
+        error_exit "Cannot use '$first_python', Python >= 3.6 is required." \
+            "Use --python=/path/to/python to specify a supported Python."
+    else
+        error_exit "Python not found. Use --python=/path/to/python"
+    fi
 fi
+
 if ! has "$make"
 then
     error_exit "GNU make ($make) not found"
 fi
 
-# Note that if the Python conditional here evaluates True we will exit
-# with status 1 which is a shell 'false' value.
-if ! $python -c 'import sys; sys.exit(sys.version_info < (3,6))'; then
+if ! check_py_version "$python"; then
   error_exit "Cannot use '$python', Python >= 3.6 is required." \
       "Use --python=/path/to/python to specify a supported Python."
 fi