lib: print Python executable path using UTF-8 (#2995)

* lib: print Python executable path using UTF-8

The Python executable path may have non-ASCII characters, which can make
the print function fail if the environment encoding is different. This fixes
this issue by using stdout.buffer, which can be used with UTF-8 encoding
for the output, regardless of the environment encoding.

Fixes: https://github.com/nodejs/node-gyp/issues/2829

* fixup! lib: print Python executable path using UTF-8
This commit is contained in:
Hüseyin Açacak 2024-03-13 19:20:35 +03:00 committed by GitHub
parent 1205fb084c
commit c4729129da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 2 deletions

View file

@ -41,7 +41,7 @@ class PythonFinder {
static findPython = (...args) => new PythonFinder(...args).findPython()
log = log.withPrefix('find Python')
argsExecutable = ['-c', 'import sys; print(sys.executable);']
argsExecutable = ['-c', 'import sys; sys.stdout.buffer.write(sys.executable.encode(\'utf-8\'));']
argsVersion = ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);']
semverRange = '>=3.6.0'

View file

@ -2,11 +2,14 @@
delete process.env.PYTHON
const { describe, it } = require('mocha')
const { describe, it, after } = require('mocha')
const assert = require('assert')
const PythonFinder = require('../lib/find-python')
const { execFile } = require('../lib/util')
const { poison } = require('./common')
const fs = require('fs')
const path = require('path')
const os = require('os')
class TestPythonFinder extends PythonFinder {
constructor (...args) {
@ -32,6 +35,32 @@ describe('find-python', function () {
assert.strictEqual(stderr, '')
})
it('find python - encoding', async function () {
const found = await PythonFinder.findPython(null)
const testFolderPath = fs.mkdtempSync(path.join(os.tmpdir(), 'test-ü-'))
const testFilePath = path.join(testFolderPath, 'python.exe')
after(function () {
try {
fs.unlinkSync(testFilePath)
fs.rmdirSync(testFolderPath)
} catch {}
})
try {
fs.symlinkSync(found, testFilePath)
} catch (err) {
switch (err.code) {
case 'EPERM':
return assert.fail(err, null, 'Please try to run console as an administrator')
default:
return assert.fail(err)
}
}
const finder = new PythonFinder(testFilePath)
await assert.doesNotReject(finder.checkCommand(testFilePath))
})
it('find python - python', async function () {
const f = new TestPythonFinder('python')
f.execFile = async function (program, args, opts) {