From c4729129daa9bb5204246b857826fb391ac961e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20A=C3=A7acak?= <110401522+huseyinacacak-janea@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:20:35 +0300 Subject: [PATCH] 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 --- lib/find-python.js | 2 +- test/test-find-python.js | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/find-python.js b/lib/find-python.js index 615da57bb8..a71c00c2b6 100644 --- a/lib/find-python.js +++ b/lib/find-python.js @@ -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' diff --git a/test/test-find-python.js b/test/test-find-python.js index c5fa35d4bc..dc7192809a 100644 --- a/test/test-find-python.js +++ b/test/test-find-python.js @@ -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) {