mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Added support for python.analysis.include
, `python.analysis.exclude… (#6251)
* Added support for `python.analysis.include`, `python.analysis.exclude` and `python.analysis.ignore` settings. These have been implemented in pylance for a while now, but they were never implemented previously in pyright. Also fixed a bug in the original implementation that caused the config file not to override the language server settings for `python.analysis.exclude` and `python.analysis.ignore` as it should. This addresses #6250. * Removed references to pylance in the help text.
This commit is contained in:
parent
05fa7d06c0
commit
08a295a261
@ -18,8 +18,14 @@ The Pyright language server honors the following settings.
|
||||
|
||||
**python.analysis.diagnosticSeverityOverrides** [map]: Allows a user to override the severity levels for individual diagnostic rules. "reportXXX" rules in the type check diagnostics settings in [configuration](configuration.md#type-check-diagnostics-settings) are supported. Use the rule name as a key and one of "error," "warning," "information," "true," "false," or "none" as value.
|
||||
|
||||
**python.analysis.exclude** [array of paths]: Paths of directories or files that should not be included. This can be overridden in the configuration file.
|
||||
|
||||
**python.analysis.extraPaths** [array of paths]: Paths to add to the default execution environment extra paths if there are no execution environments defined in the config file.
|
||||
|
||||
**python.analysis.ignore** [array of paths]: Paths of directories or files whose diagnostic output (errors and warnings) should be suppressed. This can be overridden in the configuration file.
|
||||
|
||||
**python.analysis.include** [array of paths]: Paths of directories or files that should be included. This can be overridden in the configuration file.
|
||||
|
||||
**python.analysis.logLevel** ["Error", "Warning", "Information", or "Trace"]: Level of logging for Output panel. The default value for this option is "Information".
|
||||
|
||||
**python.analysis.stubPath** [path]: Path to directory containing custom type stub files.
|
||||
|
@ -677,8 +677,7 @@ export class AnalyzerService {
|
||||
this._typeCheckingMode,
|
||||
this.serviceProvider,
|
||||
host,
|
||||
commandLineOptions.diagnosticSeverityOverrides,
|
||||
commandLineOptions.fileSpecs.length > 0
|
||||
commandLineOptions.diagnosticSeverityOverrides
|
||||
);
|
||||
|
||||
const configFileDir = getDirectoryPath(this._configFilePath!);
|
||||
|
@ -19,16 +19,16 @@ import { DiagnosticRule } from './diagnosticRules';
|
||||
import { FileSystem } from './fileSystem';
|
||||
import { Host } from './host';
|
||||
import {
|
||||
FileSpec,
|
||||
combinePaths,
|
||||
ensureTrailingDirectorySeparator,
|
||||
FileSpec,
|
||||
getFileSpec,
|
||||
isDirectory,
|
||||
normalizePath,
|
||||
realCasePath,
|
||||
resolvePaths,
|
||||
} from './pathUtils';
|
||||
import { latestStablePythonVersion, PythonVersion, versionFromString, versionToString } from './pythonVersion';
|
||||
import { PythonVersion, latestStablePythonVersion, versionFromString, versionToString } from './pythonVersion';
|
||||
import { ServiceProvider } from './serviceProvider';
|
||||
import { ServiceKeys } from './serviceProviderExtensions';
|
||||
|
||||
@ -890,39 +890,36 @@ export class ConfigOptions {
|
||||
typeCheckingMode: string | undefined,
|
||||
serviceProvider: ServiceProvider,
|
||||
host: Host,
|
||||
diagnosticOverrides?: DiagnosticSeverityOverridesMap,
|
||||
skipIncludeSection = false
|
||||
diagnosticOverrides?: DiagnosticSeverityOverridesMap
|
||||
) {
|
||||
this.initializedFromJson = true;
|
||||
const console = serviceProvider.tryGet(ServiceKeys.console) ?? new NullConsole();
|
||||
|
||||
// Read the "include" entry.
|
||||
if (!skipIncludeSection) {
|
||||
this.include = [];
|
||||
if (configObj.include !== undefined) {
|
||||
if (!Array.isArray(configObj.include)) {
|
||||
console.error(`Config "include" entry must must contain an array.`);
|
||||
} else {
|
||||
const filesList = configObj.include as string[];
|
||||
filesList.forEach((fileSpec, index) => {
|
||||
if (typeof fileSpec !== 'string') {
|
||||
console.error(`Index ${index} of "include" array should be a string.`);
|
||||
} else if (isAbsolute(fileSpec)) {
|
||||
console.error(`Ignoring path "${fileSpec}" in "include" array because it is not relative.`);
|
||||
} else {
|
||||
this.include.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (configObj.include !== undefined) {
|
||||
if (!Array.isArray(configObj.include)) {
|
||||
console.error(`Config "include" entry must must contain an array.`);
|
||||
} else {
|
||||
this.include = [];
|
||||
const filesList = configObj.include as string[];
|
||||
filesList.forEach((fileSpec, index) => {
|
||||
if (typeof fileSpec !== 'string') {
|
||||
console.error(`Index ${index} of "include" array should be a string.`);
|
||||
} else if (isAbsolute(fileSpec)) {
|
||||
console.error(`Ignoring path "${fileSpec}" in "include" array because it is not relative.`);
|
||||
} else {
|
||||
this.include.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Read the "exclude" entry.
|
||||
this.exclude = [];
|
||||
if (configObj.exclude !== undefined) {
|
||||
if (!Array.isArray(configObj.exclude)) {
|
||||
console.error(`Config "exclude" entry must contain an array.`);
|
||||
} else {
|
||||
this.exclude = [];
|
||||
const filesList = configObj.exclude as string[];
|
||||
filesList.forEach((fileSpec, index) => {
|
||||
if (typeof fileSpec !== 'string') {
|
||||
@ -937,11 +934,11 @@ export class ConfigOptions {
|
||||
}
|
||||
|
||||
// Read the "ignore" entry.
|
||||
this.ignore = [];
|
||||
if (configObj.ignore !== undefined) {
|
||||
if (!Array.isArray(configObj.ignore)) {
|
||||
console.error(`Config "ignore" entry must contain an array.`);
|
||||
} else {
|
||||
this.ignore = [];
|
||||
const filesList = configObj.ignore as string[];
|
||||
filesList.forEach((fileSpec, index) => {
|
||||
if (typeof fileSpec !== 'string') {
|
||||
@ -956,11 +953,11 @@ export class ConfigOptions {
|
||||
}
|
||||
|
||||
// Read the "strict" entry.
|
||||
this.strict = [];
|
||||
if (configObj.strict !== undefined) {
|
||||
if (!Array.isArray(configObj.strict)) {
|
||||
console.error(`Config "strict" entry must contain an array.`);
|
||||
} else {
|
||||
this.strict = [];
|
||||
const filesList = configObj.strict as string[];
|
||||
filesList.forEach((fileSpec, index) => {
|
||||
if (typeof fileSpec !== 'string') {
|
||||
|
@ -1474,7 +1474,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis
|
||||
});
|
||||
}
|
||||
|
||||
// File watcher is pylance wide service. Dispose all existing file watchers and create new ones.
|
||||
// Dispose all existing file watchers and create new ones.
|
||||
this.connection.client.register(DidChangeWatchedFilesNotification.type, { watchers }).then((d) => {
|
||||
if (this._lastFileWatcherRegistration) {
|
||||
this._lastFileWatcherRegistration.dispose();
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { AnalysisResults } from './analyzer/analysis';
|
||||
import { CacheManager } from './analyzer/cacheManager';
|
||||
import { ImportResolver } from './analyzer/importResolver';
|
||||
import { isPythonBinary } from './analyzer/pythonPathUtils';
|
||||
import { BackgroundAnalysis } from './backgroundAnalysis';
|
||||
@ -38,7 +39,6 @@ import { LanguageServerBase, ServerSettings } from './languageServerBase';
|
||||
import { CodeActionProvider } from './languageService/codeActionProvider';
|
||||
import { PyrightFileSystem } from './pyrightFileSystem';
|
||||
import { Workspace } from './workspaceFactory';
|
||||
import { CacheManager } from './analyzer/cacheManager';
|
||||
|
||||
const maxAnalysisTimeInForeground = { openFilesTimeInMs: 50, noOpenFilesTimeInMs: 200 };
|
||||
|
||||
@ -170,6 +170,10 @@ export class PyrightServer extends LanguageServerBase {
|
||||
.map((p) => resolvePaths(workspace.rootPath, expandPathVariables(workspace.rootPath, p)));
|
||||
}
|
||||
|
||||
serverSettings.fileSpecs = this._getStringValues(pythonAnalysisSection.include);
|
||||
serverSettings.excludeFileSpecs = this._getStringValues(pythonAnalysisSection.exclude);
|
||||
serverSettings.ignoreFileSpecs = this._getStringValues(pythonAnalysisSection.ignore);
|
||||
|
||||
if (pythonAnalysisSection.typeCheckingMode !== undefined) {
|
||||
serverSettings.typeCheckingMode = pythonAnalysisSection.typeCheckingMode;
|
||||
}
|
||||
@ -313,4 +317,12 @@ export class PyrightServer extends LanguageServerBase {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private _getStringValues(values: any) {
|
||||
if (!values || !Array.isArray(values) || values.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return values.filter((p) => p && isString(p)) as string[];
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +159,33 @@
|
||||
],
|
||||
"scope": "resource"
|
||||
},
|
||||
"python.analysis.include": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Paths of directories or files that should be included. If no paths are specified, pyright defaults to the workspace root directory. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character).",
|
||||
"scope": "resource"
|
||||
},
|
||||
"python.analysis.exclude": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Paths of directories or files that should not be included. These override the include directories, allowing specific subdirectories to be excluded. Note that files in the exclude paths may still be included in the analysis if they are referenced (imported) by source files that are not excluded. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no exclude paths are specified, pyright automatically excludes the following: `**/node_modules`, `**/__pycache__`, `.git` and any virtual environment directories.",
|
||||
"scope": "resource"
|
||||
},
|
||||
"python.analysis.ignore": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Paths of directories or files whose diagnostic output (errors and warnings) should be suppressed even if they are an included file or within the transitive closure of an included file. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no value is provided, the value of python.linting.ignorePatterns (if set) will be used.",
|
||||
"scope": "resource"
|
||||
},
|
||||
"python.analysis.diagnosticSeverityOverrides": {
|
||||
"type": "object",
|
||||
"description": "Allows a user to override the severity levels for individual diagnostics.",
|
||||
|
Loading…
Reference in New Issue
Block a user