Skip to content

Commit e2c75b4

Browse files
committed
python: accept Python 3 when NODE_GYP_PYTHON3=1
This allows us to start testing Python 3 without breaking node-gyp for users. This also adds support for NODE_GYP_FORCE_PYTHON, which will be the only Python binary acceptable when defined.
1 parent c79708d commit e2c75b4

File tree

3 files changed

+113
-188
lines changed

3 files changed

+113
-188
lines changed

.travis.yml

+28-2
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,61 @@ cache: pip
44
matrix:
55
include:
66
- name: "Python 2.7 on Linux"
7+
env: NODE_GYP_FORCE_PYTHON=python2
78
python: 2.7
89
- name: "Python 2.7 on macOS"
910
os: osx
1011
osx_image: xcode10.2
1112
language: shell # 'language: python' is not yet supported on macOS
13+
env: NODE_GYP_FORCE_PYTHON=python2
1214
before_install: HOMEBREW_NO_AUTO_UPDATE=1 brew install npm
1315
- name: "Node.js 6 & Python 2.7 on Windows"
1416
os: windows
1517
language: node_js
1618
node_js: 6 # node
17-
env: PATH=/c/Python27:/c/Python27/Scripts:$PATH
19+
env: >-
20+
PATH=/c/Python27:/c/Python27/Scripts:$PATH
21+
NODE_GYP_FORCE_PYTHON=/c/Python27/python.exe
1822
before_install: choco install python2
1923
- name: "Node.js 12 & Python 2.7 on Windows"
2024
os: windows
2125
language: node_js
2226
node_js: 12 # node
23-
env: PATH=/c/Python27:/c/Python27/Scripts:$PATH
27+
env: >-
28+
PATH=/c/Python27:/c/Python27/Scripts:$PATH
29+
NODE_GYP_FORCE_PYTHON=/c/Python27/python.exe
2430
before_install: choco install python2
2531
- name: "Node.js 6 & Python 3.7 on Linux"
2632
python: 3.7
33+
env: NODE_GYP_FORCE_PYTHON=python3 NODE_GYP_PYTHON3=1
2734
before_install: nvm install 6
2835
- name: "Node.js 8 & Python 3.7 on Linux"
2936
python: 3.7
37+
env: NODE_GYP_FORCE_PYTHON=python3 NODE_GYP_PYTHON3=1
3038
before_install: nvm install 8
3139
- name: "Node.js 10 & Python 3.7 on Linux"
3240
python: 3.7
41+
env: NODE_GYP_FORCE_PYTHON=python3 NODE_GYP_PYTHON3=1
3342
before_install: nvm install 10
3443
- name: "Node.js 12 & Python 3.7 on Linux"
3544
python: 3.7
45+
env: NODE_GYP_FORCE_PYTHON=python3 NODE_GYP_PYTHON3=1
3646
before_install: nvm install 12
47+
- name: "Node.js 12 & Python 3.7 on Windows"
48+
os: windows
49+
language: node_js
50+
node_js: 12 # node
51+
env: >-
52+
PATH=/c/Python37:/c/Python37/Scripts:$PATH
53+
NODE_GYP_FORCE_PYTHON=/c/Python37/python.exe
54+
NODE_GYP_PYTHON3=1
55+
before_install: choco install python
56+
allow_failures:
57+
- env: NODE_GYP_FORCE_PYTHON=python3 NODE_GYP_PYTHON3=1
58+
- env: >-
59+
PATH=/c/Python37:/c/Python37/Scripts:$PATH
60+
NODE_GYP_FORCE_PYTHON=/c/Python37/python.exe
61+
NODE_GYP_PYTHON3=1
3762
install:
3863
#- pip install -r requirements.txt
3964
- pip install flake8 # pytest # add another testing frameworks later
@@ -45,6 +70,7 @@ before_script:
4570
- flake8 . --count --exit-zero --ignore=E111,E114,W503 --max-complexity=10 --max-line-length=127 --statistics
4671
- npm install
4772
script:
73+
- node -e 'require("npmlog").level="verbose"; require("./lib/find-python")(null,()=>{})'
4874
- npm test
4975
#- pytest --capture=sys # add other tests here
5076
notifications:

lib/find-python.js

+82-58
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)