If the pythonPlatform or pythonVersion are not specified, they are now initialized based on the current platform and configured python interpreter.

This commit is contained in:
Eric Traut 2020-05-24 22:56:55 -07:00
parent 169fb12ef8
commit 998304dc78
5 changed files with 78 additions and 7 deletions

View File

@ -24,9 +24,9 @@ Relative paths specified within the config file are relative to the config file
**verboseOutput** [boolean]: Specifies whether output logs should be verbose. This is useful when diagnosing certain problems like import resolution issues.
**pythonVersion** [string, optional]: Specifies the version of Python that will be used to execute the source code. The version should be specified as a string in the format "M.m" where M is the major version and m is the minor (e.g. `"3.0"` or `"3.6"`). If a version is provided, pyright will generate errors if the source code makes use of language features that are not supported in that version. It will also tailor its use of type stub files, which conditionalizes type definitions based on the version.
**pythonVersion** [string, optional]: Specifies the version of Python that will be used to execute the source code. The version should be specified as a string in the format "M.m" where M is the major version and m is the minor (e.g. `"3.0"` or `"3.6"`). If a version is provided, pyright will generate errors if the source code makes use of language features that are not supported in that version. It will also tailor its use of type stub files, which conditionalizes type definitions based on the version. If no version is specified, pyright will use the version of the current python interpreter, if one is present.
**pythonPlatform** [string, optional]: Specifies the target platform that will be used to execute the source code. Should be one of `"Windows"`, `"Darwin"` or `"Linux"`. If specified, pyright will tailor its use of type stub files, which conditionalize type definitions based on the platform.
**pythonPlatform** [string, optional]: Specifies the target platform that will be used to execute the source code. Should be one of `"Windows"`, `"Darwin"` or `"Linux"`. If specified, pyright will tailor its use of type stub files, which conditionalize type definitions based on the platform. If no platform is specified, pyright will use the current platform.
**executionEnvironments** [array of objects, optional]: Specifies a list of execution environments (see below). Execution environments are searched from start to finish by comparing the path of a source file with the root path specified in the execution environment.

View File

@ -366,7 +366,8 @@ export class AnalyzerService {
configJsonObj,
this._typeCheckingMode,
this._console,
commandLineOptions.diagnosticSeverityOverrides
commandLineOptions.diagnosticSeverityOverrides,
commandLineOptions.pythonPath
);
const configFileDir = getDirectoryPath(configFilePath);

View File

@ -27,7 +27,10 @@ export function getDiagnosticSeverityOverrides() {
export type DiagnosticSeverityOverridesMap = { [ruleName: string]: DiagnosticSeverityOverrides };
// Some options can be specified by command line.
// Some options can be specified from a source other than the pyright config file.
// This can be from command-line parameters or some other settings mechanism, like
// that provided through a language client like the VS Code editor. These options
// are later combined with those from the config file to produce the final configuration.
export class CommandLineOptions {
constructor(executionRoot: string, fromVsCodeExtension: boolean) {
this.executionRoot = executionRoot;

View File

@ -7,6 +7,7 @@
* Class that holds the configuration options for the analyzer.
*/
import * as child_process from 'child_process';
import { isAbsolute } from 'path';
import * as pathConsts from '../common/pathConsts';
@ -15,7 +16,7 @@ import { ConsoleInterface } from './console';
import { DiagnosticRule } from './diagnosticRules';
import { FileSystem } from './fileSystem';
import { combinePaths, ensureTrailingDirectorySeparator, FileSpec, getFileSpec, normalizePath } from './pathUtils';
import { latestStablePythonVersion, PythonVersion, versionFromString } from './pythonVersion';
import { latestStablePythonVersion, PythonVersion, versionFromString, versionToString } from './pythonVersion';
export class ExecutionEnvironment {
// Default to "." which indicates every file in the project.
@ -556,7 +557,8 @@ export class ConfigOptions {
configObj: any,
typeCheckingMode: string | undefined,
console: ConsoleInterface,
diagnosticOverrides?: DiagnosticSeverityOverridesMap
diagnosticOverrides?: DiagnosticSeverityOverridesMap,
pythonPath?: string
) {
// Read the "include" entry.
this.include = [];
@ -982,6 +984,15 @@ export class ConfigOptions {
}
}
// If no default python version was specified, retrieve the version
// from the currently-selected python interpreter.
if (this.defaultPythonVersion === undefined) {
this.defaultPythonVersion = this._getPythonVersionFromPythonInterpreter(pythonPath, console);
if (this.defaultPythonVersion !== undefined) {
console.log(`Assuming Python version ${versionToString(this.defaultPythonVersion)}`);
}
}
// Read the default "pythonPlatform".
this.defaultPythonPlatform = undefined;
if (configObj.pythonPlatform !== undefined) {
@ -992,6 +1003,22 @@ export class ConfigOptions {
}
}
// If no default python platform was specified, assume that the
// user wants to use the current platform.
if (this.defaultPythonPlatform === undefined) {
if (process.platform === 'darwin') {
this.defaultPythonPlatform = 'Darwin';
} else if (process.platform === 'linux') {
this.defaultPythonPlatform = 'Linux';
} else if (process.platform === 'win32') {
this.defaultPythonPlatform = 'Windows';
}
if (this.defaultPythonPlatform !== undefined) {
console.log(`Assuming Python platform ${this.defaultPythonPlatform}`);
}
}
// Read the "typeshedPath" setting.
this.typeshedPath = undefined;
if (configObj.typeshedPath !== undefined) {
@ -1176,4 +1203,44 @@ export class ConfigOptions {
return undefined;
}
private _getPythonVersionFromPythonInterpreter(
interpreterPath: string | undefined,
console: ConsoleInterface
): PythonVersion | undefined {
try {
const commandLineArgs: string[] = ['--version'];
let execOutput: string;
if (interpreterPath) {
execOutput = child_process.execFileSync(interpreterPath, commandLineArgs, { encoding: 'utf8' });
} else {
execOutput = child_process.execFileSync('python', commandLineArgs, { encoding: 'utf8' });
}
// Parse the execOutput. It should be something like "Python 3.x.y".
const match = execOutput.match(/[0-9]+.[0-9]+.[0-9]+/);
if (!match) {
console.log(`Unable to get Python version from interpreter. Received "${execOutput}"`);
return undefined;
}
const versionString = match[0];
const version = versionFromString(versionString);
if (version === undefined) {
console.log(`Unable to get Python version from interpreter. Received "${execOutput}"`);
return undefined;
}
if (version < PythonVersion.V30) {
console.log(`Python version from interpreter is unsupported: "${execOutput}"`);
return undefined;
}
return version;
} catch {
console.log('Unable to get Python version from interpreter');
return undefined;
}
}
}

View File

@ -39,7 +39,7 @@ export function versionToString(version: PythonVersion): string {
export function versionFromString(verString: string): PythonVersion | undefined {
const split = verString.split('.');
if (split.length !== 2) {
if (split.length < 2) {
return undefined;
}