Added the ability to override type checking configuration settings for each execution environment. This allows, for example, a test directory to use different settings than the directories that contain production code. This addresses #4059.

This commit is contained in:
Eric Traut 2024-06-06 15:25:01 -07:00
parent 2c313972d3
commit 4b84651950
6 changed files with 302 additions and 3 deletions

View File

@ -239,6 +239,7 @@ The following settings can be specified for each execution environment.
- **pythonPlatform** [string, optional]: Specifies the target platform that will be used for this execution environment. If not specified, the global `pythonPlatform` setting is used instead.
In addition, any of the [type check diagnostics settings](configuration.md/type-check-diagnostics-settings) listed above can be specified. These settings act as overrides for the files in this execution environment.
## Sample Config File
The following is an example of a pyright config file:

View File

@ -723,7 +723,7 @@ export class SourceFile {
this._diagnosticRuleSet = CommentUtils.getFileLevelDirectives(
parseFileResults.tokenizerOutput.tokens,
parseFileResults.tokenizerOutput.lines,
configOptions.diagnosticRuleSet,
execEnvironment.diagnosticRuleSet,
useStrict,
commentDiags
);

View File

@ -48,10 +48,14 @@ export class ExecutionEnvironment {
// Default to no extra paths.
extraPaths: Uri[] = [];
// Diagnostic rules with overrides.
diagnosticRuleSet: DiagnosticRuleSet;
// Default to "." which indicates every file in the project.
constructor(
name: string,
root: Uri,
defaultDiagRuleSet: DiagnosticRuleSet,
defaultPythonVersion: PythonVersion | undefined,
defaultPythonPlatform: string | undefined,
defaultExtraPaths: Uri[] | undefined
@ -61,6 +65,7 @@ export class ExecutionEnvironment {
this.pythonVersion = defaultPythonVersion ?? latestStablePythonVersion;
this.pythonPlatform = defaultPythonPlatform;
this.extraPaths = Array.from(defaultExtraPaths ?? []);
this.diagnosticRuleSet = { ...defaultDiagRuleSet };
}
}
@ -1070,6 +1075,7 @@ export class ConfigOptions {
return new ExecutionEnvironment(
this._getEnvironmentName(),
this.projectRoot,
this.diagnosticRuleSet,
this.defaultPythonVersion,
this.defaultPythonPlatform,
this.defaultExtraPaths
@ -1575,6 +1581,7 @@ export class ConfigOptions {
const newExecEnv = new ExecutionEnvironment(
this._getEnvironmentName(),
configDirUri,
this.diagnosticRuleSet,
this.defaultPythonVersion,
this.defaultPythonPlatform,
this.defaultExtraPaths
@ -1652,6 +1659,24 @@ export class ConfigOptions {
}
}
// Apply overrides from the config file for the boolean overrides.
getBooleanDiagnosticRules(/* includeNonOverridable */ true).forEach((ruleName) => {
(newExecEnv.diagnosticRuleSet as any)[ruleName] = this._convertBoolean(
envObj[ruleName],
ruleName,
newExecEnv.diagnosticRuleSet[ruleName] as boolean
);
});
// Apply overrides from the config file for the diagnostic level overrides.
getDiagLevelDiagnosticRules().forEach((ruleName) => {
(newExecEnv.diagnosticRuleSet as any)[ruleName] = this._convertDiagnosticLevel(
envObj[ruleName],
ruleName,
newExecEnv.diagnosticRuleSet[ruleName] as DiagnosticLevel
);
});
return newExecEnv;
} catch {
console.error(`Config executionEnvironments index ${index} is not accessible.`);

View File

@ -12,7 +12,7 @@ import assert from 'assert';
import { AnalyzerService } from '../analyzer/service';
import { deserialize, serialize } from '../backgroundThreadBase';
import { CommandLineOptions } from '../common/commandLineOptions';
import { ConfigOptions, ExecutionEnvironment } from '../common/configOptions';
import { ConfigOptions, ExecutionEnvironment, getStandardDiagnosticRuleSet } from '../common/configOptions';
import { ConsoleInterface, NullConsole } from '../common/console';
import { NoAccessHost } from '../common/host';
import { combinePaths, normalizePath, normalizeSlashes } from '../common/pathUtils';
@ -170,6 +170,7 @@ test('FindExecEnv1', () => {
const execEnv1 = new ExecutionEnvironment(
'python',
cwd.resolvePaths('src/foo'),
getStandardDiagnosticRuleSet(),
/* defaultPythonVersion */ undefined,
/* defaultPythonPlatform */ undefined,
/* defaultExtraPaths */ undefined
@ -178,6 +179,7 @@ test('FindExecEnv1', () => {
const execEnv2 = new ExecutionEnvironment(
'python',
cwd.resolvePaths('src'),
getStandardDiagnosticRuleSet(),
/* defaultPythonVersion */ undefined,
/* defaultPythonPlatform */ undefined,
/* defaultExtraPaths */ undefined

View File

@ -15,7 +15,7 @@ import { ImportResolver } from '../analyzer/importResolver';
import { Program } from '../analyzer/program';
import { NameTypeWalker } from '../analyzer/testWalker';
import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
import { ConfigOptions, ExecutionEnvironment } from '../common/configOptions';
import { ConfigOptions, ExecutionEnvironment, getStandardDiagnosticRuleSet } from '../common/configOptions';
import { ConsoleWithLogLevel, NullConsole } from '../common/console';
import { fail } from '../common/debug';
import { Diagnostic, DiagnosticCategory } from '../common/diagnostic';
@ -74,6 +74,7 @@ export function parseSampleFile(
execEnvironment = new ExecutionEnvironment(
'python',
UriEx.file('.'),
getStandardDiagnosticRuleSet(),
/* defaultPythonVersion */ undefined,
/* defaultPythonPlatform */ undefined,
/* defaultExtraPaths */ undefined

View File

@ -898,6 +898,276 @@
"default": "",
"pattern": "^(.*)$"
},
"disableBytesTypePromotions": {
"$ref": "#/definitions/disableBytesTypePromotions"
},
"strictListInference": {
"$ref": "#/definitions/strictListInference"
},
"strictSetInference": {
"$ref": "#/definitions/strictSetInference"
},
"strictDictionaryInference": {
"$ref": "#/definitions/strictDictionaryInference"
},
"analyzeUnannotatedFunctions": {
"$ref": "#/definitions/analyzeUnannotatedFunctions"
},
"strictParameterNoneValue": {
"$ref": "#/definitions/strictParameterNoneValue"
},
"enableExperimentalFeatures": {
"$ref": "#/definitions/enableExperimentalFeatures"
},
"enableTypeIgnoreComments": {
"$ref": "#/definitions/enableTypeIgnoreComments"
},
"deprecateTypingAliases": {
"$ref": "#/definitions/deprecateTypingAliases"
},
"reportGeneralTypeIssues": {
"$ref": "#/definitions/reportGeneralTypeIssues"
},
"reportPropertyTypeMismatch": {
"$ref": "#/definitions/reportPropertyTypeMismatch"
},
"reportFunctionMemberAccess": {
"$ref": "#/definitions/reportFunctionMemberAccess"
},
"reportMissingImports": {
"$ref": "#/definitions/reportMissingImports"
},
"reportMissingModuleSource": {
"$ref": "#/definitions/reportMissingModuleSource"
},
"reportInvalidTypeForm": {
"$ref": "#/definitions/reportInvalidTypeForm"
},
"reportMissingTypeStubs": {
"$ref": "#/definitions/reportMissingTypeStubs"
},
"reportImportCycles": {
"$ref": "#/definitions/reportImportCycles"
},
"reportUnusedImport": {
"$ref": "#/definitions/reportUnusedImport"
},
"reportUnusedClass": {
"$ref": "#/definitions/reportUnusedClass"
},
"reportUnusedFunction": {
"$ref": "#/definitions/reportUnusedFunction"
},
"reportUnusedVariable": {
"$ref": "#/definitions/reportUnusedVariable"
},
"reportDuplicateImport": {
"$ref": "#/definitions/reportDuplicateImport"
},
"reportWildcardImportFromLibrary": {
"$ref": "#/definitions/reportWildcardImportFromLibrary"
},
"reportAbstractUsage": {
"$ref": "#/definitions/reportAbstractUsage"
},
"reportArgumentType": {
"$ref": "#/definitions/reportArgumentType"
},
"reportAssertTypeFailure": {
"$ref": "#/definitions/reportAssertTypeFailure"
},
"reportAssignmentType": {
"$ref": "#/definitions/reportAssignmentType"
},
"reportAttributeAccessIssue": {
"$ref": "#/definitions/reportAttributeAccessIssue"
},
"reportCallIssue": {
"$ref": "#/definitions/reportCallIssue"
},
"reportInconsistentOverload": {
"$ref": "#/definitions/reportInconsistentOverload"
},
"reportIndexIssue": {
"$ref": "#/definitions/reportIndexIssue"
},
"reportInvalidTypeArguments": {
"$ref": "#/definitions/reportInvalidTypeArguments"
},
"reportNoOverloadImplementation": {
"$ref": "#/definitions/reportNoOverloadImplementation"
},
"reportOperatorIssue": {
"$ref": "#/definitions/reportOperatorIssue"
},
"reportOptionalSubscript": {
"$ref": "#/definitions/reportOptionalSubscript"
},
"reportOptionalMemberAccess": {
"$ref": "#/definitions/reportOptionalMemberAccess"
},
"reportOptionalCall": {
"$ref": "#/definitions/reportOptionalCall"
},
"reportOptionalIterable": {
"$ref": "#/definitions/reportOptionalIterable"
},
"reportOptionalContextManager": {
"$ref": "#/definitions/reportOptionalContextManager"
},
"reportOptionalOperand": {
"$ref": "#/definitions/reportOptionalOperand"
},
"reportRedeclaration": {
"$ref": "#/definitions/reportRedeclaration"
},
"reportReturnType": {
"$ref": "#/definitions/reportReturnType"
},
"reportTypedDictNotRequiredAccess": {
"$ref": "#/definitions/reportTypedDictNotRequiredAccess"
},
"reportUntypedFunctionDecorator": {
"$ref": "#/definitions/reportUntypedFunctionDecorator"
},
"reportUntypedClassDecorator": {
"$ref": "#/definitions/reportUntypedClassDecorator"
},
"reportUntypedBaseClass": {
"$ref": "#/definitions/reportUntypedBaseClass"
},
"reportUntypedNamedTuple": {
"$ref": "#/definitions/reportUntypedNamedTuple"
},
"reportPrivateUsage": {
"$ref": "#/definitions/reportPrivateUsage"
},
"reportTypeCommentUsage": {
"$ref": "#/definitions/reportTypeCommentUsage"
},
"reportPrivateImportUsage": {
"$ref": "#/definitions/reportPrivateImportUsage"
},
"reportConstantRedefinition": {
"$ref": "#/definitions/reportConstantRedefinition"
},
"reportDeprecated": {
"$ref": "#/definitions/reportDeprecated"
},
"reportIncompatibleMethodOverride": {
"$ref": "#/definitions/reportIncompatibleMethodOverride"
},
"reportIncompatibleVariableOverride": {
"$ref": "#/definitions/reportIncompatibleVariableOverride"
},
"reportInconsistentConstructor": {
"$ref": "#/definitions/reportInconsistentConstructor"
},
"reportOverlappingOverload": {
"$ref": "#/definitions/reportOverlappingOverload"
},
"reportPossiblyUnboundVariable": {
"$ref": "#/definitions/reportPossiblyUnboundVariable"
},
"reportMissingSuperCall": {
"$ref": "#/definitions/reportMissingSuperCall"
},
"reportUninitializedInstanceVariable": {
"$ref": "#/definitions/reportUninitializedInstanceVariable"
},
"reportInvalidStringEscapeSequence": {
"$ref": "#/definitions/reportInvalidStringEscapeSequence"
},
"reportUnknownParameterType": {
"$ref": "#/definitions/reportUnknownParameterType"
},
"reportUnknownArgumentType": {
"$ref": "#/definitions/reportUnknownArgumentType"
},
"reportUnknownLambdaType": {
"$ref": "#/definitions/reportUnknownLambdaType"
},
"reportUnknownVariableType": {
"$ref": "#/definitions/reportUnknownVariableType"
},
"reportUnknownMemberType": {
"$ref": "#/definitions/reportUnknownMemberType"
},
"reportMissingParameterType": {
"$ref": "#/definitions/reportMissingParameterType"
},
"reportMissingTypeArgument": {
"$ref": "#/definitions/reportMissingTypeArgument"
},
"reportInvalidTypeVarUse": {
"$ref": "#/definitions/reportInvalidTypeVarUse"
},
"reportCallInDefaultInitializer": {
"$ref": "#/definitions/reportCallInDefaultInitializer"
},
"reportUnnecessaryIsInstance": {
"$ref": "#/definitions/reportUnnecessaryIsInstance"
},
"reportUnnecessaryCast": {
"$ref": "#/definitions/reportUnnecessaryCast"
},
"reportUnnecessaryComparison": {
"$ref": "#/definitions/reportUnnecessaryComparison"
},
"reportUnnecessaryContains": {
"$ref": "#/definitions/reportUnnecessaryContains"
},
"reportAssertAlwaysTrue": {
"$ref": "#/definitions/reportAssertAlwaysTrue"
},
"reportSelfClsParameterName": {
"$ref": "#/definitions/reportSelfClsParameterName"
},
"reportImplicitStringConcatenation": {
"$ref": "#/definitions/reportImplicitStringConcatenation"
},
"reportUnboundVariable": {
"$ref": "#/definitions/reportUnboundVariable"
},
"reportUnhashable": {
"$ref": "#/definitions/reportUnhashable"
},
"reportUndefinedVariable": {
"$ref": "#/definitions/reportUndefinedVariable"
},
"reportInvalidStubStatement": {
"$ref": "#/definitions/reportInvalidStubStatement"
},
"reportIncompleteStub": {
"$ref": "#/definitions/reportIncompleteStub"
},
"reportUnsupportedDunderAll": {
"$ref": "#/definitions/reportUnsupportedDunderAll"
},
"reportUnusedCallResult": {
"$ref": "#/definitions/reportUnusedCallResult"
},
"reportUnusedCoroutine": {
"$ref": "#/definitions/reportUnusedCoroutine"
},
"reportUnusedExcept": {
"$ref": "#/definitions/reportUnusedExcept"
},
"reportUnusedExpression": {
"$ref": "#/definitions/reportUnusedExpression"
},
"reportUnnecessaryTypeIgnoreComment": {
"$ref": "#/definitions/reportUnnecessaryTypeIgnoreComment"
},
"reportMatchNotExhaustive": {
"$ref": "#/definitions/reportMatchNotExhaustive"
},
"reportShadowedImports": {
"$ref": "#/definitions/reportShadowedImports"
},
"reportImplicitOverride": {
"$ref": "#/definitions/reportImplicitOverride"
},
"extraPaths": {
"$ref": "#/definitions/extraPaths"
},