Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to 2.0.4 #20

Merged
merged 39 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1825809
Added check for improper use of a type alias defined using the `type`…
erictraut Aug 7, 2023
f5af5bb
Fixed bug that led to a false positive error in certain cases when us…
erictraut Aug 8, 2023
889e8c9
Added internal propagation of constructorTypeVarScopeId for ParamSpec…
msfterictraut Aug 8, 2023
eb9702d
Fixed a bug that led to incorrect type narrowing on assignment in cer…
erictraut Aug 8, 2023
4b088a8
Published 1.1.321
msfterictraut Aug 9, 2023
444f331
Fixed recent regression that led to a false positive when assigning a…
erictraut Aug 9, 2023
634c807
pull-pylance-with-pyright-1.1.321 (#5676)
PylanceBot Aug 9, 2023
fb78629
Fixed a bug that led to a spurious "Unknown" type when an assignment …
msfterictraut Aug 10, 2023
ef30049
Fixed false positive error when an empty tuple was used in an `except…
msfterictraut Aug 11, 2023
7d68470
Published 1.1.322
msfterictraut Aug 11, 2023
bf47498
Fixed a condition in the code flow engine that corrupted internal sta…
erictraut Aug 11, 2023
91f5d40
Fixed bug that resulted in incorrect type evaluation for an async fun…
msfterictraut Aug 12, 2023
8166344
Support zip imports from `.jar` files (#5644)
debonte Aug 12, 2023
792dc97
Fixed bug that led to false negative when assignment expression (walr…
msfterictraut Aug 12, 2023
a0225ed
Fixed a bug that resulted in incorrect type evaluation (and a false p…
erictraut Aug 13, 2023
eefc0f4
Improved error reporting for a couple of diagnostic checks by using t…
msfterictraut Aug 13, 2023
393be11
Merge branch 'main' of https://github.com/microsoft/pyright into main
msfterictraut Aug 13, 2023
2260cce
Updated typeshed to the latest. This update includes some changes to …
msfterictraut Aug 15, 2023
5f5ade4
Revert "Reverted the change for #5446 because it's causing false posi…
erictraut Aug 15, 2023
85483be
Fixed a bug that resulted in a false positive `reportUnnecessaryCompa…
msfterictraut Aug 15, 2023
e1cade2
Added special-case handling of enum fields that are callables, which …
msfterictraut Aug 15, 2023
9d21b77
Added check to enforce a generator's "send type" in a `yield from` st…
erictraut Aug 15, 2023
968187f
Added special-case logic for fields with the name `__hash__` within a…
erictraut Aug 15, 2023
a324a05
Fixed import ordering. No functional change.
msfterictraut Aug 15, 2023
a8bc692
Added support for `...` in the last type argument of `Concatenate`. A…
msfterictraut Aug 15, 2023
99825fb
Tweaked some error messages to improve consistency.
msfterictraut Aug 15, 2023
215fc47
Fixed a bug that led to a false negative when assigning a dictionary …
msfterictraut Aug 15, 2023
7fcf314
Fixed a bug that led to a false negative when a TypeVar was used inap…
erictraut Aug 15, 2023
15588f9
Fixed bug in protocol matching that led to an incorrect protocol matc…
msfterictraut Aug 15, 2023
c552947
Added type compatibility enforcement for symbols imported via a wildc…
erictraut Aug 15, 2023
682961d
Added support for indexing into tuples of indeterminate length as lon…
erictraut Aug 15, 2023
97e432a
Fixed type narrowing bug that affected the `A is B` type narrowing pa…
msfterictraut Aug 15, 2023
88c3b75
Fixed false positive where an inner function within a method uses a T…
msfterictraut Aug 15, 2023
50a930a
Fixed a bug that led to a false positive when accessing a `cached_pro…
msfterictraut Aug 15, 2023
32ef0a2
Fixed a bug in import resolver that caused a site-packages module to …
msfterictraut Aug 16, 2023
e728500
Fixed bug that led to a false positive when a two-argument form of a …
msfterictraut Aug 16, 2023
8b83caa
Published 1.1.323
msfterictraut Aug 16, 2023
03f79a8
pull-pylance-with-pyright-1.1.323 (#5736)
PylanceBot Aug 16, 2023
9ae3587
update to 2.0.4 (upstream 1.1.323)
jackyzha0 Aug 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "1.1.320",
"version": "1.1.323",
"command": {
"version": {
"push": false,
Expand Down
4 changes: 2 additions & 2 deletions packages/pyright-internal/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/pyright-internal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "pyright-internal",
"displayName": "pyright",
"description": "Type checker for the Python language",
"version": "1.1.320",
"version": "1.1.323",
"license": "MIT",
"private": true,
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import { CancellationToken } from 'vscode-languageserver';

import { BackgroundAnalysisBase } from '../backgroundAnalysisBase';
import { ConfigOptions, ExecutionEnvironment } from '../common/configOptions';
import { ConsoleInterface } from '../common/console';
import { Diagnostic } from '../common/diagnostic';
import { FileDiagnostics } from '../common/diagnosticSink';
import { Range } from '../common/textRange';
import { AnalysisCompleteCallback, analyzeProgram } from './analysis';
import { CacheManager } from './cacheManager';
import { ImportResolver } from './importResolver';
import { MaxAnalysisTime, OpenFileOptions, Program, ISourceFileFactory } from './program';
import { MaxAnalysisTime, OpenFileOptions, Program } from './program';
import { ServiceProvider } from '../common/serviceProvider';
import '../common/serviceProviderExtensions';

export enum InvalidatedReason {
Reanalyzed,
Expand All @@ -35,21 +36,19 @@ export class BackgroundAnalysisProgram {

constructor(
protected readonly serviceId: string,
private readonly _console: ConsoleInterface,
private readonly _serviceProvider: ServiceProvider,
private _configOptions: ConfigOptions,
private _importResolver: ImportResolver,
private _backgroundAnalysis?: BackgroundAnalysisBase,
private readonly _maxAnalysisTime?: MaxAnalysisTime,
private readonly _disableChecker?: boolean,
cacheManager?: CacheManager,
sourceFileFactory?: ISourceFileFactory
cacheManager?: CacheManager
) {
this._program = new Program(
this.importResolver,
this.configOptions,
this._console,
this._serviceProvider,
undefined,
sourceFileFactory,
this._disableChecker,
cacheManager,
serviceId
Expand Down Expand Up @@ -162,7 +161,7 @@ export class BackgroundAnalysisProgram {
this._maxAnalysisTime,
this._configOptions,
this._onAnalysisCompletion,
this._console,
this._serviceProvider.console(),
token
);
}
Expand Down Expand Up @@ -198,7 +197,7 @@ export class BackgroundAnalysisProgram {
/* maxTime */ undefined,
this._configOptions,
this._onAnalysisCompletion,
this._console,
this._serviceProvider.console(),
token
);
return this._program.writeTypeStub(targetImportPath, targetIsSingleFile, stubPath, token);
Expand Down Expand Up @@ -273,7 +272,7 @@ export class BackgroundAnalysisProgram {

export type BackgroundAnalysisProgramFactory = (
serviceId: string,
console: ConsoleInterface,
serviceProvider: ServiceProvider,
configOptions: ConfigOptions,
importResolver: ImportResolver,
backgroundAnalysis?: BackgroundAnalysisBase,
Expand Down
23 changes: 16 additions & 7 deletions packages/pyright-internal/src/analyzer/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import { OperatorType, StringTokenFlags, TokenType } from '../parser/tokenizerTy
import { AnalyzerFileInfo } from './analyzerFileInfo';
import * as AnalyzerNodeInfo from './analyzerNodeInfo';
import { Declaration, DeclarationType, isAliasDeclaration } from './declaration';
import { getNameNodeForDeclaration } from './declarationUtils';
import { ImportResolver, ImportedModuleDescriptor, createImportedModuleDescriptor } from './importResolver';
import { ImportResult, ImportType } from './importResult';
import { getRelativeModuleName, getTopLevelImports } from './importStatementUtils';
Expand Down Expand Up @@ -578,13 +579,15 @@ export class Checker extends ParseTreeWalker {
this.walk(param.typeAnnotationComment);
}

// Look for method parameters that are typed with TypeVars that have the wrong variance.
if (functionTypeResult) {
const annotationNode = param.typeAnnotation || param.typeAnnotationComment;
if (annotationNode && index < functionTypeResult.functionType.details.parameters.length) {
const paramType = functionTypeResult.functionType.details.parameters[index].type;
const exemptMethods = ['__init__', '__new__'];

if (
containingClassNode &&
isTypeVar(paramType) &&
paramType.details.declaredVariance === Variance.Covariant &&
!paramType.details.isSynthesized &&
Expand Down Expand Up @@ -1039,6 +1042,7 @@ export class Checker extends ParseTreeWalker {
override visitYieldFrom(node: YieldFromNode) {
const yieldFromType = this._evaluator.getType(node.expression) || UnknownType.create();
let yieldType: Type | undefined;
let sendType: Type | undefined;

if (isClassInstance(yieldFromType) && ClassType.isBuiltIn(yieldFromType, 'Coroutine')) {
// Handle the case of old-style (pre-await) coroutines.
Expand All @@ -1054,14 +1058,15 @@ export class Checker extends ParseTreeWalker {
const generatorTypeArgs = getGeneratorTypeArgs(yieldType);
if (generatorTypeArgs) {
yieldType = generatorTypeArgs.length >= 1 ? generatorTypeArgs[0] : UnknownType.create();
sendType = generatorTypeArgs.length >= 2 ? generatorTypeArgs[1] : undefined;
} else {
yieldType =
this._evaluator.getTypeOfIterator({ type: yieldFromType }, /* isAsync */ false, node)?.type ??
UnknownType.create();
}
}

this._validateYieldType(node, yieldType);
this._validateYieldType(node, yieldType, sendType);

return true;
}
Expand Down Expand Up @@ -1492,11 +1497,14 @@ export class Checker extends ParseTreeWalker {
}

this._conditionallyReportShadowedImport(node);

if (!node.isWildcardImport) {
node.imports.forEach((importAs) => {
this._evaluator.evaluateTypesForStatement(importAs);
});
} else {
this._evaluator.evaluateTypesForStatement(node);

const importInfo = AnalyzerNodeInfo.getImportInfo(node.module);
if (
importInfo &&
Expand Down Expand Up @@ -2714,7 +2722,7 @@ export class Checker extends ParseTreeWalker {
UnknownType.create();

resultingExceptionType = mapSubtypes(iterableType, (subtype) => {
if (isAnyOrUnknown(subtype)) {
if (isAnyOrUnknown(subtype) || isNever(subtype)) {
return subtype;
}

Expand Down Expand Up @@ -5778,7 +5786,7 @@ export class Checker extends ParseTreeWalker {
name: memberName,
className: baseClassAndSymbol.classType.details.name,
}) + diagAddendum.getString(),
lastDecl.node
getNameNodeForDeclaration(lastDecl) ?? lastDecl.node
);

const origDecl = getLastTypedDeclaredForSymbol(baseClassAndSymbol.symbol);
Expand Down Expand Up @@ -5849,7 +5857,7 @@ export class Checker extends ParseTreeWalker {
name: memberName,
className: baseClassAndSymbol.classType.details.name,
}),
lastDecl.node
getNameNodeForDeclaration(lastDecl) ?? lastDecl.node
);

const origDecl = getLastTypedDeclaredForSymbol(baseClassAndSymbol.symbol);
Expand Down Expand Up @@ -6176,7 +6184,7 @@ export class Checker extends ParseTreeWalker {

// Determines whether a yield or yield from node is compatible with the
// return type annotation of the containing function.
private _validateYieldType(node: YieldNode | YieldFromNode, yieldType: Type) {
private _validateYieldType(node: YieldNode | YieldFromNode, yieldType: Type, sendType?: Type) {
const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node);
if (!enclosingFunctionNode || !enclosingFunctionNode.returnTypeAnnotation) {
return;
Expand Down Expand Up @@ -6226,8 +6234,9 @@ export class Checker extends ParseTreeWalker {
return;
}

const generatorTypeArgs = [yieldType, sendType ?? UnknownType.create(), UnknownType.create()];
const specializedGenerator = ClassType.cloneAsInstance(
ClassType.cloneForSpecialization(generatorType, [yieldType], /* isTypeArgumentExplicit */ true)
ClassType.cloneForSpecialization(generatorType, generatorTypeArgs, /* isTypeArgumentExplicit */ true)
);

const diagAddendum = new DiagnosticAddendum();
Expand Down Expand Up @@ -6319,7 +6328,7 @@ export class Checker extends ParseTreeWalker {
});

// Were all of the exception types overridden?
if (typesOfThisExcept.length === overriddenExceptionCount) {
if (typesOfThisExcept.length > 0 && typesOfThisExcept.length === overriddenExceptionCount) {
this._evaluator.addDiagnostic(
this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues,
DiagnosticRule.reportGeneralTypeIssues,
Expand Down
10 changes: 5 additions & 5 deletions packages/pyright-internal/src/analyzer/codeFlowEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export function getCodeFlowEngine(
'setIncompleteSubtype can be called only on a valid incomplete cache entry: ' +
`prev cache entry?: ${!cachedEntry} ` +
`index=${index} ` +
`isPending=${isPending}` +
`isPending=${isPending} ` +
`evaluationCount=${evaluationCount}`
);
}
Expand Down Expand Up @@ -956,16 +956,16 @@ export function getCodeFlowEngine(
? UnknownType.create(/* isIncomplete */ true)
: NeverType.createNever()),
flowTypeResult.isIncomplete,
/* isPending */ false,
/* isPending */ firstAntecedentTypeIsPending,
entryEvaluationCount + 1
);
} catch (e) {
setIncompleteSubtype(
cacheEntry = setIncompleteSubtype(
loopNode,
index,
UnknownType.create(/* isIncomplete */ true),
/* isIncomplete */ true,
/* isPending */ false,
/* isPending */ firstAntecedentTypeIsPending,
entryEvaluationCount + 1
);
throw e;
Expand Down Expand Up @@ -1452,7 +1452,7 @@ export function getCodeFlowEngine(
let subtypeCount = 0;

// Evaluate the call base type.
const callTypeResult = evaluator.getTypeOfExpression(node.leftExpression, EvaluatorFlags.DoNotSpecialize);
const callTypeResult = evaluator.getTypeOfExpression(node.leftExpression, EvaluatorFlags.CallBaseDefaults);
const callType = callTypeResult.type;

doForEachSubtype(callType, (callSubtype) => {
Expand Down
73 changes: 48 additions & 25 deletions packages/pyright-internal/src/analyzer/constraintSolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ export function assignTypeToTypeVar(
)
) {
if (!typeVarContext.isLocked() && isTypeVarInScope) {
typeVarContext.setTypeVarType(destType, constrainedType);
updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound);
}
} else {
diag?.addMessage(
Expand All @@ -380,7 +380,7 @@ export function assignTypeToTypeVar(
} else {
// Assign the type to the type var.
if (!typeVarContext.isLocked() && isTypeVarInScope) {
typeVarContext.setTypeVarType(destType, constrainedType);
updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound);
}
}

Expand Down Expand Up @@ -708,29 +708,49 @@ export function assignTypeToTypeVar(
}

if (!typeVarContext.isLocked() && isTypeVarInScope) {
let newNarrowTypeBoundNoLiterals: Type | undefined;
updateTypeVarType(
evaluator,
typeVarContext,
destType,
newNarrowTypeBound,
newWideTypeBound,
(flags & (AssignTypeFlags.PopulatingExpectedType | AssignTypeFlags.RetainLiteralsForTypeVar)) !== 0
);
}

if (
newNarrowTypeBound &&
(flags & (AssignTypeFlags.PopulatingExpectedType | AssignTypeFlags.RetainLiteralsForTypeVar)) === 0
) {
const strippedLiteral = isVariadicTypeVar(destType)
? stripLiteralValueForUnpackedTuple(evaluator, newNarrowTypeBound)
: evaluator.stripLiteralValue(newNarrowTypeBound);

// Strip the literals from the narrow type bound and see if it is still
// narrower than the wide bound.
if (strippedLiteral !== newNarrowTypeBound) {
if (!newWideTypeBound || evaluator.assignType(newWideTypeBound, strippedLiteral)) {
newNarrowTypeBoundNoLiterals = strippedLiteral;
}
return true;
}

// Updates the narrow and wide type bounds for a type variable. It also calculates the
// narrowTypeBoundNoLiterals, which is a variant of the narrow type bound that has
// literals stripped. By default, the constraint solver always uses the "no literals"
// type in its solutions unless the version with literals is required to satisfy
// the wide type bound.
export function updateTypeVarType(
evaluator: TypeEvaluator,
typeVarContext: TypeVarContext,
destType: TypeVarType,
narrowTypeBound: Type | undefined,
wideTypeBound: Type | undefined,
forceRetainLiterals = false
) {
let narrowTypeBoundNoLiterals: Type | undefined;

if (narrowTypeBound && !forceRetainLiterals) {
const strippedLiteral = isVariadicTypeVar(destType)
? stripLiteralValueForUnpackedTuple(evaluator, narrowTypeBound)
: evaluator.stripLiteralValue(narrowTypeBound);

// Strip the literals from the narrow type bound and see if it is still
// narrower than the wide bound.
if (strippedLiteral !== narrowTypeBound) {
if (!wideTypeBound || evaluator.assignType(wideTypeBound, strippedLiteral)) {
narrowTypeBoundNoLiterals = strippedLiteral;
}
}

typeVarContext.setTypeVarType(destType, newNarrowTypeBound, newNarrowTypeBoundNoLiterals, newWideTypeBound);
}

return true;
typeVarContext.setTypeVarType(destType, narrowTypeBound, narrowTypeBoundNoLiterals, wideTypeBound);
}

function assignTypeToParamSpec(
Expand Down Expand Up @@ -806,6 +826,7 @@ function assignTypeToParamSpec(
FunctionType.addParameter(newFunction, param);
});
newFunction.details.typeVarScopeId = srcType.details.typeVarScopeId;
newFunction.details.constructorTypeVarScopeId = srcType.details.constructorTypeVarScopeId;
newFunction.details.paramSpecTypeVarScopeId = srcType.details.paramSpecTypeVarScopeId;
newFunction.details.docString = srcType.details.docString;
newFunction.details.paramSpec = srcType.details.paramSpec;
Expand Down Expand Up @@ -846,7 +867,7 @@ export function populateTypeVarContextBasedOnExpectedType(
): boolean {
if (isAny(expectedType)) {
type.details.typeParameters.forEach((typeParam) => {
typeVarContext.setTypeVarType(typeParam, expectedType);
updateTypeVarType(evaluator, typeVarContext, typeParam, expectedType, expectedType);
});
return true;
}
Expand Down Expand Up @@ -891,10 +912,11 @@ export function populateTypeVarContextBasedOnExpectedType(
if (typeArgValue) {
const variance = TypeVarType.getVariance(entry.typeVar);

typeVarContext.setTypeVarType(
updateTypeVarType(
evaluator,
typeVarContext,
entry.typeVar,
variance === Variance.Covariant ? undefined : typeArgValue,
/* narrowBoundNoLiterals */ undefined,
variance === Variance.Contravariant ? undefined : typeArgValue
);

Expand Down Expand Up @@ -1016,10 +1038,11 @@ export function populateTypeVarContextBasedOnExpectedType(
typeArgValue = UnknownType.create();
}

typeVarContext.setTypeVarType(
updateTypeVarType(
evaluator,
typeVarContext,
targetTypeVar,
variance === Variance.Covariant ? undefined : typeArgValue,
/* narrowBoundNoLiterals */ undefined,
variance === Variance.Contravariant ? undefined : typeArgValue
);
} else {
Expand Down
Loading
Loading