From 47692019b326a8c47aa579c0d9b92e0a3871800a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Jan 2021 21:55:26 -0500 Subject: [PATCH] launcher: support Python 3.5 for now The codebase still supports Python 3.5, so allow use of that instead of requiring Python 3.6+. Supporting this mode well is a bit tricky as we want to first scan for newer versions before falling back to older ones. And we have to avoid infinite loops in the process. Bug: https://crbug.com/gerrit/13795 Change-Id: I47949a173899bfa9ab20d3fefa1a97bf002659f6 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/292442 Reviewed-by: Michael Mortensen Tested-by: Mike Frysinger --- repo | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/repo b/repo index f1b15c5f..dae37bde 100755 --- a/repo +++ b/repo @@ -32,6 +32,13 @@ import subprocess import sys +# These should never be newer than the main.py version since this needs to be a +# bit more flexible with older systems. See that file for more details on the +# versions we select. +MIN_PYTHON_VERSION_SOFT = (3, 6) +MIN_PYTHON_VERSION_HARD = (3, 5) + + # Keep basic logic in sync with repo_trace.py. class Trace(object): """Trace helper logic.""" @@ -70,8 +77,6 @@ def check_python_version(): def reexec(prog): exec_command([prog] + sys.argv) - MIN_PYTHON_VERSION = (3, 6) - ver = sys.version_info major = ver.major minor = ver.minor @@ -80,17 +85,24 @@ def check_python_version(): if (major, minor) < (2, 7): print('repo: error: Your Python version is too old. ' 'Please use Python {}.{} or newer instead.'.format( - *MIN_PYTHON_VERSION), file=sys.stderr) + *MIN_PYTHON_VERSION_SOFT), file=sys.stderr) sys.exit(1) # Try to re-exec the version specific Python 3 if needed. - if (major, minor) < MIN_PYTHON_VERSION: + if (major, minor) < MIN_PYTHON_VERSION_SOFT: # Python makes releases ~once a year, so try our min version +10 to help # bridge the gap. This is the fallback anyways so perf isn't critical. - min_major, min_minor = MIN_PYTHON_VERSION + min_major, min_minor = MIN_PYTHON_VERSION_SOFT for inc in range(0, 10): reexec('python{}.{}'.format(min_major, min_minor + inc)) + # Fallback to older versions if possible. + for inc in range(MIN_PYTHON_VERSION_SOFT[1] - MIN_PYTHON_VERSION_HARD[1], 0, -1): + # Don't downgrade, and don't reexec ourselves (which would infinite loop). + if (min_major, min_minor - inc) <= (major, minor): + break + reexec('python{}.{}'.format(min_major, min_minor - inc)) + # Try the generic Python 3 wrapper, but only if it's new enough. We don't # want to go from (still supported) Python 2.7 to (unsupported) Python 3.5. try: @@ -103,18 +115,19 @@ def check_python_version(): except (OSError, subprocess.CalledProcessError): python3_ver = None - # The python3 version looks like it's new enough, so give it a try. - if python3_ver and python3_ver >= MIN_PYTHON_VERSION: + # If the python3 version looks like it's new enough, give it a try. + if (python3_ver and python3_ver >= MIN_PYTHON_VERSION_HARD + and python3_ver != (major, minor)): reexec('python3') # We're still here, so diagnose things for the user. if major < 3: print('repo: warning: Python 2 is no longer supported; ' - 'Please upgrade to Python {}.{}+.'.format(*MIN_PYTHON_VERSION), + 'Please upgrade to Python {}.{}+.'.format(*MIN_PYTHON_VERSION_HARD), file=sys.stderr) - else: + elif (major, minor) < MIN_PYTHON_VERSION_HARD: print('repo: error: Python 3 version is too old; ' - 'Please use Python {}.{} or newer.'.format(*MIN_PYTHON_VERSION), + 'Please use Python {}.{} or newer.'.format(*MIN_PYTHON_VERSION_HARD), file=sys.stderr) sys.exit(1)