mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-26 10:55:06 +03:00
Added special-case bidirectional type inference for the right operand of the "|" and "|=" operators (with an expected type based on the left operand). This supports the case where the left operand is a TypedDict and the right operand is a dict expression that conforms to the TypedDict type.
This commit is contained in:
parent
4d00d36513
commit
9ae9cb7a9a
@ -10563,6 +10563,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
// For the "+" operator , use this technique only if the right operand is
|
||||
// a list expression. This heuristic handles the common case of `my_list + [0]`.
|
||||
expectedOperandType = leftType;
|
||||
} else if (node.operator === OperatorType.BitwiseOr) {
|
||||
// If this is a bitwise or ("|"), use the type of the left operand. This allows
|
||||
// us to support the case where a TypedDict is being updated with a dict expression.
|
||||
expectedOperandType = leftType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10732,7 +10736,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
|
||||
const leftTypeResult = getTypeOfExpression(node.leftExpression);
|
||||
const leftType = leftTypeResult.type;
|
||||
const rightTypeResult = getTypeOfExpression(node.rightExpression);
|
||||
|
||||
let expectedOperandType: Type | undefined;
|
||||
if (node.operator === OperatorType.BitwiseOrEqual) {
|
||||
// If this is a bitwise or ("|="), use the type of the left operand. This allows
|
||||
// us to support the case where a TypedDict is being updated with a dict expression.
|
||||
expectedOperandType = leftType;
|
||||
}
|
||||
|
||||
const rightTypeResult = getTypeOfExpression(node.rightExpression, expectedOperandType);
|
||||
const rightType = rightTypeResult.type;
|
||||
const isIncomplete = !!rightTypeResult.isIncomplete || !!leftTypeResult.isIncomplete;
|
||||
|
||||
|
24
packages/pyright-internal/src/tests/samples/typedDict17.py
Normal file
24
packages/pyright-internal/src/tests/samples/typedDict17.py
Normal file
@ -0,0 +1,24 @@
|
||||
# This sample tests the handling of the "|" and "|=" operators
|
||||
# for TypedDicts.
|
||||
|
||||
from typing import TypedDict
|
||||
|
||||
|
||||
class Person(TypedDict, total=False):
|
||||
name: str
|
||||
age: int
|
||||
|
||||
|
||||
person: Person = {}
|
||||
|
||||
person.update({"name": "Michael"})
|
||||
|
||||
person |= {"name": "Michael"}
|
||||
person = person | {"name": "Michael"}
|
||||
|
||||
|
||||
# This should generate an error.
|
||||
person |= {"name": "Michael", "other": 1}
|
||||
|
||||
# This should generate an error.
|
||||
person = person | {"name": 1}
|
@ -1107,3 +1107,9 @@ test('TypedDict16', () => {
|
||||
|
||||
TestUtils.validateResults(analysisResults, 9);
|
||||
});
|
||||
|
||||
test('TypedDict17', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDict17.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 2);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user