mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Removed support for inlined TypedDict annotations. This idea never gained enough support to make it into a PEP.
This commit is contained in:
parent
1bc5949959
commit
0e42a7ea56
@ -286,7 +286,6 @@ import {
|
||||
assignToTypedDict,
|
||||
assignTypedDictToTypedDict,
|
||||
createTypedDictType,
|
||||
createTypedDictTypeInlined,
|
||||
getTypeOfIndexedTypedDict,
|
||||
getTypedDictDictEquivalent,
|
||||
getTypedDictMappingEquivalent,
|
||||
@ -352,7 +351,6 @@ interface GetTypeArgsOptions {
|
||||
hasCustomClassGetItem?: boolean;
|
||||
isFinalAnnotation?: boolean;
|
||||
isClassVarAnnotation?: boolean;
|
||||
supportsTypedDictTypeArg?: boolean;
|
||||
}
|
||||
|
||||
interface MatchArgsToParamsResult {
|
||||
@ -620,7 +618,6 @@ export function createTypeEvaluator(
|
||||
let intClass: Type | undefined;
|
||||
let strClass: Type | undefined;
|
||||
let dictClass: Type | undefined;
|
||||
let typedDictClass: Type | undefined;
|
||||
let typedDictPrivateClass: Type | undefined;
|
||||
let supportsKeysAndGetItemClass: Type | undefined;
|
||||
let mappingClass: Type | undefined;
|
||||
@ -965,7 +962,6 @@ export function createTypeEvaluator(
|
||||
intClass = getBuiltInType(node, 'int');
|
||||
strClass = getBuiltInType(node, 'str');
|
||||
dictClass = getBuiltInType(node, 'dict');
|
||||
typedDictClass = getTypingType(node, 'TypedDict');
|
||||
typedDictPrivateClass = getTypingType(node, '_TypedDict');
|
||||
awaitableClass = getTypingType(node, 'Awaitable');
|
||||
mappingClass = getTypingType(node, 'Mapping');
|
||||
@ -7074,19 +7070,11 @@ export function createTypeEvaluator(
|
||||
const isClassVarAnnotation =
|
||||
isInstantiableClass(concreteSubtype) && ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
|
||||
|
||||
// Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
|
||||
// This feature is currently experimental.
|
||||
const supportsTypedDictTypeArg =
|
||||
AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
|
||||
ClassType.isBuiltIn(concreteSubtype, 'dict') &&
|
||||
!ClassType.isBuiltIn(concreteSubtype, 'Dict');
|
||||
|
||||
let typeArgs = getTypeArgs(node, flags, {
|
||||
isAnnotatedClass,
|
||||
hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
|
||||
isFinalAnnotation,
|
||||
isClassVarAnnotation,
|
||||
supportsTypedDictTypeArg,
|
||||
});
|
||||
|
||||
if (!isAnnotatedClass) {
|
||||
@ -7673,7 +7661,7 @@ export function createTypeEvaluator(
|
||||
node: expr,
|
||||
};
|
||||
} else {
|
||||
typeResult = getTypeArg(expr, adjFlags, !!options?.supportsTypedDictTypeArg && argIndex === 0);
|
||||
typeResult = getTypeArg(expr, adjFlags);
|
||||
}
|
||||
|
||||
return typeResult;
|
||||
@ -7726,11 +7714,7 @@ export function createTypeEvaluator(
|
||||
return typeArgs;
|
||||
}
|
||||
|
||||
function getTypeArg(
|
||||
node: ExpressionNode,
|
||||
flags: EvaluatorFlags,
|
||||
supportsDictExpression: boolean
|
||||
): TypeResultWithNode {
|
||||
function getTypeArg(node: ExpressionNode, flags: EvaluatorFlags): TypeResultWithNode {
|
||||
let typeResult: TypeResultWithNode;
|
||||
|
||||
let adjustedFlags =
|
||||
@ -7755,18 +7739,6 @@ export function createTypeEvaluator(
|
||||
|
||||
// Set the node's type so it isn't reevaluated later.
|
||||
setTypeResultForNode(node, { type: UnknownType.create() });
|
||||
} else if (node.nodeType === ParseNodeType.Dictionary && supportsDictExpression) {
|
||||
const inlinedTypeDict =
|
||||
typedDictClass && isInstantiableClass(typedDictClass)
|
||||
? createTypedDictTypeInlined(evaluatorInterface, node, typedDictClass)
|
||||
: undefined;
|
||||
const keyTypeFallback = strClass && isInstantiableClass(strClass) ? strClass : UnknownType.create();
|
||||
|
||||
typeResult = {
|
||||
type: keyTypeFallback,
|
||||
inlinedTypeDict,
|
||||
node,
|
||||
};
|
||||
} else {
|
||||
typeResult = { ...getTypeOfExpression(node, adjustedFlags), node };
|
||||
|
||||
|
@ -235,34 +235,6 @@ export function createTypedDictType(
|
||||
return classType;
|
||||
}
|
||||
|
||||
// Creates a new anonymous TypedDict class from an inlined dict[{}] type annotation.
|
||||
export function createTypedDictTypeInlined(
|
||||
evaluator: TypeEvaluator,
|
||||
dictNode: DictionaryNode,
|
||||
typedDictClass: ClassType
|
||||
): ClassType {
|
||||
const fileInfo = AnalyzerNodeInfo.getFileInfo(dictNode);
|
||||
const className = '<TypedDict>';
|
||||
|
||||
const classType = ClassType.createInstantiable(
|
||||
className,
|
||||
ParseTreeUtils.getClassFullName(dictNode, fileInfo.moduleName, className),
|
||||
fileInfo.moduleName,
|
||||
fileInfo.fileUri,
|
||||
ClassTypeFlags.TypedDictClass,
|
||||
ParseTreeUtils.getTypeSourceId(dictNode),
|
||||
/* declaredMetaclass */ undefined,
|
||||
typedDictClass.details.effectiveMetaclass
|
||||
);
|
||||
classType.details.baseClasses.push(typedDictClass);
|
||||
computeMroLinearization(classType);
|
||||
|
||||
getTypedDictFieldsFromDictSyntax(evaluator, dictNode, ClassType.getSymbolTable(classType), /* isInline */ true);
|
||||
synthesizeTypedDictClassMethods(evaluator, dictNode, classType);
|
||||
|
||||
return classType;
|
||||
}
|
||||
|
||||
export function synthesizeTypedDictClassMethods(
|
||||
evaluator: TypeEvaluator,
|
||||
node: ClassNode | ExpressionNode,
|
||||
|
@ -1,36 +0,0 @@
|
||||
# This sample tests support for inlined TypedDict definitions.
|
||||
|
||||
from typing import Dict
|
||||
|
||||
|
||||
td1: dict[{"a": int, "b": str}] = {"a": 0, "b": ""}
|
||||
|
||||
td2: dict[{"a": dict[{"b": int}]}] = {"a": {"b": 0}}
|
||||
|
||||
td3: dict[{"a": "list[float]"}] = {"a": [3]}
|
||||
|
||||
# This should generate two errors because dictionary literals can be used
|
||||
# only with dict or Dict.
|
||||
err1: list[{"a": 1}]
|
||||
|
||||
# This should generate an error because dictionary comprehensions
|
||||
# are not allowed.
|
||||
err2: dict[{"a": int for _ in range(1)}]
|
||||
|
||||
# This should generate an error because unpacked dictionary
|
||||
# entries are not allowed.
|
||||
err3: dict[{**{"a": int}}]
|
||||
|
||||
# This should generate three errors because Dict doesn't support inlined
|
||||
# TypedDict. It generates an exception at runtime.
|
||||
err4: Dict[{"c": int}]
|
||||
|
||||
# This should generate an error because an extra type argument is provided.
|
||||
err5: dict[{"a": int}, str]
|
||||
|
||||
|
||||
def func1(val: dict[{"a": int}]) -> dict[{"a": int}]:
|
||||
return {"a": val["a"] + 1}
|
||||
|
||||
|
||||
func1({"a": 3})
|
@ -737,14 +737,6 @@ test('TypedDict24', () => {
|
||||
TestUtils.validateResults(analysisResults, 1);
|
||||
});
|
||||
|
||||
test('TypedDictInline1', () => {
|
||||
const configOptions = new ConfigOptions(Uri.empty());
|
||||
configOptions.diagnosticRuleSet.enableExperimentalFeatures = true;
|
||||
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDictInline1.py'], configOptions);
|
||||
TestUtils.validateResults(analysisResults, 9);
|
||||
});
|
||||
|
||||
test('ClassVar1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['classVar1.py']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user