@@ -18,15 +18,17 @@ 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 . NODE_GYP_PYTHON3  ?  '>=2.7.0'  :  '>=2.6.0 <3.0.0' , 
2222
2323  // These can be overridden for testing: 
2424  execFile : cp . execFile , 
2525  env : process . env , 
2626  win : win , 
2727  pyLauncher : 'py.exe' , 
28-   defaultLocation : path . join ( process . env . SystemDrive  ||  'C:' ,  'Python27' , 
29-     'python.exe' ) , 
28+   winDefaultLocations : [ 
29+     path . join ( process . env . SystemDrive  ||  'C:' ,  'Python27' ,  'python.exe' ) , 
30+     path . join ( process . env . SystemDrive  ||  'C:' ,  'Python37' ,  'python.exe' ) 
31+   ] , 
3032
3133  // Logs a message at verbose level, but also saves it to be displayed later 
3234  // at error level if an error occurs. This should help diagnose the problem. 
@@ -39,65 +41,87 @@ PythonFinder.prototype = {
3941  // Ignore errors, keep trying until Python is found. 
4042  findPython : function  findPython  ( )  { 
4143    const  SKIP  =  0 ;  const  FAIL  =  1 
42-     const  toCheck  =  [ 
43-       { 
44-         before : ( )  =>  { 
45-           if  ( ! this . configPython )  { 
44+     var  toCheck  =  getChecks . apply ( this ) 
45+ 
46+     function  getChecks  ( )  { 
47+       if  ( this . env . NODE_GYP_FORCE_PYTHON )  { 
48+         return  [  { 
49+           before : ( )  =>  { 
4650            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 }  "` ) 
51+               'checking Python explicitly set from NODE_GYP_FORCE_PYTHON' ) 
52+             this . addLog ( '- process.env.NODE_GYP_FORCE_PYTHON is '  + 
53+               `"${ this . env . NODE_GYP_FORCE_PYTHON }  "` ) 
54+           } , 
55+           check : this . checkCommand , 
56+           arg : this . env . NODE_GYP_FORCE_PYTHON 
57+         }  ] 
58+       } 
59+ 
60+       var  checks  =  [ 
61+         { 
62+           before : ( )  =>  { 
63+             if  ( ! this . configPython )  { 
64+               this . addLog ( 
65+                 'Python is not set from command line or npm configuration' ) 
66+               return  SKIP 
67+             } 
68+             this . addLog ( 'checking Python explicitly set from command line or '  + 
69+               'npm configuration' ) 
70+             this . addLog ( '- "--python=" or "npm config get python" is '  + 
71+               `"${ this . configPython }  "` ) 
72+           } , 
73+           check : this . checkCommand , 
74+           arg : this . configPython 
6775        } , 
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' ) 
76+         { 
77+           before : ( )  =>  { 
78+             if  ( ! this . env . PYTHON )  { 
79+               this . addLog ( 'Python is not set from environment variable '  + 
80+                 'PYTHON' ) 
81+               return  SKIP 
82+             } 
83+             this . addLog ( 'checking Python explicitly set from environment '  + 
84+               'variable PYTHON' ) 
85+             this . addLog ( `- process.env.PYTHON is "${ this . env . PYTHON }  "` ) 
86+           } , 
87+           check : this . checkCommand , 
88+           arg : this . env . PYTHON 
8989        } , 
90-         check : this . checkPyLauncher 
91-       } , 
92-       { 
93-         before : ( )  =>  { 
94-           this . addLog ( 
95-             'checking if Python 2 is installed in the default location' ) 
90+         { 
91+           before : ( )  =>  {  this . addLog ( 'checking if "python" can be used' )  } , 
92+           check : this . checkCommand , 
93+           arg : 'python' 
9694        } , 
97-         check : this . checkExecPath , 
98-         arg : this . defaultLocation 
95+         { 
96+           before : ( )  =>  {  this . addLog ( 'checking if "python2" can be used' )  } , 
97+           check : this . checkCommand , 
98+           arg : 'python2' 
99+         } 
100+       ] 
101+ 
102+       if  ( this . win )  { 
103+         checks . push ( { 
104+           before : ( )  =>  { 
105+             this . addLog ( 
106+               'checking if the py launcher can be used to find Python 2' ) 
107+           } , 
108+           check : this . checkPyLauncher 
109+         } ) 
110+         for  ( var  i  =  0 ;  i  <  this . winDefaultLocations . length ;  ++ i )  { 
111+           const  location  =  this . winDefaultLocations [ i ] 
112+           checks . push ( { 
113+             before : ( )  =>  { 
114+               this . addLog ( 'checking if Python is '  + 
115+                 `${ location }  ` ) 
116+             } , 
117+             check : this . checkExecPath , 
118+             arg : location 
119+           } ) 
120+         } 
99121      } 
100-     ] 
122+ 
123+       return  checks 
124+     } 
101125
102126    function  runChecks  ( err )  { 
103127      this . log . silly ( 'runChecks: err = %j' ,  ( err  &&  err . stack )  ||  err ) 
@@ -276,7 +300,7 @@ PythonFinder.prototype = {
276300
277301    this . log . error ( `\n${ errorLog }  \n\n${ info }  \n` ) 
278302    process . nextTick ( this . callback . bind ( null ,  new  Error ( 
279-       'Could not find any Python 2  installation to use' ) ) ) 
303+       'Could not find any Python installation to use' ) ) ) 
280304  } 
281305} 
282306
0 commit comments