GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — codeql/python/extractor/buildtools/version.py at codeql-cli/latest · github/codeql Expand file tree/ Copy pathversion.pyMore file actions 223 lines (196 loc) · 8.94 KB / Copy pathversion.pyFile metadata and controls223 lines (196 loc) · 8.94 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 import sys import os import subprocess import tokenize import re from buildtools.helper import print_exception_indented TROVE = re.compile(r"Programming Language\s+::\s+Python\s+::\s+(\d)") if sys.version_info > (3,): import collections.abc as collections file_open = tokenize.open else: import collections file_open = open WIN = sys.platform == "win32" if WIN and "CODEQL_EXTRACTOR_PYTHON_OPTION_PYTHON_EXECUTABLE_NAME" not in os.environ: # installing `py` launcher is optional when installing Python on windows, so it's # possible that the user did not install it, see # https://github.com/github/codeql-cli-binaries/issues/125#issuecomment-1157429430 # so we check whether it has been installed, and we check only if the "python_executable_name" # extractor option has not been specified. Newer versions have a `--list` option, # but that has only been mentioned in the docs since 3.9, so to not risk it not # working on potential older versions, we'll just use `py --version` which forwards # the `--version` argument to the default python executable. try: subprocess.check_call(["py", "--version"]) except (subprocess.CalledProcessError, Exception): sys.stderr.write("The `py` launcher is required for CodeQL to work on Windows.") sys.stderr.write("Please include it when installing Python for Windows.") sys.stderr.write("see https://docs.python.org/3/using/windows.html#python-launcher-for-windows") sys.stderr.flush() sys.exit(4) # 4 was a unique exit code at the time of writing AVAILABLE_VERSIONS = [] def set_available_versions(): """Sets the global `AVAILABLE_VERSIONS` to a list of available (major) Python versions.""" global AVAILABLE_VERSIONS if AVAILABLE_VERSIONS: return # already set for version in [3, 2]: try: subprocess.check_call(" ".join(executable_name(version) + ["-c", "pass"]), shell=True) AVAILABLE_VERSIONS.append(version) except Exception: pass # If not available, we simply don't add it to the list if not AVAILABLE_VERSIONS: # If neither 'python3' nor 'python2' is available, we'll just try 'python' and hope for the best AVAILABLE_VERSIONS = [''] def executable(version): """Returns the executable to use for the given Python version.""" global AVAILABLE_VERSIONS set_available_versions() if version not in AVAILABLE_VERSIONS: available_version = AVAILABLE_VERSIONS[0] print("Wanted to run Python %s, but it is not available. Using Python %s instead" % (version, available_version)) version = available_version return executable_name(version) def executable_name(version): if WIN: return ["py", "-%s" % version] else: return ["python%s" % version] PREFERRED_PYTHON_VERSION = None def extractor_executable(): ''' Returns the executable to use for the extractor. If a Python executable name is specified using the extractor option, returns that name. In the absence of a user-specified executable name, returns the executable name for Python 3 if it is available, and Python 2 if not. ''' executable_name = os.environ.get("CODEQL_EXTRACTOR_PYTHON_OPTION_PYTHON_EXECUTABLE_NAME", None) if executable_name is not None: print("Using Python executable name provided via the python_executable_name extractor option: {}" .format(executable_name) ) return [executable_name] # Call machine_version() to ensure we've set PREFERRED_PYTHON_VERSION if PREFERRED_PYTHON_VERSION is None: machine_version() return executable(PREFERRED_PYTHON_VERSION) def machine_version(): """If only Python 2 or Python 3 is installed, will return that version""" global PREFERRED_PYTHON_VERSION print("Trying to guess Python version based on installed versions") if sys.version_info > (3,): this, other = 3, 2 else: this, other = 2, 3 try: exe = executable(other) # We need `shell=True` here in order for the test framework to function correctly. For # whatever reason, the `PATH` variable is ignored if `shell=False`. # Also, this in turn forces us to give the whole command as a string, rather than a list. # Otherwise, the effect is that the Python interpreter is invoked _as a REPL_, rather than # with the given piece of code. subprocess.check_call(" ".join(exe + [ "-c", "pass" ]), shell=True) print("This script is running Python {}, but Python {} is also available (as '{}')" .format(this, other, ' '.join(exe)) ) # If both versions are available, our preferred version is Python 3 PREFERRED_PYTHON_VERSION = 3 return None except Exception: print("Only Python {} installed -- will use that version".format(this)) PREFERRED_PYTHON_VERSION = this return this def trove_version(root): print("Trying to guess Python version based on Trove classifiers in setup.py") try: full_path = os.path.join(root, "setup.py") if not os.path.exists(full_path): print("Did not find setup.py (expected it to be at {})".format(full_path)) return None versions = set() with file_open(full_path) as fd: contents = fd.read() for match in TROVE.finditer(contents): versions.add(int(match.group(1))) if 2 in versions and 3 in versions: print("Found Trove classifiers for both Python 2 and Python 3 in setup.py -- will use Python 3") return 3 elif len(versions) == 1: result = versions.pop() print("Found Trove classifier for Python {} in setup.py -- will use that version".format(result)) return result else: print("Found no Trove classifiers for Python in setup.py") except Exception: print("Skipping due to exception:") print_exception_indented() return None def wrap_with_list(x): if isinstance(x, collections.Iterable) and not isinstance(x, str): return x else: return [x] def travis_version(root): print("Trying to guess Python version based on travis file") try: full_paths = [os.path.join(root, filename) for filename in [".travis.yml", "travis.yml"]] travis_file_paths = [path for path in full_paths if os.path.exists(path)] if not travis_file_paths: print("Did not find any travis files (expected them at either {})".format(full_paths)) return None try: import yaml except ImportError: print("Found a travis file, but yaml library not available") return None with open(travis_file_paths[0]) as travis_file: travis_yaml = yaml.safe_load(travis_file) if "python" in travis_yaml: versions = wrap_with_list(travis_yaml["python"]) else: versions = [] # 'matrix' is an alias for 'jobs' now (https://github.com/travis-ci/docs-travis-ci-com/issues/1500) # If both are defined, only the last defined will be used. if "matrix" in travis_yaml and "jobs" in travis_yaml: print("Ignoring 'matrix' and 'jobs' in Travis file, since they are both defined (only one of them should be).") else: matrix = travis_yaml.get("matrix") or travis_yaml.get("jobs") or dict() includes = matrix.get("include") or [] for include in includes: if "python" in include: versions.extend(wrap_with_list(include["python"])) found = set() for version in versions: # Yaml may convert version strings to numbers, convert them back. version = str(version) if version.startswith("2"): found.add(2) if version.startswith("3"): found.add(3) if len(found) == 1: result = found.pop() print("Only found Python {} in travis file -- will use that version".format(result)) return result elif len(found) == 2: print("Found both Python 2 and Python 3 being used in travis file -- ignoring") else: print("Found no Python being used in travis file") except Exception: print("Skipping due to exception:") print_exception_indented() return None VERSION_TAG = "LGTM_PYTHON_SETUP_VERSION" def best_version(root, default): if VERSION_TAG in os.environ: try: return int(os.environ[VERSION_TAG]) except ValueError: raise SyntaxError("Illegal value for " + VERSION_TAG) print("Will try to guess Python version, as it was not specified in `lgtm.yml`") version = trove_version(root) or travis_version(root) or machine_version() if version is None: version = default print("Could not guess Python version, will use default: Python {}".format(version)) return version |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |