Returns the path the system-wide python binary. (In case we're running in a virtualenv or venv)
()
| 119 | |
| 120 | |
| 121 | def _get_system_python_executable(): |
| 122 | """ Returns the path the system-wide python binary. |
| 123 | (In case we're running in a virtualenv or venv) |
| 124 | """ |
| 125 | # This function is required by get_package_as_folder() to work |
| 126 | # inside a virtualenv, since venv creation will fail with |
| 127 | # the virtualenv's local python binary. |
| 128 | # (venv/virtualenv incompatibility) |
| 129 | |
| 130 | # Abort if not in virtualenv or venv: |
| 131 | if not hasattr(sys, "real_prefix") and ( |
| 132 | not hasattr(sys, "base_prefix") or |
| 133 | os.path.normpath(sys.base_prefix) == |
| 134 | os.path.normpath(sys.prefix)): |
| 135 | return sys.executable |
| 136 | |
| 137 | # Extract prefix we need to look in: |
| 138 | if hasattr(sys, "real_prefix"): |
| 139 | search_prefix = sys.real_prefix # virtualenv |
| 140 | else: |
| 141 | search_prefix = sys.base_prefix # venv |
| 142 | |
| 143 | def python_binary_from_folder(path): |
| 144 | def binary_is_usable(python_bin): |
| 145 | """ Helper function to see if a given binary name refers |
| 146 | to a usable python interpreter binary |
| 147 | """ |
| 148 | |
| 149 | # Abort if path isn't present at all or a directory: |
| 150 | if not os.path.exists( |
| 151 | os.path.join(path, python_bin) |
| 152 | ) or os.path.isdir(os.path.join(path, python_bin)): |
| 153 | return |
| 154 | # We should check file not found anyway trying to run it, |
| 155 | # since it might be a dead symlink: |
| 156 | try: |
| 157 | filenotfounderror = FileNotFoundError |
| 158 | except NameError: # Python 2 |
| 159 | filenotfounderror = OSError |
| 160 | try: |
| 161 | # Run it and see if version output works with no error: |
| 162 | subprocess.check_output([ |
| 163 | os.path.join(path, python_bin), "--version" |
| 164 | ], stderr=subprocess.STDOUT) |
| 165 | return True |
| 166 | except (subprocess.CalledProcessError, filenotfounderror): |
| 167 | return False |
| 168 | |
| 169 | python_name = "python" + sys.version |
| 170 | while (not binary_is_usable(python_name) and |
| 171 | python_name.find(".") > 0): |
| 172 | # Try less specific binary name: |
| 173 | python_name = python_name.rpartition(".")[0] |
| 174 | if binary_is_usable(python_name): |
| 175 | return os.path.join(path, python_name) |
| 176 | return None |
| 177 | |
| 178 | # Return from sys.real_prefix if present: |