@@ -18,15 +18,18 @@ PythonFinder.prototype = {
1818 log : logWithPrefix ( log , 'find Python' ) ,
1919 argsExecutable : [ '-c' , 'import sys; print(sys.executable);' ] ,
2020 argsVersion : [ '-c' , 'import sys; print("%s.%s.%s" % sys.version_info[:3]);' ] ,
21- semverRange : '>=2.6.0 <3.0.0' ,
21+ semverRange : process . env . EXPERIMENTAL_NODE_GYP_PYTHON3 ? '2.7.x || >=3.5.0'
22+ : '>=2.6.0 <3.0.0' ,
2223
2324 // These can be overridden for testing:
2425 execFile : cp . execFile ,
2526 env : process . env ,
2627 win : win ,
2728 pyLauncher : 'py.exe' ,
28- defaultLocation : path . join ( process . env . SystemDrive || 'C:' , 'Python27' ,
29- 'python.exe' ) ,
29+ winDefaultLocations : [
30+ path . join ( process . env . SystemDrive || 'C:' , 'Python27' , 'python.exe' ) ,
31+ path . join ( process . env . SystemDrive || 'C:' , 'Python37' , 'python.exe' )
32+ ] ,
3033
3134 // Logs a message at verbose level, but also saves it to be displayed later
3235 // at error level if an error occurs. This should help diagnose the problem.
@@ -39,65 +42,87 @@ PythonFinder.prototype = {
3942 // Ignore errors, keep trying until Python is found.
4043 findPython : function findPython ( ) {
4144 const SKIP = 0 ; const FAIL = 1
42- const toCheck = [
43- {
44- before : ( ) => {
45- if ( ! this . configPython ) {
45+ var toCheck = getChecks . apply ( this )
46+
47+ function getChecks ( ) {
48+ if ( this . env . NODE_GYP_FORCE_PYTHON ) {
49+ return [ {
50+ before : ( ) => {
4651 this . addLog (
47- 'Python is not set from command line or npm configuration' )
48- return SKIP
49- }
50- this . addLog ( 'checking Python explicitly set from command line or ' +
51- 'npm configuration' )
52- this . addLog ( '- "--python=" or "npm config get python" is ' +
53- `"${ this . configPython } "` )
54- } ,
55- check : this . checkCommand ,
56- arg : this . configPython
57- } ,
58- {
59- before : ( ) => {
60- if ( ! this . env . PYTHON ) {
61- this . addLog ( 'Python is not set from environment variable PYTHON' )
62- return SKIP
63- }
64- this . addLog (
65- 'checking Python explicitly set from environment variable PYTHON' )
66- this . addLog ( `- process.env.PYTHON is "${ this . env . PYTHON } "` )
52+ 'checking Python explicitly set from NODE_GYP_FORCE_PYTHON' )
53+ this . addLog ( '- process.env.NODE_GYP_FORCE_PYTHON is ' +
54+ `"${ this . env . NODE_GYP_FORCE_PYTHON } "` )
55+ } ,
56+ check : this . checkCommand ,
57+ arg : this . env . NODE_GYP_FORCE_PYTHON
58+ } ]
59+ }
60+
61+ var checks = [
62+ {
63+ before : ( ) => {
64+ if ( ! this . configPython ) {
65+ this . addLog (
66+ 'Python is not set from command line or npm configuration' )
67+ return SKIP
68+ }
69+ this . addLog ( 'checking Python explicitly set from command line or ' +
70+ 'npm configuration' )
71+ this . addLog ( '- "--python=" or "npm config get python" is ' +
72+ `"${ this . configPython } "` )
73+ } ,
74+ check : this . checkCommand ,
75+ arg : this . configPython
6776 } ,
68- check : this . checkCommand ,
69- arg : this . env . PYTHON
70- } ,
71- {
72- before : ( ) => { this . addLog ( 'checking if "python2" can be used' ) } ,
73- check : this . checkCommand ,
74- arg : 'python2'
75- } ,
76- {
77- before : ( ) => { this . addLog ( 'checking if "python" can be used' ) } ,
78- check : this . checkCommand ,
79- arg : 'python'
80- } ,
81- {
82- before : ( ) => {
83- if ( ! this . win ) {
84- // Everything after this is Windows specific
85- return FAIL
86- }
87- this . addLog (
88- 'checking if the py launcher can be used to find Python 2' )
77+ {
78+ before : ( ) => {
79+ if ( ! this . env . PYTHON ) {
80+ this . addLog ( 'Python is not set from environment variable ' +
81+ 'PYTHON' )
82+ return SKIP
83+ }
84+ this . addLog ( 'checking Python explicitly set from environment ' +
85+ 'variable PYTHON' )
86+ this . addLog ( `- process.env.PYTHON is "${ this . env . PYTHON } "` )
87+ } ,
88+ check : this . checkCommand ,
89+ arg : this . env . PYTHON
8990 } ,
90- check : this . checkPyLauncher
91- } ,
92- {
93- before : ( ) => {
94- this . addLog (
95- 'checking if Python 2 is installed in the default location' )
91+ {
92+ before : ( ) => { this . addLog ( 'checking if "python" can be used' ) } ,
93+ check : this . checkCommand ,
94+ arg : 'python'
9695 } ,
97- check : this . checkExecPath ,
98- arg : this . defaultLocation
96+ {
97+ before : ( ) => { this . addLog ( 'checking if "python2" can be used' ) } ,
98+ check : this . checkCommand ,
99+ arg : 'python2'
100+ }
101+ ]
102+
103+ if ( this . win ) {
104+ checks . push ( {
105+ before : ( ) => {
106+ this . addLog (
107+ 'checking if the py launcher can be used to find Python 2' )
108+ } ,
109+ check : this . checkPyLauncher
110+ } )
111+ for ( var i = 0 ; i < this . winDefaultLocations . length ; ++ i ) {
112+ const location = this . winDefaultLocations [ i ]
113+ checks . push ( {
114+ before : ( ) => {
115+ this . addLog ( 'checking if Python is ' +
116+ `${ location } ` )
117+ } ,
118+ check : this . checkExecPath ,
119+ arg : location
120+ } )
121+ }
99122 }
100- ]
123+
124+ return checks
125+ }
101126
102127 function runChecks ( err ) {
103128 this . log . silly ( 'runChecks: err = %j' , ( err && err . stack ) || err )
@@ -276,7 +301,7 @@ PythonFinder.prototype = {
276301
277302 this . log . error ( `\n${ errorLog } \n\n${ info } \n` )
278303 process . nextTick ( this . callback . bind ( null , new Error (
279- 'Could not find any Python 2 installation to use' ) ) )
304+ 'Could not find any Python installation to use' ) ) )
280305 }
281306}
282307
0 commit comments