diff --git a/package-lock.json b/package-lock.json index 123b44622219..39ab90bf932c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "python", - "version": "2022.18.0-rc", + "version": "2022.18.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "python", - "version": "2022.18.0-rc", + "version": "2022.18.2", "license": "MIT", "dependencies": { "@vscode/extension-telemetry": "^0.6.2", @@ -131,7 +131,7 @@ "yargs": "^15.3.1" }, "engines": { - "vscode": "^1.68.0" + "vscode": "^1.73.0" } }, "node_modules/@babel/code-frame": { @@ -8442,13 +8442,10 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "node_modules/json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { "json5": "lib/cli.js" }, @@ -8682,6 +8679,20 @@ "node": ">=6.11.5" } }, + "node_modules/loader-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", + "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -9864,35 +9875,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/node-loader/node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/node-loader/node_modules/loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/node-polyfill-webpack-plugin": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", @@ -21989,13 +21971,10 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonc-parser": { "version": "3.0.0", @@ -22185,6 +22164,17 @@ "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "dev": true }, + "loader-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", + "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -23126,28 +23116,6 @@ "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } } }, "node-polyfill-webpack-plugin": { diff --git a/package.json b/package.json index 2e2368eb8de1..0a581e087a6b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "python", "displayName": "Python", "description": "IntelliSense (Pylance), Linting, Debugging (multi-threaded, remote), Jupyter Notebooks, code formatting, refactoring, unit tests, and more.", - "version": "2022.18.0-rc", + "version": "2022.18.2", "featureFlags": { "usingNewInterpreterStorage": true }, @@ -40,7 +40,7 @@ "theme": "dark" }, "engines": { - "vscode": "^1.68.0" + "vscode": "^1.73.0" }, "keywords": [ "python", diff --git a/pythonFiles/jedilsp_requirements/requirements.txt b/pythonFiles/jedilsp_requirements/requirements.txt index 44a77c8e824c..0ab00132f463 100644 --- a/pythonFiles/jedilsp_requirements/requirements.txt +++ b/pythonFiles/jedilsp_requirements/requirements.txt @@ -16,43 +16,57 @@ jedi==0.18.1 \ --hash=sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d \ --hash=sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab # via jedi-language-server -jedi-language-server==0.36.0 \ - --hash=sha256:30f69eab674ed6b7e35316ea558d2bdd150f1b05ce7a9f65dd67388ef1fa0e35 \ - --hash=sha256:d60ce0927ad4e9c81f4545804b36a5dcd028070160a7225a04acb2ddd4f3d06c +jedi-language-server==0.38.0 \ + --hash=sha256:573f790267cd149fe356d974da5e9be5f219dea9f5659895487122f7fad120c0 \ + --hash=sha256:98f439926da1ce0410d6f52d0bc0ffbefdfe71fbbd2c7d009ef9e162175c2548 # via -r pythonFiles\jedilsp_requirements\requirements.in parso==0.8.3 \ --hash=sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0 \ --hash=sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75 # via jedi -pydantic==1.8.2 \ - --hash=sha256:021ea0e4133e8c824775a0cfe098677acf6fa5a3cbf9206a376eed3fc09302cd \ - --hash=sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739 \ - --hash=sha256:05ef5246a7ffd2ce12a619cbb29f3307b7c4509307b1b49f456657b43529dc6f \ - --hash=sha256:10e5622224245941efc193ad1d159887872776df7a8fd592ed746aa25d071840 \ - --hash=sha256:18b5ea242dd3e62dbf89b2b0ec9ba6c7b5abaf6af85b95a97b00279f65845a23 \ - --hash=sha256:234a6c19f1c14e25e362cb05c68afb7f183eb931dd3cd4605eafff055ebbf287 \ - --hash=sha256:244ad78eeb388a43b0c927e74d3af78008e944074b7d0f4f696ddd5b2af43c62 \ - --hash=sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b \ - --hash=sha256:41b542c0b3c42dc17da70554bc6f38cbc30d7066d2c2815a94499b5684582ecb \ - --hash=sha256:4a03cbbe743e9c7247ceae6f0d8898f7a64bb65800a45cbdc52d65e370570820 \ - --hash=sha256:4be75bebf676a5f0f87937c6ddb061fa39cbea067240d98e298508c1bda6f3f3 \ - --hash=sha256:54cd5121383f4a461ff7644c7ca20c0419d58052db70d8791eacbbe31528916b \ - --hash=sha256:589eb6cd6361e8ac341db97602eb7f354551482368a37f4fd086c0733548308e \ - --hash=sha256:8621559dcf5afacf0069ed194278f35c255dc1a1385c28b32dd6c110fd6531b3 \ - --hash=sha256:8b223557f9510cf0bfd8b01316bf6dd281cf41826607eada99662f5e4963f316 \ - --hash=sha256:99a9fc39470010c45c161a1dc584997f1feb13f689ecf645f59bb4ba623e586b \ - --hash=sha256:a7c6002203fe2c5a1b5cbb141bb85060cbff88c2d78eccbc72d97eb7022c43e4 \ - --hash=sha256:a83db7205f60c6a86f2c44a61791d993dff4b73135df1973ecd9eed5ea0bda20 \ - --hash=sha256:ac8eed4ca3bd3aadc58a13c2aa93cd8a884bcf21cb019f8cfecaae3b6ce3746e \ - --hash=sha256:e710876437bc07bd414ff453ac8ec63d219e7690128d925c6e82889d674bb505 \ - --hash=sha256:ea5cb40a3b23b3265f6325727ddfc45141b08ed665458be8c6285e7b85bd73a1 \ - --hash=sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833 +pydantic==1.10.2 \ + --hash=sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42 \ + --hash=sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624 \ + --hash=sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e \ + --hash=sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559 \ + --hash=sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709 \ + --hash=sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9 \ + --hash=sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d \ + --hash=sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52 \ + --hash=sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda \ + --hash=sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912 \ + --hash=sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c \ + --hash=sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525 \ + --hash=sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe \ + --hash=sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41 \ + --hash=sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b \ + --hash=sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283 \ + --hash=sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965 \ + --hash=sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c \ + --hash=sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410 \ + --hash=sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5 \ + --hash=sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116 \ + --hash=sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98 \ + --hash=sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f \ + --hash=sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644 \ + --hash=sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13 \ + --hash=sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd \ + --hash=sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254 \ + --hash=sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6 \ + --hash=sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488 \ + --hash=sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5 \ + --hash=sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c \ + --hash=sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1 \ + --hash=sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a \ + --hash=sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2 \ + --hash=sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d \ + --hash=sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236 # via # jedi-language-server # pygls -pygls==0.11.3 \ - --hash=sha256:4d86fc854e6d6613cd42bf7511e9c6aac947fc8d62ff973a705570b036d969f2 \ - --hash=sha256:5c925b182f2b0aa38d0ce83a9829ca5aed8eb9c7079cffc5bddff2da1033b58f +pygls==0.12.4 \ + --hash=sha256:1b96378452217a02f19d89d9e647a4256d8d445ab3c641a589b4f73bf11898b6 \ + --hash=sha256:63b859411307ed6f99fb9dd0e71be507a17ae9b3de5c5d07c497f5bddadcc46a # via # -r pythonFiles\jedilsp_requirements\requirements.in # jedi-language-server @@ -60,13 +74,13 @@ typeguard==2.13.3 \ --hash=sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4 \ --hash=sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1 # via pygls -typing-extensions==4.2.0 \ - --hash=sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708 \ - --hash=sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376 +typing-extensions==4.4.0 \ + --hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \ + --hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e # via # importlib-metadata # pydantic -zipp==3.8.0 \ - --hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad \ - --hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099 +zipp==3.10.0 \ + --hash=sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1 \ + --hash=sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8 # via importlib-metadata diff --git a/src/client/common/extensions.ts b/src/client/common/extensions.ts index 5510d95069f7..d4c726e31ab4 100644 --- a/src/client/common/extensions.ts +++ b/src/client/common/extensions.ts @@ -39,10 +39,10 @@ declare interface String { trimQuotes(): string; /** - * String.replaceAll implementation + * String.replaceAllExtra implementation * Replaces all instances of a substring with a new string */ - replaceAll(substr: string, newSubstr: string): string; + replaceAllExtra(substr: string, newSubstr: string): string; } /** @@ -101,10 +101,10 @@ String.prototype.trimQuotes = function (this: string): string { }; /** - * String.replaceAll implementation + * String.replaceAllExtra implementation * Replaces all instances of a substring with a new substring. */ -String.prototype.replaceAll = function (this: string, substr: string, newSubstr: string): string { +String.prototype.replaceAllExtra = function (this: string, substr: string, newSubstr: string): string { if (!this) { return this; } diff --git a/src/client/common/process/logger.ts b/src/client/common/process/logger.ts index 6a8e25d76e0b..538977c65573 100644 --- a/src/client/common/process/logger.ts +++ b/src/client/common/process/logger.ts @@ -57,7 +57,7 @@ function replaceMatchesWithCharacter(original: string, match: string, character: let pattern = escapeRegExp(match); if (getOSType() === OSType.Windows) { // Match both forward and backward slash versions of 'match' for Windows. - pattern = pattern.replaceAll('\\\\', '(\\\\|/)'); + pattern = pattern.replaceAllExtra('\\\\', '(\\\\|/)'); } let regex = new RegExp(pattern, 'ig'); return regex; diff --git a/src/client/debugger/extension/configuration/dynamicdebugConfigurationService.ts b/src/client/debugger/extension/configuration/dynamicdebugConfigurationService.ts index 4fb2e7e0c225..5ab95c51332b 100644 --- a/src/client/debugger/extension/configuration/dynamicdebugConfigurationService.ts +++ b/src/client/debugger/extension/configuration/dynamicdebugConfigurationService.ts @@ -66,7 +66,7 @@ export class DynamicPythonDebugConfigurationService implements IDynamicDebugConf if (fastApiPath) { fastApiPath = path .relative(folder.uri.fsPath, fastApiPath) - .replaceAll(this.pathUtils.separator, '.') + .replaceAllExtra(this.pathUtils.separator, '.') .replace('.py', ''); providers.push({ name: 'Python: FastAPI', diff --git a/src/client/linters/linterManager.ts b/src/client/linters/linterManager.ts index 01a4c4ca38ea..72c92aa1c77d 100644 --- a/src/client/linters/linterManager.ts +++ b/src/client/linters/linterManager.ts @@ -13,8 +13,8 @@ import { Bandit } from './bandit'; import { Flake8 } from './flake8'; import { LinterInfo } from './linterInfo'; import { MyPy } from './mypy'; -import { Flake8ExtensionPrompt } from './prompts/flake8Prompt'; -import { PylintExtensionPrompt } from './prompts/pylintPrompt'; +import { getOrCreateFlake8Prompt } from './prompts/flake8Prompt'; +import { getOrCreatePylintPrompt } from './prompts/pylintPrompt'; import { Prospector } from './prospector'; import { Pycodestyle } from './pycodestyle'; import { PyDocStyle } from './pydocstyle'; @@ -112,9 +112,9 @@ export class LinterManager implements ILinterManager { case Product.bandit: return new Bandit(serviceContainer); case Product.flake8: - return new Flake8(serviceContainer, new Flake8ExtensionPrompt(serviceContainer)); + return new Flake8(serviceContainer, getOrCreateFlake8Prompt(serviceContainer)); case Product.pylint: - return new Pylint(serviceContainer, new PylintExtensionPrompt(serviceContainer)); + return new Pylint(serviceContainer, getOrCreatePylintPrompt(serviceContainer)); case Product.mypy: return new MyPy(serviceContainer); case Product.prospector: diff --git a/src/client/linters/prompts/common.ts b/src/client/linters/prompts/common.ts index 509baaf4ee89..bf459f895ead 100644 --- a/src/client/linters/prompts/common.ts +++ b/src/client/linters/prompts/common.ts @@ -1,13 +1,38 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import * as fs from 'fs-extra'; +import * as path from 'path'; import { ShowToolsExtensionPrompt } from '../../common/experiments/groups'; import { IExperimentService, IExtensions, IPersistentState, IPersistentStateFactory } from '../../common/types'; import { IServiceContainer } from '../../ioc/types'; +import { traceLog } from '../../logging'; + +function isExtensionInstalledButDisabled(extensions: IExtensions, extensionId: string): boolean { + // When debugging the python extension this `extensionPath` below will point to your repo. + // If you are debugging this feature then set the `extensionPath` to right location after + // the next line. + const pythonExt = extensions.getExtension('ms-python.python'); + if (pythonExt) { + let found = false; + traceLog(`Extension search path: ${path.dirname(pythonExt.extensionPath)}`); + fs.readdirSync(path.dirname(pythonExt.extensionPath), { withFileTypes: false }).forEach((s) => { + if (s.toString().startsWith(extensionId)) { + found = true; + } + }); + return found; + } + return false; +} export function isExtensionInstalled(serviceContainer: IServiceContainer, extensionId: string): boolean { const extensions: IExtensions = serviceContainer.get(IExtensions); const extension = extensions.getExtension(extensionId); + if (!extension) { + // The extension you are looking for might be disabled. + return isExtensionInstalledButDisabled(extensions, extensionId); + } return extension !== undefined; } diff --git a/src/client/linters/prompts/flake8Prompt.ts b/src/client/linters/prompts/flake8Prompt.ts index 547644ba0383..c60767f2fa8d 100644 --- a/src/client/linters/prompts/flake8Prompt.ts +++ b/src/client/linters/prompts/flake8Prompt.ts @@ -61,3 +61,11 @@ export class Flake8ExtensionPrompt implements IToolsExtensionPrompt { return false; } } + +let _prompt: IToolsExtensionPrompt | undefined; +export function getOrCreateFlake8Prompt(serviceContainer: IServiceContainer): IToolsExtensionPrompt { + if (!_prompt) { + _prompt = new Flake8ExtensionPrompt(serviceContainer); + } + return _prompt; +} diff --git a/src/client/linters/prompts/pylintPrompt.ts b/src/client/linters/prompts/pylintPrompt.ts index 7c1ce30f3f8e..7a0693740b32 100644 --- a/src/client/linters/prompts/pylintPrompt.ts +++ b/src/client/linters/prompts/pylintPrompt.ts @@ -74,3 +74,11 @@ export class PylintExtensionPrompt implements IToolsExtensionPrompt { return false; } } + +let _prompt: IToolsExtensionPrompt | undefined; +export function getOrCreatePylintPrompt(serviceContainer: IServiceContainer): IToolsExtensionPrompt { + if (!_prompt) { + _prompt = new PylintExtensionPrompt(serviceContainer); + } + return _prompt; +} diff --git a/src/client/pythonEnvironments/info/interpreter.ts b/src/client/pythonEnvironments/info/interpreter.ts index 72ef670f2672..b5207069ac0f 100644 --- a/src/client/pythonEnvironments/info/interpreter.ts +++ b/src/client/pythonEnvironments/info/interpreter.ts @@ -68,7 +68,7 @@ export async function getInterpreterInfo( const argv = [info.command, ...info.args]; // Concat these together to make a set of quoted strings - const quoted = argv.reduce((p, c) => (p ? `${p} "${c}"` : `"${c.replaceAll('\\', '\\\\')}"`), ''); + const quoted = argv.reduce((p, c) => (p ? `${p} "${c}"` : `"${c.replaceAllExtra('\\', '\\\\')}"`), ''); // Try shell execing the command, followed by the arguments. This will make node kill the process if it // takes too long. diff --git a/src/test/common/extensions.unit.test.ts b/src/test/common/extensions.unit.test.ts index 2e282cfc7d43..83c9b695a3ac 100644 --- a/src/test/common/extensions.unit.test.ts +++ b/src/test/common/extensions.unit.test.ts @@ -87,7 +87,7 @@ suite('String Extensions', () => { expect(quotedString3.trimQuotes()).to.be.equal(expectedString); expect(quotedString4.trimQuotes()).to.be.equal(expectedString); }); - test('String should replace all substrings with new substring', () => { + test('String should replace all substrings with new substring using replaceAllExtra', () => { const oldString = `foo \\ foo \\ foo`; const expectedString = `foo \\\\ foo \\\\ foo`; const oldString2 = `\\ foo \\ foo`; @@ -96,10 +96,10 @@ suite('String Extensions', () => { const expectedString3 = `\\\\ foo \\\\`; const oldString4 = `foo foo`; const expectedString4 = `foo foo`; - expect(oldString.replaceAll('\\', '\\\\')).to.be.equal(expectedString); - expect(oldString2.replaceAll('\\', '\\\\')).to.be.equal(expectedString2); - expect(oldString3.replaceAll('\\', '\\\\')).to.be.equal(expectedString3); - expect(oldString4.replaceAll('\\', '\\\\')).to.be.equal(expectedString4); + expect(oldString.replaceAllExtra('\\', '\\\\')).to.be.equal(expectedString); + expect(oldString2.replaceAllExtra('\\', '\\\\')).to.be.equal(expectedString2); + expect(oldString3.replaceAllExtra('\\', '\\\\')).to.be.equal(expectedString3); + expect(oldString4.replaceAllExtra('\\', '\\\\')).to.be.equal(expectedString4); }); }); diff --git a/src/test/debuggerTest.ts b/src/test/debuggerTest.ts index 9217b85e391c..1abbbec76373 100644 --- a/src/test/debuggerTest.ts +++ b/src/test/debuggerTest.ts @@ -2,13 +2,29 @@ // Licensed under the MIT License. import * as path from 'path'; +import * as fs from 'fs-extra'; import { runTests } from '@vscode/test-electron'; import { EXTENSION_ROOT_DIR_FOR_TESTS } from './constants'; +import { EXTENSION_ROOT_DIR } from '../client/common/constants'; const workspacePath = path.join(__dirname, '..', '..', 'src', 'testMultiRootWkspc', 'multi.code-workspace'); process.env.IS_CI_SERVER_TEST_DEBUGGER = '1'; process.env.VSC_PYTHON_CI_TEST = '1'; -const channel = process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL || 'stable'; + +function getChannel(): string { + if (process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL) { + return process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL; + } + + const packageJsonPath = path.join(EXTENSION_ROOT_DIR, 'package.json'); + if (fs.pathExistsSync(packageJsonPath)) { + const packageJson = fs.readJSONSync(packageJsonPath); + if (packageJson.engines.vscode.endsWith('insider')) { + return 'insiders'; + } + } + return 'stable'; +} function start() { console.log('*'.repeat(100)); @@ -17,7 +33,7 @@ function start() { extensionDevelopmentPath: EXTENSION_ROOT_DIR_FOR_TESTS, extensionTestsPath: path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'out', 'test', 'index'), launchArgs: [workspacePath], - version: channel, + version: getChannel(), extensionTestsEnv: { ...process.env, UITEST_DISABLE_INSIDERS: '1' }, }).catch((ex) => { console.error('End Debugger tests (with errors)', ex); diff --git a/src/test/standardTest.ts b/src/test/standardTest.ts index 95b1e1cf42ee..f98136754822 100644 --- a/src/test/standardTest.ts +++ b/src/test/standardTest.ts @@ -3,7 +3,7 @@ import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { downloadAndUnzipVSCode, resolveCliPathFromVSCodeExecutablePath, runTests } from '@vscode/test-electron'; -import { JUPYTER_EXTENSION_ID, PYLANCE_EXTENSION_ID } from '../client/common/constants'; +import { EXTENSION_ROOT_DIR, JUPYTER_EXTENSION_ID, PYLANCE_EXTENSION_ID } from '../client/common/constants'; import { EXTENSION_ROOT_DIR_FOR_TESTS } from './constants'; // If running smoke tests, we don't have access to this. @@ -27,7 +27,20 @@ const extensionDevelopmentPath = process.env.CODE_EXTENSIONS_PATH ? process.env.CODE_EXTENSIONS_PATH : EXTENSION_ROOT_DIR_FOR_TESTS; -const channel = process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL || 'stable'; +async function getChannel(): Promise { + if (process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL) { + return process.env.VSC_PYTHON_CI_TEST_VSC_CHANNEL; + } + + const packageJsonPath = path.join(EXTENSION_ROOT_DIR, 'package.json'); + if (await fs.pathExists(packageJsonPath)) { + const packageJson = await fs.readJSON(packageJsonPath); + if (packageJson.engines.vscode.endsWith('insider')) { + return 'insiders'; + } + } + return 'stable'; +} /** * Smoke tests & tests running in VSCode require Jupyter extension to be installed. @@ -77,6 +90,8 @@ async function installPylanceExtension(vscodeExecutablePath: string) { async function start() { console.log('*'.repeat(100)); console.log('Start Standard tests'); + const channel = await getChannel(); + console.log(`Using ${channel} build of VS Code.`); const vscodeExecutablePath = await downloadAndUnzipVSCode(channel); const baseLaunchArgs = requiresJupyterExtensionToBeInstalled() || requiresPylanceExtensionToBeInstalled() diff --git a/tsconfig.extension.json b/tsconfig.extension.json index d5805806b675..76b20c246e00 100644 --- a/tsconfig.extension.json +++ b/tsconfig.extension.json @@ -2,13 +2,14 @@ "compilerOptions": { "baseUrl": ".", "module": "commonjs", - "target": "es6", + "target": "es2021", "outDir": "out", "lib": [ "es6", "es2018", "ES2019", "ES2020", + "ES2021" ], "sourceMap": true, "rootDir": "src", diff --git a/tsconfig.json b/tsconfig.json index 89f7a9c808b8..0dbd932124af 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,14 +5,15 @@ "*": ["types/*"] }, "module": "commonjs", - "target": "es2018", + "target": "es2021", "outDir": "out", "lib": [ "es6", "es2018", "dom", "ES2019", - "ES2020" + "ES2020", + "ES2021" ], "sourceMap": true, "rootDir": "src",