diff --git a/gulpfile.js b/gulpfile.js index 60571d60386c..6ddd833657d5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,6 +14,7 @@ const relative = require('relative'); const ts = require('gulp-typescript'); const watch = require('gulp-watch'); const cp = require('child_process'); +const colors = require('colors/safe'); /** * Hygiene works by creating cascading subsets of all our files and @@ -179,7 +180,7 @@ const hygiene = exports.hygiene = (some, options) => { } }; } - const tsProject = ts.createProject('tsconfig.json', { strict: true }); + const tsProject = ts.createProject('tsconfig.json', { strict: true, noImplicitAny: false }); const reporter = customReporter(); return tsProject(reporter); } @@ -203,7 +204,7 @@ const hygiene = exports.hygiene = (some, options) => { return typescript .pipe(es.through(null, function () { if (errorCount > 0) { - this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'gulpfile.js\'.'); + this.emit('error', 'Hygiene failed with ' + errorCount + ' errors 👎. Check \'gulpfile.js\'.'); } else { this.emit('end'); } @@ -214,6 +215,8 @@ gulp.task('hygiene', () => hygiene()); gulp.task('hygiene-watch', function () { return watch(all, function () { + console.clear(); + console.log('Checking hygiene...'); run(true, true); }); }); @@ -221,11 +224,14 @@ gulp.task('hygiene-watch', function () { function run(lintOnlyModifiedFiles, doNotExit) { function exitProcessOnError(ex) { console.error(); - console.error(ex); + console.error(colors.red(ex)); if (!doNotExit) { process.exit(1); } - } + if (lintOnlyModifiedFiles && doNotExit) { + console.log('Watching for changes...'); + } +} process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); exitProcessOnError(); @@ -239,20 +245,62 @@ function run(lintOnlyModifiedFiles, doNotExit) { }).on('error', exitProcessOnError); } - const cmd = lintOnlyModifiedFiles ? 'git diff --name-only' : 'git diff --cached --name-only'; - cp.exec(cmd, { + let filesPromise; + if (lintOnlyModifiedFiles) { + filesPromise = Promise.all([getCachedFiles(), getModifiedFiles()]).then(filesList => { + const files1 = filesList[0]; + const files2 = filesList[1]; + files2.forEach(file => { + if (files1.indexOf(file) === -1) { + files1.push(file); + } + }); + return files1; + }); + } else { + filesPromise = getCachedFiles(); + } + filesPromise.then(files => { + hygiene(files, { + skipEOL: skipEOL + }) + .on('end', () => { + if (lintOnlyModifiedFiles && doNotExit) { + console.log(colors.green('Hygiene passed with 0 errors 👍.')); + console.log('Watching for changes...'); + } + }) + .on('error', exitProcessOnError); + }).catch(exitProcessOnError); + }); +} +function getCachedFiles() { + return new Promise(resolve => { + cp.exec('git diff --cached --name-only', { maxBuffer: 2000 * 1024 }, (err, out) => { if (err) { - exitProcessOnError(err); + return reject(err); } const some = out .split(/\r?\n/) .filter(l => !!l); - - hygiene(some, { - skipEOL: skipEOL - }).on('error', exitProcessOnError); + resolve(some); + }); + }); +} +function getModifiedFiles() { + return new Promise(resolve => { + cp.exec('git diff --name-only', { + maxBuffer: 2000 * 1024 + }, (err, out) => { + if (err) { + return reject(err); + } + const some = out + .split(/\r?\n/) + .filter(l => !!l); + resolve(some); }); }); } diff --git a/package.json b/package.json index 13eb42f801ee..35ee03f90a03 100644 --- a/package.json +++ b/package.json @@ -1,1592 +1,1587 @@ { - "name": "python", - "displayName": "Python", - "description": "Linting, Debugging (multi-threaded, remote), Intellisense, code formatting, refactoring, unit tests, snippets, and more.", - "version": "0.8.0", - "publisher": "ms-python", - "author": { - "name": "Microsoft Corporation" - }, - "license": "MIT", - "homepage": "https://github.com/Microsoft/vscode-python", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-python" - }, - "bugs": { - "url": "https://github.com/Microsoft/vscode-python/issues" - }, - "icon": "icon.png", - "galleryBanner": { - "color": "#1e415e", - "theme": "dark" - }, - "engines": { - "vscode": "^1.17.0" - }, - "recommendations": [ - "donjayamanne.jupyter" - ], - "keywords": [ - "python", - "django", - "unittest", - "multi-root ready" - ], - "categories": [ - "Languages", - "Debuggers", - "Linters", - "Snippets", - "Formatters", - "Other" - ], - "activationEvents": [ - "onLanguage:python", - "onCommand:python.execInTerminal", - "onCommand:python.sortImports", - "onCommand:python.runtests", - "onCommand:python.debugtests", - "onCommand:python.setInterpreter", - "onCommand:python.setShebangInterpreter", - "onCommand:python.viewTestUI", - "onCommand:python.viewTestOutput", - "onCommand:python.selectAndRunTestMethod", - "onCommand:python.selectAndDebugTestMethod", - "onCommand:python.selectAndRunTestFile", - "onCommand:python.runCurrentTestFile", - "onCommand:python.runFailedTests", - "onCommand:python.execSelectionInTerminal", - "onCommand:python.execSelectionInDjangoShell", - "onCommand:jupyter.runSelectionLine", - "onCommand:jupyter.execCurrentCell", - "onCommand:jupyter.execCurrentCellAndAdvance", - "onCommand:python.buildWorkspaceSymbols", - "onCommand:python.updateSparkLibrary", - "onCommand:python.startREPL", - "onCommand:python.goToPythonObject" - ], - "main": "./out/client/extension", - "contributes": { - "snippets": [ - { - "language": "python", - "path": "./snippets/python.json" - } - ], - "keybindings": [ - { - "command": "jupyter.runSelectionLine", - "key": "ctrl+alt+enter", - "when": "editorFocus && !replaceActive && !searchViewletVisible && !findWidgetVisible" - } - ], - "commands": [ - { - "command": "python.sortImports", - "title": "Sort Imports", - "category": "Python Refactor" - }, - { - "command": "python.startREPL", - "title": "Start REPL", - "category": "Python" - }, - { - "command": "python.buildWorkspaceSymbols", - "title": "Build Workspace Symbols", - "category": "Python" - }, - { - "command": "python.runtests", - "title": "Run All Unit Tests", - "category": "Python" - }, - { - "command": "python.debugtests", - "title": "Debug All Unit Tests", - "category": "Python" - }, - { - "command": "python.execInTerminal", - "title": "Run Python File in Terminal", - "category": "Python" - }, - { - "command": "python.setInterpreter", - "title": "Select Interpreter", - "category": "Python" - }, - { - "command": "python.updateSparkLibrary", - "title": "Update Workspace PySpark Libraries", - "category": "Python" - }, - { - "command": "python.refactorExtractVariable", - "title": "Extract Variable", - "category": "Python Refactor" - }, - { - "command": "python.refactorExtractMethod", - "title": "Extract Method", - "category": "Python Refactor" - }, - { - "command": "python.viewTestOutput", - "title": "Show Unit Test Output", - "category": "Python" - }, - { - "command": "python.selectAndRunTestMethod", - "title": "Run Unit Test Method ...", - "category": "Python" - }, - { - "command": "python.selectAndDebugTestMethod", - "title": "Debug Unit Test Method ...", - "category": "Python" - }, - { - "command": "python.selectAndRunTestFile", - "title": "Run Unit Test File ...", - "category": "Python" - }, - { - "command": "python.runCurrentTestFile", - "title": "Run Current Unit Test File", - "category": "Python" - }, - { - "command": "python.runFailedTests", - "title": "Run Failed Unit Tests", - "category": "Python" - }, - { - "command": "python.execSelectionInTerminal", - "title": "Run Selection/Line in Python Terminal", - "category": "Python" - }, - { - "command": "python.execSelectionInDjangoShell", - "title": "Run Selection/Line in Django Shell", - "category": "Python" - }, - { - "command": "jupyter.runSelectionLine", - "title": "Run Selection/Line", - "category": "Jupyter" - }, - { - "command": "jupyter.execCurrentCell", - "title": "Run Cell", - "category": "Jupyter" - }, - { - "command": "jupyter.execCurrentCellAndAdvance", - "title": "Run Cell and Advance", - "category": "Jupyter" - }, - { - "command": "jupyter.gotToPreviousCell", - "title": "Go to Previous Cell", - "category": "Jupyter" - }, - { - "command": "jupyter.gotToNextCell", - "title": "Go to Next Cell", - "category": "Jupyter" - }, - { - "command": "python.goToPythonObject", - "title": "Go to Python Object", - "category": "Python" - } - ], - "menus": { - "editor/context": [ - { - "command": "python.refactorExtractVariable", - "title": "Refactor: Extract Variable", - "group": "Refactor", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.refactorExtractMethod", - "title": "Refactor: Extract Method", - "group": "Refactor", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.sortImports", - "title": "Refactor: Sort Imports", - "group": "Refactor", - "when": "editorLangId == python" - }, - { - "command": "python.execSelectionInTerminal", - "group": "Python", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.execSelectionInDjangoShell", - "group": "Python", - "when": "editorHasSelection && editorLangId == python && python.isDjangoProject" - }, - { - "when": "resourceLangId == python", - "command": "python.execInTerminal", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.runCurrentTestFile", - "group": "Python" - } - ], - "explorer/context": [ - { - "when": "resourceLangId == python", - "command": "python.runtests", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.debugtests", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.execInTerminal", - "group": "Python" - } - ] - }, - "debuggers": [ - { - "type": "python", - "label": "Python", - "languages": [ - "python" - ], - "enableBreakpointsFor": { - "languageIds": [ - "python", - "html" - ] - }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "program": "./out/client/debugger/Main.js", - "runtime": "node", - "configurationSnippets": [ - { - "label": "%python.snippet.launch.standard.label%", - "description": "%python.snippet.launch.standard.description%", - "body": { - "name": "Python", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceFolder}\"", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.pyspark.label%", - "description": "%python.snippet.launch.pyspark.description%", - "body": { - "name": "PySpark", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "osx": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" - }, - "windows": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit.cmd\"" - }, - "linux": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" - }, - "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceFolder}\"", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.module.label%", - "description": "%python.snippet.launch.module.description%", - "body": { - "name": "Python Module", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "module": "module.name", - "cwd": "^\"\\${workspaceFolder}\"", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.terminal.label%", - "description": "%python.snippet.launch.terminal.description%", - "body": { - "name": "Integrated Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "", - "console": "integratedTerminal", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [] - } - }, - { - "label": "%python.snippet.launch.externalTerminal.label%", - "description": "%python.snippet.launch.externalTerminal.description%", - "body": { - "name": "External Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "", - "console": "externalTerminal", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [] - } - }, - { - "label": "%python.snippet.launch.django.label%", - "description": "%python.snippet.launch.django.description%", - "body": { - "name": "Django", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceFolder}/manage.py\"", - "cwd": "^\"\\${workspaceFolder}\"", - "args": [ - "runserver", - "--noreload", - "--nothreading" - ], - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput", - "DjangoDebugging" - ] - } - }, - { - "label": "%python.snippet.launch.flask.label%", - "description": "%python.snippet.launch.flask.description%", - "body": { - "name": "Flask", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "^\"\\${workspaceFolder}\"", - "env": { - "FLASK_APP": "^\"\\${workspaceFolder}/quickstart/app.py\"" - }, - "args": [ - "run", - "--no-debugger", - "--no-reload" - ], - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.flaskOld.label%", - "description": "%python.snippet.launch.flaskOld.description%", - "body": { - "name": "Flask (old)", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceFolder}/run.py\"", - "cwd": "^\"\\${workspaceFolder}\"", - "args": [], - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.pyramid.label%", - "description": "%python.snippet.launch.pyramid.description%", - "body": { - "name": "Pyramid", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "cwd": "^\"\\${workspaceFolder}\"", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "args": [ - "^\"\\${workspaceFolder}/development.ini\"" - ], - "debugOptions": [ - "RedirectOutput", - "Pyramid" - ] - } - }, - { - "label": "%python.snippet.launch.watson.label%", - "description": "%python.snippet.launch.watson.description%", - "body": { - "name": "Watson", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceFolder}/console.py\"", - "cwd": "^\"\\${workspaceFolder}\"", - "args": [ - "dev", - "runserver", - "--noreload=True" - ], - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [ - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.scrapy.label%", - "description": "%python.snippet.launch.scrapy.description%", - "body": { - "name": "Scrapy", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "~/.virtualenvs/scrapy/bin/scrapy", - "cwd": "^\"\\${workspaceFolder}\"", - "args": [ - "crawl", - "specs", - "-o", - "bikes.json" - ], - "console": "integratedTerminal", - "env": {}, - "envFile": "^\"\\${workspaceFolder}/.env\"", - "debugOptions": [] - } - }, - { - "label": "%python.snippet.launch.attach.label%", - "description": "%python.snippet.launch.attach.description%", - "body": { - "name": "Attach (Remote Debug)", - "type": "python", - "request": "attach", - "localRoot": "^\"\\${workspaceFolder}\"", - "remoteRoot": "^\"\\${workspaceFolder}\"", - "port": 3000, - "secret": "my_secret", - "host": "localhost" - } - } - ], - "configurationAttributes": { - "launch": { - "properties": { - "module": { - "type": "string", - "description": "Name of the module to be debugged.", - "default": "" - }, - "program": { - "type": "string", - "description": "Absolute path to the program.", - "default": "${file}" - }, - "pythonPath": { - "type": "string", - "description": "Path (fully qualified) to python executable. Defaults to the value in settings.json", - "default": "${config:python.pythonPath}" - }, - "args": { - "type": "array", - "description": "Command line arguments passed to the program", - "default": [], - "items": { - "type": "string" - } - }, - "stopOnEntry": { - "type": "boolean", - "description": "Automatically stop after launch.", - "default": true - }, - "console": { - "enum": [ - "none", - "integratedTerminal", - "externalTerminal" - ], - "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", - "default": "none" - }, - "cwd": { - "type": "string", - "description": "Absolute path to the working directory of the program being debugged. Default is the root directory of the file (leave empty).", - "default": "" - }, - "debugOptions": { - "type": "array", - "description": "Advanced options, view read me for further details.", - "items": { - "type": "string", - "enum": [ - "RedirectOutput", - "DebugStdLib", - "BreakOnSystemExitZero", - "DjangoDebugging", - "Sudo", - "IgnoreDjangoTemplateWarnings", - "Pyramid" - ] - }, - "default": [ - "RedirectOutput" - ] - }, - "exceptionHandling": { - "description": "List of exception types and how they are handled during debugging (ignore, always break or break only if unhandled).", - "properties": { - "ignore": { - "type": "array", - "description": "Never break into these exceptions, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - }, - "always": { - "type": "array", - "description": "Always break into these exceptions, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - }, - "unhandled": { - "type": "array", - "description": "Break into these exceptions if they aren't handled, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - } - } - }, - "env": { - "type": "object", - "description": "Environment variables defined as a key value pair. Property ends up being the Environment Variable and the value of the property ends up being the value of the Env Variable.", - "default": {} - }, - "envFile": { - "type": "string", - "description": "Absolute path to a file containing environment variable definitions.", - "default": "" - } - } - }, - "attach": { - "required": [ - "localRoot", - "remoteRoot" - ], - "properties": { - "localRoot": { - "type": "string", - "description": "Local source root that corrresponds to the 'remoteRoot'.", - "default": "${workspaceFolder}" - }, - "remoteRoot": { - "type": "string", - "description": "The source root of the remote host.", - "default": "" - }, - "port": { - "type": "number", - "description": "Debug port to attach", - "default": 0 - }, - "host": { - "type": "string", - "description": "IP Address of the of remote server (default is localhost or use 127.0.0.1).", - "default": "localhost" - }, - "secret": { - "type": "string", - "description": "Secret used to authenticate for remote debugging.", - "default": "" - } - } - } - }, - "initialConfigurations": [ - { - "name": "Python", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "${workspaceFolder}", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - }, - { - "name": "Python: Attach", - "type": "python", - "request": "attach", - "localRoot": "${workspaceFolder}", - "remoteRoot": "${workspaceFolder}", - "port": 3000, - "secret": "my_secret", - "host": "localhost" - }, - { - "name": "Python: Terminal (integrated)", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "", - "console": "integratedTerminal", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [] - }, - { - "name": "Python: Terminal (external)", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "", - "console": "externalTerminal", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [] - }, - { - "name": "Python: Django", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceFolder}/manage.py", - "cwd": "${workspaceFolder}", - "args": [ - "runserver", - "--noreload", - "--nothreading" - ], - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput", - "DjangoDebugging" - ] - }, - { - "name": "Python: Flask (0.11.x or later)", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "${config:python.pythonPath}", - "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "${workspaceFolder}", - "env": { - "FLASK_APP": "${workspaceFolder}/quickstart/app.py" - }, - "args": [ - "run", - "--no-debugger", - "--no-reload" - ], - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - }, - { - "name": "Python: Flask (0.10.x or earlier)", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceFolder}/run.py", - "cwd": "${workspaceFolder}", - "args": [], - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - }, - { - "name": "Python: PySpark", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "osx": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" - }, - "windows": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit.cmd" - }, - "linux": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" - }, - "program": "${file}", - "cwd": "${workspaceFolder}", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - }, - { - "name": "Python: Module", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "module": "module.name", - "cwd": "${workspaceFolder}", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - }, - { - "name": "Python: Pyramid", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "cwd": "${workspaceFolder}", - "env": {}, - "envFile": "${workspaceFolder}/.env", - "args": [ - "${workspaceFolder}/development.ini" - ], - "debugOptions": [ - "RedirectOutput", - "Pyramid" - ] - }, - { - "name": "Python: Watson", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceFolder}/console.py", - "cwd": "${workspaceFolder}", - "args": [ - "dev", - "runserver", - "--noreload=True" - ], - "env": {}, - "envFile": "${workspaceFolder}/.env", - "debugOptions": [ - "RedirectOutput" - ] - } - ] - } - ], - "configuration": { - "type": "object", - "title": "Python Configuration", - "properties": { - "python.pythonPath": { - "type": "string", - "default": "python", - "description": "Path to Python, you can use a custom version of Python by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.venvPath": { - "type": "string", - "default": "", - "description": "Path to folder with a list of Virtual Environments (e.g. ~/.pyenv, ~/Envs, ~/.virtualenvs).", - "scope": "resource" - }, - "python.envFile": { - "type": "string", - "description": "Absolute path to a file containing environment variable definitions.", - "default": "${workspaceFolder}/.env", - "scope": "resource" - }, - "python.jediPath": { - "type": "string", - "default": "", - "description": "Path to directory containing the Jedi library (this path will contain the 'Jedi' sub directory).", - "scope": "resource" - }, - "python.sortImports.path": { - "type": "string", - "description": "Path to isort script, default using inner version", - "default": "", - "scope": "resource" - }, - "python.sortImports.args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.disablePromptForFeatures": { - "type": "array", - "default": [], - "description": "Do not display a prompt to install these features", - "items": { - "type": "string", - "default": "pylint", - "description": "Feature", - "enum": [ - "flake8", - "mypy", - "pep8", - "pylama", - "prospector", - "pydocstyle", - "pylint" - ] - }, - "scope": "resource" - }, - "python.linting.enabled": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files.", - "scope": "resource" - }, - "python.linting.enabledWithoutWorkspace": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when no workspace is opened.", - "scope": "resource" - }, - "python.linting.prospectorEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using prospector.", - "scope": "resource" - }, - "python.linting.pylintEnabled": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files using pylint.", - "scope": "resource" - }, - "python.linting.pep8Enabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pep8", - "scope": "resource" - }, - "python.linting.flake8Enabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using flake8", - "scope": "resource" - }, - "python.linting.pydocstyleEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pydocstyle", - "scope": "resource" - }, - "python.linting.mypyEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using mypy.", - "scope": "resource" - }, - "python.linting.lintOnTextChange": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when modified.", - "scope": "resource" - }, - "python.linting.lintOnSave": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when saved.", - "scope": "resource" - }, - "python.linting.maxNumberOfProblems": { - "type": "number", - "default": 100, - "description": "Controls the maximum number of problems produced by the server.", - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.convention": { - "type": "string", - "default": "Information", - "description": "Severity of Pylint message type 'Convention/C'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.refactor": { - "type": "string", - "default": "Hint", - "description": "Severity of Pylint message type 'Refactor/R'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.warning": { - "type": "string", - "default": "Warning", - "description": "Severity of Pylint message type 'Warning/W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.error": { - "type": "string", - "default": "Error", - "description": "Severity of Pylint message type 'Error/E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.fatal": { - "type": "string", - "default": "Error", - "description": "Severity of Pylint message type 'Fatal/F'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pep8CategorySeverity.W": { - "type": "string", - "default": "Warning", - "description": "Severity of Pep8 message type 'W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pep8CategorySeverity.E": { - "type": "string", - "default": "Error", - "description": "Severity of Pep8 message type 'E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.F": { - "type": "string", - "default": "Error", - "description": "Severity of Flake8 message type 'F'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.E": { - "type": "string", - "default": "Error", - "description": "Severity of Flake8 message type 'E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.W": { - "type": "string", - "default": "Warning", - "description": "Severity of Flake8 message type 'W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.mypyCategorySeverity.error": { - "type": "string", - "default": "Error", - "description": "Severity of Mypy message type 'Error'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.mypyCategorySeverity.note": { - "type": "string", - "default": "Information", - "description": "Severity of Mypy message type 'Note'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.prospectorPath": { - "type": "string", - "default": "prospector", - "description": "Path to Prospector, you can use a custom version of prospector by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pylintPath": { - "type": "string", - "default": "pylint", - "description": "Path to Pylint, you can use a custom version of pylint by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pep8Path": { - "type": "string", - "default": "pep8", - "description": "Path to pep8, you can use a custom version of pep8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.flake8Path": { - "type": "string", - "default": "flake8", - "description": "Path to flake8, you can use a custom version of flake8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pydocstylePath": { - "type": "string", - "default": "pydocstyle", - "description": "Path to pydocstyle, you can use a custom version of pydocstyle by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.mypyPath": { - "type": "string", - "default": "mypy", - "description": "Path to mypy, you can use a custom version of mypy by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.prospectorArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pylintArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pep8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.flake8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pydocstyleArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.mypyArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [ - "--ignore-missing-imports", - "--follow-imports=silent" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.outputWindow": { - "type": "string", - "default": "Python", - "description": "The output window name for the linting messages, defaults to Python output window.", - "scope": "resource" - }, - "python.formatting.provider": { - "type": "string", - "default": "autopep8", - "description": "Provider for formatting. Possible options include 'autopep8' and 'yapf'.", - "enum": [ - "autopep8", - "yapf", - "none" - ], - "scope": "resource" - }, - "python.formatting.autopep8Path": { - "type": "string", - "default": "autopep8", - "description": "Path to autopep8, you can use a custom version of autopep8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.formatting.yapfPath": { - "type": "string", - "default": "yapf", - "description": "Path to yapf, you can use a custom version of yapf by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.formatting.autopep8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.formatting.yapfArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.formatting.formatOnSave": { - "type": "boolean", - "default": false, - "description": "Format the document upon saving.", - "scope": "resource" - }, - "python.formatting.outputWindow": { - "type": "string", - "default": "Python", - "description": "The output window name for the formatting messages, defaults to Python output window.", - "scope": "resource" - }, - "python.autoComplete.preloadModules": { - "type": "array", - "items": { - "type": "string" - }, - "default": [], - "description": "Comma delimited list of modules preloaded to speed up Auto Complete (e.g. add Numpy, Pandas, etc, items slow to load when autocompleting).", - "scope": "resource" - }, - "python.autoComplete.extraPaths": { - "type": "array", - "default": [], - "description": "List of paths to libraries and the like that need to be imported by auto complete engine. E.g. when using Google App SDK, the paths are not in system path, hence need to be added into this list.", - "scope": "resource" - }, - "python.autoComplete.addBrackets": { - "type": "boolean", - "default": false, - "description": "Automatically add brackets for functions.", - "scope": "resource" - }, - "python.workspaceSymbols.tagFilePath": { - "type": "string", - "default": "${workspaceFolder}/.vscode/tags", - "description": "Fully qualified path to tag file (exuberant ctag file), used to provide workspace symbols.", - "scope": "resource" - }, - "python.workspaceSymbols.enabled": { - "type": "boolean", - "default": true, - "description": "Set to 'false' to disable Workspace Symbol provider using ctags.", - "scope": "resource" - }, - "python.workspaceSymbols.rebuildOnStart": { - "type": "boolean", - "default": true, - "description": "Whether to re-build the tags file on start (defaults to true).", - "scope": "resource" - }, - "python.workspaceSymbols.rebuildOnFileSave": { - "type": "boolean", - "default": true, - "description": "Whether to re-build the tags file on when changes made to python files are saved.", - "scope": "resource" - }, - "python.workspaceSymbols.ctagsPath": { - "type": "string", - "default": "ctags", - "description": "Fully qualilified path to the ctags executable (else leave as ctags, assuming it is in current path).", - "scope": "resource" - }, - "python.workspaceSymbols.exclusionPatterns": { - "type": "array", - "default": [ - "**/site-packages/**" - ], - "items": { - "type": "string" - }, - "description": "Pattern used to exclude files and folders from ctags See http://ctags.sourceforge.net/ctags.html.", - "scope": "resource" - }, - "python.unitTest.promptToConfigure": { - "type": "boolean", - "default": true, - "description": "Where to prompt to configure a test framework if potential tests directories are discovered.", - "scope": "resource" - }, - "python.unitTest.debugPort": { - "type": "number", - "default": 3000, - "description": "Port number used for debugging of unittests.", - "scope": "resource" - }, - "python.unitTest.cwd": { - "type": "string", - "default": null, - "description": "Optional working directory for unit tests.", - "scope": "resource" - }, - "python.unitTest.nosetestsEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using nosetests.", - "scope": "resource" - }, - "python.unitTest.nosetestPath": { - "type": "string", - "default": "nosetests", - "description": "Path to nosetests, you can use a custom version of nosetests by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.unitTest.pyTestEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using pytest.", - "scope": "resource" - }, - "python.unitTest.pyTestPath": { - "type": "string", - "default": "py.test", - "description": "Path to pytest (py.test), you can use a custom version of pytest by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.unitTest.nosetestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.pyTestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.unittestEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using unittest.", - "scope": "resource" - }, - "python.unitTest.unittestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [ - "-v", - "-s", - ".", - "-p", - "*test*.py" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.ignorePatterns": { - "type": "array", - "description": "Patterns used to exclude files or folders from being linted.", - "default": [ - ".vscode/*.py", - "**/site-packages/**/*.py" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pylamaEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pylama.", - "scope": "resource" - }, - "python.linting.pylamaPath": { - "type": "string", - "default": "pylama", - "description": "Path to pylama, you can use a custom version of pylama by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pylamaArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.outputWindow": { - "type": "string", - "default": "Python Test Log", - "description": "The output window name for the unit test messages, defaults to Python output window.", - "scope": "resource" - }, - "python.terminal.executeInFileDir": { - "type": "boolean", - "default": false, - "description": "When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder.", - "scope": "resource" - }, - "python.terminal.launchArgs": { - "type": "array", - "default": [], - "description": "Python launch arguments to use when executing a file in the terminal.", - "scope": "resource" - } - } - }, - "languages": [ - { - "id": "pip-requirements", - "aliases": [ - "pip requirements", - "requirements.txt" - ], - "filenames": [ - "requirements.txt" - ], - "filenamePatterns": [ - "*-requirements.txt", - "requirements-*.txt" - ], - "configuration": "./languages/pip-requirements.json" - }, - { - "id": "yaml", - "filenames": [ - ".condarc" - ] - } - ], - "grammars": [ - { - "language": "pip-requirements", - "scopeName": "source.pip-requirements", - "path": "./syntaxes/pip-requirements.tmLanguage.json" - } - ], - "jsonValidation": [ - { - "fileMatch": ".condarc", - "url": "./schemas/condarc.json" - }, - { - "fileMatch": "environment.yml", - "url": "./schemas/conda-environment.json" - }, - { - "fileMatch": "meta.yaml", - "url": "./schemas/conda-meta.json" - } - ], - "yamlValidation": [ - { - "fileMatch": ".condarc", - "url": "./schemas/condarc.json" - }, - { - "fileMatch": "environment.yml", - "url": "./schemas/conda-environment.json" - }, - { - "fileMatch": "meta.yaml", - "url": "./schemas/conda-meta.json" - } - ] - }, - "scripts": { - "vscode:prepublish": "tsc -p ./", - "compile": "tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js", - "precommit": "node gulpfile.js", - "lint-staged": "node gulpfile.js", - "lint": "tslint src/**/*.ts -t verbose" - }, - "dependencies": { - "diff-match-patch": "^1.0.0", - "fs-extra": "^4.0.2", - "fuzzy": "^0.1.3", - "get-port": "^3.2.0", - "line-by-line": "^0.1.5", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "named-js-regexp": "^1.3.1", - "semver": "^5.4.1", - "tmp": "0.0.29", - "tree-kill": "^1.1.0", - "uint64be": "^1.0.1", - "untildify": "^3.0.2", - "vscode-debugadapter": "^1.0.1", - "vscode-debugprotocol": "^1.0.1", - "vscode-extension-telemetry": "^0.0.5", - "vscode-languageclient": "^3.1.0", - "vscode-languageserver": "^3.1.0", - "winreg": "^1.2.4", - "xml2js": "^0.4.17" - }, - "devDependencies": { - "@types/chai": "^4.0.4", - "@types/chai-as-promised": "^7.1.0", - "@types/fs-extra": "^4.0.2", - "@types/get-port": "^3.2.0", - "@types/lodash": "^4.14.74", - "@types/mocha": "^2.2.43", - "@types/node": "^6.0.40", - "@types/semver": "^5.4.0", - "@types/sinon": "^2.3.2", - "@types/uuid": "^3.3.27", - "@types/winreg": "^1.2.30", - "@types/xml2js": "^0.4.0", - "chai": "^4.1.2", - "chai-as-promised": "^7.1.1", - "event-stream": "^3.3.4", - "gulp": "^3.9.1", - "gulp-filter": "^5.0.1", - "gulp-typescript": "^3.2.2", - "gulp-watch": "^4.3.11", - "husky": "^0.14.3", - "mocha": "^2.3.3", - "relative": "^3.0.2", - "retyped-diff-match-patch-tsd-ambient": "^1.0.0-0", - "sinon": "^2.3.6", - "tslint": "^5.7.0", - "tslint-eslint-rules": "^4.1.1", - "tslint-microsoft-contrib": "^5.0.1", - "typescript": "^2.5.2", - "typescript-formatter": "^6.0.0", - "vscode": "^1.1.5" - } + "name": "python", + "displayName": "Python", + "description": "Linting, Debugging (multi-threaded, remote), Intellisense, code formatting, refactoring, unit tests, snippets, and more.", + "version": "0.8.0", + "publisher": "ms-python", + "author": { + "name": "Microsoft Corporation" + }, + "license": "MIT", + "homepage": "https://github.com/Microsoft/vscode-python", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/vscode-python" + }, + "bugs": { + "url": "https://github.com/Microsoft/vscode-python/issues" + }, + "icon": "icon.png", + "galleryBanner": { + "color": "#1e415e", + "theme": "dark" + }, + "engines": { + "vscode": "^1.17.0" + }, + "recommendations": [ + "donjayamanne.jupyter" + ], + "keywords": [ + "python", + "django", + "unittest", + "multi-root ready" + ], + "categories": [ + "Languages", + "Debuggers", + "Linters", + "Snippets", + "Formatters", + "Other" + ], + "activationEvents": [ + "onLanguage:python", + "onCommand:python.execInTerminal", + "onCommand:python.sortImports", + "onCommand:python.runtests", + "onCommand:python.debugtests", + "onCommand:python.setInterpreter", + "onCommand:python.setShebangInterpreter", + "onCommand:python.viewTestUI", + "onCommand:python.viewTestOutput", + "onCommand:python.selectAndRunTestMethod", + "onCommand:python.selectAndDebugTestMethod", + "onCommand:python.selectAndRunTestFile", + "onCommand:python.runCurrentTestFile", + "onCommand:python.runFailedTests", + "onCommand:python.execSelectionInTerminal", + "onCommand:python.execSelectionInDjangoShell", + "onCommand:jupyter.runSelectionLine", + "onCommand:jupyter.execCurrentCell", + "onCommand:jupyter.execCurrentCellAndAdvance", + "onCommand:python.buildWorkspaceSymbols", + "onCommand:python.updateSparkLibrary", + "onCommand:python.startREPL", + "onCommand:python.goToPythonObject" + ], + "main": "./out/client/extension", + "contributes": { + "snippets": [ + { + "language": "python", + "path": "./snippets/python.json" + } + ], + "keybindings": [ + { + "command": "jupyter.runSelectionLine", + "key": "ctrl+alt+enter", + "when": "editorFocus && !replaceActive && !searchViewletVisible && !findWidgetVisible" + } + ], + "commands": [ + { + "command": "python.sortImports", + "title": "Sort Imports", + "category": "Python Refactor" + }, + { + "command": "python.startREPL", + "title": "Start REPL", + "category": "Python" + }, + { + "command": "python.buildWorkspaceSymbols", + "title": "Build Workspace Symbols", + "category": "Python" + }, + { + "command": "python.runtests", + "title": "Run All Unit Tests", + "category": "Python" + }, + { + "command": "python.debugtests", + "title": "Debug All Unit Tests", + "category": "Python" + }, + { + "command": "python.execInTerminal", + "title": "Run Python File in Terminal", + "category": "Python" + }, + { + "command": "python.setInterpreter", + "title": "Select Interpreter", + "category": "Python" + }, + { + "command": "python.updateSparkLibrary", + "title": "Update Workspace PySpark Libraries", + "category": "Python" + }, + { + "command": "python.refactorExtractVariable", + "title": "Extract Variable", + "category": "Python Refactor" + }, + { + "command": "python.refactorExtractMethod", + "title": "Extract Method", + "category": "Python Refactor" + }, + { + "command": "python.viewTestOutput", + "title": "Show Unit Test Output", + "category": "Python" + }, + { + "command": "python.selectAndRunTestMethod", + "title": "Run Unit Test Method ...", + "category": "Python" + }, + { + "command": "python.selectAndDebugTestMethod", + "title": "Debug Unit Test Method ...", + "category": "Python" + }, + { + "command": "python.selectAndRunTestFile", + "title": "Run Unit Test File ...", + "category": "Python" + }, + { + "command": "python.runCurrentTestFile", + "title": "Run Current Unit Test File", + "category": "Python" + }, + { + "command": "python.runFailedTests", + "title": "Run Failed Unit Tests", + "category": "Python" + }, + { + "command": "python.execSelectionInTerminal", + "title": "Run Selection/Line in Python Terminal", + "category": "Python" + }, + { + "command": "python.execSelectionInDjangoShell", + "title": "Run Selection/Line in Django Shell", + "category": "Python" + }, + { + "command": "jupyter.runSelectionLine", + "title": "Run Selection/Line", + "category": "Jupyter" + }, + { + "command": "jupyter.execCurrentCell", + "title": "Run Cell", + "category": "Jupyter" + }, + { + "command": "jupyter.execCurrentCellAndAdvance", + "title": "Run Cell and Advance", + "category": "Jupyter" + }, + { + "command": "jupyter.gotToPreviousCell", + "title": "Go to Previous Cell", + "category": "Jupyter" + }, + { + "command": "jupyter.gotToNextCell", + "title": "Go to Next Cell", + "category": "Jupyter" + }, + { + "command": "python.goToPythonObject", + "title": "Go to Python Object", + "category": "Python" + } + ], + "menus": { + "editor/context": [ + { + "command": "python.refactorExtractVariable", + "title": "Refactor: Extract Variable", + "group": "Refactor", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.refactorExtractMethod", + "title": "Refactor: Extract Method", + "group": "Refactor", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.sortImports", + "title": "Refactor: Sort Imports", + "group": "Refactor", + "when": "editorLangId == python" + }, + { + "command": "python.execSelectionInTerminal", + "group": "Python", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.execSelectionInDjangoShell", + "group": "Python", + "when": "editorHasSelection && editorLangId == python && python.isDjangoProject" + }, + { + "when": "resourceLangId == python", + "command": "python.execInTerminal", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.runCurrentTestFile", + "group": "Python" + } + ], + "explorer/context": [ + { + "when": "resourceLangId == python", + "command": "python.runtests", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.debugtests", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.execInTerminal", + "group": "Python" + } + ] + }, + "debuggers": [ + { + "type": "python", + "label": "Python", + "languages": [ + "python" + ], + "enableBreakpointsFor": { + "languageIds": [ + "python", + "html" + ] + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "program": "./out/client/debugger/Main.js", + "runtime": "node", + "configurationSnippets": [ + { + "label": "%python.snippet.launch.standard.label%", + "description": "%python.snippet.launch.standard.description%", + "body": { + "name": "Python", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "^\"\\${workspaceFolder}\"", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.pyspark.label%", + "description": "%python.snippet.launch.pyspark.description%", + "body": { + "name": "PySpark", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "osx": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" + }, + "windows": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit.cmd\"" + }, + "linux": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" + }, + "program": "^\"\\${file}\"", + "cwd": "^\"\\${workspaceFolder}\"", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.module.label%", + "description": "%python.snippet.launch.module.description%", + "body": { + "name": "Python Module", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "module": "module.name", + "cwd": "^\"\\${workspaceFolder}\"", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.terminal.label%", + "description": "%python.snippet.launch.terminal.description%", + "body": { + "name": "Integrated Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "", + "console": "integratedTerminal", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [] + } + }, + { + "label": "%python.snippet.launch.externalTerminal.label%", + "description": "%python.snippet.launch.externalTerminal.description%", + "body": { + "name": "External Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "", + "console": "externalTerminal", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [] + } + }, + { + "label": "%python.snippet.launch.django.label%", + "description": "%python.snippet.launch.django.description%", + "body": { + "name": "Django", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceFolder}/manage.py\"", + "cwd": "^\"\\${workspaceFolder}\"", + "args": [ + "runserver", + "--noreload", + "--nothreading" + ], + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput", + "DjangoDebugging" + ] + } + }, + { + "label": "%python.snippet.launch.flask.label%", + "description": "%python.snippet.launch.flask.description%", + "body": { + "name": "Flask", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", + "cwd": "^\"\\${workspaceFolder}\"", + "env": { + "FLASK_APP": "^\"\\${workspaceFolder}/quickstart/app.py\"" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload" + ], + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.flaskOld.label%", + "description": "%python.snippet.launch.flaskOld.description%", + "body": { + "name": "Flask (old)", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceFolder}/run.py\"", + "cwd": "^\"\\${workspaceFolder}\"", + "args": [], + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.pyramid.label%", + "description": "%python.snippet.launch.pyramid.description%", + "body": { + "name": "Pyramid", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "cwd": "^\"\\${workspaceFolder}\"", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "args": [ + "^\"\\${workspaceFolder}/development.ini\"" + ], + "debugOptions": [ + "RedirectOutput", + "Pyramid" + ] + } + }, + { + "label": "%python.snippet.launch.watson.label%", + "description": "%python.snippet.launch.watson.description%", + "body": { + "name": "Watson", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceFolder}/console.py\"", + "cwd": "^\"\\${workspaceFolder}\"", + "args": [ + "dev", + "runserver", + "--noreload=True" + ], + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [ + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.scrapy.label%", + "description": "%python.snippet.launch.scrapy.description%", + "body": { + "name": "Scrapy", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "~/.virtualenvs/scrapy/bin/scrapy", + "cwd": "^\"\\${workspaceFolder}\"", + "args": [ + "crawl", + "specs", + "-o", + "bikes.json" + ], + "console": "integratedTerminal", + "env": {}, + "envFile": "^\"\\${workspaceFolder}/.env\"", + "debugOptions": [] + } + }, + { + "label": "%python.snippet.launch.attach.label%", + "description": "%python.snippet.launch.attach.description%", + "body": { + "name": "Attach (Remote Debug)", + "type": "python", + "request": "attach", + "localRoot": "^\"\\${workspaceFolder}\"", + "remoteRoot": "^\"\\${workspaceFolder}\"", + "port": 3000, + "secret": "my_secret", + "host": "localhost" + } + } + ], + "configurationAttributes": { + "launch": { + "properties": { + "module": { + "type": "string", + "description": "Name of the module to be debugged.", + "default": "" + }, + "program": { + "type": "string", + "description": "Absolute path to the program.", + "default": "${file}" + }, + "pythonPath": { + "type": "string", + "description": "Path (fully qualified) to python executable. Defaults to the value in settings.json", + "default": "${config:python.pythonPath}" + }, + "args": { + "type": "array", + "description": "Command line arguments passed to the program", + "default": [], + "items": { + "type": "string" + } + }, + "stopOnEntry": { + "type": "boolean", + "description": "Automatically stop after launch.", + "default": true + }, + "console": { + "enum": [ + "none", + "integratedTerminal", + "externalTerminal" + ], + "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", + "default": "none" + }, + "cwd": { + "type": "string", + "description": "Absolute path to the working directory of the program being debugged. Default is the root directory of the file (leave empty).", + "default": "" + }, + "debugOptions": { + "type": "array", + "description": "Advanced options, view read me for further details.", + "items": { + "type": "string", + "enum": [ + "RedirectOutput", + "DebugStdLib", + "BreakOnSystemExitZero", + "DjangoDebugging", + "Sudo", + "IgnoreDjangoTemplateWarnings", + "Pyramid" + ] + }, + "default": [ + "RedirectOutput" + ] + }, + "exceptionHandling": { + "description": "List of exception types and how they are handled during debugging (ignore, always break or break only if unhandled).", + "properties": { + "ignore": { + "type": "array", + "description": "Never break into these exceptions, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + }, + "always": { + "type": "array", + "description": "Always break into these exceptions, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + }, + "unhandled": { + "type": "array", + "description": "Break into these exceptions if they aren't handled, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + } + } + }, + "env": { + "type": "object", + "description": "Environment variables defined as a key value pair. Property ends up being the Environment Variable and the value of the property ends up being the value of the Env Variable.", + "default": {} + }, + "envFile": { + "type": "string", + "description": "Absolute path to a file containing environment variable definitions.", + "default": "" + } + } + }, + "attach": { + "required": [ + "localRoot", + "remoteRoot" + ], + "properties": { + "localRoot": { + "type": "string", + "description": "Local source root that corrresponds to the 'remoteRoot'.", + "default": "${workspaceFolder}" + }, + "remoteRoot": { + "type": "string", + "description": "The source root of the remote host.", + "default": "" + }, + "port": { + "type": "number", + "description": "Debug port to attach", + "default": 0 + }, + "host": { + "type": "string", + "description": "IP Address of the of remote server (default is localhost or use 127.0.0.1).", + "default": "localhost" + }, + "secret": { + "type": "string", + "description": "Secret used to authenticate for remote debugging.", + "default": "" + } + } + } + }, + "initialConfigurations": [ + { + "name": "Python", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "${workspaceFolder}", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + }, + { + "name": "Python: Attach", + "type": "python", + "request": "attach", + "localRoot": "${workspaceFolder}", + "remoteRoot": "${workspaceFolder}", + "port": 3000, + "secret": "my_secret", + "host": "localhost" + }, + { + "name": "Python: Terminal (integrated)", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "", + "console": "integratedTerminal", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [] + }, + { + "name": "Python: Terminal (external)", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "", + "console": "externalTerminal", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [] + }, + { + "name": "Python: Django", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceFolder}/manage.py", + "cwd": "${workspaceFolder}", + "args": [ + "runserver", + "--noreload", + "--nothreading" + ], + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput", + "DjangoDebugging" + ] + }, + { + "name": "Python: Flask (0.11.x or later)", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "${config:python.pythonPath}", + "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", + "cwd": "${workspaceFolder}", + "env": { + "FLASK_APP": "${workspaceFolder}/quickstart/app.py" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload" + ], + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + }, + { + "name": "Python: Flask (0.10.x or earlier)", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceFolder}/run.py", + "cwd": "${workspaceFolder}", + "args": [], + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + }, + { + "name": "Python: PySpark", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "osx": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" + }, + "windows": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit.cmd" + }, + "linux": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" + }, + "program": "${file}", + "cwd": "${workspaceFolder}", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + }, + { + "name": "Python: Module", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "module": "module.name", + "cwd": "${workspaceFolder}", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + }, + { + "name": "Python: Pyramid", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "cwd": "${workspaceFolder}", + "env": {}, + "envFile": "${workspaceFolder}/.env", + "args": [ + "${workspaceFolder}/development.ini" + ], + "debugOptions": [ + "RedirectOutput", + "Pyramid" + ] + }, + { + "name": "Python: Watson", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceFolder}/console.py", + "cwd": "${workspaceFolder}", + "args": [ + "dev", + "runserver", + "--noreload=True" + ], + "env": {}, + "envFile": "${workspaceFolder}/.env", + "debugOptions": [ + "RedirectOutput" + ] + } + ] + } + ], + "configuration": { + "type": "object", + "title": "Python Configuration", + "properties": { + "python.pythonPath": { + "type": "string", + "default": "python", + "description": "Path to Python, you can use a custom version of Python by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.venvPath": { + "type": "string", + "default": "", + "description": "Path to folder with a list of Virtual Environments (e.g. ~/.pyenv, ~/Envs, ~/.virtualenvs).", + "scope": "resource" + }, + "python.envFile": { + "type": "string", + "description": "Absolute path to a file containing environment variable definitions.", + "default": "${workspaceFolder}/.env", + "scope": "resource" + }, + "python.jediPath": { + "type": "string", + "default": "", + "description": "Path to directory containing the Jedi library (this path will contain the 'Jedi' sub directory).", + "scope": "resource" + }, + "python.sortImports.path": { + "type": "string", + "description": "Path to isort script, default using inner version", + "default": "", + "scope": "resource" + }, + "python.sortImports.args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.disablePromptForFeatures": { + "type": "array", + "default": [], + "description": "Do not display a prompt to install these features", + "items": { + "type": "string", + "default": "pylint", + "description": "Feature", + "enum": [ + "flake8", + "mypy", + "pep8", + "pylama", + "prospector", + "pydocstyle", + "pylint" + ] + }, + "scope": "resource" + }, + "python.linting.enabled": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files.", + "scope": "resource" + }, + "python.linting.enabledWithoutWorkspace": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when no workspace is opened.", + "scope": "resource" + }, + "python.linting.prospectorEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using prospector.", + "scope": "resource" + }, + "python.linting.pylintEnabled": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files using pylint.", + "scope": "resource" + }, + "python.linting.pep8Enabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pep8", + "scope": "resource" + }, + "python.linting.flake8Enabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using flake8", + "scope": "resource" + }, + "python.linting.pydocstyleEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pydocstyle", + "scope": "resource" + }, + "python.linting.mypyEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using mypy.", + "scope": "resource" + }, + "python.linting.lintOnTextChange": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when modified.", + "scope": "resource" + }, + "python.linting.lintOnSave": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when saved.", + "scope": "resource" + }, + "python.linting.maxNumberOfProblems": { + "type": "number", + "default": 100, + "description": "Controls the maximum number of problems produced by the server.", + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.convention": { + "type": "string", + "default": "Information", + "description": "Severity of Pylint message type 'Convention/C'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.refactor": { + "type": "string", + "default": "Hint", + "description": "Severity of Pylint message type 'Refactor/R'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.warning": { + "type": "string", + "default": "Warning", + "description": "Severity of Pylint message type 'Warning/W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.error": { + "type": "string", + "default": "Error", + "description": "Severity of Pylint message type 'Error/E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.fatal": { + "type": "string", + "default": "Error", + "description": "Severity of Pylint message type 'Fatal/F'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pep8CategorySeverity.W": { + "type": "string", + "default": "Warning", + "description": "Severity of Pep8 message type 'W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pep8CategorySeverity.E": { + "type": "string", + "default": "Error", + "description": "Severity of Pep8 message type 'E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.F": { + "type": "string", + "default": "Error", + "description": "Severity of Flake8 message type 'F'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.E": { + "type": "string", + "default": "Error", + "description": "Severity of Flake8 message type 'E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.W": { + "type": "string", + "default": "Warning", + "description": "Severity of Flake8 message type 'W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.mypyCategorySeverity.error": { + "type": "string", + "default": "Error", + "description": "Severity of Mypy message type 'Error'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.mypyCategorySeverity.note": { + "type": "string", + "default": "Information", + "description": "Severity of Mypy message type 'Note'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.prospectorPath": { + "type": "string", + "default": "prospector", + "description": "Path to Prospector, you can use a custom version of prospector by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pylintPath": { + "type": "string", + "default": "pylint", + "description": "Path to Pylint, you can use a custom version of pylint by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pep8Path": { + "type": "string", + "default": "pep8", + "description": "Path to pep8, you can use a custom version of pep8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.flake8Path": { + "type": "string", + "default": "flake8", + "description": "Path to flake8, you can use a custom version of flake8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pydocstylePath": { + "type": "string", + "default": "pydocstyle", + "description": "Path to pydocstyle, you can use a custom version of pydocstyle by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.mypyPath": { + "type": "string", + "default": "mypy", + "description": "Path to mypy, you can use a custom version of mypy by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.prospectorArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pylintArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pep8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.flake8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pydocstyleArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.mypyArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [ + "--ignore-missing-imports", + "--follow-imports=silent" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.outputWindow": { + "type": "string", + "default": "Python", + "description": "The output window name for the linting messages, defaults to Python output window.", + "scope": "resource" + }, + "python.formatting.provider": { + "type": "string", + "default": "autopep8", + "description": "Provider for formatting. Possible options include 'autopep8' and 'yapf'.", + "enum": [ + "autopep8", + "yapf", + "none" + ], + "scope": "resource" + }, + "python.formatting.autopep8Path": { + "type": "string", + "default": "autopep8", + "description": "Path to autopep8, you can use a custom version of autopep8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.formatting.yapfPath": { + "type": "string", + "default": "yapf", + "description": "Path to yapf, you can use a custom version of yapf by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.formatting.autopep8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.formatting.yapfArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.formatting.outputWindow": { + "type": "string", + "default": "Python", + "description": "The output window name for the formatting messages, defaults to Python output window.", + "scope": "resource" + }, + "python.autoComplete.preloadModules": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "Comma delimited list of modules preloaded to speed up Auto Complete (e.g. add Numpy, Pandas, etc, items slow to load when autocompleting).", + "scope": "resource" + }, + "python.autoComplete.extraPaths": { + "type": "array", + "default": [], + "description": "List of paths to libraries and the like that need to be imported by auto complete engine. E.g. when using Google App SDK, the paths are not in system path, hence need to be added into this list.", + "scope": "resource" + }, + "python.autoComplete.addBrackets": { + "type": "boolean", + "default": false, + "description": "Automatically add brackets for functions.", + "scope": "resource" + }, + "python.workspaceSymbols.tagFilePath": { + "type": "string", + "default": "${workspaceFolder}/.vscode/tags", + "description": "Fully qualified path to tag file (exuberant ctag file), used to provide workspace symbols.", + "scope": "resource" + }, + "python.workspaceSymbols.enabled": { + "type": "boolean", + "default": true, + "description": "Set to 'false' to disable Workspace Symbol provider using ctags.", + "scope": "resource" + }, + "python.workspaceSymbols.rebuildOnStart": { + "type": "boolean", + "default": true, + "description": "Whether to re-build the tags file on start (defaults to true).", + "scope": "resource" + }, + "python.workspaceSymbols.rebuildOnFileSave": { + "type": "boolean", + "default": true, + "description": "Whether to re-build the tags file on when changes made to python files are saved.", + "scope": "resource" + }, + "python.workspaceSymbols.ctagsPath": { + "type": "string", + "default": "ctags", + "description": "Fully qualilified path to the ctags executable (else leave as ctags, assuming it is in current path).", + "scope": "resource" + }, + "python.workspaceSymbols.exclusionPatterns": { + "type": "array", + "default": [ + "**/site-packages/**" + ], + "items": { + "type": "string" + }, + "description": "Pattern used to exclude files and folders from ctags See http://ctags.sourceforge.net/ctags.html.", + "scope": "resource" + }, + "python.unitTest.promptToConfigure": { + "type": "boolean", + "default": true, + "description": "Where to prompt to configure a test framework if potential tests directories are discovered.", + "scope": "resource" + }, + "python.unitTest.debugPort": { + "type": "number", + "default": 3000, + "description": "Port number used for debugging of unittests.", + "scope": "resource" + }, + "python.unitTest.cwd": { + "type": "string", + "default": null, + "description": "Optional working directory for unit tests.", + "scope": "resource" + }, + "python.unitTest.nosetestsEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using nosetests.", + "scope": "resource" + }, + "python.unitTest.nosetestPath": { + "type": "string", + "default": "nosetests", + "description": "Path to nosetests, you can use a custom version of nosetests by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.unitTest.pyTestEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using pytest.", + "scope": "resource" + }, + "python.unitTest.pyTestPath": { + "type": "string", + "default": "py.test", + "description": "Path to pytest (py.test), you can use a custom version of pytest by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.unitTest.nosetestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.pyTestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.unittestEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using unittest.", + "scope": "resource" + }, + "python.unitTest.unittestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [ + "-v", + "-s", + ".", + "-p", + "*test*.py" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.ignorePatterns": { + "type": "array", + "description": "Patterns used to exclude files or folders from being linted.", + "default": [ + ".vscode/*.py", + "**/site-packages/**/*.py" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pylamaEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pylama.", + "scope": "resource" + }, + "python.linting.pylamaPath": { + "type": "string", + "default": "pylama", + "description": "Path to pylama, you can use a custom version of pylama by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pylamaArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.outputWindow": { + "type": "string", + "default": "Python Test Log", + "description": "The output window name for the unit test messages, defaults to Python output window.", + "scope": "resource" + }, + "python.terminal.executeInFileDir": { + "type": "boolean", + "default": false, + "description": "When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder.", + "scope": "resource" + }, + "python.terminal.launchArgs": { + "type": "array", + "default": [], + "description": "Python launch arguments to use when executing a file in the terminal.", + "scope": "resource" + } + } + }, + "languages": [ + { + "id": "pip-requirements", + "aliases": [ + "pip requirements", + "requirements.txt" + ], + "filenames": [ + "requirements.txt" + ], + "filenamePatterns": [ + "*-requirements.txt", + "requirements-*.txt" + ], + "configuration": "./languages/pip-requirements.json" + }, + { + "id": "yaml", + "filenames": [ + ".condarc" + ] + } + ], + "grammars": [ + { + "language": "pip-requirements", + "scopeName": "source.pip-requirements", + "path": "./syntaxes/pip-requirements.tmLanguage.json" + } + ], + "jsonValidation": [ + { + "fileMatch": ".condarc", + "url": "./schemas/condarc.json" + }, + { + "fileMatch": "environment.yml", + "url": "./schemas/conda-environment.json" + }, + { + "fileMatch": "meta.yaml", + "url": "./schemas/conda-meta.json" + } + ], + "yamlValidation": [ + { + "fileMatch": ".condarc", + "url": "./schemas/condarc.json" + }, + { + "fileMatch": "environment.yml", + "url": "./schemas/conda-environment.json" + }, + { + "fileMatch": "meta.yaml", + "url": "./schemas/conda-meta.json" + } + ] + }, + "scripts": { + "vscode:prepublish": "tsc -p ./", + "compile": "tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install", + "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js", + "precommit": "node gulpfile.js", + "lint-staged": "node gulpfile.js", + "lint": "tslint src/**/*.ts -t verbose" + }, + "dependencies": { + "diff-match-patch": "^1.0.0", + "fs-extra": "^4.0.2", + "fuzzy": "^0.1.3", + "get-port": "^3.2.0", + "line-by-line": "^0.1.5", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "named-js-regexp": "^1.3.1", + "semver": "^5.4.1", + "tmp": "0.0.29", + "tree-kill": "^1.1.0", + "uint64be": "^1.0.1", + "untildify": "^3.0.2", + "vscode-debugadapter": "^1.0.1", + "vscode-debugprotocol": "^1.0.1", + "vscode-extension-telemetry": "^0.0.5", + "vscode-languageclient": "^3.1.0", + "vscode-languageserver": "^3.1.0", + "winreg": "^1.2.4", + "xml2js": "^0.4.17" + }, + "devDependencies": { + "@types/chai": "^4.0.4", + "@types/chai-as-promised": "^7.1.0", + "@types/fs-extra": "^4.0.2", + "@types/get-port": "^3.2.0", + "@types/lodash": "^4.14.74", + "@types/mocha": "^2.2.43", + "@types/node": "^6.0.40", + "@types/semver": "^5.4.0", + "@types/sinon": "^2.3.2", + "@types/uuid": "^3.3.27", + "@types/winreg": "^1.2.30", + "@types/xml2js": "^0.4.0", + "chai": "^4.1.2", + "chai-as-promised": "^7.1.1", + "colors": "^1.1.2", + "event-stream": "^3.3.4", + "gulp": "^3.9.1", + "gulp-filter": "^5.0.1", + "gulp-typescript": "^3.2.2", + "gulp-watch": "^4.3.11", + "husky": "^0.14.3", + "mocha": "^2.3.3", + "relative": "^3.0.2", + "retyped-diff-match-patch-tsd-ambient": "^1.0.0-0", + "sinon": "^2.3.6", + "tslint": "^5.7.0", + "tslint-eslint-rules": "^4.1.1", + "tslint-microsoft-contrib": "^5.0.1", + "typescript": "^2.5.2", + "typescript-formatter": "^6.0.0", + "vscode": "^1.1.5" + } } diff --git a/src/client/banner.ts b/src/client/banner.ts index 74296ebef9b9..137e44b175c7 100644 --- a/src/client/banner.ts +++ b/src/client/banner.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { window } from 'vscode'; -import { launch } from './common/browser'; +import { launch } from './common/net/browser'; import { IPersistentStateFactory, PersistentState } from './common/persistentState'; const BANNER_URL = 'https://aka.ms/pvsc-at-msft'; diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index 0e1f8b74576b..bc1a15e2f037 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -108,7 +108,6 @@ export interface IFormattingSettings { autopep8Args: string[]; yapfPath: string; yapfArgs: string[]; - formatOnSave: boolean; outputWindow: string; } export interface IAutoCompeteSettings { @@ -291,8 +290,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { autopep8Args: [], autopep8Path: 'autopep8', outputWindow: 'python', provider: 'autopep8', - yapfArgs: [], yapfPath: 'yapf', - formatOnSave: false + yapfArgs: [], yapfPath: 'yapf' }; this.formatting.autopep8Path = getAbsolutePath(systemVariables.resolveAny(this.formatting.autopep8Path), workspaceRoot); this.formatting.yapfPath = getAbsolutePath(systemVariables.resolveAny(this.formatting.yapfPath), workspaceRoot); diff --git a/src/client/common/featureDeprecationManager.ts b/src/client/common/featureDeprecationManager.ts index b25710df3e4b..1a139b53647a 100644 --- a/src/client/common/featureDeprecationManager.ts +++ b/src/client/common/featureDeprecationManager.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { commands, Disposable, window } from 'vscode'; -import { launch } from './browser'; +import { commands, Disposable, window, workspace } from 'vscode'; +import { launch } from './net/browser'; import { IPersistentStateFactory } from './persistentState'; type deprecatedFeatureInfo = { @@ -10,6 +10,7 @@ type deprecatedFeatureInfo = { message: string; moreInfoUrl: string; commands?: string[]; + setting?: string; }; const jupyterDeprecationInfo: deprecatedFeatureInfo = { @@ -21,22 +22,31 @@ const jupyterDeprecationInfo: deprecatedFeatureInfo = { 'jupyter.gotToNextCell'] }; +const deprecatedFeatures: deprecatedFeatureInfo[] = [ + { + doNotDisplayPromptStateKey: 'SHOW_DEPRECATED_FEATURE_PROMPT_FORMAT_ON_SAVE', + message: 'The setting \'python.formatting.formatOnSave\' is deprecated, please use \'editor.formatOnSave\'.', + moreInfoUrl: 'https://github.com/Microsoft/vscode-python/issues/309', + setting: 'formatting.formatOnSave' + } +]; + export interface IFeatureDeprecationManager extends Disposable { + initialize(): void; } export class FeatureDeprecationManager implements IFeatureDeprecationManager { private disposables: Disposable[] = []; - constructor(private persistentStateFactory: IPersistentStateFactory, private jupyterExtensionInstalled: boolean) { - this.handleDeprecationOfJupyter(); - } + private settingDeprecationNotified: string[] = []; + constructor(private persistentStateFactory: IPersistentStateFactory, private jupyterExtensionInstalled: boolean) { } public dispose() { this.disposables.forEach(disposable => disposable.dispose()); } - private handleDeprecationOfJupyter() { - if (this.jupyterExtensionInstalled) { - return; + public initialize() { + if (!this.jupyterExtensionInstalled) { + deprecatedFeatures.push(jupyterDeprecationInfo); } - this.registerDeprecation(jupyterDeprecationInfo); + deprecatedFeatures.forEach(this.registerDeprecation.bind(this)); } private registerDeprecation(deprecatedInfo: deprecatedFeatureInfo) { if (Array.isArray(deprecatedInfo.commands)) { @@ -44,13 +54,36 @@ export class FeatureDeprecationManager implements IFeatureDeprecationManager { this.disposables.push(commands.registerCommand(cmd, () => this.notifyDeprecation(deprecatedInfo), this)); }); } + if (deprecatedInfo.setting) { + this.checkAndNotifyDeprecatedSetting(deprecatedInfo); + } + } + private checkAndNotifyDeprecatedSetting(deprecatedInfo: deprecatedFeatureInfo) { + const setting = deprecatedInfo.setting!; + let notify = false; + if (Array.isArray(workspace.workspaceFolders) && workspace.workspaceFolders.length > 0) { + workspace.workspaceFolders.forEach(workspaceFolder => { + if (notify) { + return; + } + const pythonConfig = workspace.getConfiguration('python', workspaceFolder.uri); + notify = pythonConfig.has(setting) && this.settingDeprecationNotified.indexOf(setting) === -1; + }); + } else { + const pythonConfig = workspace.getConfiguration('python'); + notify = pythonConfig.has(setting) && this.settingDeprecationNotified.indexOf(setting) === -1; + } + + if (notify) { + this.settingDeprecationNotified.push(setting); + this.notifyDeprecation(deprecatedInfo); + } } private async notifyDeprecation(deprecatedInfo: deprecatedFeatureInfo) { const notificationPromptEnabled = this.persistentStateFactory.createGlobalPersistentState(deprecatedInfo.doNotDisplayPromptStateKey, true); if (!notificationPromptEnabled.value) { return; } - const moreInfo = 'Learn more'; const doNotShowAgain = 'Never show again'; const option = await window.showInformationMessage(deprecatedInfo.message, moreInfo, doNotShowAgain); diff --git a/src/client/common/browser.ts b/src/client/common/net/browser.ts similarity index 100% rename from src/client/common/browser.ts rename to src/client/common/net/browser.ts diff --git a/src/client/common/comms/SocketStream.ts b/src/client/common/net/socket/SocketStream.ts similarity index 100% rename from src/client/common/comms/SocketStream.ts rename to src/client/common/net/socket/SocketStream.ts diff --git a/src/client/common/comms/socketCallbackHandler.ts b/src/client/common/net/socket/socketCallbackHandler.ts similarity index 100% rename from src/client/common/comms/socketCallbackHandler.ts rename to src/client/common/net/socket/socketCallbackHandler.ts diff --git a/src/client/common/comms/socketServer.ts b/src/client/common/net/socket/socketServer.ts similarity index 96% rename from src/client/common/comms/socketServer.ts rename to src/client/common/net/socket/socketServer.ts index 9d87c140ed60..24a139cb638a 100644 --- a/src/client/common/comms/socketServer.ts +++ b/src/client/common/net/socket/socketServer.ts @@ -2,7 +2,7 @@ import * as net from "net"; import { EventEmitter } from 'events'; -import { createDeferred } from '../helpers'; +import { createDeferred } from '../../helpers'; export class SocketServer extends EventEmitter { private socketServer: net.Server = null; @@ -52,4 +52,4 @@ export class SocketServer extends EventEmitter { // let msg = "Debugger client timedout, " + d; }); } -} \ No newline at end of file +} diff --git a/src/client/common/registry.ts b/src/client/common/platform/registry.ts similarity index 100% rename from src/client/common/registry.ts rename to src/client/common/platform/registry.ts diff --git a/src/client/common/windowService.ts b/src/client/common/windowService.ts deleted file mode 100644 index 66ed651c9c85..000000000000 --- a/src/client/common/windowService.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as vscode from 'vscode'; -import { OutputChannel, StatusBarAlignment, StatusBarItem } from 'vscode'; - -export interface IWindowsSrevice { - /** - * Create a new [output channel](#OutputChannel) with the given name. - * - * @param name Human-readable string which will be used to represent the channel in the UI. - */ - createOutputChannel(name: string): OutputChannel; - /** - * Creates a status bar [item](#StatusBarItem). - * - * @param alignment The alignment of the item. - * @param priority The priority of the item. Higher values mean the item should be shown more to the left. - * @return A new status bar item. - */ - createStatusBarItem(alignment?: StatusBarAlignment, priority?: number): StatusBarItem; - /** - * Show an information message to users. Optionally provide an array of items which will be presented as - * clickable buttons. - * - * @param message The message to show. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showInformationMessage(message: string, ...items: string[]): Thenable; - /** - * Show a warning message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showWarningMessage(message: string, ...items: string[]): Thenable; - /** - * Show an error message. - * - * @see [showInformationMessage](#window.showInformationMessage) - * - * @param message The message to show. - * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. - */ - showErrorMessage(message: string, ...items: string[]): Thenable; -} - -export class WindowService implements IWindowsSrevice { - public createOutputChannel(name: string): OutputChannel { - return vscode.window.createOutputChannel(name); - } - public createStatusBarItem(alignment?: StatusBarAlignment, priority?: number): StatusBarItem { - return vscode.window.createStatusBarItem.apply(vscode.window, arguments); - } - public showInformationMessage(message: string, ...items: string[]): Thenable { - return vscode.window.showInformationMessage.apply(vscode.window, arguments); - } - public showWarningMessage(message: string, ...items: string[]): Thenable { - return vscode.window.showWarningMessage.apply(vscode.window, arguments); - } - public showErrorMessage(message: string, ...items: string[]): Thenable { - return vscode.window.showErrorMessage.apply(vscode.window, arguments); - } -} diff --git a/src/client/debugger/DebugServers/RemoteDebugServer.ts b/src/client/debugger/DebugServers/RemoteDebugServer.ts index f8a617e8d63b..2899d103def4 100644 --- a/src/client/debugger/DebugServers/RemoteDebugServer.ts +++ b/src/client/debugger/DebugServers/RemoteDebugServer.ts @@ -4,7 +4,7 @@ import {DebugSession, OutputEvent} from "vscode-debugadapter"; import {IPythonProcess, IDebugServer, AttachRequestArguments} from "../Common/Contracts"; import * as net from "net"; import {BaseDebugServer} from "./BaseDebugServer"; -import {SocketStream} from "../../common/comms/SocketStream"; +import {SocketStream} from "../../common/net/socket/SocketStream"; const DebuggerProtocolVersion = 6; // must be kept in sync with PTVSDBG_VER in attach_server.py const DebuggerSignature = "PTVSDBG"; @@ -93,7 +93,7 @@ export class RemoteDebugServer extends BaseDebugServer { } // If we are talking the same protocol but different version, reply with signature + version before bailing out - // so that ptvsd has a chance to gracefully close the socket on its side. + // so that ptvsd has a chance to gracefully close the socket on its side. that.stream.EndTransaction(); that.stream.Write(DebuggerSignatureBytes); that.stream.WriteInt64(DebuggerProtocolVersion); @@ -200,4 +200,4 @@ export class RemoteDebugServer extends BaseDebugServer { }); }); } -} \ No newline at end of file +} diff --git a/src/client/debugger/PythonProcess.ts b/src/client/debugger/PythonProcess.ts index 0a643630c94c..b37a70bafed8 100644 --- a/src/client/debugger/PythonProcess.ts +++ b/src/client/debugger/PythonProcess.ts @@ -9,7 +9,7 @@ import { PythonEvaluationResultReprKind, IExecutionCommand, enum_EXCEPTION_STATE import { Commands } from "./ProxyCommands"; import { IdDispenser } from "../common/idDispenser"; import { PythonProcessCallbackHandler } from "./PythonProcessCallbackHandler"; -import { SocketStream } from "../common/comms/SocketStream"; +import { SocketStream } from "../common/net/socket/SocketStream"; export class PythonProcess extends EventEmitter implements IPythonProcess { private id: number; diff --git a/src/client/debugger/PythonProcessCallbackHandler.ts b/src/client/debugger/PythonProcessCallbackHandler.ts index a11dc85e82e1..50e7bdf7b517 100644 --- a/src/client/debugger/PythonProcessCallbackHandler.ts +++ b/src/client/debugger/PythonProcessCallbackHandler.ts @@ -5,7 +5,7 @@ import { IDjangoStackFrame, PythonEvaluationResultFlags, PythonLanguageVersion, import * as utils from "./Common/Utils"; import { EventEmitter } from "events"; import { Commands } from "./ProxyCommands"; -import { SocketStream } from "../common/comms/SocketStream"; +import { SocketStream } from "../common/net/socket/SocketStream"; import { ExtractTryStatements } from "./Common/TryParser"; import * as path from "path"; import {IdDispenser} from '../common/idDispenser'; diff --git a/src/client/extension.ts b/src/client/extension.ts index a5b535f4bd80..ff1acf102139 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -18,7 +18,6 @@ import { JediFactory } from './languageServices/jediProxyFactory'; import { PythonCompletionItemProvider } from './providers/completionProvider'; import { PythonDefinitionProvider } from './providers/definitionProvider'; import { activateExecInTerminalProvider } from './providers/execInTerminalProvider'; -import { activateFormatOnSaveProvider } from './providers/formatOnSaveProvider'; import { PythonFormattingEditProvider } from './providers/formatProvider'; import { PythonHoverProvider } from './providers/hoverProvider'; import { LintProvider } from './providers/lintProvider'; @@ -46,9 +45,7 @@ const activationDeferred = createDeferred(); export const activated = activationDeferred.promise; // tslint:disable-next-line:max-func-body-length export async function activate(context: vscode.ExtensionContext) { - const jupyterExtInstalled = vscode.extensions.getExtension('donjayamanne.jupyter'); const persistentStateFactory = new PersistentStateFactory(context.globalState, context.workspaceState); - context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled)); const pythonSettings = settings.PythonSettings.getInstance(); // tslint:disable-next-line:no-floating-promises sendStartupTelemetry(activated); @@ -75,7 +72,6 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(...activateExecInTerminalProvider()); context.subscriptions.push(activateUpdateSparkLibraryProvider()); activateSimplePythonRefactorProvider(context, formatOutChannel); - context.subscriptions.push(activateFormatOnSaveProvider(PYTHON, formatOutChannel)); const jediFactory = new JediFactory(context.asAbsolutePath('.')); context.subscriptions.push(...activateGoToObjectDefinitionProvider(jediFactory)); @@ -124,6 +120,7 @@ export async function activate(context: vscode.ExtensionContext) { // tslint:disable-next-line:promise-function-async const linterProvider = new LintProvider(context, lintingOutChannel, (a, b) => Promise.resolve(false)); context.subscriptions.push(); + const jupyterExtInstalled = vscode.extensions.getExtension('donjayamanne.jupyter'); if (jupyterExtInstalled) { if (jupyterExtInstalled.isActive) { // tslint:disable-next-line:no-unsafe-any @@ -155,6 +152,10 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(feedbackService); // tslint:disable-next-line:no-unused-expression new BannerService(persistentStateFactory); + + const deprecationMgr = new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled); + deprecationMgr.initialize(); + context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled)); } async function sendStartupTelemetry(activatedPromise: Promise) { diff --git a/src/client/feedback/feedbackService.ts b/src/client/feedback/feedbackService.ts index 0ab8d13dce6b..2a99017309d3 100644 --- a/src/client/feedback/feedbackService.ts +++ b/src/client/feedback/feedbackService.ts @@ -3,8 +3,8 @@ import { window } from 'vscode'; import { commands, Disposable, TextDocument, workspace } from 'vscode'; -import { launch } from '../common/browser'; import { PythonLanguage } from '../common/constants'; +import { launch } from '../common/net/browser'; import { IPersistentStateFactory, PersistentState } from '../common/persistentState'; import { FEEDBACK } from '../telemetry/constants'; import { captureTelemetry, sendTelemetryEvent } from '../telemetry/index'; diff --git a/src/client/interpreter/contracts.ts b/src/client/interpreter/contracts.ts index 1bee73bb62b8..f1371688ccc6 100644 --- a/src/client/interpreter/contracts.ts +++ b/src/client/interpreter/contracts.ts @@ -1,5 +1,5 @@ import { ConfigurationTarget, Disposable, Uri } from 'vscode'; -import { Architecture } from '../common/registry'; +import { Architecture } from '../common/platform/registry'; export interface IInterpreterLocatorService extends Disposable { getInterpreters(resource?: Uri): Promise; diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index 69103313a909..dce82ad331be 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -1,6 +1,6 @@ import * as child_process from 'child_process'; import { ConfigurationTarget, window, workspace } from 'vscode'; -import { RegistryImplementation } from '../common/registry'; +import { RegistryImplementation } from '../common/platform/registry'; import { Is_64Bit, IS_WINDOWS } from '../common/utils'; import { WorkspacePythonPath } from './contracts'; import { CondaLocatorService } from './locators/services/condaLocator'; diff --git a/src/client/interpreter/locators/helpers.ts b/src/client/interpreter/locators/helpers.ts index 934648b70de6..4efeb34d9721 100644 --- a/src/client/interpreter/locators/helpers.ts +++ b/src/client/interpreter/locators/helpers.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { getArchitectureDislayName } from '../../common/registry'; +import { getArchitectureDislayName } from '../../common/platform/registry'; import { fsReaddirAsync, IS_WINDOWS } from '../../common/utils'; import { PythonInterpreter } from '../contracts'; diff --git a/src/client/interpreter/locators/index.ts b/src/client/interpreter/locators/index.ts index 3918766cfd3e..ac8b0a451d3c 100644 --- a/src/client/interpreter/locators/index.ts +++ b/src/client/interpreter/locators/index.ts @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as path from 'path'; import { Disposable, Uri, workspace } from 'vscode'; -import { RegistryImplementation } from '../../common/registry'; +import { RegistryImplementation } from '../../common/platform/registry'; import { arePathsSame, Is_64Bit, IS_WINDOWS } from '../../common/utils'; import { IInterpreterLocatorService, PythonInterpreter } from '../contracts'; import { InterpreterVersionService } from '../interpreterVersion'; diff --git a/src/client/interpreter/locators/services/windowsRegistryService.ts b/src/client/interpreter/locators/services/windowsRegistryService.ts index f100e55a72aa..aa74aefd2606 100644 --- a/src/client/interpreter/locators/services/windowsRegistryService.ts +++ b/src/client/interpreter/locators/services/windowsRegistryService.ts @@ -2,7 +2,7 @@ import * as fs from 'fs-extra'; import * as _ from 'lodash'; import * as path from 'path'; import { Uri } from 'vscode'; -import { Architecture, Hive, IRegistry } from '../../../common/registry'; +import { Architecture, Hive, IRegistry } from '../../../common/platform/registry'; import { IInterpreterLocatorService, PythonInterpreter } from '../../contracts'; // tslint:disable-next-line:variable-name diff --git a/src/client/jedi/main.ts b/src/client/jedi/main.ts index 6586a1e27eb4..2a4d287831cb 100644 --- a/src/client/jedi/main.ts +++ b/src/client/jedi/main.ts @@ -4,7 +4,7 @@ import * as child_process from 'child_process'; import * as path from 'path'; import * as vscode from 'vscode'; import { SocketClient } from './socketClient'; -import { SocketServer } from '../common/comms/socketServer'; +import { SocketServer } from '../common/net/socket/socketServer'; import { createDeferred, Deferred } from '../common/helpers'; import { PythonSettings } from '../common/configSettings'; import { EventEmitter } from 'events'; diff --git a/src/client/jedi/socketClient.ts b/src/client/jedi/socketClient.ts index 75e08d0d5f06..26b807c78f61 100644 --- a/src/client/jedi/socketClient.ts +++ b/src/client/jedi/socketClient.ts @@ -1,8 +1,8 @@ "use strict"; -import { SocketCallbackHandler } from "../common/comms/socketCallbackHandler"; +import { SocketCallbackHandler } from "../common/net/socket/socketCallbackHandler"; import { RequestCommands, ResponseCommands } from "./commands"; -import { SocketServer } from '../common/comms/socketServer'; +import { SocketServer } from '../common/net/socket/socketServer'; import { IdDispenser } from '../common/idDispenser'; import { createDeferred, Deferred } from '../common/helpers'; import { OutputChannel, CancellationToken } from 'vscode'; diff --git a/src/client/providers/formatOnSaveProvider.ts b/src/client/providers/formatOnSaveProvider.ts deleted file mode 100644 index 1b550f0d6cc4..000000000000 --- a/src/client/providers/formatOnSaveProvider.ts +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; - -// Solution for auto-formatting borrowed from the "go" language VSCode extension. - -import * as vscode from "vscode"; -import { BaseFormatter } from "./../formatters/baseFormatter"; -import { YapfFormatter } from "./../formatters/yapfFormatter"; -import { AutoPep8Formatter } from "./../formatters/autoPep8Formatter"; -import { DummyFormatter } from "./../formatters/dummyFormatter"; -import { PythonSettings } from "./../common/configSettings"; - -export function activateFormatOnSaveProvider(languageFilter: vscode.DocumentFilter, outputChannel: vscode.OutputChannel): vscode.Disposable { - const formatters = new Map(); - const yapfFormatter = new YapfFormatter(outputChannel); - const autoPep8 = new AutoPep8Formatter(outputChannel); - const dummyFormatter = new DummyFormatter(outputChannel); - - formatters.set(yapfFormatter.Id, yapfFormatter); - formatters.set(autoPep8.Id, autoPep8); - formatters.set(dummyFormatter.Id, dummyFormatter); - - return vscode.workspace.onWillSaveTextDocument(e => { - const document = e.document; - if (document.languageId !== languageFilter.language) { - return; - } - const textEditor = vscode.window.activeTextEditor; - const editorConfig = vscode.workspace.getConfiguration('editor'); - const globalEditorFormatOnSave = editorConfig && editorConfig.has('formatOnSave') && editorConfig.get('formatOnSave') === true; - const settings = PythonSettings.getInstance(document.uri); - if ((settings.formatting.formatOnSave || globalEditorFormatOnSave) && textEditor.document === document) { - const formatter = formatters.get(settings.formatting.provider); - e.waitUntil(formatter.formatDocument(document, null, null)); - } - }, null, null); -} diff --git a/src/test/common.ts b/src/test/common.ts index 851ed6cae5a9..15d2a4727ea7 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -13,7 +13,7 @@ export type PythonSettingKeys = 'workspaceSymbols.enabled' | 'pythonPath' | 'linting.flake8Enabled' | 'linting.pep8Enabled' | 'linting.pylamaEnabled' | 'linting.prospectorEnabled' | 'linting.pydocstyleEnabled' | 'linting.mypyEnabled' | 'unitTest.nosetestArgs' | 'unitTest.pyTestArgs' | 'unitTest.unittestArgs' | - 'formatting.formatOnSave' | 'formatting.provider' | 'sortImports.args' | + 'formatting.provider' | 'sortImports.args' | 'unitTest.nosetestsEnabled' | 'unitTest.pyTestEnabled' | 'unitTest.unittestEnabled' | 'linting.enabledWithoutWorkspace'; diff --git a/src/test/common/socketCallbackHandler.test.ts b/src/test/common/socketCallbackHandler.test.ts index d32cd43eed26..217f11822aa6 100644 --- a/src/test/common/socketCallbackHandler.test.ts +++ b/src/test/common/socketCallbackHandler.test.ts @@ -10,9 +10,9 @@ import * as assert from 'assert'; // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import { SocketStream } from '../../client/common/comms/SocketStream'; -import { SocketServer } from '../../client/common/comms/socketServer'; -import { SocketCallbackHandler } from '../../client/common/comms/socketCallbackHandler'; +import { SocketStream } from '../../client/common/net/socket/SocketStream'; +import { SocketServer } from '../../client/common/net/socket/socketServer'; +import { SocketCallbackHandler } from '../../client/common/net/socket/socketCallbackHandler'; import { createDeferred, Deferred } from '../../client/common/helpers'; import { IdDispenser } from '../../client/common/idDispenser'; diff --git a/src/test/common/socketStream.test.ts b/src/test/common/socketStream.test.ts index 761196b489e0..3cae966392f7 100644 --- a/src/test/common/socketStream.test.ts +++ b/src/test/common/socketStream.test.ts @@ -11,7 +11,7 @@ import * as assert from 'assert'; // You can import and use all API from the 'vscode' module // as well as import your extension to test it import * as vscode from 'vscode'; -import { SocketStream } from '../../client/common/comms/SocketStream'; +import { SocketStream } from '../../client/common/net/socket/SocketStream'; import * as net from 'net'; const uint64be = require("uint64be"); diff --git a/src/test/format/extension.format.test.ts b/src/test/format/extension.format.test.ts index ce41edead475..b7c650b2e5dd 100644 --- a/src/test/format/extension.format.test.ts +++ b/src/test/format/extension.format.test.ts @@ -1,23 +1,12 @@ -import { updateSetting } from '../common'; - -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. - - -// The module 'assert' provides assertion methods from node import * as assert from 'assert'; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from 'vscode'; -import * as path from 'path'; import * as fs from 'fs-extra'; -import { EOL } from 'os'; -import { PythonSettings } from '../../client/common/configSettings'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { CancellationTokenSource } from 'vscode'; +import { execPythonFile } from '../../client/common/utils'; import { AutoPep8Formatter } from '../../client/formatters/autoPep8Formatter'; -import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST, IS_TRAVIS } from '../initialize'; import { YapfFormatter } from '../../client/formatters/yapfFormatter'; -import { execPythonFile } from '../../client/common/utils'; +import { closeActiveWindows, initialize, initializeTest } from '../initialize'; const ch = vscode.window.createOutputChannel('Tests'); const pythoFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'formatting'); @@ -29,8 +18,6 @@ const autoPep8FileToAutoFormat = path.join(pythoFilesPath, 'autoPep8FileToAutoFo const yapfFileToFormat = path.join(pythoFilesPath, 'yapfFileToFormat.py'); const yapfFileToAutoFormat = path.join(pythoFilesPath, 'yapfFileToAutoFormat.py'); -const configUpdateTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; - let formattedYapf = ''; let formattedAutoPep8 = ''; @@ -46,74 +33,30 @@ suite('Formatting', () => { await Promise.all([yapf, autoPep8]).then(formattedResults => { formattedYapf = formattedResults[0]; formattedAutoPep8 = formattedResults[1]; - }).then(() => { }); + }); }); - setup(() => initializeTest()); + setup(initializeTest); suiteTeardown(async () => { [autoPep8FileToFormat, autoPep8FileToAutoFormat, yapfFileToFormat, yapfFileToAutoFormat].forEach(file => { if (fs.existsSync(file)) { fs.unlinkSync(file); } }); - await updateSetting('formatting.formatOnSave', false, vscode.Uri.file(pythoFilesPath), configUpdateTarget) await closeActiveWindows(); }); - teardown(() => closeActiveWindows()); - - function testFormatting(formatter: AutoPep8Formatter | YapfFormatter, formattedContents: string, fileToFormat: string): PromiseLike { - let textEditor: vscode.TextEditor; - let textDocument: vscode.TextDocument; - return vscode.workspace.openTextDocument(fileToFormat).then(document => { - textDocument = document; - return vscode.window.showTextDocument(textDocument); - }).then(editor => { - assert(vscode.window.activeTextEditor, 'No active editor'); - textEditor = editor; - return formatter.formatDocument(textDocument, null, null); - }).then(edits => { - return textEditor.edit(editBuilder => { - edits.forEach(edit => editBuilder.replace(edit.range, edit.newText)); - }); - }).then(edited => { - assert.equal(textEditor.document.getText(), formattedContents, 'Formatted text is not the same'); - }, reason => { - assert.fail(reason, undefined, 'Formatting failed', ''); - }); - } - test('AutoPep8', done => { - testFormatting(new AutoPep8Formatter(ch), formattedAutoPep8, autoPep8FileToFormat).then(done, done); - }); + teardown(closeActiveWindows); - test('Yapf', done => { - testFormatting(new YapfFormatter(ch), formattedYapf, yapfFileToFormat).then(done, done); - }); - - async function testAutoFormatting(formatter: string, formattedContents: string, fileToFormat: string): Promise { - await updateSetting('formatting.formatOnSave', true, vscode.Uri.file(fileToFormat), configUpdateTarget); - await updateSetting('formatting.provider', formatter, vscode.Uri.file(fileToFormat), configUpdateTarget); + async function testFormatting(formatter: AutoPep8Formatter | YapfFormatter, formattedContents: string, fileToFormat: string) { const textDocument = await vscode.workspace.openTextDocument(fileToFormat); - const editor = await vscode.window.showTextDocument(textDocument); - assert(vscode.window.activeTextEditor, 'No active editor'); - const edited = await editor.edit(editBuilder => { - editBuilder.insert(new vscode.Position(0, 0), '#\n'); - }); - const saved = await textDocument.save(); - await new Promise((resolve, reject) => { - setTimeout(() => { - resolve(); - }, 5000); + const textEditor = await vscode.window.showTextDocument(textDocument); + const options = { insertSpaces: textEditor.options.insertSpaces! as boolean, tabSize: textEditor.options.tabSize! as number }; + const edits = await formatter.formatDocument(textDocument, options, new CancellationTokenSource().token); + await textEditor.edit(editBuilder => { + edits.forEach(edit => editBuilder.replace(edit.range, edit.newText)); }); - const text = textDocument.getText(); - assert.equal(text === formattedContents, true, 'Formatted contents are not the same'); + assert.equal(textEditor.document.getText(), formattedContents, 'Formatted text is not the same'); } - test('AutoPep8 autoformat on save', done => { - testAutoFormatting('autopep8', `#${EOL}` + formattedAutoPep8, autoPep8FileToAutoFormat).then(done, done); - }); + test('AutoPep8', () => testFormatting(new AutoPep8Formatter(ch), formattedAutoPep8, autoPep8FileToFormat)); - // For some reason doesn't ever work on travis - if (!IS_TRAVIS) { - test('Yapf autoformat on save', done => { - testAutoFormatting('yapf', `#${EOL}` + formattedYapf, yapfFileToAutoFormat).then(done, done); - }); - } + test('Yapf', () => testFormatting(new YapfFormatter(ch), formattedYapf, yapfFileToFormat)); }); diff --git a/src/test/interpreters/mocks.ts b/src/test/interpreters/mocks.ts index be61eb9c52c9..5ae12af5c396 100644 --- a/src/test/interpreters/mocks.ts +++ b/src/test/interpreters/mocks.ts @@ -1,4 +1,4 @@ -import { Architecture, Hive, IRegistry } from '../../client/common/registry'; +import { Architecture, Hive, IRegistry } from '../../client/common/platform/registry'; import { IInterpreterLocatorService, PythonInterpreter } from '../../client/interpreter/contracts'; import { IInterpreterVersionService } from '../../client/interpreter/interpreterVersion'; import { CondaLocatorService } from '../../client/interpreter/locators/services/condaLocator'; diff --git a/src/test/interpreters/windowsRegistryService.test.ts b/src/test/interpreters/windowsRegistryService.test.ts index aedad057a4d0..203d69ac3c68 100644 --- a/src/test/interpreters/windowsRegistryService.test.ts +++ b/src/test/interpreters/windowsRegistryService.test.ts @@ -1,16 +1,17 @@ import * as assert from 'assert'; import * as path from 'path'; -import { initialize, initializeTest } from '../initialize'; +import { Architecture, Hive } from '../../client/common/platform/registry'; import { IS_WINDOWS } from '../../client/debugger/Common/Utils'; import { WindowsRegistryService } from '../../client/interpreter/locators/services/windowsRegistryService'; +import { initialize, initializeTest } from '../initialize'; import { MockRegistry } from './mocks'; -import { Architecture, Hive } from '../../client/common/registry'; const environmentsPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'environments'); +// tslint:disable-next-line:max-func-body-length suite('Interpreters from Windows Registry', () => { - suiteSetup(() => initialize()); - setup(() => initializeTest()); + suiteSetup(initialize); + setup(initializeTest); if (IS_WINDOWS) { test('Must return an empty list (x86)', async () => { const registry = new MockRegistry([], []); @@ -36,7 +37,7 @@ suite('Interpreters from Windows Registry', () => { { key: '\\Software\\Python\\Company One\\Tag1\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'path1') }, { key: '\\Software\\Python\\Company One\\Tag1\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'path1', 'one.exe'), name: 'ExecutablePath' }, { key: '\\Software\\Python\\Company One\\Tag1', hive: Hive.HKCU, arch: Architecture.x86, value: 'Version.Tag1', name: 'Version' }, - { key: '\\Software\\Python\\Company One\\Tag1', hive: Hive.HKCU, arch: Architecture.x86, value: 'DisplayName.Tag1', name: 'DisplayName' }, + { key: '\\Software\\Python\\Company One\\Tag1', hive: Hive.HKCU, arch: Architecture.x86, value: 'DisplayName.Tag1', name: 'DisplayName' } ]; const registry = new MockRegistry(registryKeys, registryValues); const winRegistry = new WindowsRegistryService(registry, false); @@ -70,7 +71,7 @@ suite('Interpreters from Windows Registry', () => { assert.equal(interpreters[0].path, path.join(environmentsPath, 'path1', 'python.exe'), 'Incorrect path'); assert.equal(interpreters[0].version, 'Tag1', 'Incorrect version'); }); - test(`Must ignore company 'PyLauncher'`, async () => { + test('Must ignore company \'PyLauncher\'', async () => { const registryKeys = [ { key: '\\Software\\Python', hive: Hive.HKCU, arch: Architecture.x86, values: ['\\Software\\Python\\PyLauncher'] }, { key: '\\Software\\Python\\PythonCore', hive: Hive.HKCU, arch: Architecture.x86, values: ['\\Software\\Python\\PyLauncher\\Tag1'] } @@ -88,7 +89,7 @@ suite('Interpreters from Windows Registry', () => { test('Must return a single entry and when registry contains only the InstallPath', async () => { const registryKeys = [ { key: '\\Software\\Python', hive: Hive.HKCU, arch: Architecture.x86, values: ['\\Software\\Python\\Company One'] }, - { key: '\\Software\\Python\\Company One', hive: Hive.HKCU, arch: Architecture.x86, values: ['\\Software\\Python\\Company One\\Tag1'] }, + { key: '\\Software\\Python\\Company One', hive: Hive.HKCU, arch: Architecture.x86, values: ['\\Software\\Python\\Company One\\Tag1'] } ]; const registryValues = [ { key: '\\Software\\Python\\Company One\\Tag1\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'path1') } @@ -187,6 +188,7 @@ suite('Interpreters from Windows Registry', () => { { key: '\\Software\\Python\\Company Two\\Tag B\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: 'DisplayName.Tag B', name: 'DisplayName' }, { key: '\\Software\\Python\\Company Two\\Tag C\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'conda', 'envs', 'numpy') }, + // tslint:disable-next-line:no-any { key: '\\Software\\Python\\Company Five\\Five !\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: undefined }, { key: '\\Software\\Python\\Company Three\\Tag !\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'conda', 'envs', 'numpy') }, @@ -245,6 +247,7 @@ suite('Interpreters from Windows Registry', () => { { key: '\\Software\\Python\\Company Two\\Tag B\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: 'DisplayName.Tag B', name: 'DisplayName' }, { key: '\\Software\\Python\\Company Two\\Tag C\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'non-existent-path', 'envs', 'numpy') }, + // tslint:disable-next-line:no-any { key: '\\Software\\Python\\Company Five\\Five !\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: undefined }, { key: '\\Software\\Python\\Company Three\\Tag !\\InstallPath', hive: Hive.HKCU, arch: Architecture.x86, value: path.join(environmentsPath, 'non-existent-path', 'envs', 'numpy') }, diff --git a/tslint.json b/tslint.json index 4b73db1ed4b3..8eb25597c0cc 100644 --- a/tslint.json +++ b/tslint.json @@ -53,7 +53,6 @@ "function-name": false, "variable-name": false, "no-floating-promises": false, - "promise-function-async": false, "no-empty-interface": false } }