Find the relevant python executable that is of the given python major version. Will test, in decreasing priority order: * the current Python interpreter * 'pythonX' executable in PATH (with X the given major version) if available * 'python' executable in PATH if available *
()
| 57 | |
| 58 | |
| 59 | def find_python_executable() -> str: |
| 60 | """ |
| 61 | Find the relevant python executable that is of the given python major version. |
| 62 | Will test, in decreasing priority order: |
| 63 | |
| 64 | * the current Python interpreter |
| 65 | * 'pythonX' executable in PATH (with X the given major version) if available |
| 66 | * 'python' executable in PATH if available |
| 67 | * Windows Python launcher 'py' executable in PATH if available |
| 68 | |
| 69 | Incompatible python versions for Certbot will be evicted (e.g. Python 3 |
| 70 | versions less than 3.7). |
| 71 | |
| 72 | :rtype: str |
| 73 | :return: the relevant python executable path |
| 74 | :raise RuntimeError: if no relevant python executable path could be found |
| 75 | """ |
| 76 | python_executable_path = None |
| 77 | |
| 78 | # First try, current python executable |
| 79 | if _check_version('{0}.{1}.{2}'.format( |
| 80 | sys.version_info[0], sys.version_info[1], sys.version_info[2])): |
| 81 | return sys.executable |
| 82 | |
| 83 | # Second try, with python executables in path |
| 84 | for one_version in ('3', '',): |
| 85 | try: |
| 86 | one_python = 'python{0}'.format(one_version) |
| 87 | output = subprocess.check_output([one_python, '--version'], |
| 88 | universal_newlines=True, stderr=subprocess.STDOUT) |
| 89 | if _check_version(output.strip().split()[1]): |
| 90 | return subprocess.check_output([one_python, '-c', |
| 91 | 'import sys; sys.stdout.write(sys.executable);'], |
| 92 | universal_newlines=True) |
| 93 | except (subprocess.CalledProcessError, OSError): |
| 94 | pass |
| 95 | |
| 96 | # Last try, with Windows Python launcher |
| 97 | try: |
| 98 | output_version = subprocess.check_output(['py', '-3', '--version'], |
| 99 | universal_newlines=True, stderr=subprocess.STDOUT) |
| 100 | if _check_version(output_version.strip().split()[1]): |
| 101 | return subprocess.check_output(['py', env_arg, '-c', |
| 102 | 'import sys; sys.stdout.write(sys.executable);'], |
| 103 | universal_newlines=True) |
| 104 | except (subprocess.CalledProcessError, OSError): |
| 105 | pass |
| 106 | |
| 107 | if not python_executable_path: |
| 108 | raise RuntimeError('Error, no compatible Python executable for Certbot could be found.') |
| 109 | |
| 110 | |
| 111 | def _check_version(version_str): |
no test coverage detected