diff --git a/client/schemas/pyrightconfig.schema.json b/client/schemas/pyrightconfig.schema.json index 06c52b8ac..25d001e1f 100644 --- a/client/schemas/pyrightconfig.schema.json +++ b/client/schemas/pyrightconfig.schema.json @@ -294,6 +294,12 @@ "title": "Controls reporting assert expressions that will always evaluate to true", "default": "warning" }, + "reportImplicitStringConcatenation": { + "$id": "#/properties/reportImplicitStringConcatenation", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting usage of implicit concatenation of string literals", + "default": "warning" + }, "pythonVersion": { "$id": "#/properties/pythonVersion", "type": "string", diff --git a/docs/configuration.md b/docs/configuration.md index 46eaf3386..5adb7c62c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -106,6 +106,8 @@ The following settings control pyright’s diagnostic output (warnings or errors **reportSelfClsParameterName** [boolean or string, optional]: Generate or suppress diagnostics for a missing or misnamed “self” parameter in instance methods and “cls” parameter in class methods. Instance methods in metaclasses (classes that derive from “type”) are allowed to use “cls” for instance methods. The default value for this setting is 'warning'. +**reportImplicitStringConcatenation** [boolean or string, optional]: Generate or suppress diagnostics for two or more string literals that follow each other, indicating an implicit concatenation. This is considered a bad practice and often masks bugs such as missing commas. The default value for this setting is 'none'. + ## Execution Environment Options Pyright allows multiple “execution environments” to be defined for different portions of your source tree. For example, a subtree may be designed to run with different import search paths or a different version of the python interpreter than the rest of the source base. diff --git a/server/src/analyzer/checker.ts b/server/src/analyzer/checker.ts index 352513366..fb5b22508 100644 --- a/server/src/analyzer/checker.ts +++ b/server/src/analyzer/checker.ts @@ -497,6 +497,13 @@ export class Checker extends ParseTreeWalker { this._evaluator.getType(node); } + if (node.strings.length > 1) { + this._evaluator.addDiagnosticForTextRange(this._fileInfo, + this._fileInfo.diagnosticSettings.reportImplicitStringConcatenation, + DiagnosticRule.reportImplicitStringConcatenation, + `Implicit string concatenation not allowed`, node); + } + return true; } diff --git a/server/src/common/configOptions.ts b/server/src/common/configOptions.ts index 4ba44aa1b..2f91f1f35 100644 --- a/server/src/common/configOptions.ts +++ b/server/src/common/configOptions.ts @@ -158,6 +158,9 @@ export interface DiagnosticSettings { // Report when "self" or "cls" parameter is missing or is misnamed. reportSelfClsParameterName: DiagnosticLevel; + + // Report implicit concatenation of string literals. + reportImplicitStringConcatenation: DiagnosticLevel; } export function cloneDiagnosticSettings( @@ -214,7 +217,8 @@ export function getDiagLevelSettings() { DiagnosticRule.reportUnnecessaryIsInstance, DiagnosticRule.reportUnnecessaryCast, DiagnosticRule.reportAssertAlwaysTrue, - DiagnosticRule.reportSelfClsParameterName + DiagnosticRule.reportSelfClsParameterName, + DiagnosticRule.reportImplicitStringConcatenation ]; } @@ -256,7 +260,8 @@ export function getStrictDiagnosticSettings(): DiagnosticSettings { reportUnnecessaryIsInstance: 'error', reportUnnecessaryCast: 'error', reportAssertAlwaysTrue: 'error', - reportSelfClsParameterName: 'error' + reportSelfClsParameterName: 'error', + reportImplicitStringConcatenation: 'none' }; return diagSettings; @@ -300,7 +305,8 @@ export function getDefaultDiagnosticSettings(): DiagnosticSettings { reportUnnecessaryIsInstance: 'none', reportUnnecessaryCast: 'none', reportAssertAlwaysTrue: 'warning', - reportSelfClsParameterName: 'warning' + reportSelfClsParameterName: 'warning', + reportImplicitStringConcatenation: 'none' }; return diagSettings; @@ -671,7 +677,12 @@ export class ConfigOptions { // Read the "reportSelfClsParameterName" entry. reportSelfClsParameterName: this._convertDiagnosticLevel( configObj.reportSelfClsParameterName, DiagnosticRule.reportSelfClsParameterName, - defaultSettings.reportSelfClsParameterName) + defaultSettings.reportSelfClsParameterName), + + // Read the "reportImplicitStringConcatenation" entry. + reportImplicitStringConcatenation: this._convertDiagnosticLevel( + configObj.reportImplicitStringConcatenation, DiagnosticRule.reportImplicitStringConcatenation, + defaultSettings.reportImplicitStringConcatenation) }; // Read the "venvPath". diff --git a/server/src/common/diagnosticRules.ts b/server/src/common/diagnosticRules.ts index 359bc61da..eefb7c827 100644 --- a/server/src/common/diagnosticRules.ts +++ b/server/src/common/diagnosticRules.ts @@ -46,5 +46,6 @@ export const enum DiagnosticRule { reportUnnecessaryIsInstance = 'reportUnnecessaryIsInstance', reportUnnecessaryCast = 'reportUnnecessaryCast', reportAssertAlwaysTrue = 'reportAssertAlwaysTrue', - reportSelfClsParameterName = 'reportSelfClsParameterName' + reportSelfClsParameterName = 'reportSelfClsParameterName', + reportImplicitStringConcatenation = 'reportImplicitStringConcatenation' }