Skip to content

Commit

Permalink
Merge pull request microsoft#1161 from jakebailey/pull-pyright-124
Browse files Browse the repository at this point in the history
Sync pyright
  • Loading branch information
jakebailey committed Feb 26, 2021
2 parents 8509808 + a99bbd5 commit 0637345
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 23 deletions.
4 changes: 2 additions & 2 deletions packages/pyright/.gitrepo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/microsoft/pyright.git
branch = master
commit = f5916b7965413f98e2f3ee5fab737112a630c845
parent = 5a713a5aeeba0a6d7581135a1bc7bf13f094e756
commit = 177714b1a6852d9848ee659a82f450b8230303a0
parent = ab6d9f50e697bf169ac53e5ae8b1f82346359607
method = merge
cmdver = 0.4.1
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ export const enum EvaluatorFlags {
// normally not allowed if ExpectingType is set.
GenericClassTypeAllowed = 1 << 9,

// A type annotation restricts the types of expressions that are
// allowed. If this flag is set, illegal type expressions are
// flagged as errors.
ExpectingTypeAnnotation = 1 << 10,

// TypeVars within this expression must not refer to type vars
// used in an outer scope that.
DisallowTypeVarsWithScopeId = 1 << 11,
Expand Down Expand Up @@ -922,7 +927,17 @@ export function createTypeEvaluator(
}

case ParseNodeType.Call: {
typeResult = getTypeFromCall(node, expectedTypeAlt);
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
addDiagnostic(
getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues,
DiagnosticRule.reportGeneralTypeIssues,
Localizer.Diagnostic.typeAnnotationCall(),
node
);
typeResult = { node, type: UnknownType.create() };
} else {
typeResult = getTypeFromCall(node, expectedTypeAlt);
}
break;
}

Expand Down Expand Up @@ -1114,7 +1129,21 @@ export function createTypeEvaluator(
}

case ParseNodeType.Unpack: {
const iterType = getTypeOfExpression(node.expression, expectedTypeAlt, flags).type;
let iterExpectedType: Type | undefined;
if (expectedTypeAlt) {
const iterableType = getBuiltInType(node, 'Iterable');
if (iterableType && isClass(iterableType)) {
iterExpectedType = ObjectType.create(
ClassType.cloneForSpecialization(
iterableType,
[expectedTypeAlt],
/* isTypeArgumentExplicit */ true
)
);
}
}

const iterType = getTypeOfExpression(node.expression, iterExpectedType, flags).type;
if (
(flags & EvaluatorFlags.TypeVarTupleDisallowed) === 0 &&
isVariadicTypeVar(iterType) &&
Expand All @@ -1135,7 +1164,8 @@ export function createTypeEvaluator(
EvaluatorFlags.EvaluateStringLiteralAsType |
EvaluatorFlags.ParamSpecDisallowed |
EvaluatorFlags.TypeVarTupleDisallowed |
EvaluatorFlags.ExpectingType
EvaluatorFlags.ExpectingType |
EvaluatorFlags.ExpectingTypeAnnotation
);
break;
}
Expand Down Expand Up @@ -1217,6 +1247,7 @@ export function createTypeEvaluator(

let evaluatorFlags =
EvaluatorFlags.ExpectingType |
EvaluatorFlags.ExpectingTypeAnnotation |
EvaluatorFlags.ConvertEllipsisToAny |
EvaluatorFlags.EvaluateStringLiteralAsType |
EvaluatorFlags.ParamSpecDisallowed;
Expand Down Expand Up @@ -3048,7 +3079,7 @@ export function createTypeEvaluator(
EvaluatorFlags.DoNotSpecialize
);

const indexTypeResult = getTypeFromIndexWithBaseType(
getTypeFromIndexWithBaseType(
target,
baseTypeResult.type,
{
Expand All @@ -3060,7 +3091,7 @@ export function createTypeEvaluator(
EvaluatorFlags.None
);

writeTypeCache(target, indexTypeResult.type);
writeTypeCache(target, type);
break;
}

Expand Down Expand Up @@ -3751,6 +3782,7 @@ export function createTypeEvaluator(
EvaluatorFlags.DoNotSpecialize |
(flags &
(EvaluatorFlags.ExpectingType |
EvaluatorFlags.ExpectingTypeAnnotation |
EvaluatorFlags.AllowForwardReferences |
EvaluatorFlags.AssociateTypeVarsWithCurrentScope));
const baseTypeResult = getTypeOfExpression(node.leftExpression, undefined, baseTypeFlags);
Expand Down Expand Up @@ -5229,6 +5261,7 @@ export function createTypeEvaluator(
let adjustedFlags =
flags |
EvaluatorFlags.ExpectingType |
EvaluatorFlags.ExpectingTypeAnnotation |
EvaluatorFlags.ConvertEllipsisToAny |
EvaluatorFlags.EvaluateStringLiteralAsType |
EvaluatorFlags.FinalDisallowed;
Expand Down Expand Up @@ -5372,7 +5405,9 @@ export function createTypeEvaluator(
}

function buildTupleTypesList(entryTypeResults: TypeResult[]): Type[] {
let tupleTypes: Type[] = [];
const entryTypes: Type[] = [];
let isOpenEnded = false;

for (const typeResult of entryTypeResults) {
if (typeResult.unpackedType) {
// Is this an unpacked tuple? If so, we can append the individual
Expand All @@ -5384,24 +5419,26 @@ export function createTypeEvaluator(

// If the Tuple wasn't specialized or has a "..." type parameter, we can't
// make any determination about its contents.
if (!typeArgs || typeArgs.some((t) => isEllipsisType(t))) {
tupleTypes = [AnyType.create(/* isEllipsis */ false), AnyType.create(/* isEllipsis */ true)];
break;
}

for (const typeArg of typeArgs) {
tupleTypes.push(typeArg);
if (!typeArgs || isOpenEndedTupleClass(typeResult.unpackedType.classType)) {
entryTypes.push(typeResult.type);
isOpenEnded = true;
} else {
entryTypes.push(...typeArgs);
}
} else {
tupleTypes = [AnyType.create(/* isEllipsis */ false), AnyType.create(/* isEllipsis */ true)];
break;
entryTypes.push(typeResult.type);
isOpenEnded = true;
}
} else {
tupleTypes.push(typeResult.type);
entryTypes.push(typeResult.type);
}
}

return tupleTypes;
if (isOpenEnded) {
return [combineTypes(entryTypes), AnyType.create(/* isEllipsis */ true)];
}

return entryTypes;
}

function updateNamedTupleBaseClass(classType: ClassType, typeArgs: Type[], isTypeArgumentExplicit: boolean) {
Expand Down Expand Up @@ -13916,7 +13953,9 @@ export function createTypeEvaluator(
if (nodeToEvaluate.nodeType === ParseNodeType.TypeAnnotation) {
evaluateTypeAnnotationExpression(nodeToEvaluate);
} else {
getTypeOfExpression(nodeToEvaluate);
const fileInfo = getFileInfo(nodeToEvaluate);
const flags = fileInfo.isStubFile ? EvaluatorFlags.AllowForwardReferences : EvaluatorFlags.None;
getTypeOfExpression(nodeToEvaluate, /* expectedType */ undefined, flags);
}
}

Expand Down Expand Up @@ -16210,7 +16249,8 @@ export function createTypeEvaluator(
}
}
} else {
let allowForwardReferences = false;
const fileInfo = getFileInfo(node);
let allowForwardReferences = fileInfo.isStubFile;

// Determine if this node is within a quoted type annotation.
if (ParseTreeUtils.isWithinTypeAnnotation(node, !isAnnotationEvaluationPostponed(getFileInfo(node)))) {
Expand Down Expand Up @@ -19365,6 +19405,9 @@ export function createTypeEvaluator(
if (result) {
assignedSubtype = ObjectType.create(result);
}
} else if (isAnyOrUnknown(assignedSubtype)) {
// Any or Unknown do not narrow because they're assignable to all types.
return declaredType;
}

return assignedSubtype;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ export namespace Localizer {
export const typeAliasNotInModule = () => getRawString('Diagnostic.typeAliasNotInModule');
export const typeAliasRedeclared = () =>
new ParameterizedString<{ name: string }>(getRawString('Diagnostic.typeAliasRedeclared'));
export const typeAnnotationCall = () => getRawString('Diagnostic.typeAnnotationCall');
export const typeArgListNotAllowed = () => getRawString('Diagnostic.typeArgListNotAllowed');
export const typeArgsExpectingNone = () => getRawString('Diagnostic.typeArgsExpectingNone');
export const typeArgsMismatchOne = () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@
"typeAliasNotInModule": "A TypeAlias can be defined only within a module scope",
"typeAliasRedeclared": "\"{name}\" is declared as a TypeAlias and can be assigned only once",
"typeArgListNotAllowed": "List expression not allowed for this type argument",
"typeAnnotationCall": "Illegal type annotation: call expression not allowed",
"typeArgsExpectingNone": "Expected no type arguments",
"typeArgsMismatchOne": "Expected one type argument but received {received}",
"typeArgsMissingForAlias": "Expected type arguments for generic type alias \"{name}\"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,12 @@ def func5(self) -> "Optional"[int]:

class ClassC:
pass


def func10():
pass

# This should generate an error because function calls
# are not allowed within a type annotation.
x: func10()

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This sample tests type inference for tuples that contain unpack
# operators.

from typing import Literal


def func1(a: int, *args: int):
v1 = (a, *args)
t1: Literal["tuple[int, ...]"] = reveal_type(v1)


def func2(a: int, *args: str):
v1 = (a, *args)
t1: Literal["tuple[int | str, ...]"] = reveal_type(v1)


def func3(a: int, b: str, *args: str):
v1 = (*args, a, *args, b, *(a, b, a))
t1: Literal["tuple[str | int, ...]"] = reveal_type(v1)


def func4():
a = 3.4
b = [1, 2, 3]
v1 = (a, *b)
t1: Literal["tuple[float | int, ...]"] = reveal_type(v1)
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ def func1(v1: List[Optional[complex]]):
t_v1_0_updated1: Literal["None"] = reveal_type(v1[0])
t_v1_1_updated1: Literal["None"] = reveal_type(v1[1])

v1[0], v1[1] = 1, 2
t_v1_0_updated2: Literal["Literal[1]"] = reveal_type(v1[0])
t_v1_1_updated2: Literal["Literal[2]"] = reveal_type(v1[1])

v1 = []
t_v1_0_updated2: Literal["complex | None"] = reveal_type(v1[0])
t_v1_0_updated3: Literal["complex | None"] = reveal_type(v1[0])

i = 1
if v1[i]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ test('Function14', () => {
test('Annotations1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['annotations1.py']);

TestUtils.validateResults(analysisResults, 3);
TestUtils.validateResults(analysisResults, 4);
});

test('Annotations2', () => {
Expand Down Expand Up @@ -834,6 +834,12 @@ test('Tuples11', () => {
TestUtils.validateResults(analysisResults, 1);
});

test('Tuples12', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['tuples12.py']);

TestUtils.validateResults(analysisResults, 0);
});

test('NamedTuples1', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['namedTuples1.py']);

Expand Down

0 comments on commit 0637345

Please sign in to comment.