11import * as path from 'path' ;
2- import { LogOutputChannel , QuickPickItem , Uri , window } from 'vscode' ;
2+ import { CancellationError , CancellationToken , LogOutputChannel , QuickPickItem , Uri , window } from 'vscode' ;
33import {
44 EnvironmentManager ,
55 Package ,
@@ -110,10 +110,20 @@ export async function isUvInstalled(log?: LogOutputChannel): Promise<boolean> {
110110 return available . promise ;
111111}
112112
113- export async function runUV ( args : string [ ] , cwd ?: string , log ?: LogOutputChannel ) : Promise < string > {
113+ export async function runUV (
114+ args : string [ ] ,
115+ cwd ?: string ,
116+ log ?: LogOutputChannel ,
117+ token ?: CancellationToken ,
118+ ) : Promise < string > {
114119 log ?. info ( `Running: uv ${ args . join ( ' ' ) } ` ) ;
115120 return new Promise < string > ( ( resolve , reject ) => {
116121 const proc = ch . spawn ( 'uv' , args , { cwd : cwd } ) ;
122+ token ?. onCancellationRequested ( ( ) => {
123+ proc . kill ( ) ;
124+ reject ( new CancellationError ( ) ) ;
125+ } ) ;
126+
117127 let builder = '' ;
118128 proc . stdout ?. on ( 'data' , ( data ) => {
119129 const s = data . toString ( 'utf-8' ) ;
@@ -134,10 +144,20 @@ export async function runUV(args: string[], cwd?: string, log?: LogOutputChannel
134144 } ) ;
135145}
136146
137- export async function runPython ( python : string , args : string [ ] , cwd ?: string , log ?: LogOutputChannel ) : Promise < string > {
147+ export async function runPython (
148+ python : string ,
149+ args : string [ ] ,
150+ cwd ?: string ,
151+ log ?: LogOutputChannel ,
152+ token ?: CancellationToken ,
153+ ) : Promise < string > {
138154 log ?. info ( `Running: ${ python } ${ args . join ( ' ' ) } ` ) ;
139155 return new Promise < string > ( ( resolve , reject ) => {
140156 const proc = ch . spawn ( python , args , { cwd : cwd } ) ;
157+ token ?. onCancellationRequested ( ( ) => {
158+ proc . kill ( ) ;
159+ reject ( new CancellationError ( ) ) ;
160+ } ) ;
141161 let builder = '' ;
142162 proc . stdout ?. on ( 'data' , ( data ) => {
143163 const s = data . toString ( 'utf-8' ) ;
@@ -312,6 +332,7 @@ export async function installPackages(
312332 options : PackageInstallOptions ,
313333 api : PythonEnvironmentApi ,
314334 manager : PackageManager ,
335+ token ?: CancellationToken ,
315336) : Promise < Package [ ] > {
316337 if ( environment . version . startsWith ( '2.' ) ) {
317338 throw new Error ( 'Python 2.* is not supported (deprecated)' ) ;
@@ -333,13 +354,15 @@ export async function installPackages(
333354 [ ...installArgs , '--python' , environment . execInfo . run . executable , ...packages ] ,
334355 undefined ,
335356 manager . log ,
357+ token ,
336358 ) ;
337359 } else {
338360 await runPython (
339361 environment . execInfo . run . executable ,
340362 [ '-m' , ...installArgs , ...packages ] ,
341363 undefined ,
342364 manager . log ,
365+ token ,
343366 ) ;
344367 }
345368
@@ -353,6 +376,7 @@ export async function uninstallPackages(
353376 api : PythonEnvironmentApi ,
354377 manager : PackageManager ,
355378 packages : string [ ] | Package [ ] ,
379+ token ?: CancellationToken ,
356380) : Promise < Package [ ] > {
357381 if ( environment . version . startsWith ( '2.' ) ) {
358382 throw new Error ( 'Python 2.* is not supported (deprecated)' ) ;
@@ -383,13 +407,15 @@ export async function uninstallPackages(
383407 [ 'pip' , 'uninstall' , '--python' , environment . execInfo . run . executable , ...remove ] ,
384408 undefined ,
385409 manager . log ,
410+ token ,
386411 ) ;
387412 } else {
388413 await runPython (
389414 environment . execInfo . run . executable ,
390415 [ '-m' , 'pip' , 'uninstall' , '-y' , ...remove ] ,
391416 undefined ,
392417 manager . log ,
418+ token ,
393419 ) ;
394420 }
395421 return refreshPackages ( environment , api , manager ) ;
0 commit comments