Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our official announcement
Dowse for Python 2.7 installations on your system and make them available to node-gyp
subprocesses.
node-gyp
only works with Python 2, and this is unlikely to change in the near future.
Furthermore, while node-gyp
allows you to override the Python executable it discovers itself by specifying a PYTHON
environment variable or setting the python
npm config option, certain node-gyp
builds will only work correctly if the python 2 executable is on the ${PATH}
with the exact name "python", because the Makefiles they generate execute generated files with a shebang line of #!/usr/bin/env python
.
Fixing this upstream would be tricky and require changes to trickle through a number of dependent projects. Hence @atom/dowsing-rod, which exists to:
- Locate a compatible Python 2 executable (a) from an existing
$PYTHON
variable (b) as anypython
,python2
, orpython2.7
executable on your$PATH
or (c) specified directly as a.python2-bin
file. - Set the
$PYTHON
environment variable to the discovered binary's path. Prepend a directory containing a wrapper script to your$PATH
so that shebang scripts will execute your chosen Python binary properly.
$ npm install @atom/dowsing-rod
You'll also likely want to add .python2-bin
to your .gitignore
:
$ echo '.python2-bin' >> .gitignore
To fix your node-gyp rebuild
command, add the following to your package.json
:
{
"scripts": {
"install": "with-python2-env node-gyp rebuild"
}
}
If you're launching node-gyp as a subprocess yourself (like we do within the build scripts, for example), you can modify your process' environment directly:
const path = require('path')
const dowsingRod = require('@atom/dowsing-rod')
const options = {
// npm binary used to read config settings
npmBin: 'npm',
// file to store located Python binary
pythonBinFile: path.join(process.cwd(), '.python2-bin')
}
// Options are optional with the defaults shown.
const promise = dowsingRod.setPythonEnv(options, process.env)
// Any exec or spawn calls after the returned promise resolves will have the correct Python environments.
// Or, if you wish to do something with the path yourself:
dowsingRod.getPythonBin(options)
.then(pythonBin => console.log(`Python binary: ${pythonBin}`))
// Synchronous variants are also exported:
dowsingRod.setPythonEnvSync(options, process.env)
const pythonBin = dowsingRod.getPythonBinSync(options)