8000 Adopt new Python locator (#23617) · igorgaming/vscode-python@1439637 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 1439637

Browse files
authored
Adopt new Python locator (microsoft#23617)
1 parent d15a2b9 commit 1439637

File tree

7 files changed

+285
-174
lines changed

7 files changed

+285
-174
lines changed

src/client/common/utils/iterable.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
/* eslint-disable @typescript-eslint/no-explicit-any */
5+
// eslint-disable-next-line @typescript-eslint/no-namespace
6+
export namespace Iterable {
7+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
8+
export function is<T = any>(thing: any): thing is Iterable<T> {
9+
return thing && typeof thing === 'object' && typeof thing[Symbol.iterator] === 'function';
10+
}
11+
}

src/client/common/utils/resourceLifecycle.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,50 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
// eslint-disable-next-line max-classes-per-file
45
import { IDisposable } from '../types';
6+
import { Iterable } from './iterable';
57

68
interface IDisposables extends IDisposable {
79
push(...disposable: IDisposable[]): void;
810
}
911

12+
export const EmptyDisposable = {
13+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
14+
dispose: () => {
15+
/** */
16+
},
17+
};
18+
19+
/**
20+
* Disposes of the value(s) passed in.
21+
*/
22+
export function dispose<T extends IDisposable>(disposable: T): T;
23+
export function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;
24+
export function dispose<T extends IDisposable, A extends Iterable<T> = Iterable<T>>(disposables: A): A;
25+
export function dispose<T extends IDisposable>(disposables: Array<T>): Array<T>;
26+
export function dispose<T extends IDisposable>(disposables: ReadonlyArray<T>): ReadonlyArray<T>;
27+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, consistent-return
28+
export function dispose<T extends IDisposable>(arg: T | Iterable<T> | undefined): any {
29+
if (Iterable.is(arg)) {
30+
for (const d of arg) {
31+
if (d) {
32+
try {
33+
d.dispose();
34+
} catch (e) {
35+
console.warn(`dispose() failed for ${d}`, e);
36+
}
37+
}
38+
}
39+
40+
return Array.isArray(arg) ? [] : arg;
41+
}
42+
if (arg) {
43+
arg.dispose();
44+
return arg;
45+
}
46+
}
47+
1048
/**
1149
* Safely dispose each of the disposables.
1250
*/
@@ -43,3 +81,118 @@ export class Disposables implements IDisposables {
4381
await disposeAll(disposables);
4482
}
4583
}
84+
85+
/**
86+
* Manages a collection of disposable values.
87+
*
88+
* This is the preferred way to manage multiple disposables. A `DisposableStore` is safer to work with than an
89+
* `IDisposable[]` as it considers edge cases, such as registering the same value multiple times or adding an item to a
90+
* store that has already been disposed of.
91+
*/
92+
export class DisposableStore implements IDisposable {
93+
static DISABLE_DISPOSED_WARNING = false;
94+
95+
private readonly _toDispose = new Set<IDisposable>();
96+
97+
private _isDisposed = false;
98+
99+
constructor(...disposables: IDisposable[]) {
100+
disposables.forEach((disposable) => this.add(disposable));
101+
}
102+
103+
/**
104+
* Dispose of all registered disposables and mark this object as disposed.
105+
*
106+
* Any future disposables added to this object will be disposed of on `add`.
107+
*/
108+
public dispose(): void {
109+
if (this._isDisposed) {
110+
return;
111+
}
112+
113+
this._isDisposed = true;
114+
this.clear();
115+
}
116+
117+
/**
118+
* @return `true` if this object has been disposed of.
119+
*/
120+
public get isDisposed(): boolean {
121+
return this._isDisposed;
122+
}
123+
124+
/**
125+
* Dispose of all registered disposables but do not mark this object as disposed.
126+
*/
127+
public clear(): void {
128+
if (this._toDispose.size === 0) {
129+
return;
130+
}
131+
132+
try {
133+
dispose(this._toDispose);
134+
} finally {
135+
this._toDispose.clear();
136+
}
137+
}
138+
139+
/**
140+
* Add a new {@link IDisposable disposable} to the collection.
141+
*/
142+
public add<T extends IDisposable>(o: T): T {
143+
if (!o) {
144+
return o;
145+
}
146+
if (((o as unknown) as DisposableStore) === this) {
147+
throw new Error('Cannot register a disposable on itself!');
148+
}
149+
150+
if (this._isDisposed) {
151+
if (!DisposableStore.DISABLE_DISPOSED_WARNING) {
152+
console.warn(
153+
new Error(
154+
'Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!',
155+
).stack,
156+
);
157+
}
158+
} else {
159+
this._toDispose.add(o);
160+
}
161+
162+
return o;
163+
}
164+
}
165+
166+
/**
167+
* Abstract class for a {@link IDisposable disposable} object.
168+
*
169+
* Subclasses can {@linkcode _register} disposables that will be automatically cleaned up when this object is disposed of.
170+
*/
171+
export abstract class DisposableBase implements IDisposable {
172+
protected readonly _store = new DisposableStore();
173+
174+
private _isDisposed = false;
175+
176+
public get isDisposed(): boolean {
177+
return this._isDisposed;
178+
}
179+
180+
constructor(...disposables: IDisposable[]) {
181+
disposables.forEach((disposable) => this._store.add(disposable));
182+
}
183+
184+
public dispose(): void {
185+
this._store.dispose();
186+
this._isDisposed = true;
187+
}
188+
189+
/**
190+
* Adds `o` to the collection of disposables managed by this object.
191+
*/
192+
public _register<T extends IDisposable>(o: T): T {
193+
if (((o as unknown) as DisposableBase) === this) {
194+
throw new Error('Cannot register a disposable on itself!');
195+
}
196+
return this._store.add(o);
197+
}
198+
}

src/client/pythonEnvironments/base/locator.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,6 @@ export type BasicEnvInfo = {
157157
* E.g. display name as provided by Windows Registry or Windows Store, etc
158158
*/
159159
displayName?: string;
160-
/**
161-
* Command used to run Python in this environment.
162-
* E.g. `conda run -n envName python` or `python.exe`
163-
*/
164-
pythonRunCommand?: string[];
165160
identifiedUsingNativeLocator?: boolean;
166161
arch?: Architecture;
167162
ctime?: number;

0 commit comments

Comments
 (0)
0