質問: vscodeでpythonのコードを書いています。最近のアップデートの影響か、次のような現象が起きています: * vscodeでpythonファイル(`???.py`)を編集するために開くと、短いときで十数秒、長いときで数分、vscodeのウインドウ自体が固まり一切の操作ができなくなる 次のように調査をしましたが、結局原因は不明でした: 1. 仮想マシン上(VMWare)にWindows 10 Pro (build 18363.900)をクリーンインストール 2. pythonの環境としてAnacondaを用いた ``` > conda info conda version : 4.8.3 conda-build version : 3.17.8 python version : 3.7.3.final.0 ``` 3. VSCodeはポータブル版を新たに取得して実行 (version 1.47.2) * `settings.json`は空(`python.jediEnabled`,`python.languageServer`の設定はしていない)です 4. 拡張機能として ms-python.python のみをインストール * v2020.1.58038 をインストールしたとき、先述の現象は起きない(普通に使える) * v2020.1.58038 より後のバージョン(v2020.2.62710以降)をインストールしたとき、先述の問題が発生 いずれのケースでも、vscodeの操作が可能になれば、実行やデバッグ、intellisense等、動作に問題はありません。 これ以上は自分の知識では調べられなかったので、なにか追加で原因を調べるための方法、もしくは解決策などをご存知でしたらお教え頂ければ幸いです。また、情報に不足があればご指摘ください。 以上、よろしくお願いいたします。 追記 2020/08/01 ------------- procmonで調べてみては、というアイデアをいただいたので調べてみたところ、次のことがわかりました。 * この問題が発生するとき(拡張機能のバージョンがv2020.2.62710以降のとき)、~~Cドライブ全体~~`C:\WINDOWS`ディレクトリをスキャンするようなアクセス(`QueryDirectory`など)が大量に現れる * 上記のアクセスはv2020.1.58038をインストールしているとき、もしくは拡張機能を無効にしたときは現れない このことから、あるバージョン以降ではなにかを検索するためにCドライブをスキャンするようなコードになってしまったのではないかと考えられます。
回答: 拡張機能のソースをいじる方法ですが、一応対処する方法が見つかったので紹介します。 この現象の原因は`src/clinet/pythonEnvironments/discovery/locators/sevices/KnownPathService.ts`において、環境変数`PATH`に`C:\WINDOWS\System32`が含まれているとき、このディレクトリを`lookForInterpretersInDirectory`を経由して`readdir`するため、(`C:\WINDOWS\System32`は単純にファイル数が多いので)処理に時間がかかっているためです。実際、次のようなコードで`C:\WINDOWS`以下のディレクトリを`PATH`から取り除けば、今回の問題は発生しませんでした: ``` diff --git a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts index 5dd284cc1..3e3a17d19 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts @@ -95,9 +95,14 @@ export class KnownSearchPathsForInterpreters implements IKnownSearchPathsForInte const platformService = this.serviceContainer.get(IPlatformService); const pathUtils = this.serviceContainer.get(IPathUtils); + // ignores C:\\WINDOWS, C:\\WINDOWS\\System32 + const ignoreWinDirFilter = platformService.isWindows + ? (p: string): boolean => !/:\\WINDOWS/i.test(p) + : (_: string): boolean => true; + const searchPaths = currentProcess.env[platformService.pathVariableName]!.split(pathUtils.delimiter) .map((p) => p.trim()) - .filter((p) => p.length > 0); + .filter((p) => p.length > 0 && ignoreWinDirFilter(p)); if (!platformService.isWindows) { ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/sbin'].forEach((p) => { ``` (このdiffはコミット`c3af16de`版からの差分です) ただ、これらのディレクトリは`PATH`に既定で入っている気がするので、私の環境だけこういう現象が起きるのはなぜなのかはわかりませんでした。これ以上はどうしたらいいかわからないので、とりあえず個人的にはこの編集したローカルリポジトリを`extensions`ディレクトリに配置して使うことにしました。 もし同じ障害に遭遇した方がいらっしゃれば、助けになれば幸いです。