FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
codeql/python/extractor/buildtools/version.py at codeql-cli/v2.26.0 · github/codeql · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
github
/
codeql
Public
Notifications
You must be signed in to change notification settings
Fork
2.1k
Star
10k
Code
Issues
997
Pull requests
459
Discussions
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
codeql
/
python
/
extractor
/
buildtools
/
version.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
223 lines (196 loc) · 8.94 KB
Breadcrumbs
codeql
/
python
/
extractor
/
buildtools
/
version.py
Copy path
File metadata and controls
223 lines (196 loc) · 8.94 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
Back
|
FazBrowse Home
|
New Git URL