Skip to content

Commit 78d9908

Browse files
authored
exit early when a valid Python version is found
1 parent f0a3f23 commit 78d9908

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

src/installer/get-python.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ async function verifyFileIntegrity(filePath, expectedSHA) {
170170

171171
/**
172172
* Search for existing Python executable in system PATH with version validation
173-
* Only accepts Python versions 3.10 through 3.13
174-
* @returns {Promise<string|null>} Path to Python executable or null if not found
173+
* Only accepts Python versions 3.10 through 3.13. Stops at first valid installation found.
174+
* @returns {Promise<string|null>} Path to first valid Python executable or null if not found
175175
*/
176176
export async function findPythonExecutable() {
177177
const exenames = proc.IS_WINDOWS ? ['python.exe'] : ['python3', 'python'];
@@ -180,7 +180,7 @@ export async function findPythonExecutable() {
180180

181181
log('info', 'Searching for compatible Python installation (3.10-3.13)');
182182

183-
// Search through all PATH locations for Python executables
183+
// Search through all PATH locations for Python executables with early exit
184184
for (const location of envPath.split(path.delimiter)) {
185185
for (const exename of exenames) {
186186
const executable = path.normalize(path.join(location, exename)).replace(/"/g, '');
@@ -197,7 +197,7 @@ export async function findPythonExecutable() {
197197
}
198198
}
199199

200-
// Check for specific distutils module error
200+
// Only reached if no valid Python installation found
201201
for (const err of errors) {
202202
if (err.toString().includes('Could not find distutils module')) {
203203
throw err;
@@ -218,7 +218,7 @@ async function isValidPythonVersion(executable) {
218218
const { execSync } = require('child_process');
219219
const output = execSync(`"${executable}" --version`, {
220220
encoding: 'utf8',
221-
timeout: 1000,
221+
timeout: 3000,
222222
stdio: ['ignore', 'pipe', 'pipe']
223223
});
224224

@@ -690,7 +690,7 @@ async function downloadRegistryFile(regfile, destinationDir, options = {}) {
690690
archivePath = path.join(options.predownloadedPackageDir, regfile.name);
691691
if (await fileExists(archivePath)) {
692692
log('info', `Using predownloaded package: ${regfile.name}`);
693-
693+
694694
// Verify integrity of predownloaded file if digest is available
695695
if (regfile.digest && !(await verifyFileIntegrity(archivePath, regfile.digest))) {
696696
log('warn', 'Predownloaded file failed integrity check, re-downloading');
@@ -701,7 +701,7 @@ async function downloadRegistryFile(regfile, destinationDir, options = {}) {
701701
}
702702

703703
archivePath = path.join(destinationDir, regfile.name);
704-
704+
705705
// Skip if already downloaded and verified
706706
if (await fileExists(archivePath)) {
707707
if (regfile.digest) {
@@ -717,9 +717,9 @@ async function downloadRegistryFile(regfile, destinationDir, options = {}) {
717717
}
718718

719719
const pipeline = promisify(stream.pipeline);
720-
720+
721721
log('info', `Downloading Python package: ${regfile.name} (${Math.round(regfile.size / 1024 / 1024)}MB)`);
722-
722+
723723
await pipeline(
724724
got.stream(regfile.download_url, {
725725
timeout: { request: 60000 },
@@ -730,12 +730,12 @@ async function downloadRegistryFile(regfile, destinationDir, options = {}) {
730730
}),
731731
fs.createWriteStream(archivePath)
732732
);
733-
733+
734734
// Verify download completed successfully
735735
if (!(await fileExists(archivePath))) {
736736
throw new Error('Failed to download Python archive');
737737
}
738-
738+
739739
// Verify file integrity using SHA256 if available
740740
if (regfile.digest) {
741741
if (!(await verifyFileIntegrity(archivePath, regfile.digest))) {
@@ -745,7 +745,7 @@ async function downloadRegistryFile(regfile, destinationDir, options = {}) {
745745
} else {
746746
log('warn', 'No SHA256 digest available for verification');
747747
}
748-
748+
749749
return archivePath;
750750
}
751751

@@ -773,7 +773,7 @@ async function extractArchive(source, destination) {
773773
await fs.promises.mkdir(destination, { recursive: true });
774774

775775
const filename = path.basename(source);
776-
776+
777777
if (filename.endsWith('.tar.zst')) {
778778
return await extractTarZst(source, destination);
779779
} else if (filename.endsWith('.tar.gz')) {
@@ -791,7 +791,7 @@ async function extractArchive(source, destination) {
791791
*/
792792
async function extractTarGz(source, destination) {
793793
const pipeline = promisify(stream.pipeline);
794-
794+
795795
await pipeline(
796796
fs.createReadStream(source, { highWaterMark: 64 * 1024 }),
797797
zlib.createGunzip({ chunkSize: 64 * 1024 }),
@@ -801,7 +801,7 @@ async function extractTarGz(source, destination) {
801801
preservePaths: false,
802802
})
803803
);
804-
804+
805805
return destination;
806806
}
807807

@@ -815,12 +815,12 @@ async function extractTarZst(source, destination) {
815815
// Read and decompress file using fzstd
816816
const compressedData = await fs.promises.readFile(source);
817817
const decompressedData = decompress(compressedData);
818-
818+
819819
// Create memory-based stream for tar extraction
820820
const decompressedStream = stream.Readable.from(decompressedData);
821-
821+
822822
const pipeline = promisify(stream.pipeline);
823-
823+
824824
await pipeline(
825825
decompressedStream,
826826
tar.extract({
@@ -829,6 +829,6 @@ async function extractTarZst(source, destination) {
829829
preservePaths: false,
830830
})
831831
);
832-
832+
833833
return destination;
834834
}

0 commit comments

Comments
 (0)