mirror of
https://github.com/microsoft/pyright.git
synced 2024-08-17 03:40:44 +03:00
Merge branch 'main' into add-azure-devops-release
This commit is contained in:
commit
ba50f35bb1
4
.github/workflows/mypy_primer_pr.yaml
vendored
4
.github/workflows/mypy_primer_pr.yaml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
shard-index: [0, 1]
|
shard-index: [0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
--repo pyright_to_test \
|
--repo pyright_to_test \
|
||||||
--type-checker pyright \
|
--type-checker pyright \
|
||||||
--new $GITHUB_SHA --old base_commit \
|
--new $GITHUB_SHA --old base_commit \
|
||||||
--num-shards 2 --shard-index ${{ matrix.shard-index }} \
|
--num-shards 8 --shard-index ${{ matrix.shard-index }} \
|
||||||
--debug \
|
--debug \
|
||||||
--output concise \
|
--output concise \
|
||||||
| tee diff_${{ matrix.shard-index }}.txt
|
| tee diff_${{ matrix.shard-index }}.txt
|
||||||
|
@ -3092,106 +3092,123 @@ export class Checker extends ParseTreeWalker {
|
|||||||
|
|
||||||
private _reportInvalidOverload(name: string, symbol: Symbol) {
|
private _reportInvalidOverload(name: string, symbol: Symbol) {
|
||||||
const typedDecls = symbol.getTypedDeclarations();
|
const typedDecls = symbol.getTypedDeclarations();
|
||||||
if (typedDecls.length >= 1) {
|
if (typedDecls.length === 0) {
|
||||||
const primaryDecl = typedDecls[0];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (primaryDecl.type === DeclarationType.Function) {
|
const primaryDecl = typedDecls[0];
|
||||||
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
|
||||||
const overloadedFunctions = isOverloadedFunction(type)
|
|
||||||
? OverloadedFunctionType.getOverloads(type)
|
|
||||||
: isFunction(type) && FunctionType.isOverloaded(type)
|
|
||||||
? [type]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
if (overloadedFunctions.length === 1) {
|
if (primaryDecl.type !== DeclarationType.Function) {
|
||||||
// There should never be a single overload.
|
return;
|
||||||
this._evaluator.addDiagnostic(
|
}
|
||||||
DiagnosticRule.reportInconsistentOverload,
|
|
||||||
LocMessage.singleOverload().format({ name }),
|
|
||||||
primaryDecl.node.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the file is not a stub and this is the first overload,
|
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
||||||
// verify that there is an implementation.
|
const overloadedFunctions = isOverloadedFunction(type)
|
||||||
if (!this._fileInfo.isStubFile && overloadedFunctions.length > 0) {
|
? OverloadedFunctionType.getOverloads(type)
|
||||||
let implementationFunction: FunctionType | undefined;
|
: isFunction(type) && FunctionType.isOverloaded(type)
|
||||||
let exemptMissingImplementation = false;
|
? [type]
|
||||||
|
: [];
|
||||||
|
|
||||||
if (isOverloadedFunction(type)) {
|
// If the implementation has no name, it was synthesized probably by a
|
||||||
implementationFunction = OverloadedFunctionType.getImplementation(type);
|
// decorator that used a callable with a ParamSpec that captured the
|
||||||
|
// overloaded signature. We'll exempt it from this check.
|
||||||
|
if (isOverloadedFunction(type)) {
|
||||||
|
const overloads = OverloadedFunctionType.getOverloads(type);
|
||||||
|
if (overloads.length > 0 && overloads[0].details.name === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (isFunction(type)) {
|
||||||
|
if (type.details.name === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the implementation has no name, it was synthesized probably by a
|
if (overloadedFunctions.length === 1) {
|
||||||
// decorator that used a callable with a ParamSpec that captured the
|
// There should never be a single overload.
|
||||||
// overloaded signature. We'll exempt it from this check.
|
this._evaluator.addDiagnostic(
|
||||||
const overloads = OverloadedFunctionType.getOverloads(type);
|
DiagnosticRule.reportInconsistentOverload,
|
||||||
if (overloads.length > 0 && overloads[0].details.name === '') {
|
LocMessage.singleOverload().format({ name }),
|
||||||
exemptMissingImplementation = true;
|
primaryDecl.node.name
|
||||||
}
|
);
|
||||||
} else if (isFunction(type) && !FunctionType.isOverloaded(type)) {
|
}
|
||||||
implementationFunction = type;
|
|
||||||
|
// If the file is not a stub and this is the first overload,
|
||||||
|
// verify that there is an implementation.
|
||||||
|
if (this._fileInfo.isStubFile || overloadedFunctions.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let implementationFunction: FunctionType | undefined;
|
||||||
|
|
||||||
|
if (isOverloadedFunction(type)) {
|
||||||
|
implementationFunction = OverloadedFunctionType.getImplementation(type);
|
||||||
|
} else if (isFunction(type) && !FunctionType.isOverloaded(type)) {
|
||||||
|
implementationFunction = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!implementationFunction) {
|
||||||
|
const containingClassNode = ParseTreeUtils.getEnclosingClassOrFunction(primaryDecl.node);
|
||||||
|
if (containingClassNode && containingClassNode.nodeType === ParseNodeType.Class) {
|
||||||
|
const classType = this._evaluator.getTypeOfClass(containingClassNode);
|
||||||
|
if (classType) {
|
||||||
|
if (ClassType.isProtocolClass(classType.classType)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!implementationFunction) {
|
if (ClassType.supportsAbstractMethods(classType.classType)) {
|
||||||
const containingClassNode = ParseTreeUtils.getEnclosingClassOrFunction(primaryDecl.node);
|
if (
|
||||||
if (containingClassNode && containingClassNode.nodeType === ParseNodeType.Class) {
|
isOverloadedFunction(type) &&
|
||||||
const classType = this._evaluator.getTypeOfClass(containingClassNode);
|
OverloadedFunctionType.getOverloads(type).every((overload) =>
|
||||||
if (classType) {
|
FunctionType.isAbstractMethod(overload)
|
||||||
if (ClassType.isProtocolClass(classType.classType)) {
|
)
|
||||||
exemptMissingImplementation = true;
|
) {
|
||||||
} else if (ClassType.supportsAbstractMethods(classType.classType)) {
|
return;
|
||||||
if (
|
|
||||||
isOverloadedFunction(type) &&
|
|
||||||
OverloadedFunctionType.getOverloads(type).every((overload) =>
|
|
||||||
FunctionType.isAbstractMethod(overload)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
exemptMissingImplementation = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a method within a protocol class, don't require that
|
|
||||||
// there is an implementation.
|
|
||||||
if (!exemptMissingImplementation) {
|
|
||||||
this._evaluator.addDiagnostic(
|
|
||||||
DiagnosticRule.reportNoOverloadImplementation,
|
|
||||||
LocMessage.overloadWithoutImplementation().format({
|
|
||||||
name: primaryDecl.node.name.value,
|
|
||||||
}),
|
|
||||||
primaryDecl.node.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (isOverloadedFunction(type)) {
|
|
||||||
// Verify that all overload signatures are assignable to implementation signature.
|
|
||||||
OverloadedFunctionType.getOverloads(type).forEach((overload, index) => {
|
|
||||||
const diag = new DiagnosticAddendum();
|
|
||||||
if (!this._isLegalOverloadImplementation(overload, implementationFunction!, diag)) {
|
|
||||||
if (implementationFunction!.details.declaration) {
|
|
||||||
const diagnostic = this._evaluator.addDiagnostic(
|
|
||||||
DiagnosticRule.reportInconsistentOverload,
|
|
||||||
LocMessage.overloadImplementationMismatch().format({
|
|
||||||
name,
|
|
||||||
index: index + 1,
|
|
||||||
}) + diag.getString(),
|
|
||||||
implementationFunction!.details.declaration.node.name
|
|
||||||
);
|
|
||||||
|
|
||||||
if (diagnostic && overload.details.declaration) {
|
|
||||||
diagnostic.addRelatedInfo(
|
|
||||||
LocAddendum.overloadSignature(),
|
|
||||||
overload.details.declaration?.uri ?? primaryDecl.uri,
|
|
||||||
overload.details.declaration?.range ?? primaryDecl.range
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a method within a protocol class, don't require that
|
||||||
|
// there is an implementation.
|
||||||
|
this._evaluator.addDiagnostic(
|
||||||
|
DiagnosticRule.reportNoOverloadImplementation,
|
||||||
|
LocMessage.overloadWithoutImplementation().format({
|
||||||
|
name: primaryDecl.node.name.value,
|
||||||
|
}),
|
||||||
|
primaryDecl.node.name
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isOverloadedFunction(type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that all overload signatures are assignable to implementation signature.
|
||||||
|
OverloadedFunctionType.getOverloads(type).forEach((overload, index) => {
|
||||||
|
const diag = new DiagnosticAddendum();
|
||||||
|
if (!this._isLegalOverloadImplementation(overload, implementationFunction!, diag)) {
|
||||||
|
if (implementationFunction!.details.declaration) {
|
||||||
|
const diagnostic = this._evaluator.addDiagnostic(
|
||||||
|
DiagnosticRule.reportInconsistentOverload,
|
||||||
|
LocMessage.overloadImplementationMismatch().format({
|
||||||
|
name,
|
||||||
|
index: index + 1,
|
||||||
|
}) + diag.getString(),
|
||||||
|
implementationFunction!.details.declaration.node.name
|
||||||
|
);
|
||||||
|
|
||||||
|
if (diagnostic && overload.details.declaration) {
|
||||||
|
diagnostic.addRelatedInfo(
|
||||||
|
LocAddendum.overloadSignature(),
|
||||||
|
overload.details.declaration?.uri ?? primaryDecl.uri,
|
||||||
|
overload.details.declaration?.range ?? primaryDecl.range
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _reportMultipleFinalDeclarations(name: string, symbol: Symbol, scopeType: ScopeType) {
|
private _reportMultipleFinalDeclarations(name: string, symbol: Symbol, scopeType: ScopeType) {
|
||||||
|
@ -134,6 +134,11 @@ export interface IncompleteType {
|
|||||||
isRecursionSentinel?: boolean;
|
isRecursionSentinel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ReachabilityCacheEntry {
|
||||||
|
isReachable: boolean | undefined;
|
||||||
|
isReachableFrom: Map<number, boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
// Define a user type guard function for IncompleteType.
|
// Define a user type guard function for IncompleteType.
|
||||||
export function isIncompleteType(cachedType: CachedType): cachedType is IncompleteType {
|
export function isIncompleteType(cachedType: CachedType): cachedType is IncompleteType {
|
||||||
return !!(cachedType as IncompleteType).isIncompleteType;
|
return !!(cachedType as IncompleteType).isIncompleteType;
|
||||||
@ -164,6 +169,7 @@ export function getCodeFlowEngine(
|
|||||||
speculativeTypeTracker: SpeculativeTypeTracker
|
speculativeTypeTracker: SpeculativeTypeTracker
|
||||||
): CodeFlowEngine {
|
): CodeFlowEngine {
|
||||||
const isReachableRecursionSet = new Set<number>();
|
const isReachableRecursionSet = new Set<number>();
|
||||||
|
const reachabilityCache = new Map<number, ReachabilityCacheEntry>();
|
||||||
const callIsNoReturnCache = new Map<number, boolean>();
|
const callIsNoReturnCache = new Map<number, boolean>();
|
||||||
const isExceptionContextManagerCache = new Map<number, boolean>();
|
const isExceptionContextManagerCache = new Map<number, boolean>();
|
||||||
let flowIncompleteGeneration = 1;
|
let flowIncompleteGeneration = 1;
|
||||||
@ -1182,11 +1188,29 @@ export function getCodeFlowEngine(
|
|||||||
printControlFlowGraph(flowNode, /* reference */ undefined, 'isFlowNodeReachable');
|
printControlFlowGraph(flowNode, /* reference */ undefined, 'isFlowNodeReachable');
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFlowNodeReachableRecursive(
|
function cacheReachabilityResult(isReachable: boolean): boolean {
|
||||||
flowNode: FlowNode,
|
// If there is a finally gate set, we will not cache the results
|
||||||
sourceFlowNode: FlowNode | undefined,
|
// because this can affect the reachability.
|
||||||
recursionCount = 0
|
if (closedFinallyGateSet.size > 0) {
|
||||||
): boolean {
|
return isReachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cacheEntry = reachabilityCache.get(flowNode.id);
|
||||||
|
if (!cacheEntry) {
|
||||||
|
cacheEntry = { isReachable: undefined, isReachableFrom: new Map<number, boolean>() };
|
||||||
|
reachabilityCache.set(flowNode.id, cacheEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourceFlowNode) {
|
||||||
|
cacheEntry.isReachable = isReachable;
|
||||||
|
} else {
|
||||||
|
cacheEntry.isReachableFrom.set(sourceFlowNode.id, isReachable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isReachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFlowNodeReachableRecursive(flowNode: FlowNode, recursionCount = 0): boolean {
|
||||||
// Cut off the recursion at some point to prevent a stack overflow.
|
// Cut off the recursion at some point to prevent a stack overflow.
|
||||||
const maxFlowNodeReachableRecursionCount = 64;
|
const maxFlowNodeReachableRecursionCount = 64;
|
||||||
if (recursionCount > maxFlowNodeReachableRecursionCount) {
|
if (recursionCount > maxFlowNodeReachableRecursionCount) {
|
||||||
@ -1197,21 +1221,36 @@ export function getCodeFlowEngine(
|
|||||||
let curFlowNode = flowNode;
|
let curFlowNode = flowNode;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
// See if we've already cached this result.
|
||||||
|
const cacheEntry = reachabilityCache.get(flowNode.id);
|
||||||
|
if (cacheEntry !== undefined && closedFinallyGateSet.size === 0) {
|
||||||
|
if (!sourceFlowNode) {
|
||||||
|
if (cacheEntry.isReachable !== undefined) {
|
||||||
|
return cacheEntry.isReachable;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const isReachableFrom = cacheEntry.isReachableFrom.get(sourceFlowNode.id);
|
||||||
|
if (isReachableFrom !== undefined) {
|
||||||
|
return isReachableFrom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we've already visited this node, we can assume
|
// If we've already visited this node, we can assume
|
||||||
// it wasn't reachable.
|
// it wasn't reachable.
|
||||||
if (visitedFlowNodeSet.has(curFlowNode.id)) {
|
if (visitedFlowNodeSet.has(curFlowNode.id)) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that we've been here before.
|
// Note that we've been here before.
|
||||||
visitedFlowNodeSet.add(curFlowNode.id);
|
visitedFlowNodeSet.add(curFlowNode.id);
|
||||||
|
|
||||||
if (curFlowNode.flags & FlowFlags.Unreachable) {
|
if (curFlowNode.flags & FlowFlags.Unreachable) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curFlowNode === sourceFlowNode) {
|
if (curFlowNode === sourceFlowNode) {
|
||||||
return true;
|
return cacheReachabilityResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -1271,7 +1310,7 @@ export function getCodeFlowEngine(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isUnreachable) {
|
if (isUnreachable) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1287,7 +1326,7 @@ export function getCodeFlowEngine(
|
|||||||
// it always raises an exception or otherwise doesn't return,
|
// it always raises an exception or otherwise doesn't return,
|
||||||
// so we can assume that the code before this is unreachable.
|
// so we can assume that the code before this is unreachable.
|
||||||
if (!ignoreNoReturn && isCallNoReturn(evaluator, callFlowNode)) {
|
if (!ignoreNoReturn && isCallNoReturn(evaluator, callFlowNode)) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
curFlowNode = callFlowNode.antecedent;
|
curFlowNode = callFlowNode.antecedent;
|
||||||
@ -1304,29 +1343,29 @@ export function getCodeFlowEngine(
|
|||||||
isExceptionContextManager(evaluator, expr, contextMgrNode.isAsync)
|
isExceptionContextManager(evaluator, expr, contextMgrNode.isAsync)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelNode = curFlowNode as FlowLabel;
|
const labelNode = curFlowNode as FlowLabel;
|
||||||
for (const antecedent of labelNode.antecedents) {
|
for (const antecedent of labelNode.antecedents) {
|
||||||
if (isFlowNodeReachableRecursive(antecedent, sourceFlowNode, recursionCount)) {
|
if (isFlowNodeReachableRecursive(antecedent, recursionCount)) {
|
||||||
return true;
|
return cacheReachabilityResult(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curFlowNode.flags & FlowFlags.Start) {
|
if (curFlowNode.flags & FlowFlags.Start) {
|
||||||
// If we hit the start but were looking for a particular source flow
|
// If we hit the start but were looking for a particular source flow
|
||||||
// node, return false. Otherwise, the start is what we're looking for.
|
// node, return false. Otherwise, the start is what we're looking for.
|
||||||
return sourceFlowNode ? false : true;
|
return cacheReachabilityResult(sourceFlowNode ? false : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curFlowNode.flags & FlowFlags.PreFinallyGate) {
|
if (curFlowNode.flags & FlowFlags.PreFinallyGate) {
|
||||||
const preFinallyFlowNode = curFlowNode as FlowPreFinallyGate;
|
const preFinallyFlowNode = curFlowNode as FlowPreFinallyGate;
|
||||||
if (closedFinallyGateSet.has(preFinallyFlowNode.id)) {
|
if (closedFinallyGateSet.has(preFinallyFlowNode.id)) {
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
curFlowNode = preFinallyFlowNode.antecedent;
|
curFlowNode = preFinallyFlowNode.antecedent;
|
||||||
@ -1339,10 +1378,8 @@ export function getCodeFlowEngine(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
closedFinallyGateSet.add(postFinallyFlowNode.preFinallyGate.id);
|
closedFinallyGateSet.add(postFinallyFlowNode.preFinallyGate.id);
|
||||||
return isFlowNodeReachableRecursive(
|
return cacheReachabilityResult(
|
||||||
postFinallyFlowNode.antecedent,
|
isFlowNodeReachableRecursive(postFinallyFlowNode.antecedent, recursionCount)
|
||||||
sourceFlowNode,
|
|
||||||
recursionCount
|
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
if (!wasGateClosed) {
|
if (!wasGateClosed) {
|
||||||
@ -1353,7 +1390,7 @@ export function getCodeFlowEngine(
|
|||||||
|
|
||||||
// We shouldn't get here.
|
// We shouldn't get here.
|
||||||
fail('Unexpected flow node flags');
|
fail('Unexpected flow node flags');
|
||||||
return false;
|
return cacheReachabilityResult(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1364,7 +1401,7 @@ export function getCodeFlowEngine(
|
|||||||
isReachableRecursionSet.add(flowNode.id);
|
isReachableRecursionSet.add(flowNode.id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return isFlowNodeReachableRecursive(flowNode, sourceFlowNode);
|
return isFlowNodeReachableRecursive(flowNode);
|
||||||
} finally {
|
} finally {
|
||||||
isReachableRecursionSet.delete(flowNode.id);
|
isReachableRecursionSet.delete(flowNode.id);
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1020,7 @@ function assignTypeToParamSpec(
|
|||||||
// performs this reverse mapping of type arguments and populates the type var
|
// performs this reverse mapping of type arguments and populates the type var
|
||||||
// map for the target type. If the type is not assignable to the expected type,
|
// map for the target type. If the type is not assignable to the expected type,
|
||||||
// it returns false.
|
// it returns false.
|
||||||
export function populateTypeVarContextBasedOnExpectedType(
|
export function addConstraintsForExpectedType(
|
||||||
evaluator: TypeEvaluator,
|
evaluator: TypeEvaluator,
|
||||||
type: ClassType,
|
type: ClassType,
|
||||||
expectedType: Type,
|
expectedType: Type,
|
||||||
|
@ -17,7 +17,7 @@ import { DiagnosticAddendum } from '../common/diagnostic';
|
|||||||
import { DiagnosticRule } from '../common/diagnosticRules';
|
import { DiagnosticRule } from '../common/diagnosticRules';
|
||||||
import { LocMessage } from '../localization/localize';
|
import { LocMessage } from '../localization/localize';
|
||||||
import { ArgumentCategory, ExpressionNode, ParameterCategory } from '../parser/parseNodes';
|
import { ArgumentCategory, ExpressionNode, ParameterCategory } from '../parser/parseNodes';
|
||||||
import { populateTypeVarContextBasedOnExpectedType } from './constraintSolver';
|
import { addConstraintsForExpectedType } from './constraintSolver';
|
||||||
import { applyConstructorTransform, hasConstructorTransform } from './constructorTransform';
|
import { applyConstructorTransform, hasConstructorTransform } from './constructorTransform';
|
||||||
import { getTypeVarScopesForNode } from './parseTreeUtils';
|
import { getTypeVarScopesForNode } from './parseTreeUtils';
|
||||||
import { CallResult, FunctionArgument, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
import { CallResult, FunctionArgument, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
||||||
@ -25,14 +25,17 @@ import {
|
|||||||
InferenceContext,
|
InferenceContext,
|
||||||
MemberAccessFlags,
|
MemberAccessFlags,
|
||||||
UniqueSignatureTracker,
|
UniqueSignatureTracker,
|
||||||
|
addTypeVarsToListIfUnique,
|
||||||
applySolvedTypeVars,
|
applySolvedTypeVars,
|
||||||
buildTypeVarContextFromSpecializedClass,
|
buildTypeVarContextFromSpecializedClass,
|
||||||
convertToInstance,
|
convertToInstance,
|
||||||
|
convertTypeToParamSpecValue,
|
||||||
doForEachSignature,
|
doForEachSignature,
|
||||||
doForEachSubtype,
|
doForEachSubtype,
|
||||||
ensureFunctionSignaturesAreUnique,
|
ensureFunctionSignaturesAreUnique,
|
||||||
getTypeVarArgumentsRecursive,
|
getTypeVarArgumentsRecursive,
|
||||||
getTypeVarScopeId,
|
getTypeVarScopeId,
|
||||||
|
getTypeVarScopeIds,
|
||||||
isTupleClass,
|
isTupleClass,
|
||||||
lookUpClassMember,
|
lookUpClassMember,
|
||||||
mapSubtypes,
|
mapSubtypes,
|
||||||
@ -60,6 +63,7 @@ import {
|
|||||||
isInstantiableClass,
|
isInstantiableClass,
|
||||||
isNever,
|
isNever,
|
||||||
isOverloadedFunction,
|
isOverloadedFunction,
|
||||||
|
isParamSpec,
|
||||||
isTypeVar,
|
isTypeVar,
|
||||||
isUnion,
|
isUnion,
|
||||||
isUnknown,
|
isUnknown,
|
||||||
@ -286,7 +290,7 @@ function validateNewAndInitMethods(
|
|||||||
newMethodReturnType = applySolvedTypeVars(
|
newMethodReturnType = applySolvedTypeVars(
|
||||||
ClassType.cloneAsInstance(type),
|
ClassType.cloneAsInstance(type),
|
||||||
new TypeVarContext(getTypeVarScopeId(type)),
|
new TypeVarContext(getTypeVarScopeId(type)),
|
||||||
{ unknownIfNotFound: true }
|
{ unknownIfNotFound: true, tupleClassType: evaluator.getTupleClassType() }
|
||||||
) as ClassType;
|
) as ClassType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +543,7 @@ function validateInitMethod(
|
|||||||
typeVarContext.addSolveForScope(getTypeVarScopeId(initMethodType));
|
typeVarContext.addSolveForScope(getTypeVarScopeId(initMethodType));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
!addConstraintsForExpectedType(
|
||||||
evaluator,
|
evaluator,
|
||||||
ClassType.cloneAsInstance(type),
|
ClassType.cloneAsInstance(type),
|
||||||
expectedSubType,
|
expectedSubType,
|
||||||
@ -548,54 +552,56 @@ function validateInitMethod(
|
|||||||
errorNode.start
|
errorNode.start
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const specializedConstructor = applySolvedTypeVars(initMethodType, typeVarContext);
|
return undefined;
|
||||||
|
|
||||||
let callResult: CallResult | undefined;
|
|
||||||
callResult = evaluator.useSpeculativeMode(errorNode, () => {
|
|
||||||
return evaluator.validateCallArguments(
|
|
||||||
errorNode,
|
|
||||||
argList,
|
|
||||||
{ type: specializedConstructor },
|
|
||||||
typeVarContext.clone(),
|
|
||||||
skipUnknownArgCheck,
|
|
||||||
/* inferenceContext */ undefined,
|
|
||||||
signatureTracker
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!callResult.argumentErrors) {
|
|
||||||
// Call validateCallArguments again, this time without speculative
|
|
||||||
// mode, so any errors are reported.
|
|
||||||
callResult = evaluator.validateCallArguments(
|
|
||||||
errorNode,
|
|
||||||
argList,
|
|
||||||
{ type: specializedConstructor },
|
|
||||||
typeVarContext,
|
|
||||||
skipUnknownArgCheck,
|
|
||||||
/* inferenceContext */ undefined,
|
|
||||||
signatureTracker
|
|
||||||
);
|
|
||||||
|
|
||||||
if (callResult.isTypeIncomplete) {
|
|
||||||
isTypeIncomplete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callResult.argumentErrors) {
|
|
||||||
argumentErrors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callResult.overloadsUsedForCall) {
|
|
||||||
appendArray(overloadsUsedForCall, callResult.overloadsUsedForCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that we've found an expected type that works.
|
|
||||||
foundWorkingExpectedType = true;
|
|
||||||
|
|
||||||
return applyExpectedSubtypeForConstructor(evaluator, type, expectedSubType, typeVarContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
const specializedConstructor = applySolvedTypeVars(initMethodType, typeVarContext);
|
||||||
|
|
||||||
|
let callResult: CallResult | undefined;
|
||||||
|
callResult = evaluator.useSpeculativeMode(errorNode, () => {
|
||||||
|
return evaluator.validateCallArguments(
|
||||||
|
errorNode,
|
||||||
|
argList,
|
||||||
|
{ type: specializedConstructor },
|
||||||
|
typeVarContext.clone(),
|
||||||
|
skipUnknownArgCheck,
|
||||||
|
/* inferenceContext */ undefined,
|
||||||
|
signatureTracker
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (callResult.argumentErrors) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call validateCallArguments again, this time without speculative
|
||||||
|
// mode, so any errors are reported.
|
||||||
|
callResult = evaluator.validateCallArguments(
|
||||||
|
errorNode,
|
||||||
|
argList,
|
||||||
|
{ type: specializedConstructor },
|
||||||
|
typeVarContext,
|
||||||
|
skipUnknownArgCheck,
|
||||||
|
/* inferenceContext */ undefined,
|
||||||
|
signatureTracker
|
||||||
|
);
|
||||||
|
|
||||||
|
if (callResult.isTypeIncomplete) {
|
||||||
|
isTypeIncomplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callResult.argumentErrors) {
|
||||||
|
argumentErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callResult.overloadsUsedForCall) {
|
||||||
|
appendArray(overloadsUsedForCall, callResult.overloadsUsedForCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that we've found an expected type that works.
|
||||||
|
foundWorkingExpectedType = true;
|
||||||
|
|
||||||
|
return applyExpectedSubtypeForConstructor(evaluator, type, expectedSubType, typeVarContext);
|
||||||
},
|
},
|
||||||
/* sortSubtypes */ true
|
/* sortSubtypes */ true
|
||||||
);
|
);
|
||||||
@ -704,7 +710,7 @@ function validateFallbackConstructorCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (expectedType) {
|
if (expectedType) {
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluator,
|
evaluator,
|
||||||
ClassType.cloneAsInstance(type),
|
ClassType.cloneAsInstance(type),
|
||||||
expectedType,
|
expectedType,
|
||||||
@ -818,6 +824,7 @@ function applyExpectedTypeForConstructor(
|
|||||||
|
|
||||||
const specializedType = applySolvedTypeVars(type, typeVarContext, {
|
const specializedType = applySolvedTypeVars(type, typeVarContext, {
|
||||||
unknownIfNotFound: unsolvedTypeVarsAreUnknown,
|
unknownIfNotFound: unsolvedTypeVarsAreUnknown,
|
||||||
|
tupleClassType: evaluator.getTupleClassType(),
|
||||||
}) as ClassType;
|
}) as ClassType;
|
||||||
return ClassType.cloneAsInstance(specializedType);
|
return ClassType.cloneAsInstance(specializedType);
|
||||||
}
|
}
|
||||||
@ -1086,10 +1093,43 @@ function createFunctionFromInitMethod(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const convertedInit = FunctionType.clone(boundInit);
|
const convertedInit = FunctionType.clone(boundInit);
|
||||||
convertedInit.details.declaredReturnType = boundInit.strippedFirstParamType ?? selfType ?? objectType;
|
let returnType = selfType;
|
||||||
|
if (!returnType) {
|
||||||
|
returnType = objectType;
|
||||||
|
|
||||||
|
// If this is a generic type, self-specialize the class (i.e. fill in
|
||||||
|
// its own type parameters as type arguments).
|
||||||
|
if (objectType.details.typeParameters.length > 0 && !objectType.typeArguments) {
|
||||||
|
const typeVarContext = new TypeVarContext(getTypeVarScopeIds(objectType));
|
||||||
|
|
||||||
|
// If a TypeVar is not used in any of the parameter types, it should take
|
||||||
|
// on its default value (typically Unknown) in the resulting specialized type.
|
||||||
|
const typeVarsInParams: TypeVarType[] = [];
|
||||||
|
|
||||||
|
convertedInit.details.parameters.forEach((param, index) => {
|
||||||
|
const paramType = FunctionType.getEffectiveParameterType(convertedInit, index);
|
||||||
|
addTypeVarsToListIfUnique(typeVarsInParams, getTypeVarArgumentsRecursive(paramType));
|
||||||
|
});
|
||||||
|
|
||||||
|
typeVarsInParams.forEach((typeVar) => {
|
||||||
|
if (isParamSpec(typeVar)) {
|
||||||
|
typeVarContext.setTypeVarType(typeVar, convertTypeToParamSpecValue(typeVar));
|
||||||
|
} else {
|
||||||
|
typeVarContext.setTypeVarType(typeVar, typeVar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
returnType = applySolvedTypeVars(objectType, typeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: evaluator.getTupleClassType(),
|
||||||
|
}) as ClassType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedInit.details.declaredReturnType = boundInit.strippedFirstParamType ?? returnType;
|
||||||
|
|
||||||
if (convertedInit.specializedTypes) {
|
if (convertedInit.specializedTypes) {
|
||||||
convertedInit.specializedTypes.returnType = selfType ?? objectType;
|
convertedInit.specializedTypes.returnType = returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!convertedInit.details.docString && classType.details.docString) {
|
if (!convertedInit.details.docString && classType.details.docString) {
|
||||||
|
@ -821,7 +821,10 @@ function getConverterInputType(
|
|||||||
const inputTypeVarContext = new TypeVarContext(typeVar.scopeId);
|
const inputTypeVarContext = new TypeVarContext(typeVar.scopeId);
|
||||||
|
|
||||||
if (evaluator.assignType(targetFunction, signature, diagAddendum, inputTypeVarContext)) {
|
if (evaluator.assignType(targetFunction, signature, diagAddendum, inputTypeVarContext)) {
|
||||||
const overloadSolution = applySolvedTypeVars(typeVar, inputTypeVarContext, { unknownIfNotFound: true });
|
const overloadSolution = applySolvedTypeVars(typeVar, inputTypeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: evaluator.getTupleClassType(),
|
||||||
|
});
|
||||||
acceptedTypes.push(overloadSolution);
|
acceptedTypes.push(overloadSolution);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -109,7 +109,8 @@ export class ImportResolver {
|
|||||||
private _cachedFilesForPath = new Map<string, Uri[]>();
|
private _cachedFilesForPath = new Map<string, Uri[]>();
|
||||||
private _cachedDirExistenceForRoot = new Map<string, boolean>();
|
private _cachedDirExistenceForRoot = new Map<string, boolean>();
|
||||||
private _stdlibModules: Set<string> | undefined;
|
private _stdlibModules: Set<string> | undefined;
|
||||||
protected cachedParentImportResults: ParentDirectoryCache;
|
|
||||||
|
protected readonly cachedParentImportResults: ParentDirectoryCache;
|
||||||
|
|
||||||
constructor(readonly serviceProvider: ServiceProvider, private _configOptions: ConfigOptions, readonly host: Host) {
|
constructor(readonly serviceProvider: ServiceProvider, private _configOptions: ConfigOptions, readonly host: Host) {
|
||||||
this.cachedParentImportResults = new ParentDirectoryCache(() => this.getPythonSearchPaths([]));
|
this.cachedParentImportResults = new ParentDirectoryCache(() => this.getPythonSearchPaths([]));
|
||||||
@ -172,7 +173,7 @@ export class ImportResolver {
|
|||||||
return suggestions;
|
return suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const root = this.getParentImportResolutionRoot(sourceFileUri, execEnv.root);
|
const root = getParentImportResolutionRoot(sourceFileUri, execEnv.root);
|
||||||
const origin = sourceFileUri.getDirectory();
|
const origin = sourceFileUri.getDirectory();
|
||||||
|
|
||||||
let current: Uri | undefined = origin;
|
let current: Uri | undefined = origin;
|
||||||
@ -533,7 +534,7 @@ export class ImportResolver {
|
|||||||
execEnv: ExecutionEnvironment,
|
execEnv: ExecutionEnvironment,
|
||||||
moduleDescriptor: ImportedModuleDescriptor
|
moduleDescriptor: ImportedModuleDescriptor
|
||||||
): ImportResult {
|
): ImportResult {
|
||||||
const importName = this.formatImportName(moduleDescriptor);
|
const importName = formatImportName(moduleDescriptor);
|
||||||
const importFailureInfo: string[] = [];
|
const importFailureInfo: string[] = [];
|
||||||
const importResult = this._resolveImportStrict(
|
const importResult = this._resolveImportStrict(
|
||||||
importName,
|
importName,
|
||||||
@ -559,7 +560,7 @@ export class ImportResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the given file is in the parent directory import resolution cache.
|
// Check whether the given file is in the parent directory import resolution cache.
|
||||||
const root = this.getParentImportResolutionRoot(sourceFileUri, execEnv.root);
|
const root = getParentImportResolutionRoot(sourceFileUri, execEnv.root);
|
||||||
if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFileUri, root)) {
|
if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFileUri, root)) {
|
||||||
return importResult;
|
return importResult;
|
||||||
}
|
}
|
||||||
@ -776,74 +777,12 @@ export class ImportResolver {
|
|||||||
|
|
||||||
protected getNativeModuleName(uri: Uri): string | undefined {
|
protected getNativeModuleName(uri: Uri): string | undefined {
|
||||||
const fileExtension = uri.lastExtension.toLowerCase();
|
const fileExtension = uri.lastExtension.toLowerCase();
|
||||||
if (this._isNativeModuleFileExtension(fileExtension)) {
|
if (_isNativeModuleFileExtension(fileExtension)) {
|
||||||
return stripFileExtension(uri.fileName, /* multiDotExtension */ true);
|
return stripFileExtension(uri.fileName, /* multiDotExtension */ true);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getModuleNameFromPath(
|
|
||||||
containerPath: Uri,
|
|
||||||
fileUri: Uri,
|
|
||||||
stripTopContainerDir = false
|
|
||||||
): string | undefined {
|
|
||||||
const moduleNameInfo = this.getModuleNameInfoFromPath(containerPath, fileUri, stripTopContainerDir);
|
|
||||||
if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return moduleNameInfo.moduleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getModuleNameInfoFromPath(
|
|
||||||
containerPath: Uri,
|
|
||||||
fileUri: Uri,
|
|
||||||
stripTopContainerDir = false
|
|
||||||
): ModuleNameInfoFromPath | undefined {
|
|
||||||
let fileUriWithoutExtension = fileUri.stripExtension();
|
|
||||||
|
|
||||||
// If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
|
|
||||||
if (this._isNativeModuleFileExtension(fileUri.lastExtension)) {
|
|
||||||
fileUriWithoutExtension = fileUriWithoutExtension.stripExtension();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fileUriWithoutExtension.startsWith(containerPath)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strip off the '/__init__' if it's present.
|
|
||||||
if (fileUriWithoutExtension.pathEndsWith('__init__')) {
|
|
||||||
fileUriWithoutExtension = fileUriWithoutExtension.getDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = Array.from(containerPath.getRelativePathComponents(fileUriWithoutExtension));
|
|
||||||
if (stripTopContainerDir) {
|
|
||||||
if (parts.length === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
parts.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parts.length === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the case where the symbol was resolved to a stubs package
|
|
||||||
// rather than the real package. We'll strip off the "-stubs" suffix
|
|
||||||
// in this case.
|
|
||||||
if (parts[0].endsWith(stubsSuffix)) {
|
|
||||||
parts[0] = parts[0].substr(0, parts[0].length - stubsSuffix.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether parts contains invalid characters.
|
|
||||||
const containsInvalidCharacters = parts.some((p) => !this._isIdentifier(p));
|
|
||||||
|
|
||||||
return {
|
|
||||||
moduleName: parts.join('.'),
|
|
||||||
containsInvalidCharacters,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Potentially modifies the ImportResult by removing some or all of the
|
// Potentially modifies the ImportResult by removing some or all of the
|
||||||
// implicit import entries. Only the imported symbols should be included.
|
// implicit import entries. Only the imported symbols should be included.
|
||||||
protected filterImplicitImports(
|
protected filterImplicitImports(
|
||||||
@ -880,22 +819,6 @@ export class ImportResolver {
|
|||||||
return newImportResult;
|
return newImportResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected formatImportName(moduleDescriptor: ImportedModuleDescriptor) {
|
|
||||||
return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getParentImportResolutionRoot(sourceFileUri: Uri, executionRoot: Uri | undefined): Uri {
|
|
||||||
if (!this._isDefaultWorkspace(executionRoot)) {
|
|
||||||
return executionRoot!;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sourceFileUri.getDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _isDefaultWorkspace(uri: Uri | undefined) {
|
|
||||||
return !uri || uri.isEmpty() || Uri.isDefaultWorkspace(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _resolveImportStrict(
|
private _resolveImportStrict(
|
||||||
importName: string,
|
importName: string,
|
||||||
sourceFileUri: Uri,
|
sourceFileUri: Uri,
|
||||||
@ -1119,7 +1042,7 @@ export class ImportResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (stdLibTypeshedPath) {
|
if (stdLibTypeshedPath) {
|
||||||
moduleName = this.getModuleNameFromPath(stdLibTypeshedPath, fileUri);
|
moduleName = getModuleNameFromPath(stdLibTypeshedPath, fileUri);
|
||||||
if (moduleName) {
|
if (moduleName) {
|
||||||
const moduleDescriptor: ImportedModuleDescriptor = {
|
const moduleDescriptor: ImportedModuleDescriptor = {
|
||||||
leadingDots: 0,
|
leadingDots: 0,
|
||||||
@ -1149,7 +1072,7 @@ export class ImportResolver {
|
|||||||
|
|
||||||
// Look for it in the root directory of the execution environment.
|
// Look for it in the root directory of the execution environment.
|
||||||
if (execEnv.root) {
|
if (execEnv.root) {
|
||||||
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(execEnv.root, fileUri);
|
const candidateModuleNameInfo = _getModuleNameInfoFromPath(execEnv.root, fileUri);
|
||||||
|
|
||||||
if (candidateModuleNameInfo) {
|
if (candidateModuleNameInfo) {
|
||||||
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
||||||
@ -1163,7 +1086,7 @@ export class ImportResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const extraPath of execEnv.extraPaths) {
|
for (const extraPath of execEnv.extraPaths) {
|
||||||
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(extraPath, fileUri);
|
const candidateModuleNameInfo = _getModuleNameInfoFromPath(extraPath, fileUri);
|
||||||
|
|
||||||
if (candidateModuleNameInfo) {
|
if (candidateModuleNameInfo) {
|
||||||
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
||||||
@ -1182,7 +1105,7 @@ export class ImportResolver {
|
|||||||
|
|
||||||
// Check for a typings file.
|
// Check for a typings file.
|
||||||
if (this._configOptions.stubPath) {
|
if (this._configOptions.stubPath) {
|
||||||
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(this._configOptions.stubPath, fileUri);
|
const candidateModuleNameInfo = _getModuleNameInfoFromPath(this._configOptions.stubPath, fileUri);
|
||||||
|
|
||||||
if (candidateModuleNameInfo) {
|
if (candidateModuleNameInfo) {
|
||||||
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
||||||
@ -1209,7 +1132,7 @@ export class ImportResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (thirdPartyTypeshedPath) {
|
if (thirdPartyTypeshedPath) {
|
||||||
const candidateModuleName = this.getModuleNameFromPath(
|
const candidateModuleName = getModuleNameFromPath(
|
||||||
thirdPartyTypeshedPath,
|
thirdPartyTypeshedPath,
|
||||||
fileUri,
|
fileUri,
|
||||||
/* stripTopContainerDir */ true
|
/* stripTopContainerDir */ true
|
||||||
@ -1226,7 +1149,7 @@ export class ImportResolver {
|
|||||||
|
|
||||||
const thirdPartyTypeshedPathEx = this.getTypeshedPathEx(execEnv, importFailureInfo);
|
const thirdPartyTypeshedPathEx = this.getTypeshedPathEx(execEnv, importFailureInfo);
|
||||||
if (thirdPartyTypeshedPathEx) {
|
if (thirdPartyTypeshedPathEx) {
|
||||||
const candidateModuleName = this.getModuleNameFromPath(thirdPartyTypeshedPathEx, fileUri);
|
const candidateModuleName = getModuleNameFromPath(thirdPartyTypeshedPathEx, fileUri);
|
||||||
|
|
||||||
// Does this candidate look better than the previous best module name?
|
// Does this candidate look better than the previous best module name?
|
||||||
// We'll always try to use the shortest version.
|
// We'll always try to use the shortest version.
|
||||||
@ -1241,7 +1164,7 @@ export class ImportResolver {
|
|||||||
const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
|
const pythonSearchPaths = this.getPythonSearchPaths(importFailureInfo);
|
||||||
|
|
||||||
for (const searchPath of pythonSearchPaths) {
|
for (const searchPath of pythonSearchPaths) {
|
||||||
const candidateModuleNameInfo = this.getModuleNameInfoFromPath(searchPath, fileUri);
|
const candidateModuleNameInfo = _getModuleNameInfoFromPath(searchPath, fileUri);
|
||||||
|
|
||||||
if (candidateModuleNameInfo) {
|
if (candidateModuleNameInfo) {
|
||||||
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
if (candidateModuleNameInfo.containsInvalidCharacters) {
|
||||||
@ -1260,7 +1183,7 @@ export class ImportResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (detectPyTyped && importType === ImportType.ThirdParty) {
|
if (detectPyTyped && importType === ImportType.ThirdParty) {
|
||||||
const root = this.getParentImportResolutionRoot(fileUri, execEnv.root);
|
const root = getParentImportResolutionRoot(fileUri, execEnv.root);
|
||||||
|
|
||||||
// Go up directories one by one looking for a py.typed file.
|
// Go up directories one by one looking for a py.typed file.
|
||||||
let current: Uri | undefined = fileUri.getDirectory();
|
let current: Uri | undefined = fileUri.getDirectory();
|
||||||
@ -1552,7 +1475,7 @@ export class ImportResolver {
|
|||||||
moduleDescriptor: ImportedModuleDescriptor,
|
moduleDescriptor: ImportedModuleDescriptor,
|
||||||
allowPyi: boolean
|
allowPyi: boolean
|
||||||
): ImportResult | undefined {
|
): ImportResult | undefined {
|
||||||
const importName = this.formatImportName(moduleDescriptor);
|
const importName = formatImportName(moduleDescriptor);
|
||||||
const importFailureInfo: string[] = [];
|
const importFailureInfo: string[] = [];
|
||||||
|
|
||||||
// Check for a local stub file using stubPath.
|
// Check for a local stub file using stubPath.
|
||||||
@ -1828,16 +1751,6 @@ export class ImportResolver {
|
|||||||
return bestImportSoFar;
|
return bestImportSoFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isIdentifier(value: string) {
|
|
||||||
for (let i = 0; i < value.length; i++) {
|
|
||||||
if (i === 0 ? !isIdentifierStartChar(value.charCodeAt(i)) : !isIdentifierChar(value.charCodeAt(i))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _findTypeshedPath(
|
private _findTypeshedPath(
|
||||||
execEnv: ExecutionEnvironment,
|
execEnv: ExecutionEnvironment,
|
||||||
moduleDescriptor: ImportedModuleDescriptor,
|
moduleDescriptor: ImportedModuleDescriptor,
|
||||||
@ -2588,7 +2501,7 @@ export class ImportResolver {
|
|||||||
// Make sure we don't use parent folder resolution when checking whether the given name is resolvable.
|
// Make sure we don't use parent folder resolution when checking whether the given name is resolvable.
|
||||||
let importResult: ImportResult | undefined;
|
let importResult: ImportResult | undefined;
|
||||||
if (strictOnly) {
|
if (strictOnly) {
|
||||||
const importName = this.formatImportName(moduleDescriptor);
|
const importName = formatImportName(moduleDescriptor);
|
||||||
const importFailureInfo: string[] = [];
|
const importFailureInfo: string[] = [];
|
||||||
|
|
||||||
importResult = this._resolveImportStrict(
|
importResult = this._resolveImportStrict(
|
||||||
@ -2653,7 +2566,7 @@ export class ImportResolver {
|
|||||||
if (fileExt === '.py' || fileExt === '.pyi') {
|
if (fileExt === '.py' || fileExt === '.pyi') {
|
||||||
strippedFileName = stripFileExtension(filePath.fileName);
|
strippedFileName = stripFileExtension(filePath.fileName);
|
||||||
} else if (
|
} else if (
|
||||||
this._isNativeModuleFileExtension(fileExt) &&
|
_isNativeModuleFileExtension(fileExt) &&
|
||||||
!this.fileExistsCached(filePath.packageUri) &&
|
!this.fileExistsCached(filePath.packageUri) &&
|
||||||
!this.fileExistsCached(filePath.packageStubUri)
|
!this.fileExistsCached(filePath.packageStubUri)
|
||||||
) {
|
) {
|
||||||
@ -2770,15 +2683,10 @@ export class ImportResolver {
|
|||||||
const fileExtension = fileUri.lastExtension.toLowerCase();
|
const fileExtension = fileUri.lastExtension.toLowerCase();
|
||||||
const withoutExtension = stripFileExtension(fileUri.fileName, /* multiDotExtension */ true);
|
const withoutExtension = stripFileExtension(fileUri.fileName, /* multiDotExtension */ true);
|
||||||
return (
|
return (
|
||||||
this._isNativeModuleFileExtension(fileExtension) &&
|
_isNativeModuleFileExtension(fileExtension) && equateStringsCaseInsensitive(moduleName, withoutExtension)
|
||||||
equateStringsCaseInsensitive(moduleName, withoutExtension)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isNativeModuleFileExtension(fileExtension: string): boolean {
|
|
||||||
return supportedNativeLibExtensions.some((ext) => ext === fileExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _tryWalkUp(current: Uri | undefined): Uri | undefined {
|
private _tryWalkUp(current: Uri | undefined): Uri | undefined {
|
||||||
if (!current || current.isEmpty() || current.isRoot()) {
|
if (!current || current.isEmpty() || current.isRoot()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -2796,7 +2704,7 @@ export class ImportResolver {
|
|||||||
return (
|
return (
|
||||||
current &&
|
current &&
|
||||||
!current.isEmpty() &&
|
!current.isEmpty() &&
|
||||||
(current.isChild(root) || (current.equals(root) && this._isDefaultWorkspace(execEnv.root)))
|
(current.isChild(root) || (current.equals(root) && _isDefaultWorkspace(execEnv.root)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2806,3 +2714,95 @@ export type ImportResolverFactory = (
|
|||||||
options: ConfigOptions,
|
options: ConfigOptions,
|
||||||
host: Host
|
host: Host
|
||||||
) => ImportResolver;
|
) => ImportResolver;
|
||||||
|
|
||||||
|
export function formatImportName(moduleDescriptor: ImportedModuleDescriptor) {
|
||||||
|
return '.'.repeat(moduleDescriptor.leadingDots) + moduleDescriptor.nameParts.join('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getParentImportResolutionRoot(sourceFileUri: Uri, executionRoot: Uri | undefined): Uri {
|
||||||
|
if (!_isDefaultWorkspace(executionRoot)) {
|
||||||
|
return executionRoot!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceFileUri.getDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getModuleNameFromPath(
|
||||||
|
containerPath: Uri,
|
||||||
|
fileUri: Uri,
|
||||||
|
stripTopContainerDir = false
|
||||||
|
): string | undefined {
|
||||||
|
const moduleNameInfo = _getModuleNameInfoFromPath(containerPath, fileUri, stripTopContainerDir);
|
||||||
|
if (!moduleNameInfo || moduleNameInfo.containsInvalidCharacters) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return moduleNameInfo.moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getModuleNameInfoFromPath(
|
||||||
|
containerPath: Uri,
|
||||||
|
fileUri: Uri,
|
||||||
|
stripTopContainerDir = false
|
||||||
|
): ModuleNameInfoFromPath | undefined {
|
||||||
|
let fileUriWithoutExtension = fileUri.stripExtension();
|
||||||
|
|
||||||
|
// If module is native, strip platform part, such as 'cp36-win_amd64' in 'mtrand.cp36-win_amd64'.
|
||||||
|
if (_isNativeModuleFileExtension(fileUri.lastExtension)) {
|
||||||
|
fileUriWithoutExtension = fileUriWithoutExtension.stripExtension();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileUriWithoutExtension.startsWith(containerPath)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip off the '/__init__' if it's present.
|
||||||
|
if (fileUriWithoutExtension.pathEndsWith('__init__')) {
|
||||||
|
fileUriWithoutExtension = fileUriWithoutExtension.getDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = Array.from(containerPath.getRelativePathComponents(fileUriWithoutExtension));
|
||||||
|
if (stripTopContainerDir) {
|
||||||
|
if (parts.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
parts.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the case where the symbol was resolved to a stubs package
|
||||||
|
// rather than the real package. We'll strip off the "-stubs" suffix
|
||||||
|
// in this case.
|
||||||
|
if (parts[0].endsWith(stubsSuffix)) {
|
||||||
|
parts[0] = parts[0].substr(0, parts[0].length - stubsSuffix.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether parts contains invalid characters.
|
||||||
|
const containsInvalidCharacters = parts.some((p) => !_isIdentifier(p));
|
||||||
|
|
||||||
|
return {
|
||||||
|
moduleName: parts.join('.'),
|
||||||
|
containsInvalidCharacters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isNativeModuleFileExtension(fileExtension: string): boolean {
|
||||||
|
return supportedNativeLibExtensions.some((ext) => ext === fileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isDefaultWorkspace(uri: Uri | undefined) {
|
||||||
|
return !uri || uri.isEmpty() || Uri.isDefaultWorkspace(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isIdentifier(value: string) {
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
if (i === 0 ? !isIdentifierStartChar(value.charCodeAt(i)) : !isIdentifierChar(value.charCodeAt(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -703,7 +703,7 @@ export function getTypeOfBinaryOperation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
// Exempt "|" because it might be a union operation involving unknowns.
|
// Exempt "|" because it might be a union operation involving unknowns.
|
||||||
if (node.operator !== OperatorType.BitwiseOr) {
|
if (node.operator !== OperatorType.BitwiseOr) {
|
||||||
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.binaryOperationNotAllowed(), node);
|
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.binaryOperationNotAllowed(), node);
|
||||||
@ -950,7 +950,7 @@ export function getTypeOfUnaryOperation(
|
|||||||
flags: EvaluatorFlags,
|
flags: EvaluatorFlags,
|
||||||
inferenceContext: InferenceContext | undefined
|
inferenceContext: InferenceContext | undefined
|
||||||
): TypeResult {
|
): TypeResult {
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.unaryOperationNotAllowed(), node);
|
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.unaryOperationNotAllowed(), node);
|
||||||
return { type: UnknownType.create() };
|
return { type: UnknownType.create() };
|
||||||
}
|
}
|
||||||
@ -1087,7 +1087,7 @@ export function getTypeOfTernaryOperation(
|
|||||||
): TypeResult {
|
): TypeResult {
|
||||||
const fileInfo = getFileInfo(node);
|
const fileInfo = getFileInfo(node);
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.ternaryNotAllowed(), node);
|
evaluator.addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.ternaryNotAllowed(), node);
|
||||||
return { type: UnknownType.create() };
|
return { type: UnknownType.create() };
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import {
|
|||||||
PatternValueNode,
|
PatternValueNode,
|
||||||
} from '../parser/parseNodes';
|
} from '../parser/parseNodes';
|
||||||
import { CodeFlowReferenceExpressionNode } from './codeFlowTypes';
|
import { CodeFlowReferenceExpressionNode } from './codeFlowTypes';
|
||||||
import { populateTypeVarContextBasedOnExpectedType } from './constraintSolver';
|
import { addConstraintsForExpectedType } from './constraintSolver';
|
||||||
import { getTypeVarScopesForNode, isMatchingExpression } from './parseTreeUtils';
|
import { getTypeVarScopesForNode, isMatchingExpression } from './parseTreeUtils';
|
||||||
import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes';
|
||||||
import {
|
import {
|
||||||
@ -685,7 +685,7 @@ function narrowTypeBasedOnClassPattern(
|
|||||||
// specialize it with Unknown type arguments.
|
// specialize it with Unknown type arguments.
|
||||||
if (isClass(exprType) && !exprType.typeAliasInfo) {
|
if (isClass(exprType) && !exprType.typeAliasInfo) {
|
||||||
exprType = ClassType.cloneRemoveTypePromotions(exprType);
|
exprType = ClassType.cloneRemoveTypePromotions(exprType);
|
||||||
exprType = specializeWithUnknownTypeArgs(exprType);
|
exprType = specializeWithUnknownTypeArgs(exprType, evaluator.getTupleClassType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are there any positional arguments? If so, try to get the mappings for
|
// Are there any positional arguments? If so, try to get the mappings for
|
||||||
@ -921,7 +921,7 @@ function narrowTypeBasedOnClassPattern(
|
|||||||
|
|
||||||
const matchTypeInstance = ClassType.cloneAsInstance(unspecializedMatchType);
|
const matchTypeInstance = ClassType.cloneAsInstance(unspecializedMatchType);
|
||||||
if (
|
if (
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluator,
|
evaluator,
|
||||||
matchTypeInstance,
|
matchTypeInstance,
|
||||||
subjectSubtypeExpanded,
|
subjectSubtypeExpanded,
|
||||||
@ -932,6 +932,7 @@ function narrowTypeBasedOnClassPattern(
|
|||||||
) {
|
) {
|
||||||
resultType = applySolvedTypeVars(matchTypeInstance, typeVarContext, {
|
resultType = applySolvedTypeVars(matchTypeInstance, typeVarContext, {
|
||||||
unknownIfNotFound: true,
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: evaluator.getTupleClassType(),
|
||||||
}) as ClassType;
|
}) as ClassType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1454,7 +1455,7 @@ function getSequencePatternInfo(
|
|||||||
if (sequenceType && isInstantiableClass(sequenceType)) {
|
if (sequenceType && isInstantiableClass(sequenceType)) {
|
||||||
const sequenceTypeVarContext = new TypeVarContext(getTypeVarScopeId(sequenceType));
|
const sequenceTypeVarContext = new TypeVarContext(getTypeVarScopeId(sequenceType));
|
||||||
if (
|
if (
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluator,
|
evaluator,
|
||||||
ClassType.cloneAsInstance(sequenceType),
|
ClassType.cloneAsInstance(sequenceType),
|
||||||
subtype,
|
subtype,
|
||||||
|
@ -102,7 +102,7 @@ export function assignClassToProtocol(
|
|||||||
// If the caller has provided a destination type var context,
|
// If the caller has provided a destination type var context,
|
||||||
// we can't use the cached value unless the dest has no type
|
// we can't use the cached value unless the dest has no type
|
||||||
// parameters to solve.
|
// parameters to solve.
|
||||||
if (!destTypeVarContext || destType.details.typeParameters.length === 0) {
|
if (!destTypeVarContext || !requiresSpecialization(destType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,7 +643,7 @@ export class AnalyzerService {
|
|||||||
|
|
||||||
const configs = this._getExtendedConfigurations(configFilePath ?? pyprojectFilePath);
|
const configs = this._getExtendedConfigurations(configFilePath ?? pyprojectFilePath);
|
||||||
|
|
||||||
if (configs) {
|
if (configs && configs.length > 0) {
|
||||||
for (const config of configs) {
|
for (const config of configs) {
|
||||||
configOptions.initializeFromJson(
|
configOptions.initializeFromJson(
|
||||||
config.configFileJsonObj,
|
config.configFileJsonObj,
|
||||||
|
@ -97,7 +97,7 @@ import {
|
|||||||
isCodeFlowSupportedForReference,
|
isCodeFlowSupportedForReference,
|
||||||
wildcardImportReferenceKey,
|
wildcardImportReferenceKey,
|
||||||
} from './codeFlowTypes';
|
} from './codeFlowTypes';
|
||||||
import { assignTypeToTypeVar, populateTypeVarContextBasedOnExpectedType, updateTypeVarType } from './constraintSolver';
|
import { addConstraintsForExpectedType, assignTypeToTypeVar, updateTypeVarType } from './constraintSolver';
|
||||||
import {
|
import {
|
||||||
createFunctionFromConstructor,
|
createFunctionFromConstructor,
|
||||||
getBoundInitMethod,
|
getBoundInitMethod,
|
||||||
@ -1266,7 +1266,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ParseNodeType.AssignmentExpression: {
|
case ParseNodeType.AssignmentExpression: {
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.walrusNotAllowed(), node);
|
addError(LocMessage.walrusNotAllowed(), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,7 +1294,7 @@ export function createTypeEvaluator(
|
|||||||
typeResult = getTypeOfExpression(
|
typeResult = getTypeOfExpression(
|
||||||
node.typeAnnotation,
|
node.typeAnnotation,
|
||||||
EvaluatorFlags.ExpectingInstantiableType |
|
EvaluatorFlags.ExpectingInstantiableType |
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType |
|
EvaluatorFlags.EvaluateStringLiteralAsType |
|
||||||
EvaluatorFlags.DisallowParamSpec |
|
EvaluatorFlags.DisallowParamSpec |
|
||||||
EvaluatorFlags.DisallowTypeVarTuple |
|
EvaluatorFlags.DisallowTypeVarTuple |
|
||||||
@ -1337,7 +1337,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
// If this is a PEP 695 type alias, remove the special form so the type
|
// If this is a PEP 695 type alias, remove the special form so the type
|
||||||
// printer prints it as its aliased type rather than TypeAliasType.
|
// printer prints it as its aliased type rather than TypeAliasType.
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
if (typeResult.type.specialForm && ClassType.isBuiltIn(typeResult.type.specialForm, 'TypeAliasType')) {
|
if (typeResult.type.specialForm && ClassType.isBuiltIn(typeResult.type.specialForm, 'TypeAliasType')) {
|
||||||
typeResult.type = TypeBase.cloneAsSpecialForm(typeResult.type, undefined);
|
typeResult.type = TypeBase.cloneAsSpecialForm(typeResult.type, undefined);
|
||||||
}
|
}
|
||||||
@ -1404,7 +1404,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfAwaitOperator(node: AwaitNode, flags: EvaluatorFlags, inferenceContext?: InferenceContext) {
|
function getTypeOfAwaitOperator(node: AwaitNode, flags: EvaluatorFlags, inferenceContext?: InferenceContext) {
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.awaitNotAllowed(), node);
|
addError(LocMessage.awaitNotAllowed(), node);
|
||||||
return { type: UnknownType.create() };
|
return { type: UnknownType.create() };
|
||||||
}
|
}
|
||||||
@ -1484,7 +1484,7 @@ export function createTypeEvaluator(
|
|||||||
ClassType.isBuiltIn(iterType, 'tuple')
|
ClassType.isBuiltIn(iterType, 'tuple')
|
||||||
) {
|
) {
|
||||||
typeResult = { type: ClassType.cloneForUnpacked(iterType) };
|
typeResult = { type: ClassType.cloneForUnpacked(iterType) };
|
||||||
} else if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
} else if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.unpackInAnnotation(), node, node.starToken);
|
addError(LocMessage.unpackInAnnotation(), node, node.starToken);
|
||||||
typeResult = { type: UnknownType.create() };
|
typeResult = { type: UnknownType.create() };
|
||||||
} else {
|
} else {
|
||||||
@ -1726,7 +1726,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
let evaluatorFlags =
|
let evaluatorFlags =
|
||||||
EvaluatorFlags.ExpectingInstantiableType |
|
EvaluatorFlags.ExpectingInstantiableType |
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.ConvertEllipsisToAny |
|
EvaluatorFlags.ConvertEllipsisToAny |
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType;
|
EvaluatorFlags.EvaluateStringLiteralAsType;
|
||||||
|
|
||||||
@ -4411,7 +4411,7 @@ export function createTypeEvaluator(
|
|||||||
node,
|
node,
|
||||||
name,
|
name,
|
||||||
!allowForwardReferences,
|
!allowForwardReferences,
|
||||||
allowForwardReferences && (flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0
|
allowForwardReferences && (flags & EvaluatorFlags.ExpectingTypeExpression) !== 0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!symbolWithScope) {
|
if (!symbolWithScope) {
|
||||||
@ -4424,7 +4424,7 @@ export function createTypeEvaluator(
|
|||||||
alias,
|
alias,
|
||||||
alias.value,
|
alias.value,
|
||||||
!allowForwardReferences,
|
!allowForwardReferences,
|
||||||
allowForwardReferences && (flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0
|
allowForwardReferences && (flags & EvaluatorFlags.ExpectingTypeExpression) !== 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4517,7 +4517,7 @@ export function createTypeEvaluator(
|
|||||||
const codeFlowTypeResult = getFlowTypeOfReference(node, /* startNode */ undefined, {
|
const codeFlowTypeResult = getFlowTypeOfReference(node, /* startNode */ undefined, {
|
||||||
targetSymbolId: symbol.id,
|
targetSymbolId: symbol.id,
|
||||||
typeAtStart: { type: typeAtStart, isIncomplete: isTypeAtStartIncomplete },
|
typeAtStart: { type: typeAtStart, isIncomplete: isTypeAtStartIncomplete },
|
||||||
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0,
|
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeExpression) !== 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (codeFlowTypeResult.type) {
|
if (codeFlowTypeResult.type) {
|
||||||
@ -4532,7 +4532,7 @@ export function createTypeEvaluator(
|
|||||||
// Detect, report, and fill in missing type arguments if appropriate.
|
// Detect, report, and fill in missing type arguments if appropriate.
|
||||||
type = reportMissingTypeArguments(node, type, flags);
|
type = reportMissingTypeArguments(node, type, flags);
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
// Verify that the name does not refer to a (non type alias) variable.
|
// Verify that the name does not refer to a (non type alias) variable.
|
||||||
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
||||||
let isAllowedTypeForVariable = isTypeVar(type) || isTypeAliasPlaceholder(type);
|
let isAllowedTypeForVariable = isTypeVar(type) || isTypeAliasPlaceholder(type);
|
||||||
@ -4593,7 +4593,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
type = convertTypeVarToRuntimeInstance(node, type, flags);
|
type = convertTypeVarToRuntimeInstance(node, type, flags);
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) === 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) === 0) {
|
||||||
reportUseOfTypeCheckOnly(type, node);
|
reportUseOfTypeCheckOnly(type, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4926,7 +4926,10 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
let defaultType: Type;
|
let defaultType: Type;
|
||||||
if (param.details.isDefaultExplicit || param.details.isParamSpec) {
|
if (param.details.isDefaultExplicit || param.details.isParamSpec) {
|
||||||
defaultType = applySolvedTypeVars(param, typeVarContext, { unknownIfNotFound: true });
|
defaultType = applySolvedTypeVars(param, typeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
|
});
|
||||||
} else if (param.details.isVariadic && tupleClass && isInstantiableClass(tupleClass)) {
|
} else if (param.details.isVariadic && tupleClass && isInstantiableClass(tupleClass)) {
|
||||||
defaultType = makeTupleObject(
|
defaultType = makeTupleObject(
|
||||||
[{ type: UnknownType.create(), isUnbounded: true }],
|
[{ type: UnknownType.create(), isUnbounded: true }],
|
||||||
@ -4951,7 +4954,10 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
type = TypeBase.cloneForTypeAlias(
|
type = TypeBase.cloneForTypeAlias(
|
||||||
applySolvedTypeVars(type, typeVarContext, { unknownIfNotFound: true }),
|
applySolvedTypeVars(type, typeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
|
}),
|
||||||
type.typeAliasInfo.name,
|
type.typeAliasInfo.name,
|
||||||
type.typeAliasInfo.fullName,
|
type.typeAliasInfo.fullName,
|
||||||
type.typeAliasInfo.moduleName,
|
type.typeAliasInfo.moduleName,
|
||||||
@ -5088,7 +5094,7 @@ export function createTypeEvaluator(
|
|||||||
let leftExprFlags = EvaluatorFlags.MemberAccessBaseDefaults;
|
let leftExprFlags = EvaluatorFlags.MemberAccessBaseDefaults;
|
||||||
leftExprFlags |=
|
leftExprFlags |=
|
||||||
flags &
|
flags &
|
||||||
(EvaluatorFlags.ExpectingTypeAnnotation |
|
(EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.VariableTypeAnnotation |
|
EvaluatorFlags.VariableTypeAnnotation |
|
||||||
EvaluatorFlags.AllowForwardReferences |
|
EvaluatorFlags.AllowForwardReferences |
|
||||||
EvaluatorFlags.NotParsedByInterpreter |
|
EvaluatorFlags.NotParsedByInterpreter |
|
||||||
@ -5155,7 +5161,7 @@ export function createTypeEvaluator(
|
|||||||
const codeFlowTypeResult = getFlowTypeOfReference(node, /* startNode */ undefined, {
|
const codeFlowTypeResult = getFlowTypeOfReference(node, /* startNode */ undefined, {
|
||||||
targetSymbolId: indeterminateSymbolId,
|
targetSymbolId: indeterminateSymbolId,
|
||||||
typeAtStart: { type: typeAtStart, isIncomplete: isTypeAtStartIncomplete },
|
typeAtStart: { type: typeAtStart, isIncomplete: isTypeAtStartIncomplete },
|
||||||
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0,
|
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeExpression) !== 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (codeFlowTypeResult.type) {
|
if (codeFlowTypeResult.type) {
|
||||||
@ -5288,7 +5294,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// It's illegal to reference a member from a type variable.
|
// It's illegal to reference a member from a type variable.
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
if (!isIncomplete) {
|
if (!isIncomplete) {
|
||||||
addDiagnostic(
|
addDiagnostic(
|
||||||
DiagnosticRule.reportGeneralTypeIssues,
|
DiagnosticRule.reportGeneralTypeIssues,
|
||||||
@ -5632,7 +5638,7 @@ export function createTypeEvaluator(
|
|||||||
type = isFunctionRule ? AnyType.create() : UnknownType.create();
|
type = isFunctionRule ? AnyType.create() : UnknownType.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) === 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) === 0) {
|
||||||
reportUseOfTypeCheckOnly(type, node.memberName);
|
reportUseOfTypeCheckOnly(type, node.memberName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6515,7 +6521,7 @@ export function createTypeEvaluator(
|
|||||||
type: indexTypeResult.type,
|
type: indexTypeResult.type,
|
||||||
isIncomplete: !!baseTypeResult.isIncomplete || !!indexTypeResult.isIncomplete,
|
isIncomplete: !!baseTypeResult.isIncomplete || !!indexTypeResult.isIncomplete,
|
||||||
},
|
},
|
||||||
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0,
|
skipConditionalNarrowing: (flags & EvaluatorFlags.ExpectingTypeExpression) !== 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (codeFlowTypeResult.type) {
|
if (codeFlowTypeResult.type) {
|
||||||
@ -6855,7 +6861,10 @@ export function createTypeEvaluator(
|
|||||||
if (index < typeArgs.length) {
|
if (index < typeArgs.length) {
|
||||||
typeArgType = convertToInstance(typeArgs[index].type);
|
typeArgType = convertToInstance(typeArgs[index].type);
|
||||||
} else if (param.details.isDefaultExplicit) {
|
} else if (param.details.isDefaultExplicit) {
|
||||||
typeArgType = applySolvedTypeVars(param, typeVarContext, { unknownIfNotFound: true });
|
typeArgType = applySolvedTypeVars(param, typeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
typeArgType = UnknownType.create();
|
typeArgType = UnknownType.create();
|
||||||
}
|
}
|
||||||
@ -7018,7 +7027,7 @@ export function createTypeEvaluator(
|
|||||||
getIndexAccessMagicMethodName(usage)
|
getIndexAccessMagicMethodName(usage)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
||||||
addDiagnostic(
|
addDiagnostic(
|
||||||
DiagnosticRule.reportInvalidTypeArguments,
|
DiagnosticRule.reportInvalidTypeArguments,
|
||||||
@ -7059,7 +7068,7 @@ export function createTypeEvaluator(
|
|||||||
// Special-case InitVar, used in dataclasses.
|
// Special-case InitVar, used in dataclasses.
|
||||||
const typeArgs = getTypeArgs(node, flags);
|
const typeArgs = getTypeArgs(node, flags);
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
if ((flags & EvaluatorFlags.VariableTypeAnnotation) === 0) {
|
if ((flags & EvaluatorFlags.VariableTypeAnnotation) === 0) {
|
||||||
addError(LocMessage.initVarNotAllowed(), node.baseExpression);
|
addError(LocMessage.initVarNotAllowed(), node.baseExpression);
|
||||||
}
|
}
|
||||||
@ -7743,7 +7752,7 @@ export function createTypeEvaluator(
|
|||||||
signatureTracker: UniqueSignatureTracker | undefined
|
signatureTracker: UniqueSignatureTracker | undefined
|
||||||
): TypeResult {
|
): TypeResult {
|
||||||
if (
|
if (
|
||||||
(flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0 &&
|
(flags & EvaluatorFlags.ExpectingTypeExpression) !== 0 &&
|
||||||
node.parent?.nodeType !== ParseNodeType.Argument
|
node.parent?.nodeType !== ParseNodeType.Argument
|
||||||
) {
|
) {
|
||||||
// This is allowed inside of an index trailer, specifically
|
// This is allowed inside of an index trailer, specifically
|
||||||
@ -7769,7 +7778,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
flags &= ~(
|
flags &= ~(
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType |
|
EvaluatorFlags.EvaluateStringLiteralAsType |
|
||||||
EvaluatorFlags.ExpectingInstantiableType
|
EvaluatorFlags.ExpectingInstantiableType
|
||||||
);
|
);
|
||||||
@ -7872,7 +7881,7 @@ export function createTypeEvaluator(
|
|||||||
} else {
|
} else {
|
||||||
const tupleTypeVarContext = new TypeVarContext(getTypeVarScopeId(tupleClass));
|
const tupleTypeVarContext = new TypeVarContext(getTypeVarScopeId(tupleClass));
|
||||||
if (
|
if (
|
||||||
!populateTypeVarContextBasedOnExpectedType(
|
!addConstraintsForExpectedType(
|
||||||
evaluatorInterface,
|
evaluatorInterface,
|
||||||
ClassType.cloneAsInstance(tupleClass),
|
ClassType.cloneAsInstance(tupleClass),
|
||||||
inferenceContext.expectedType,
|
inferenceContext.expectedType,
|
||||||
@ -8001,7 +8010,7 @@ export function createTypeEvaluator(
|
|||||||
// allowed, and it's a common mistake, so we want to emit a diagnostic
|
// allowed, and it's a common mistake, so we want to emit a diagnostic
|
||||||
// that guides the user to the right solution.
|
// that guides the user to the right solution.
|
||||||
if (
|
if (
|
||||||
(flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0 &&
|
(flags & EvaluatorFlags.ExpectingTypeExpression) !== 0 &&
|
||||||
node.leftExpression.nodeType === ParseNodeType.Name &&
|
node.leftExpression.nodeType === ParseNodeType.Name &&
|
||||||
node.leftExpression.value === 'type'
|
node.leftExpression.value === 'type'
|
||||||
) {
|
) {
|
||||||
@ -8129,7 +8138,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.typeAnnotationCall(), node);
|
addDiagnostic(DiagnosticRule.reportInvalidTypeForm, LocMessage.typeAnnotationCall(), node);
|
||||||
|
|
||||||
typeResult = { type: UnknownType.create() };
|
typeResult = { type: UnknownType.create() };
|
||||||
@ -11316,7 +11325,7 @@ export function createTypeEvaluator(
|
|||||||
if (isClassInstance(effectiveExpectedType) && !isTypeSame(effectiveReturnType, effectiveExpectedType)) {
|
if (isClassInstance(effectiveExpectedType) && !isTypeSame(effectiveReturnType, effectiveExpectedType)) {
|
||||||
const tempTypeVarContext = new TypeVarContext(getTypeVarScopeId(effectiveReturnType));
|
const tempTypeVarContext = new TypeVarContext(getTypeVarScopeId(effectiveReturnType));
|
||||||
if (
|
if (
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluatorInterface,
|
evaluatorInterface,
|
||||||
effectiveReturnType,
|
effectiveReturnType,
|
||||||
effectiveExpectedType,
|
effectiveExpectedType,
|
||||||
@ -11333,6 +11342,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
effectiveExpectedType = applySolvedTypeVars(genericReturnType, tempTypeVarContext, {
|
effectiveExpectedType = applySolvedTypeVars(genericReturnType, tempTypeVarContext, {
|
||||||
unknownIfNotFound: true,
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
});
|
});
|
||||||
|
|
||||||
effectiveFlags |= AssignTypeFlags.SkipPopulateUnknownExpectedType;
|
effectiveFlags |= AssignTypeFlags.SkipPopulateUnknownExpectedType;
|
||||||
@ -11633,6 +11643,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
let specializedReturnType = applySolvedTypeVars(returnType, typeVarContext, {
|
let specializedReturnType = applySolvedTypeVars(returnType, typeVarContext, {
|
||||||
unknownIfNotFound,
|
unknownIfNotFound,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
unknownExemptTypeVars: getUnknownExemptTypeVarsForReturnType(type, returnType),
|
unknownExemptTypeVars: getUnknownExemptTypeVarsForReturnType(type, returnType),
|
||||||
eliminateUnsolvedInUnions,
|
eliminateUnsolvedInUnions,
|
||||||
applyInScopePlaceholders: true,
|
applyInScopePlaceholders: true,
|
||||||
@ -12067,7 +12078,7 @@ export function createTypeEvaluator(
|
|||||||
EvaluatorFlags.DisallowTypeVarTuple |
|
EvaluatorFlags.DisallowTypeVarTuple |
|
||||||
EvaluatorFlags.DisallowFinal |
|
EvaluatorFlags.DisallowFinal |
|
||||||
EvaluatorFlags.DoNotSpecialize
|
EvaluatorFlags.DoNotSpecialize
|
||||||
: EvaluatorFlags.DoNotSpecialize | EvaluatorFlags.DisallowFinal;
|
: EvaluatorFlags.DisallowFinal | EvaluatorFlags.DoNotSpecialize;
|
||||||
const exprTypeResult = getTypeOfExpression(
|
const exprTypeResult = getTypeOfExpression(
|
||||||
argParam.argument.valueExpression,
|
argParam.argument.valueExpression,
|
||||||
flags,
|
flags,
|
||||||
@ -12516,6 +12527,7 @@ export function createTypeEvaluator(
|
|||||||
const concreteDefaultType = makeTopLevelTypeVarsConcrete(
|
const concreteDefaultType = makeTopLevelTypeVarsConcrete(
|
||||||
applySolvedTypeVars(typeVar.details.defaultType, typeVarContext, {
|
applySolvedTypeVars(typeVar.details.defaultType, typeVarContext, {
|
||||||
unknownIfNotFound: true,
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -13006,14 +13018,12 @@ export function createTypeEvaluator(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let classFlags = baseClass.details.flags & ~(ClassTypeFlags.BuiltInClass | ClassTypeFlags.SpecialBuiltIn);
|
|
||||||
classFlags |= ClassTypeFlags.Final | ClassTypeFlags.NewTypeClass | ClassTypeFlags.ValidTypeAliasClass;
|
|
||||||
const classType = ClassType.createInstantiable(
|
const classType = ClassType.createInstantiable(
|
||||||
className,
|
className,
|
||||||
ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className),
|
ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className),
|
||||||
fileInfo.moduleName,
|
fileInfo.moduleName,
|
||||||
fileInfo.fileUri,
|
fileInfo.fileUri,
|
||||||
classFlags,
|
ClassTypeFlags.Final | ClassTypeFlags.NewTypeClass | ClassTypeFlags.ValidTypeAliasClass,
|
||||||
ParseTreeUtils.getTypeSourceId(errorNode),
|
ParseTreeUtils.getTypeSourceId(errorNode),
|
||||||
/* declaredMetaclass */ undefined,
|
/* declaredMetaclass */ undefined,
|
||||||
baseClass.details.effectiveMetaclass
|
baseClass.details.effectiveMetaclass
|
||||||
@ -13255,7 +13265,7 @@ export function createTypeEvaluator(
|
|||||||
inferenceContext: InferenceContext | undefined
|
inferenceContext: InferenceContext | undefined
|
||||||
): TypeResult {
|
): TypeResult {
|
||||||
if (
|
if (
|
||||||
(flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0 &&
|
(flags & EvaluatorFlags.ExpectingTypeExpression) !== 0 &&
|
||||||
node.parent?.nodeType !== ParseNodeType.Argument
|
node.parent?.nodeType !== ParseNodeType.Argument
|
||||||
) {
|
) {
|
||||||
const diag = new DiagnosticAddendum();
|
const diag = new DiagnosticAddendum();
|
||||||
@ -13397,7 +13407,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
const dictTypeVarContext = new TypeVarContext(getTypeVarScopeId(builtInDict));
|
const dictTypeVarContext = new TypeVarContext(getTypeVarScopeId(builtInDict));
|
||||||
if (
|
if (
|
||||||
!populateTypeVarContextBasedOnExpectedType(
|
!addConstraintsForExpectedType(
|
||||||
evaluatorInterface,
|
evaluatorInterface,
|
||||||
builtInDict,
|
builtInDict,
|
||||||
inferenceContext.expectedType,
|
inferenceContext.expectedType,
|
||||||
@ -13575,7 +13585,7 @@ export function createTypeEvaluator(
|
|||||||
const keyFlags =
|
const keyFlags =
|
||||||
flags &
|
flags &
|
||||||
~(
|
~(
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType |
|
EvaluatorFlags.EvaluateStringLiteralAsType |
|
||||||
EvaluatorFlags.ExpectingInstantiableType
|
EvaluatorFlags.ExpectingInstantiableType
|
||||||
);
|
);
|
||||||
@ -13837,7 +13847,7 @@ export function createTypeEvaluator(
|
|||||||
inferenceContext: InferenceContext | undefined
|
inferenceContext: InferenceContext | undefined
|
||||||
): TypeResult {
|
): TypeResult {
|
||||||
if (
|
if (
|
||||||
(flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0 &&
|
(flags & EvaluatorFlags.ExpectingTypeExpression) !== 0 &&
|
||||||
node.nodeType === ParseNodeType.List &&
|
node.nodeType === ParseNodeType.List &&
|
||||||
node.parent?.nodeType !== ParseNodeType.Argument
|
node.parent?.nodeType !== ParseNodeType.Argument
|
||||||
) {
|
) {
|
||||||
@ -13847,7 +13857,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
flags &= ~(
|
flags &= ~(
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType |
|
EvaluatorFlags.EvaluateStringLiteralAsType |
|
||||||
EvaluatorFlags.ExpectingInstantiableType
|
EvaluatorFlags.ExpectingInstantiableType
|
||||||
);
|
);
|
||||||
@ -14016,7 +14026,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
const typeVarContext = new TypeVarContext(getTypeVarScopeId(expectedClassType));
|
const typeVarContext = new TypeVarContext(getTypeVarScopeId(expectedClassType));
|
||||||
if (
|
if (
|
||||||
!populateTypeVarContextBasedOnExpectedType(
|
!addConstraintsForExpectedType(
|
||||||
evaluatorInterface,
|
evaluatorInterface,
|
||||||
ClassType.cloneAsInstance(expectedClassType),
|
ClassType.cloneAsInstance(expectedClassType),
|
||||||
inferenceContext.expectedType,
|
inferenceContext.expectedType,
|
||||||
@ -14921,7 +14931,7 @@ export function createTypeEvaluator(
|
|||||||
// If no type arguments are provided, the resulting type
|
// If no type arguments are provided, the resulting type
|
||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.optionalExtraArgs(), errorNode);
|
addError(LocMessage.optionalExtraArgs(), errorNode);
|
||||||
return UnknownType.create();
|
return UnknownType.create();
|
||||||
}
|
}
|
||||||
@ -15139,7 +15149,7 @@ export function createTypeEvaluator(
|
|||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if (!typeArgs) {
|
if (!typeArgs) {
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.typeGuardArgCount(), errorNode);
|
addError(LocMessage.typeGuardArgCount(), errorNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15184,7 +15194,7 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
const enclosingClassTypeResult = enclosingClass ? getTypeOfClass(enclosingClass) : undefined;
|
const enclosingClassTypeResult = enclosingClass ? getTypeOfClass(enclosingClass) : undefined;
|
||||||
if (!enclosingClassTypeResult) {
|
if (!enclosingClassTypeResult) {
|
||||||
if ((flags & (EvaluatorFlags.ExpectingTypeAnnotation | EvaluatorFlags.ExpectingInstantiableType)) !== 0) {
|
if ((flags & (EvaluatorFlags.ExpectingTypeExpression | EvaluatorFlags.ExpectingInstantiableType)) !== 0) {
|
||||||
addDiagnostic(DiagnosticRule.reportGeneralTypeIssues, LocMessage.selfTypeContext(), errorNode);
|
addDiagnostic(DiagnosticRule.reportGeneralTypeIssues, LocMessage.selfTypeContext(), errorNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15246,7 +15256,7 @@ export function createTypeEvaluator(
|
|||||||
// If no type arguments are provided, the resulting type
|
// If no type arguments are provided, the resulting type
|
||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if (!typeArgs && (flags & EvaluatorFlags.ExpectingTypeAnnotation) === 0) {
|
if (!typeArgs && (flags & EvaluatorFlags.ExpectingTypeExpression) === 0) {
|
||||||
return { type: classType };
|
return { type: classType };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15330,7 +15340,7 @@ export function createTypeEvaluator(
|
|||||||
// If no type arguments are provided, the resulting type
|
// If no type arguments are provided, the resulting type
|
||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if (!typeArgs && (flags & EvaluatorFlags.ExpectingTypeAnnotation) === 0) {
|
if (!typeArgs && (flags & EvaluatorFlags.ExpectingTypeExpression) === 0) {
|
||||||
return classType;
|
return classType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15654,7 +15664,7 @@ export function createTypeEvaluator(
|
|||||||
// If no type arguments are provided, the resulting type
|
// If no type arguments are provided, the resulting type
|
||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) {
|
if ((flags & EvaluatorFlags.ExpectingTypeExpression) !== 0) {
|
||||||
addError(LocMessage.unionTypeArgCount(), errorNode);
|
addError(LocMessage.unionTypeArgCount(), errorNode);
|
||||||
return NeverType.createNever();
|
return NeverType.createNever();
|
||||||
}
|
}
|
||||||
@ -15741,7 +15751,7 @@ export function createTypeEvaluator(
|
|||||||
// If no type arguments are provided, the resulting type
|
// If no type arguments are provided, the resulting type
|
||||||
// depends on whether we're evaluating a type annotation or
|
// depends on whether we're evaluating a type annotation or
|
||||||
// we're in some other context.
|
// we're in some other context.
|
||||||
if ((flags & (EvaluatorFlags.ExpectingTypeAnnotation | EvaluatorFlags.DisallowNakedGeneric)) !== 0) {
|
if ((flags & (EvaluatorFlags.ExpectingTypeExpression | EvaluatorFlags.DisallowNakedGeneric)) !== 0) {
|
||||||
addError(LocMessage.genericTypeArgMissing(), errorNode);
|
addError(LocMessage.genericTypeArgMissing(), errorNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16113,19 +16123,8 @@ export function createTypeEvaluator(
|
|||||||
flags |= EvaluatorFlags.DoNotSpecialize;
|
flags |= EvaluatorFlags.DoNotSpecialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDeclaredTypeAlias(node.leftExpression)) {
|
|
||||||
flags |=
|
|
||||||
EvaluatorFlags.ExpectingInstantiableType |
|
|
||||||
EvaluatorFlags.ExpectingTypeAnnotation |
|
|
||||||
EvaluatorFlags.EvaluateStringLiteralAsType |
|
|
||||||
EvaluatorFlags.DisallowParamSpec |
|
|
||||||
EvaluatorFlags.DisallowTypeVarTuple |
|
|
||||||
EvaluatorFlags.DisallowClassVar;
|
|
||||||
flags &= ~EvaluatorFlags.DoNotSpecialize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this type already cached?
|
// Is this type already cached?
|
||||||
let rightHandType = readTypeCache(node.rightExpression, flags);
|
let rightHandType = readTypeCache(node.rightExpression, /* flags */ undefined);
|
||||||
let isIncomplete = false;
|
let isIncomplete = false;
|
||||||
let expectedTypeDiagAddendum: DiagnosticAddendum | undefined;
|
let expectedTypeDiagAddendum: DiagnosticAddendum | undefined;
|
||||||
|
|
||||||
@ -16138,76 +16137,118 @@ export function createTypeEvaluator(
|
|||||||
writeTypeCache(node.rightExpression, { type: rightHandType }, EvaluatorFlags.None);
|
writeTypeCache(node.rightExpression, { type: rightHandType }, EvaluatorFlags.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!rightHandType) {
|
if (!rightHandType) {
|
||||||
// Determine whether there is a declared type.
|
// Determine whether there is a declared type.
|
||||||
const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
|
const declaredType = getDeclaredTypeForExpression(node.leftExpression, { method: 'set' });
|
||||||
method: 'set',
|
|
||||||
});
|
|
||||||
|
|
||||||
let typeAliasNameNode: NameNode | undefined;
|
let typeAliasNameNode: NameNode | undefined;
|
||||||
let isSpeculativeTypeAlias = false;
|
let isSpeculativeTypeAlias = false;
|
||||||
|
let typeAliasPlaceholder: TypeVarType | undefined;
|
||||||
|
|
||||||
if (isDeclaredTypeAlias(node.leftExpression)) {
|
if (isDeclaredTypeAlias(node.leftExpression)) {
|
||||||
typeAliasNameNode = (node.leftExpression as TypeAnnotationNode).valueExpression as NameNode;
|
flags =
|
||||||
|
EvaluatorFlags.ExpectingInstantiableType |
|
||||||
|
EvaluatorFlags.ExpectingTypeExpression |
|
||||||
|
EvaluatorFlags.EvaluateStringLiteralAsType |
|
||||||
|
EvaluatorFlags.DisallowParamSpec |
|
||||||
|
EvaluatorFlags.DisallowTypeVarTuple |
|
||||||
|
EvaluatorFlags.DisallowClassVar;
|
||||||
|
|
||||||
if (!isLegalTypeAliasExpressionForm(node.rightExpression)) {
|
typeAliasNameNode = (node.leftExpression as TypeAnnotationNode).valueExpression as NameNode;
|
||||||
addDiagnostic(
|
|
||||||
DiagnosticRule.reportInvalidTypeForm,
|
if (!isLegalTypeAliasExpressionForm(node.rightExpression)) {
|
||||||
LocMessage.typeAliasIllegalExpressionForm(),
|
addDiagnostic(
|
||||||
node.rightExpression
|
DiagnosticRule.reportInvalidTypeForm,
|
||||||
);
|
LocMessage.typeAliasIllegalExpressionForm(),
|
||||||
}
|
node.rightExpression
|
||||||
} else if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
|
||||||
const symbolWithScope = lookUpSymbolRecursive(
|
|
||||||
node.leftExpression,
|
|
||||||
node.leftExpression.value,
|
|
||||||
/* honorCodeFlow */ false
|
|
||||||
);
|
);
|
||||||
if (symbolWithScope) {
|
}
|
||||||
const decls = symbolWithScope.symbol.getDeclarations();
|
} else if (node.leftExpression.nodeType === ParseNodeType.Name) {
|
||||||
if (decls.length === 1 && isPossibleTypeAliasOrTypedDict(decls[0])) {
|
const symbolWithScope = lookUpSymbolRecursive(
|
||||||
|
node.leftExpression,
|
||||||
|
node.leftExpression.value,
|
||||||
|
/* honorCodeFlow */ false
|
||||||
|
);
|
||||||
|
|
||||||
|
if (symbolWithScope) {
|
||||||
|
const decls = symbolWithScope.symbol.getDeclarations();
|
||||||
|
|
||||||
|
if (decls.length === 1) {
|
||||||
|
if (isPossibleTypeAliasDeclaration(decls[0])) {
|
||||||
typeAliasNameNode = node.leftExpression;
|
typeAliasNameNode = node.leftExpression;
|
||||||
isSpeculativeTypeAlias = true;
|
isSpeculativeTypeAlias = true;
|
||||||
|
} else if (isPossibleTypeDictFactoryCall(decls[0])) {
|
||||||
|
// Handle calls to TypedDict factory functions like type
|
||||||
|
// aliases to support recursive field type definitions.
|
||||||
|
typeAliasNameNode = node.leftExpression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Synthesize a type variable that represents the type alias while we're
|
if (typeAliasNameNode) {
|
||||||
// evaluating it. This allows us to handle recursive definitions.
|
typeAliasPlaceholder = synthesizeTypeAliasPlaceholder(typeAliasNameNode);
|
||||||
let typeAliasTypeVar: TypeVarType | undefined;
|
|
||||||
if (typeAliasNameNode) {
|
|
||||||
typeAliasTypeVar = TypeVarType.createInstantiable(`__type_alias_${typeAliasNameNode.value}`);
|
|
||||||
typeAliasTypeVar.details.isSynthesized = true;
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasName = typeAliasNameNode.value;
|
|
||||||
const scopeId = ParseTreeUtils.getScopeIdForNode(typeAliasNameNode);
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasIsPep695Syntax = false;
|
|
||||||
typeAliasTypeVar.scopeId = scopeId;
|
|
||||||
|
|
||||||
// Write the type back to the type cache. It will be replaced below.
|
writeTypeCache(node, { type: typeAliasPlaceholder }, /* flags */ undefined);
|
||||||
writeTypeCache(node, { type: typeAliasTypeVar }, /* flags */ undefined);
|
writeTypeCache(node.leftExpression, { type: typeAliasPlaceholder }, /* flags */ undefined);
|
||||||
writeTypeCache(node.leftExpression, { type: typeAliasTypeVar }, /* flags */ undefined);
|
|
||||||
if (node.leftExpression.nodeType === ParseNodeType.TypeAnnotation) {
|
if (node.leftExpression.nodeType === ParseNodeType.TypeAnnotation) {
|
||||||
writeTypeCache(
|
writeTypeCache(
|
||||||
node.leftExpression.valueExpression,
|
node.leftExpression.valueExpression,
|
||||||
{ type: typeAliasTypeVar },
|
{ type: typeAliasPlaceholder },
|
||||||
/* flags */ undefined
|
/* flags */ undefined
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const srcTypeResult = getTypeOfExpression(
|
const srcTypeResult = getTypeOfExpression(node.rightExpression, flags, makeInferenceContext(declaredType));
|
||||||
node.rightExpression,
|
|
||||||
flags,
|
rightHandType = srcTypeResult.type;
|
||||||
makeInferenceContext(declaredType)
|
expectedTypeDiagAddendum = srcTypeResult.expectedTypeDiagAddendum;
|
||||||
|
if (srcTypeResult.isIncomplete) {
|
||||||
|
isIncomplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this was a speculative type alias, it becomes a real type alias
|
||||||
|
// only if the evaluated type is an instantiable type.
|
||||||
|
if (isSpeculativeTypeAlias && !isLegalImplicitTypeAliasType(rightHandType)) {
|
||||||
|
typeAliasNameNode = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeAliasNameNode) {
|
||||||
|
assert(typeAliasPlaceholder !== undefined);
|
||||||
|
|
||||||
|
// If this is a type alias, record its name based on the assignment target.
|
||||||
|
rightHandType = transformTypeForTypeAlias(
|
||||||
|
rightHandType,
|
||||||
|
typeAliasNameNode,
|
||||||
|
typeAliasNameNode,
|
||||||
|
/* isPep695Syntax */ false,
|
||||||
|
/* isPep695TypeVarType */ false
|
||||||
);
|
);
|
||||||
let srcType = srcTypeResult.type;
|
|
||||||
expectedTypeDiagAddendum = srcTypeResult.expectedTypeDiagAddendum;
|
if (isTypeAliasRecursive(typeAliasPlaceholder, rightHandType)) {
|
||||||
if (srcTypeResult.isIncomplete) {
|
addDiagnostic(
|
||||||
isIncomplete = true;
|
DiagnosticRule.reportGeneralTypeIssues,
|
||||||
|
LocMessage.typeAliasIsRecursiveDirect().format({
|
||||||
|
name: typeAliasNameNode.value,
|
||||||
|
}),
|
||||||
|
node.rightExpression
|
||||||
|
);
|
||||||
|
|
||||||
|
rightHandType = UnknownType.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the resulting type to the boundType of the original type alias
|
||||||
|
// to support recursive type aliases.
|
||||||
|
typeAliasPlaceholder.details.boundType = rightHandType;
|
||||||
|
|
||||||
|
// Record the type parameters within the recursive type alias so it
|
||||||
|
// can be specialized.
|
||||||
|
typeAliasPlaceholder.details.recursiveTypeParameters = rightHandType.typeAliasInfo?.typeParameters;
|
||||||
|
} else {
|
||||||
// If the RHS is a constant boolean expression, assign it a literal type.
|
// If the RHS is a constant boolean expression, assign it a literal type.
|
||||||
const constExprValue = evaluateStaticBoolExpression(
|
const constExprValue = evaluateStaticBoolExpression(
|
||||||
node.rightExpression,
|
node.rightExpression,
|
||||||
@ -16218,46 +16259,7 @@ export function createTypeEvaluator(
|
|||||||
if (constExprValue !== undefined) {
|
if (constExprValue !== undefined) {
|
||||||
const boolType = getBuiltInObject(node, 'bool');
|
const boolType = getBuiltInObject(node, 'bool');
|
||||||
if (isClassInstance(boolType)) {
|
if (isClassInstance(boolType)) {
|
||||||
srcType = ClassType.cloneWithLiteral(boolType, constExprValue);
|
rightHandType = ClassType.cloneWithLiteral(boolType, constExprValue);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is an enum, transform the type as required.
|
|
||||||
rightHandType = srcType;
|
|
||||||
|
|
||||||
if (typeAliasNameNode) {
|
|
||||||
// If this was a speculative type alias, it becomes a real type alias
|
|
||||||
// only if the evaluated type is an instantiable type.
|
|
||||||
if (!isSpeculativeTypeAlias || isLegalImplicitTypeAliasType(rightHandType)) {
|
|
||||||
// If this is a type alias, record its name based on the assignment target.
|
|
||||||
rightHandType = transformTypeForTypeAlias(
|
|
||||||
rightHandType,
|
|
||||||
typeAliasNameNode,
|
|
||||||
typeAliasNameNode,
|
|
||||||
/* isPep695Syntax */ false,
|
|
||||||
/* isPep695TypeVarType */ false
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(typeAliasTypeVar !== undefined);
|
|
||||||
if (isTypeAliasRecursive(typeAliasTypeVar, rightHandType)) {
|
|
||||||
addDiagnostic(
|
|
||||||
DiagnosticRule.reportGeneralTypeIssues,
|
|
||||||
LocMessage.typeAliasIsRecursiveDirect().format({
|
|
||||||
name: typeAliasNameNode.value,
|
|
||||||
}),
|
|
||||||
node.rightExpression
|
|
||||||
);
|
|
||||||
|
|
||||||
rightHandType = UnknownType.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the resulting type to the boundType of the original type alias
|
|
||||||
// to support recursive type aliases.
|
|
||||||
typeAliasTypeVar.details.boundType = rightHandType;
|
|
||||||
|
|
||||||
// Record the type parameters within the recursive type alias so it
|
|
||||||
// can be specialized.
|
|
||||||
typeAliasTypeVar.details.recursiveTypeParameters = rightHandType.typeAliasInfo?.typeParameters;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16275,39 +16277,18 @@ export function createTypeEvaluator(
|
|||||||
writeTypeCache(node, { type: rightHandType, isIncomplete }, EvaluatorFlags.None);
|
writeTypeCache(node, { type: rightHandType, isIncomplete }, EvaluatorFlags.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPossibleTypeAliasOrTypedDict(decl: Declaration) {
|
// Synthesize a TypeVar that acts as a placeholder for a type alias. This allows
|
||||||
if (isPossibleTypeAliasDeclaration(decl)) {
|
// the type alias definition to refer to itself.
|
||||||
return true;
|
function synthesizeTypeAliasPlaceholder(nameNode: NameNode): TypeVarType {
|
||||||
}
|
const placeholder = TypeVarType.createInstantiable(`__type_alias_${nameNode.value}`);
|
||||||
|
placeholder.details.isSynthesized = true;
|
||||||
|
placeholder.details.recursiveTypeAliasName = nameNode.value;
|
||||||
|
const scopeId = ParseTreeUtils.getScopeIdForNode(nameNode);
|
||||||
|
placeholder.details.recursiveTypeAliasScopeId = scopeId;
|
||||||
|
placeholder.details.recursiveTypeAliasIsPep695Syntax = false;
|
||||||
|
placeholder.scopeId = scopeId;
|
||||||
|
|
||||||
if (
|
return placeholder;
|
||||||
decl.type === DeclarationType.Variable &&
|
|
||||||
decl.node.parent &&
|
|
||||||
decl.node.parent.nodeType === ParseNodeType.Assignment &&
|
|
||||||
decl.node.parent.rightExpression?.nodeType === ParseNodeType.Call
|
|
||||||
) {
|
|
||||||
const callLeftNode = decl.node.parent.rightExpression.leftExpression;
|
|
||||||
|
|
||||||
// Use a simple heuristic to determine whether this is potentially
|
|
||||||
// a call to the TypedDict call. This avoids the expensive (and potentially
|
|
||||||
// recursive) call to getTypeOfExpression in cases where it's not needed.
|
|
||||||
if (
|
|
||||||
(callLeftNode.nodeType === ParseNodeType.Name && callLeftNode.value) === 'TypedDict' ||
|
|
||||||
(callLeftNode.nodeType === ParseNodeType.MemberAccess &&
|
|
||||||
callLeftNode.memberName.value === 'TypedDict' &&
|
|
||||||
callLeftNode.leftExpression.nodeType === ParseNodeType.Name)
|
|
||||||
) {
|
|
||||||
// See if this is a call to TypedDict. We want to support
|
|
||||||
// recursive type references in a TypedDict call.
|
|
||||||
const callType = getTypeOfExpression(callLeftNode, EvaluatorFlags.CallBaseDefaults).type;
|
|
||||||
|
|
||||||
if (isInstantiableClass(callType) && ClassType.isBuiltIn(callType, 'TypedDict')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluates the type of a type alias (i.e. "type") statement. This code
|
// Evaluates the type of a type alias (i.e. "type") statement. This code
|
||||||
@ -16346,15 +16327,9 @@ export function createTypeEvaluator(
|
|||||||
|
|
||||||
// Synthesize a type variable that represents the type alias while we're
|
// Synthesize a type variable that represents the type alias while we're
|
||||||
// evaluating it. This allows us to handle recursive definitions.
|
// evaluating it. This allows us to handle recursive definitions.
|
||||||
const typeAliasTypeVar = TypeVarType.createInstantiable(`__type_alias_${nameNode.value}`);
|
const typeAliasTypeVar = synthesizeTypeAliasPlaceholder(nameNode);
|
||||||
typeAliasTypeVar.details.isSynthesized = true;
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasName = nameNode.value;
|
|
||||||
const scopeId = ParseTreeUtils.getScopeIdForNode(nameNode);
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
|
||||||
typeAliasTypeVar.details.recursiveTypeAliasIsPep695Syntax = isPep695Syntax;
|
|
||||||
typeAliasTypeVar.scopeId = scopeId;
|
|
||||||
|
|
||||||
// Write the type to the type cache. It will be replaced below.
|
// Write the type to the type cache to support recursive type alias definitions.
|
||||||
writeTypeCache(nameNode, { type: typeAliasTypeVar }, /* flags */ undefined);
|
writeTypeCache(nameNode, { type: typeAliasTypeVar }, /* flags */ undefined);
|
||||||
|
|
||||||
// Set a partial type to handle recursive (self-referential) type aliases.
|
// Set a partial type to handle recursive (self-referential) type aliases.
|
||||||
@ -18340,6 +18315,7 @@ export function createTypeEvaluator(
|
|||||||
// Replace any unsolved TypeVars with Unknown (including all function-scoped TypeVars).
|
// Replace any unsolved TypeVars with Unknown (including all function-scoped TypeVars).
|
||||||
inferredParamType = applySolvedTypeVars(inferredParamType, typeVarContext, {
|
inferredParamType = applySolvedTypeVars(inferredParamType, typeVarContext, {
|
||||||
unknownIfNotFound: true,
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18764,6 +18740,11 @@ export function createTypeEvaluator(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const statements = functionDecl.node.suite.statements;
|
||||||
|
if (statements.some((statement) => statement.nodeType !== ParseNodeType.StatementList)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (const raiseStatement of functionDecl.raiseStatements) {
|
for (const raiseStatement of functionDecl.raiseStatements) {
|
||||||
if (!raiseStatement.typeExpression || raiseStatement.valueExpression) {
|
if (!raiseStatement.typeExpression || raiseStatement.valueExpression) {
|
||||||
return false;
|
return false;
|
||||||
@ -19494,6 +19475,16 @@ export function createTypeEvaluator(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward-declared type annotation expressions need to be be evaluated
|
||||||
|
// in context so they have the appropriate flags set. Most of these cases
|
||||||
|
// will have been detected above when calling getParentAnnotationNode,
|
||||||
|
// but TypeAlias expressions are not handled there.
|
||||||
|
const stringEnclosure = ParseTreeUtils.getParentNodeOfType(parent, ParseNodeType.StringList);
|
||||||
|
if (stringEnclosure) {
|
||||||
|
nodeToEvaluate = stringEnclosure as StringListNode;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// The left expression of a call or member access expression is not generally contextual.
|
// The left expression of a call or member access expression is not generally contextual.
|
||||||
if (parent.nodeType === ParseNodeType.Call || parent.nodeType === ParseNodeType.MemberAccess) {
|
if (parent.nodeType === ParseNodeType.Call || parent.nodeType === ParseNodeType.MemberAccess) {
|
||||||
if (nodeToEvaluate === parent.leftExpression) {
|
if (nodeToEvaluate === parent.leftExpression) {
|
||||||
@ -19520,15 +19511,7 @@ export function createTypeEvaluator(
|
|||||||
// The base expression of an index expression is not contextual.
|
// The base expression of an index expression is not contextual.
|
||||||
if (nodeToEvaluate === parent.baseExpression) {
|
if (nodeToEvaluate === parent.baseExpression) {
|
||||||
flags = EvaluatorFlags.IndexBaseDefaults;
|
flags = EvaluatorFlags.IndexBaseDefaults;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else if (parent.nodeType === ParseNodeType.StringList && nodeToEvaluate === parent.typeAnnotation) {
|
|
||||||
// Forward-declared type annotation expressions need to be be evaluated
|
|
||||||
// in context so they have the appropriate flags set. Most of these cases
|
|
||||||
// will have been detected above when calling getParentAnnotationNode,
|
|
||||||
// but TypeAlias expressions are not handled there.
|
|
||||||
nodeToEvaluate = parent;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isExpressionNode(parent)) {
|
if (!isExpressionNode(parent)) {
|
||||||
@ -19873,7 +19856,19 @@ export function createTypeEvaluator(
|
|||||||
// don't bother doing additional work.
|
// don't bother doing additional work.
|
||||||
let cacheEntry = readTypeCacheEntry(subnode);
|
let cacheEntry = readTypeCacheEntry(subnode);
|
||||||
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
||||||
return cacheEntry.typeResult;
|
const typeResult = cacheEntry.typeResult;
|
||||||
|
|
||||||
|
// Handle the special case where a function or class is partially evaluated.
|
||||||
|
// Indicate that these are not complete types.
|
||||||
|
if (isFunction(typeResult.type) && FunctionType.isPartiallyEvaluated(typeResult.type)) {
|
||||||
|
return { ...typeResult, isIncomplete: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClass(typeResult.type) && ClassType.isPartiallyEvaluated(typeResult.type)) {
|
||||||
|
return { ...typeResult, isIncomplete: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
@ -20024,7 +20019,7 @@ export function createTypeEvaluator(
|
|||||||
case 'Protocol': {
|
case 'Protocol': {
|
||||||
if (
|
if (
|
||||||
(flags &
|
(flags &
|
||||||
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeAnnotation)) !==
|
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeExpression)) !==
|
||||||
0
|
0
|
||||||
) {
|
) {
|
||||||
addError(LocMessage.protocolNotAllowed(), errorNode);
|
addError(LocMessage.protocolNotAllowed(), errorNode);
|
||||||
@ -20049,7 +20044,7 @@ export function createTypeEvaluator(
|
|||||||
case 'TypedDict': {
|
case 'TypedDict': {
|
||||||
if (
|
if (
|
||||||
(flags &
|
(flags &
|
||||||
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeAnnotation)) !==
|
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeExpression)) !==
|
||||||
0
|
0
|
||||||
) {
|
) {
|
||||||
addError(LocMessage.typedDictNotAllowed(), errorNode);
|
addError(LocMessage.typedDictNotAllowed(), errorNode);
|
||||||
@ -20060,7 +20055,7 @@ export function createTypeEvaluator(
|
|||||||
case 'Literal': {
|
case 'Literal': {
|
||||||
if (
|
if (
|
||||||
(flags &
|
(flags &
|
||||||
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeAnnotation)) !==
|
(EvaluatorFlags.DisallowNonTypeSpecialForms | EvaluatorFlags.ExpectingTypeExpression)) !==
|
||||||
0
|
0
|
||||||
) {
|
) {
|
||||||
addError(LocMessage.literalNotAllowed(), errorNode);
|
addError(LocMessage.literalNotAllowed(), errorNode);
|
||||||
@ -20375,7 +20370,10 @@ export function createTypeEvaluator(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const solvedDefaultType = applySolvedTypeVars(typeParam, typeVarContext, { unknownIfNotFound: true });
|
const solvedDefaultType = applySolvedTypeVars(typeParam, typeVarContext, {
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
tupleClassType: getTupleClassType(),
|
||||||
|
});
|
||||||
typeArgTypes.push(solvedDefaultType);
|
typeArgTypes.push(solvedDefaultType);
|
||||||
if (isParamSpec(typeParam)) {
|
if (isParamSpec(typeParam)) {
|
||||||
typeVarContext.setTypeVarType(typeParam, convertTypeToParamSpecValue(solvedDefaultType));
|
typeVarContext.setTypeVarType(typeParam, convertTypeToParamSpecValue(solvedDefaultType));
|
||||||
@ -20510,7 +20508,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options?.allowRequired) {
|
if (options?.allowRequired) {
|
||||||
flags |= EvaluatorFlags.AllowRequired | EvaluatorFlags.ExpectingTypeAnnotation;
|
flags |= EvaluatorFlags.AllowRequired | EvaluatorFlags.ExpectingTypeExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.allowUnpackedTuple) {
|
if (options?.allowUnpackedTuple) {
|
||||||
@ -20524,7 +20522,7 @@ export function createTypeEvaluator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options?.enforceTypeAnnotationRules) {
|
if (options?.enforceTypeAnnotationRules) {
|
||||||
flags |= EvaluatorFlags.ExpectingTypeAnnotation;
|
flags |= EvaluatorFlags.ExpectingTypeExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.disallowProtocolAndTypedDict) {
|
if (options?.disallowProtocolAndTypedDict) {
|
||||||
@ -22347,7 +22345,7 @@ export function createTypeEvaluator(
|
|||||||
getEffectiveTypeOfSymbol(member.symbol),
|
getEffectiveTypeOfSymbol(member.symbol),
|
||||||
member.classType,
|
member.classType,
|
||||||
/* selfClass */ undefined,
|
/* selfClass */ undefined,
|
||||||
typeClass ?? UnknownType.create()
|
typeClass && isInstantiableClass(typeClass) ? typeClass : undefined
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return UnknownType.create();
|
return UnknownType.create();
|
||||||
@ -25944,7 +25942,7 @@ export function createTypeEvaluator(
|
|||||||
!assignedType.tupleTypeArguments
|
!assignedType.tupleTypeArguments
|
||||||
) {
|
) {
|
||||||
const typeVarContext = new TypeVarContext(getTypeVarScopeId(assignedType));
|
const typeVarContext = new TypeVarContext(getTypeVarScopeId(assignedType));
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluatorInterface,
|
evaluatorInterface,
|
||||||
ClassType.cloneForSpecialization(
|
ClassType.cloneForSpecialization(
|
||||||
assignedType,
|
assignedType,
|
||||||
@ -27118,6 +27116,43 @@ export function createTypeEvaluator(
|
|||||||
return isLegal;
|
return isLegal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPossibleTypeAliasOrTypedDict(decl: Declaration) {
|
||||||
|
return isPossibleTypeAliasDeclaration(decl) || isPossibleTypeDictFactoryCall(decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPossibleTypeDictFactoryCall(decl: Declaration) {
|
||||||
|
if (
|
||||||
|
decl.type !== DeclarationType.Variable ||
|
||||||
|
!decl.node.parent ||
|
||||||
|
decl.node.parent.nodeType !== ParseNodeType.Assignment ||
|
||||||
|
decl.node.parent.rightExpression?.nodeType !== ParseNodeType.Call
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const callLeftNode = decl.node.parent.rightExpression.leftExpression;
|
||||||
|
|
||||||
|
// Use a simple heuristic to determine whether this is potentially
|
||||||
|
// a call to the TypedDict call. This avoids the expensive (and potentially
|
||||||
|
// recursive) call to getTypeOfExpression in cases where it's not needed.
|
||||||
|
if (
|
||||||
|
(callLeftNode.nodeType === ParseNodeType.Name && callLeftNode.value) === 'TypedDict' ||
|
||||||
|
(callLeftNode.nodeType === ParseNodeType.MemberAccess &&
|
||||||
|
callLeftNode.memberName.value === 'TypedDict' &&
|
||||||
|
callLeftNode.leftExpression.nodeType === ParseNodeType.Name)
|
||||||
|
) {
|
||||||
|
// See if this is a call to TypedDict. We want to support
|
||||||
|
// recursive type references in a TypedDict call.
|
||||||
|
const callType = getTypeOfExpression(callLeftNode, EvaluatorFlags.CallBaseDefaults).type;
|
||||||
|
|
||||||
|
if (isInstantiableClass(callType) && ClassType.isBuiltIn(callType, 'TypedDict')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function printObjectTypeForClass(type: ClassType): string {
|
function printObjectTypeForClass(type: ClassType): string {
|
||||||
return TypePrinter.printObjectTypeForClass(
|
return TypePrinter.printObjectTypeForClass(
|
||||||
type,
|
type,
|
||||||
|
@ -86,10 +86,9 @@ export const enum EvaluatorFlags {
|
|||||||
// than an instance (object)
|
// than an instance (object)
|
||||||
ExpectingInstantiableType = 1 << 7,
|
ExpectingInstantiableType = 1 << 7,
|
||||||
|
|
||||||
// A type annotation restricts the types of expressions that are
|
// A type expression imposes grammatical and semantic limits on an
|
||||||
// allowed. If this flag is set, illegal type expressions are
|
// expression. If this flag is set, illegal type expressions are
|
||||||
// flagged as errors.
|
ExpectingTypeExpression = 1 << 8,
|
||||||
ExpectingTypeAnnotation = 1 << 8,
|
|
||||||
|
|
||||||
// Suppress the reportMissingTypeArgument diagnostic in this context.
|
// Suppress the reportMissingTypeArgument diagnostic in this context.
|
||||||
AllowMissingTypeArgs = 1 << 9,
|
AllowMissingTypeArgs = 1 << 9,
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
} from '../parser/parseNodes';
|
} from '../parser/parseNodes';
|
||||||
import { KeywordType, OperatorType } from '../parser/tokenizerTypes';
|
import { KeywordType, OperatorType } from '../parser/tokenizerTypes';
|
||||||
import { getFileInfo } from './analyzerNodeInfo';
|
import { getFileInfo } from './analyzerNodeInfo';
|
||||||
import { populateTypeVarContextBasedOnExpectedType } from './constraintSolver';
|
import { addConstraintsForExpectedType } from './constraintSolver';
|
||||||
import { Declaration, DeclarationType } from './declaration';
|
import { Declaration, DeclarationType } from './declaration';
|
||||||
import { transformTypeForEnumMember } from './enums';
|
import { transformTypeForEnumMember } from './enums';
|
||||||
import * as ParseTreeUtils from './parseTreeUtils';
|
import * as ParseTreeUtils from './parseTreeUtils';
|
||||||
@ -638,7 +638,7 @@ export function getTypeNarrowingCallback(
|
|||||||
);
|
);
|
||||||
const arg1Type = arg1TypeResult.type;
|
const arg1Type = arg1TypeResult.type;
|
||||||
|
|
||||||
const classTypeList = getIsInstanceClassTypes(arg1Type);
|
const classTypeList = getIsInstanceClassTypes(evaluator, arg1Type);
|
||||||
const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
|
const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
|
||||||
|
|
||||||
if (classTypeList) {
|
if (classTypeList) {
|
||||||
@ -1146,7 +1146,10 @@ function narrowTypeForIsEllipsis(evaluator: TypeEvaluator, type: Type, isPositiv
|
|||||||
// that accepts a single class, and a more complex form that accepts a tuple
|
// that accepts a single class, and a more complex form that accepts a tuple
|
||||||
// of classes (including arbitrarily-nested tuples). This method determines
|
// of classes (including arbitrarily-nested tuples). This method determines
|
||||||
// which form and returns a list of classes or undefined.
|
// which form and returns a list of classes or undefined.
|
||||||
function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | FunctionType)[] | undefined {
|
function getIsInstanceClassTypes(
|
||||||
|
evaluator: TypeEvaluator,
|
||||||
|
argType: Type
|
||||||
|
): (ClassType | TypeVarType | FunctionType)[] | undefined {
|
||||||
let foundNonClassType = false;
|
let foundNonClassType = false;
|
||||||
const classTypeList: (ClassType | TypeVarType | FunctionType)[] = [];
|
const classTypeList: (ClassType | TypeVarType | FunctionType)[] = [];
|
||||||
|
|
||||||
@ -1155,7 +1158,7 @@ function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | Func
|
|||||||
const addClassTypesToList = (types: Type[]) => {
|
const addClassTypesToList = (types: Type[]) => {
|
||||||
types.forEach((subtype) => {
|
types.forEach((subtype) => {
|
||||||
if (isClass(subtype)) {
|
if (isClass(subtype)) {
|
||||||
subtype = specializeWithUnknownTypeArgs(subtype);
|
subtype = specializeWithUnknownTypeArgs(subtype, evaluator.getTupleClassType());
|
||||||
|
|
||||||
if (isInstantiableClass(subtype) && ClassType.isBuiltIn(subtype, 'Callable')) {
|
if (isInstantiableClass(subtype) && ClassType.isBuiltIn(subtype, 'Callable')) {
|
||||||
subtype = convertToInstantiable(getUnknownTypeForCallable());
|
subtype = convertToInstantiable(getUnknownTypeForCallable());
|
||||||
@ -1359,7 +1362,8 @@ function narrowTypeForIsInstanceInternal(
|
|||||||
concreteFilterType,
|
concreteFilterType,
|
||||||
/* typeArguments */ undefined,
|
/* typeArguments */ undefined,
|
||||||
/* isTypeArgumentExplicit */ false
|
/* isTypeArgumentExplicit */ false
|
||||||
)
|
),
|
||||||
|
evaluator.getTupleClassType()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,7 +1455,7 @@ function narrowTypeForIsInstanceInternal(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
populateTypeVarContextBasedOnExpectedType(
|
addConstraintsForExpectedType(
|
||||||
evaluator,
|
evaluator,
|
||||||
unspecializedFilterType,
|
unspecializedFilterType,
|
||||||
concreteVarType,
|
concreteVarType,
|
||||||
@ -1463,7 +1467,11 @@ function narrowTypeForIsInstanceInternal(
|
|||||||
specializedFilterType = applySolvedTypeVars(
|
specializedFilterType = applySolvedTypeVars(
|
||||||
unspecializedFilterType,
|
unspecializedFilterType,
|
||||||
typeVarContext,
|
typeVarContext,
|
||||||
{ unknownIfNotFound: true, useUnknownOverDefault: true }
|
{
|
||||||
|
unknownIfNotFound: true,
|
||||||
|
useUnknownOverDefault: true,
|
||||||
|
tupleClassType: evaluator.getTupleClassType(),
|
||||||
|
}
|
||||||
) as ClassType;
|
) as ClassType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1764,7 +1772,11 @@ function narrowTypeForIsInstanceInternal(
|
|||||||
|
|
||||||
const filteredType = evaluator.mapSubtypesExpandTypeVars(
|
const filteredType = evaluator.mapSubtypesExpandTypeVars(
|
||||||
expandedTypes,
|
expandedTypes,
|
||||||
/* options */ undefined,
|
{
|
||||||
|
expandCallback: (type) => {
|
||||||
|
return evaluator.expandPromotionTypes(errorNode, type);
|
||||||
|
},
|
||||||
|
},
|
||||||
(subtype, unexpandedSubtype) => {
|
(subtype, unexpandedSubtype) => {
|
||||||
// If we fail to filter anything in the negative case, we need to decide
|
// If we fail to filter anything in the negative case, we need to decide
|
||||||
// whether to retain the original TypeVar or replace it with its specialized
|
// whether to retain the original TypeVar or replace it with its specialized
|
||||||
@ -2459,33 +2471,69 @@ function narrowTypeForClassComparison(
|
|||||||
isPositiveTest: boolean
|
isPositiveTest: boolean
|
||||||
): Type {
|
): Type {
|
||||||
return mapSubtypes(referenceType, (subtype) => {
|
return mapSubtypes(referenceType, (subtype) => {
|
||||||
const concreteSubtype = evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
let concreteSubtype = evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
||||||
|
|
||||||
if (isPositiveTest) {
|
if (isPositiveTest) {
|
||||||
if (isNoneInstance(concreteSubtype)) {
|
if (isNoneInstance(concreteSubtype)) {
|
||||||
return undefined;
|
return isNoneTypeClass(classType) ? classType : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isClassInstance(concreteSubtype) && TypeBase.isInstance(subtype)) {
|
if (
|
||||||
if (ClassType.isBuiltIn(concreteSubtype, 'type')) {
|
isClassInstance(concreteSubtype) &&
|
||||||
return classType;
|
TypeBase.isInstance(subtype) &&
|
||||||
|
ClassType.isBuiltIn(concreteSubtype, 'type')
|
||||||
|
) {
|
||||||
|
concreteSubtype =
|
||||||
|
concreteSubtype.typeArguments && concreteSubtype.typeArguments.length > 0
|
||||||
|
? convertToInstantiable(concreteSubtype.typeArguments[0])
|
||||||
|
: UnknownType.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnyOrUnknown(concreteSubtype)) {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClass(concreteSubtype)) {
|
||||||
|
if (TypeBase.isInstance(concreteSubtype)) {
|
||||||
|
return ClassType.isBuiltIn(concreteSubtype, 'object') ? classType : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
const isSuperType = isIsinstanceFilterSuperclass(
|
||||||
}
|
evaluator,
|
||||||
|
subtype,
|
||||||
|
concreteSubtype,
|
||||||
|
classType,
|
||||||
|
classType,
|
||||||
|
/* isInstanceCheck */ false
|
||||||
|
);
|
||||||
|
|
||||||
if (isInstantiableClass(concreteSubtype) && ClassType.isFinal(concreteSubtype)) {
|
if (!classType.includeSubclasses) {
|
||||||
if (
|
// Handle the case where the LHS and RHS operands are specific
|
||||||
!ClassType.isSameGenericClass(concreteSubtype, classType) &&
|
// classes, as opposed to types that represent classes and their
|
||||||
!isIsinstanceFilterSuperclass(
|
// subclasses.
|
||||||
|
if (!concreteSubtype.includeSubclasses) {
|
||||||
|
return ClassType.isSameGenericClass(concreteSubtype, classType) ? classType : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSubType = isIsinstanceFilterSubclass(
|
||||||
evaluator,
|
evaluator,
|
||||||
subtype,
|
|
||||||
concreteSubtype,
|
concreteSubtype,
|
||||||
classType,
|
classType,
|
||||||
classType,
|
|
||||||
/* isInstanceCheck */ false
|
/* isInstanceCheck */ false
|
||||||
)
|
);
|
||||||
) {
|
|
||||||
|
if (isSuperType) {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSubType) {
|
||||||
|
return addConditionToType(classType, getTypeCondition(concreteSubtype));
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClassType.isFinal(concreteSubtype) && !isSuperType) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,12 +245,13 @@ export const enum AssignTypeFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplyTypeVarOptions {
|
export interface ApplyTypeVarOptions {
|
||||||
|
typeClassType?: ClassType;
|
||||||
|
tupleClassType?: ClassType;
|
||||||
unknownIfNotFound?: boolean;
|
unknownIfNotFound?: boolean;
|
||||||
useUnknownOverDefault?: boolean;
|
useUnknownOverDefault?: boolean;
|
||||||
unknownExemptTypeVars?: TypeVarType[];
|
unknownExemptTypeVars?: TypeVarType[];
|
||||||
useNarrowBoundOnly?: boolean;
|
useNarrowBoundOnly?: boolean;
|
||||||
eliminateUnsolvedInUnions?: boolean;
|
eliminateUnsolvedInUnions?: boolean;
|
||||||
typeClassType?: Type;
|
|
||||||
applyInScopePlaceholders?: boolean;
|
applyInScopePlaceholders?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,7 +1074,7 @@ export function specializeWithDefaultTypeArgs(type: ClassType): ClassType {
|
|||||||
|
|
||||||
// Specializes the class with "Unknown" type args (or the equivalent for ParamSpecs
|
// Specializes the class with "Unknown" type args (or the equivalent for ParamSpecs
|
||||||
// or TypeVarTuples).
|
// or TypeVarTuples).
|
||||||
export function specializeWithUnknownTypeArgs(type: ClassType): ClassType {
|
export function specializeWithUnknownTypeArgs(type: ClassType, tupleClassType?: ClassType): ClassType {
|
||||||
if (type.details.typeParameters.length === 0) {
|
if (type.details.typeParameters.length === 0) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@ -1091,18 +1092,22 @@ export function specializeWithUnknownTypeArgs(type: ClassType): ClassType {
|
|||||||
|
|
||||||
return ClassType.cloneForSpecialization(
|
return ClassType.cloneForSpecialization(
|
||||||
type,
|
type,
|
||||||
type.details.typeParameters.map((param) => getUnknownTypeForTypeVar(param)),
|
type.details.typeParameters.map((param) => getUnknownTypeForTypeVar(param, tupleClassType)),
|
||||||
/* isTypeArgumentExplicit */ false,
|
/* isTypeArgumentExplicit */ false,
|
||||||
/* includeSubclasses */ type.includeSubclasses
|
/* includeSubclasses */ type.includeSubclasses
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns "Unknown" for simple TypeVars or the equivalent for a ParamSpec.
|
// Returns "Unknown" for simple TypeVars or the equivalent for a ParamSpec.
|
||||||
export function getUnknownTypeForTypeVar(typeVar: TypeVarType): Type {
|
export function getUnknownTypeForTypeVar(typeVar: TypeVarType, tupleClassType?: ClassType): Type {
|
||||||
if (typeVar.details.isParamSpec) {
|
if (typeVar.details.isParamSpec) {
|
||||||
return getUnknownTypeForParamSpec();
|
return getUnknownTypeForParamSpec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeVar.details.isVariadic && tupleClassType) {
|
||||||
|
return getUnknownTypeForVariadicTypeVar(tupleClassType);
|
||||||
|
}
|
||||||
|
|
||||||
return UnknownType.create();
|
return UnknownType.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1118,6 +1123,19 @@ export function getUnknownTypeForParamSpec(): FunctionType {
|
|||||||
return newFunction;
|
return newFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUnknownTypeForVariadicTypeVar(tupleClassType: ClassType): Type {
|
||||||
|
assert(isInstantiableClass(tupleClassType) && ClassType.isBuiltIn(tupleClassType, 'tuple'));
|
||||||
|
|
||||||
|
return ClassType.cloneAsInstance(
|
||||||
|
specializeTupleClass(
|
||||||
|
tupleClassType,
|
||||||
|
[{ type: UnknownType.create(), isUnbounded: true }],
|
||||||
|
/* isTypeArgumentExplicit */ true,
|
||||||
|
/* isUnpackedTuple */ true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the equivalent of "Callable[..., Unknown]".
|
// Returns the equivalent of "Callable[..., Unknown]".
|
||||||
export function getUnknownTypeForCallable(): FunctionType {
|
export function getUnknownTypeForCallable(): FunctionType {
|
||||||
const newFunction = FunctionType.createSynthesizedInstance('', FunctionTypeFlags.GradualCallableForm);
|
const newFunction = FunctionType.createSynthesizedInstance('', FunctionTypeFlags.GradualCallableForm);
|
||||||
@ -1374,7 +1392,7 @@ export function partiallySpecializeType(
|
|||||||
type: Type,
|
type: Type,
|
||||||
contextClassType: ClassType,
|
contextClassType: ClassType,
|
||||||
selfClass?: ClassType | TypeVarType,
|
selfClass?: ClassType | TypeVarType,
|
||||||
typeClassType?: Type
|
typeClassType?: ClassType
|
||||||
): Type {
|
): Type {
|
||||||
// If the context class is not specialized (or doesn't need specialization),
|
// If the context class is not specialized (or doesn't need specialization),
|
||||||
// then there's no need to do any more work.
|
// then there's no need to do any more work.
|
||||||
@ -3115,7 +3133,7 @@ export function computeMroLinearization(classType: ClassType): boolean {
|
|||||||
// The first class in the MRO is the class itself.
|
// The first class in the MRO is the class itself.
|
||||||
const typeVarContext = buildTypeVarContextFromSpecializedClass(classType);
|
const typeVarContext = buildTypeVarContextFromSpecializedClass(classType);
|
||||||
let specializedClassType = applySolvedTypeVars(classType, typeVarContext);
|
let specializedClassType = applySolvedTypeVars(classType, typeVarContext);
|
||||||
if (!isClass(specializedClassType) && !isAny(specializedClassType) && !isUnknown(specializedClassType)) {
|
if (!isClass(specializedClassType) && !isAnyOrUnknown(specializedClassType)) {
|
||||||
specializedClassType = UnknownType.create();
|
specializedClassType = UnknownType.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3159,11 +3177,16 @@ export function computeMroLinearization(classType: ClassType): boolean {
|
|||||||
|
|
||||||
if (!isInstantiableClass(classList[0])) {
|
if (!isInstantiableClass(classList[0])) {
|
||||||
foundValidHead = true;
|
foundValidHead = true;
|
||||||
assert(isClass(classList[0]) || isAnyOrUnknown(classList[0]));
|
let head = classList[0];
|
||||||
classType.details.mro.push(classList[0]);
|
if (!isClass(head) && !isAnyOrUnknown(head)) {
|
||||||
|
head = UnknownType.create();
|
||||||
|
}
|
||||||
|
classType.details.mro.push(head);
|
||||||
classList.shift();
|
classList.shift();
|
||||||
break;
|
break;
|
||||||
} else if (!isInTail(classList[0], classListsToMerge)) {
|
}
|
||||||
|
|
||||||
|
if (!isInTail(classList[0], classListsToMerge)) {
|
||||||
foundValidHead = true;
|
foundValidHead = true;
|
||||||
classType.details.mro.push(classList[0]);
|
classType.details.mro.push(classList[0]);
|
||||||
filterClass(classList[0], classListsToMerge);
|
filterClass(classList[0], classListsToMerge);
|
||||||
@ -3186,8 +3209,11 @@ export function computeMroLinearization(classType: ClassType): boolean {
|
|||||||
// Handle the situation by pull the head off the first empty list.
|
// Handle the situation by pull the head off the first empty list.
|
||||||
// This allows us to make forward progress.
|
// This allows us to make forward progress.
|
||||||
if (!isInstantiableClass(nonEmptyList[0])) {
|
if (!isInstantiableClass(nonEmptyList[0])) {
|
||||||
assert(isClass(nonEmptyList[0]) || isAnyOrUnknown(nonEmptyList[0]));
|
let head = nonEmptyList[0];
|
||||||
classType.details.mro.push(nonEmptyList[0]);
|
if (!isClass(head) && !isAnyOrUnknown(head)) {
|
||||||
|
head = UnknownType.create();
|
||||||
|
}
|
||||||
|
classType.details.mro.push(head);
|
||||||
nonEmptyList.shift();
|
nonEmptyList.shift();
|
||||||
} else {
|
} else {
|
||||||
classType.details.mro.push(nonEmptyList[0]);
|
classType.details.mro.push(nonEmptyList[0]);
|
||||||
@ -3290,6 +3316,8 @@ export function convertTypeToParamSpecValue(type: Type): FunctionType {
|
|||||||
newFunction.details.typeVarScopeId = newFunction.details.higherOrderTypeVarScopeIds.pop();
|
newFunction.details.typeVarScopeId = newFunction.details.higherOrderTypeVarScopeIds.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newFunction.details.constructorTypeVarScopeId = type.details.constructorTypeVarScopeId;
|
||||||
|
|
||||||
return newFunction;
|
return newFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3328,6 +3356,7 @@ export function convertParamSpecValueToType(type: FunctionType): Type {
|
|||||||
|
|
||||||
FunctionType.addHigherOrderTypeVarScopeIds(functionType, withoutParamSpec.details.typeVarScopeId);
|
FunctionType.addHigherOrderTypeVarScopeIds(functionType, withoutParamSpec.details.typeVarScopeId);
|
||||||
FunctionType.addHigherOrderTypeVarScopeIds(functionType, withoutParamSpec.details.higherOrderTypeVarScopeIds);
|
FunctionType.addHigherOrderTypeVarScopeIds(functionType, withoutParamSpec.details.higherOrderTypeVarScopeIds);
|
||||||
|
functionType.details.constructorTypeVarScopeId = withoutParamSpec.details.constructorTypeVarScopeId;
|
||||||
|
|
||||||
withoutParamSpec.details.parameters.forEach((entry, index) => {
|
withoutParamSpec.details.parameters.forEach((entry, index) => {
|
||||||
FunctionType.addParameter(functionType, {
|
FunctionType.addParameter(functionType, {
|
||||||
@ -4122,7 +4151,7 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer {
|
|||||||
|
|
||||||
if (this._options.unknownIfNotFound) {
|
if (this._options.unknownIfNotFound) {
|
||||||
return this._options.useUnknownOverDefault
|
return this._options.useUnknownOverDefault
|
||||||
? specializeWithUnknownTypeArgs(subtype)
|
? specializeWithUnknownTypeArgs(subtype, this._options.tupleClassType)
|
||||||
: specializeWithDefaultTypeArgs(subtype);
|
: specializeWithDefaultTypeArgs(subtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4160,7 +4189,7 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer {
|
|||||||
return this._solveDefaultType(typeVar.details.defaultType, recursionCount);
|
return this._solveDefaultType(typeVar.details.defaultType, recursionCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnknownType.create();
|
return getUnknownTypeForTypeVar(typeVar, this._options.tupleClassType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,9 +825,7 @@ export namespace ClassType {
|
|||||||
newClassType.includeSubclasses = true;
|
newClassType.includeSubclasses = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
newClassType.tupleTypeArguments = tupleTypeArguments?.map((t) =>
|
newClassType.tupleTypeArguments = tupleTypeArguments ? [...tupleTypeArguments] : undefined;
|
||||||
isNever(t.type) ? { type: UnknownType.create(), isUnbounded: t.isUnbounded, isOptional: t.isOptional } : t
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isEmptyContainer !== undefined) {
|
if (isEmptyContainer !== undefined) {
|
||||||
newClassType.isEmptyContainer = isEmptyContainer;
|
newClassType.isEmptyContainer = isEmptyContainer;
|
||||||
@ -1766,6 +1764,7 @@ export namespace FunctionType {
|
|||||||
|
|
||||||
FunctionType.addHigherOrderTypeVarScopeIds(newFunction, paramSpecValue.details.typeVarScopeId);
|
FunctionType.addHigherOrderTypeVarScopeIds(newFunction, paramSpecValue.details.typeVarScopeId);
|
||||||
FunctionType.addHigherOrderTypeVarScopeIds(newFunction, paramSpecValue.details.higherOrderTypeVarScopeIds);
|
FunctionType.addHigherOrderTypeVarScopeIds(newFunction, paramSpecValue.details.higherOrderTypeVarScopeIds);
|
||||||
|
newFunction.details.constructorTypeVarScopeId = paramSpecValue.details.constructorTypeVarScopeId;
|
||||||
|
|
||||||
if (!newFunction.details.methodClass && paramSpecValue.details.methodClass) {
|
if (!newFunction.details.methodClass && paramSpecValue.details.methodClass) {
|
||||||
newFunction.details.methodClass = paramSpecValue.details.methodClass;
|
newFunction.details.methodClass = paramSpecValue.details.methodClass;
|
||||||
|
@ -24,11 +24,13 @@ export class BackgroundAnalysis extends BackgroundAnalysisBase {
|
|||||||
constructor(serviceProvider: ServiceProvider) {
|
constructor(serviceProvider: ServiceProvider) {
|
||||||
super(serviceProvider.console());
|
super(serviceProvider.console());
|
||||||
|
|
||||||
|
const index = ++BackgroundAnalysis._workerIndex;
|
||||||
const initialData: InitializationData = {
|
const initialData: InitializationData = {
|
||||||
rootUri: getRootUri(serviceProvider)?.toString() ?? '',
|
rootUri: getRootUri(serviceProvider)?.toString() ?? '',
|
||||||
|
serviceId: index.toString(),
|
||||||
cancellationFolderName: getCancellationFolderName(),
|
cancellationFolderName: getCancellationFolderName(),
|
||||||
runner: undefined,
|
runner: undefined,
|
||||||
workerIndex: ++BackgroundAnalysis._workerIndex,
|
workerIndex: index,
|
||||||
};
|
};
|
||||||
|
|
||||||
// this will load this same file in BG thread and start listener
|
// this will load this same file in BG thread and start listener
|
||||||
|
@ -310,7 +310,14 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase
|
|||||||
const console = this.getConsole();
|
const console = this.getConsole();
|
||||||
this.logTracker = new LogTracker(console, `BG(${threadId})`);
|
this.logTracker = new LogTracker(console, `BG(${threadId})`);
|
||||||
|
|
||||||
this._program = new Program(this.importResolver, this._configOptions, serviceProvider, this.logTracker);
|
this._program = new Program(
|
||||||
|
this.importResolver,
|
||||||
|
this._configOptions,
|
||||||
|
serviceProvider,
|
||||||
|
this.logTracker,
|
||||||
|
undefined,
|
||||||
|
data.serviceId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get program(): Program {
|
get program(): Program {
|
||||||
|
@ -251,10 +251,10 @@ export function getBackgroundWaiter<T>(port: MessagePort, deserializer: (v: any)
|
|||||||
|
|
||||||
export interface InitializationData {
|
export interface InitializationData {
|
||||||
rootUri: string;
|
rootUri: string;
|
||||||
|
serviceId: string;
|
||||||
|
workerIndex: number;
|
||||||
cancellationFolderName: string | undefined;
|
cancellationFolderName: string | undefined;
|
||||||
runner: string | undefined;
|
runner: string | undefined;
|
||||||
title?: string;
|
|
||||||
workerIndex: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RequestResponse {
|
export interface RequestResponse {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Helper functions relating to collections and arrays.
|
* Helper functions relating to collections and arrays.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { compareValues, Comparison, equateValues, isArray } from './core';
|
import { compareValues, Comparison, equateValues, isArray, MapLike } from './core';
|
||||||
|
|
||||||
export const emptyArray: never[] = [] as never[];
|
export const emptyArray: never[] = [] as never[];
|
||||||
export type EqualityComparer<T> = (a: T, b: T) => boolean;
|
export type EqualityComparer<T> = (a: T, b: T) => boolean;
|
||||||
@ -318,7 +318,7 @@ export function getNestedProperty(object: any, property: string) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOrAdd<K, V>(map: Map<K, V>, key: K, newValueFactory: () => V): V {
|
export function getOrAdd<K, V>(map: MapLike<K, V>, key: K, newValueFactory: () => V): V {
|
||||||
const value = map.get(key);
|
const value = map.get(key);
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -102,8 +102,11 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|||||||
* The `in` and `for-in` operators can *not* be safely used,
|
* The `in` and `for-in` operators can *not* be safely used,
|
||||||
* since `Object.prototype` may be modified by outside code.
|
* since `Object.prototype` may be modified by outside code.
|
||||||
*/
|
*/
|
||||||
export interface MapLike<T> {
|
export interface MapLike<K, V> {
|
||||||
[index: string]: T;
|
readonly [Symbol.toStringTag]: string;
|
||||||
|
get(key: K): V | undefined;
|
||||||
|
has(key: K): boolean;
|
||||||
|
set(key: K, value: V): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +115,7 @@ export interface MapLike<T> {
|
|||||||
* @param map A map-like.
|
* @param map A map-like.
|
||||||
* @param key A property key.
|
* @param key A property key.
|
||||||
*/
|
*/
|
||||||
export function hasProperty(map: MapLike<any>, key: string): boolean {
|
export function hasProperty(map: { [index: string]: any }, key: string): boolean {
|
||||||
return hasOwnProperty.call(map, key);
|
return hasOwnProperty.call(map, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ export function expandPathVariables(path: string, rootPath: Uri, workspaces: Wor
|
|||||||
const ws_regexp = RegExp(`\\$\\{workspaceFolder:${escapedWorkspaceName}\\}`, 'g');
|
const ws_regexp = RegExp(`\\$\\{workspaceFolder:${escapedWorkspaceName}\\}`, 'g');
|
||||||
path = path.replace(ws_regexp, workspace.rootUri.getPath());
|
path = path.replace(ws_regexp, workspace.rootUri.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.HOME !== undefined) {
|
if (process.env.HOME !== undefined) {
|
||||||
replace(/\$\{env:HOME\}/g, process.env.HOME || '');
|
replace(/\$\{env:HOME\}/g, process.env.HOME || '');
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ import { printLiteralValue } from '../analyzer/typePrinter';
|
|||||||
import {
|
import {
|
||||||
ClassType,
|
ClassType,
|
||||||
combineTypes,
|
combineTypes,
|
||||||
|
EnumLiteral,
|
||||||
FunctionType,
|
FunctionType,
|
||||||
isClass,
|
isClass,
|
||||||
isClassInstance,
|
isClassInstance,
|
||||||
@ -127,6 +128,7 @@ import {
|
|||||||
import { DocumentSymbolCollector } from './documentSymbolCollector';
|
import { DocumentSymbolCollector } from './documentSymbolCollector';
|
||||||
import { getAutoImportText, getDocumentationPartsForTypeAndDecl } from './tooltipUtils';
|
import { getAutoImportText, getDocumentationPartsForTypeAndDecl } from './tooltipUtils';
|
||||||
import '../common/serviceProviderExtensions';
|
import '../common/serviceProviderExtensions';
|
||||||
|
import { transformTypeForEnumMember } from '../analyzer/enums';
|
||||||
|
|
||||||
namespace Keywords {
|
namespace Keywords {
|
||||||
const base: string[] = [
|
const base: string[] = [
|
||||||
@ -705,13 +707,7 @@ export class CompletionProvider {
|
|||||||
// Handle enum members specially. Enum members normally look like
|
// Handle enum members specially. Enum members normally look like
|
||||||
// variables, but the are declared using assignment expressions
|
// variables, but the are declared using assignment expressions
|
||||||
// within an enum class.
|
// within an enum class.
|
||||||
if (
|
if (this._isEnumMember(detail.boundObjectOrClass, name)) {
|
||||||
primaryDecl.type === DeclarationType.Variable &&
|
|
||||||
detail.boundObjectOrClass &&
|
|
||||||
isInstantiableClass(detail.boundObjectOrClass) &&
|
|
||||||
ClassType.isEnumClass(detail.boundObjectOrClass) &&
|
|
||||||
primaryDecl.node.parent?.nodeType === ParseNodeType.Assignment
|
|
||||||
) {
|
|
||||||
itemKind = CompletionItemKind.EnumMember;
|
itemKind = CompletionItemKind.EnumMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,19 +753,16 @@ export class CompletionProvider {
|
|||||||
|
|
||||||
if (isClass(subtype)) {
|
if (isClass(subtype)) {
|
||||||
const instance = TypeBase.isInstance(subtype);
|
const instance = TypeBase.isInstance(subtype);
|
||||||
if (ClassType.isEnumClass(subtype) && instance) {
|
getMembersForClass(subtype, symbolTable, instance);
|
||||||
// We don't add members for instances of enum members, but do add members of `enum.Enum` itself.
|
|
||||||
// ex) 'MyEnum.member.' <= here
|
|
||||||
const enumType = subtype.details.baseClasses.find(
|
|
||||||
(t) => isClass(t) && ClassType.isBuiltIn(t, 'Enum')
|
|
||||||
) as ClassType | undefined;
|
|
||||||
if (!enumType) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMembersForClass(enumType, symbolTable, /* instance */ true);
|
if (ClassType.isEnumClass(subtype) && instance) {
|
||||||
} else {
|
// Don't show enum member out of another enum member
|
||||||
getMembersForClass(subtype, symbolTable, instance);
|
// ex) Enum.Member. <= shouldn't show `Member` again.
|
||||||
|
for (const name of symbolTable.keys()) {
|
||||||
|
if (this._isEnumMember(subtype, name)) {
|
||||||
|
symbolTable.delete(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (isModule(subtype)) {
|
} else if (isModule(subtype)) {
|
||||||
getMembersForModule(subtype, symbolTable);
|
getMembersForModule(subtype, symbolTable);
|
||||||
@ -3143,6 +3136,21 @@ export class CompletionProvider {
|
|||||||
// before doing more expensive type evaluation.
|
// before doing more expensive type evaluation.
|
||||||
return decl.isMethod && decl.node.decorators.length > 0;
|
return decl.isMethod && decl.node.decorators.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _isEnumMember(containingType: ClassType | undefined, name: string) {
|
||||||
|
if (!containingType || !ClassType.isEnumClass(containingType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const symbolType = transformTypeForEnumMember(this.evaluator, containingType, name);
|
||||||
|
|
||||||
|
return (
|
||||||
|
symbolType &&
|
||||||
|
isClassInstance(symbolType) &&
|
||||||
|
ClassType.isSameGenericClass(symbolType, containingType) &&
|
||||||
|
symbolType.literalValue instanceof EnumLiteral
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompletionMap {
|
export class CompletionMap {
|
||||||
|
@ -118,7 +118,7 @@ export function setLocaleOverride(locale: string) {
|
|||||||
localeOverride = locale.toLowerCase();
|
localeOverride = locale.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocaleFromEnv() {
|
export function getLocaleFromEnv(): string {
|
||||||
if (localeOverride) {
|
if (localeOverride) {
|
||||||
return localeOverride;
|
return localeOverride;
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ export function getLocaleFromEnv() {
|
|||||||
const vscodeConfigString = env?.VSCODE_NLS_CONFIG;
|
const vscodeConfigString = env?.VSCODE_NLS_CONFIG;
|
||||||
if (vscodeConfigString) {
|
if (vscodeConfigString) {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(vscodeConfigString).locale;
|
return JSON.parse(vscodeConfigString).locale || defaultLocale;
|
||||||
} catch {
|
} catch {
|
||||||
// Fall through
|
// Fall through
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ export function getLocaleFromEnv() {
|
|||||||
// This string may contain a local followed by an encoding (e.g. "en-us.UTF-8").
|
// This string may contain a local followed by an encoding (e.g. "en-us.UTF-8").
|
||||||
const localeStringSplit = localeString.split('.');
|
const localeStringSplit = localeString.split('.');
|
||||||
if (localeStringSplit.length > 0 && localeStringSplit[0]) {
|
if (localeStringSplit.length > 0 && localeStringSplit[0]) {
|
||||||
return localeStringSplit[0];
|
return localeStringSplit[0] || defaultLocale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -158,8 +158,8 @@
|
|||||||
"enumMemberDelete": "Člen výčtu {name} se nedá odstranit.",
|
"enumMemberDelete": "Člen výčtu {name} se nedá odstranit.",
|
||||||
"enumMemberSet": "Člen výčtu {name} se nedá přiřadit.",
|
"enumMemberSet": "Člen výčtu {name} se nedá přiřadit.",
|
||||||
"enumMemberTypeAnnotation": "Poznámky typu nejsou pro členy výčtu povolené",
|
"enumMemberTypeAnnotation": "Poznámky typu nejsou pro členy výčtu povolené",
|
||||||
"exceptionGroupIncompatible": "Syntaxe skupiny výjimek (except*) vyžaduje Python 3.11 nebo novější",
|
"exceptionGroupIncompatible": "Syntaxe skupiny výjimek (\"except*\") vyžaduje Python 3.11 nebo novější",
|
||||||
"exceptionGroupTypeIncorrect": "Typ výjimky v kromě* se nedá odvodit z BaseGroupException.",
|
"exceptionGroupTypeIncorrect": "Typ výjimky v except* se nedá odvodit z BaseGroupException.",
|
||||||
"exceptionTypeIncorrect": "„{type}“ se neodvozuje od BaseException",
|
"exceptionTypeIncorrect": "„{type}“ se neodvozuje od BaseException",
|
||||||
"exceptionTypeNotClass": "{type} není platná třída výjimky",
|
"exceptionTypeNotClass": "{type} není platná třída výjimky",
|
||||||
"exceptionTypeNotInstantiable": "Konstruktor pro výjimku typu {type} vyžaduje jeden nebo více argumentů",
|
"exceptionTypeNotInstantiable": "Konstruktor pro výjimku typu {type} vyžaduje jeden nebo více argumentů",
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Argumenty typu nejsou u třídy Protocol povoleny při použití syntaxe parametru typu",
|
"protocolBaseClassWithTypeArgs": "Argumenty typu nejsou u třídy Protocol povoleny při použití syntaxe parametru typu",
|
||||||
"protocolIllegal": "Použití protokolu vyžaduje Python 3.7 nebo novější",
|
"protocolIllegal": "Použití protokolu vyžaduje Python 3.7 nebo novější",
|
||||||
"protocolNotAllowed": "„Protocol“ nejde v tomto kontextu použít.",
|
"protocolNotAllowed": "„Protocol“ nejde v tomto kontextu použít.",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "Argument typu pro „protokol“ musí být parametr typu",
|
||||||
"protocolUnsafeOverlap": "Třída se nebezpečně překrývá s názvem „{name}“ a může vytvořit shodu při spuštění.",
|
"protocolUnsafeOverlap": "Třída se nebezpečně překrývá s názvem „{name}“ a může vytvořit shodu při spuštění.",
|
||||||
"protocolVarianceContravariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kontravariantní",
|
"protocolVarianceContravariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kontravariantní",
|
||||||
"protocolVarianceCovariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kovariantní",
|
"protocolVarianceCovariant": "Proměnná typu „{variable}“ použitá v obecném protokolu „{class}“ by měla být kovariantní",
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
"enumMemberSet": "Das Enumerationselement \"{name}\" kann nicht zugewiesen werden.",
|
"enumMemberSet": "Das Enumerationselement \"{name}\" kann nicht zugewiesen werden.",
|
||||||
"enumMemberTypeAnnotation": "Typanmerkungen sind für Enumerationsmember nicht zulässig",
|
"enumMemberTypeAnnotation": "Typanmerkungen sind für Enumerationsmember nicht zulässig",
|
||||||
"exceptionGroupIncompatible": "Die Ausnahmegruppensyntax (\"except*\") erfordert Python 3.11 oder höher.",
|
"exceptionGroupIncompatible": "Die Ausnahmegruppensyntax (\"except*\") erfordert Python 3.11 oder höher.",
|
||||||
"exceptionGroupTypeIncorrect": "Der Ausnahmetyp in „except*“ kann nicht von BaseGroupException abgeleitet werden.",
|
"exceptionGroupTypeIncorrect": "Der Ausnahmetyp in except* kann nicht von BaseGroupException abgeleitet werden.",
|
||||||
"exceptionTypeIncorrect": "\"{type}\" ist nicht von BaseException abgeleitet.",
|
"exceptionTypeIncorrect": "\"{type}\" ist nicht von BaseException abgeleitet.",
|
||||||
"exceptionTypeNotClass": "\"{type}\" ist keine gültige Ausnahmeklasse.",
|
"exceptionTypeNotClass": "\"{type}\" ist keine gültige Ausnahmeklasse.",
|
||||||
"exceptionTypeNotInstantiable": "Der Konstruktor für den Ausnahmetyp \"{type}\" erfordert mindestens ein Argument.",
|
"exceptionTypeNotInstantiable": "Der Konstruktor für den Ausnahmetyp \"{type}\" erfordert mindestens ein Argument.",
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Typargumente sind mit der Protokollklasse nicht zulässig, wenn die Typparametersyntax verwendet wird.",
|
"protocolBaseClassWithTypeArgs": "Typargumente sind mit der Protokollklasse nicht zulässig, wenn die Typparametersyntax verwendet wird.",
|
||||||
"protocolIllegal": "Die Verwendung von \"Protocol\" erfordert Python 3.7 oder höher.",
|
"protocolIllegal": "Die Verwendung von \"Protocol\" erfordert Python 3.7 oder höher.",
|
||||||
"protocolNotAllowed": "\"Protocol\" kann in diesem Kontext nicht verwendet werden.",
|
"protocolNotAllowed": "\"Protocol\" kann in diesem Kontext nicht verwendet werden.",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "Das Typargument für „Protocol“ muss ein Typparameter sein.",
|
||||||
"protocolUnsafeOverlap": "Die Klasse überlappt unsicher mit „{name}“ und könnte zur Laufzeit eine Übereinstimmung erzeugen.",
|
"protocolUnsafeOverlap": "Die Klasse überlappt unsicher mit „{name}“ und könnte zur Laufzeit eine Übereinstimmung erzeugen.",
|
||||||
"protocolVarianceContravariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"contravariant\" sein.",
|
"protocolVarianceContravariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"contravariant\" sein.",
|
||||||
"protocolVarianceCovariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"covariant\" sein.",
|
"protocolVarianceCovariant": "Die Typvariable \"{variable}\", die im generischen Protokoll \"{class}\" verwendet wird, muss \"covariant\" sein.",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "No se permiten argumentos de tipo con la clase Protocol cuando se usa la sintaxis de parámetro de tipo",
|
"protocolBaseClassWithTypeArgs": "No se permiten argumentos de tipo con la clase Protocol cuando se usa la sintaxis de parámetro de tipo",
|
||||||
"protocolIllegal": "El uso de \"Protocolo\" requiere Python 3.7 o posterior.",
|
"protocolIllegal": "El uso de \"Protocolo\" requiere Python 3.7 o posterior.",
|
||||||
"protocolNotAllowed": "\"Protocolo\" no puede utilizarse en este contexto",
|
"protocolNotAllowed": "\"Protocolo\" no puede utilizarse en este contexto",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "El argumento de tipo para \"Protocol\" debe ser un parámetro de tipo",
|
||||||
"protocolUnsafeOverlap": "La clase se superpone \"{name}\" de forma no segura y podría producir una coincidencia en tiempo de ejecución",
|
"protocolUnsafeOverlap": "La clase se superpone \"{name}\" de forma no segura y podría producir una coincidencia en tiempo de ejecución",
|
||||||
"protocolVarianceContravariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser contravariante.",
|
"protocolVarianceContravariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser contravariante.",
|
||||||
"protocolVarianceCovariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser covariante",
|
"protocolVarianceCovariant": "La variable de tipo \"{variable}\" usada en el protocolo genérico \"{class}\" debe ser covariante",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Les arguments de type ne sont pas autorisés avec la classe Protocol lors de l'utilisation de la syntaxe des paramètres de type",
|
"protocolBaseClassWithTypeArgs": "Les arguments de type ne sont pas autorisés avec la classe Protocol lors de l'utilisation de la syntaxe des paramètres de type",
|
||||||
"protocolIllegal": "L’utilisation de « Protocole » nécessite Python 3.7 ou une version plus récente",
|
"protocolIllegal": "L’utilisation de « Protocole » nécessite Python 3.7 ou une version plus récente",
|
||||||
"protocolNotAllowed": "\"Protocole\" ne peut pas être utilisé dans ce contexte",
|
"protocolNotAllowed": "\"Protocole\" ne peut pas être utilisé dans ce contexte",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "L’argument de type pour « Protocol » doit être un paramètre de type",
|
||||||
"protocolUnsafeOverlap": "La classe chevauche « {name} » de manière non sécurisée et peut produire une correspondance au moment de l’exécution",
|
"protocolUnsafeOverlap": "La classe chevauche « {name} » de manière non sécurisée et peut produire une correspondance au moment de l’exécution",
|
||||||
"protocolVarianceContravariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être contravariante",
|
"protocolVarianceContravariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être contravariante",
|
||||||
"protocolVarianceCovariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être covariante",
|
"protocolVarianceCovariant": "La variable de type \"{variable}\" utilisée dans le protocole générique \"{class}\" doit être covariante",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Gli argomenti tipo non sono consentiti con la classe Protocollo quando si usa la sintassi dei parametri tipo",
|
"protocolBaseClassWithTypeArgs": "Gli argomenti tipo non sono consentiti con la classe Protocollo quando si usa la sintassi dei parametri tipo",
|
||||||
"protocolIllegal": "L'uso del \"protocollo\" richiede Python 3.7 o versione successiva",
|
"protocolIllegal": "L'uso del \"protocollo\" richiede Python 3.7 o versione successiva",
|
||||||
"protocolNotAllowed": "\"Protocol\" non può essere usato in questo contesto",
|
"protocolNotAllowed": "\"Protocol\" non può essere usato in questo contesto",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "L'argomento di tipo per \"Protocol\" deve essere un parametro di tipo",
|
||||||
"protocolUnsafeOverlap": "La classe si sovrappone a \"{name}\" in modo non sicuro e può produrre una corrispondenza in fase di esecuzione",
|
"protocolUnsafeOverlap": "La classe si sovrappone a \"{name}\" in modo non sicuro e può produrre una corrispondenza in fase di esecuzione",
|
||||||
"protocolVarianceContravariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere controvariante",
|
"protocolVarianceContravariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere controvariante",
|
||||||
"protocolVarianceCovariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere covariante",
|
"protocolVarianceCovariant": "La variabile di tipo \"{variable}\" usata nel protocollo generico \"{class}\" deve essere covariante",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "型パラメーター構文を使用する場合、Protocol クラスでは型引数を使用できません",
|
"protocolBaseClassWithTypeArgs": "型パラメーター構文を使用する場合、Protocol クラスでは型引数を使用できません",
|
||||||
"protocolIllegal": "\"Protocol\" を使用するには Python 3.7 以降が必要です",
|
"protocolIllegal": "\"Protocol\" を使用するには Python 3.7 以降が必要です",
|
||||||
"protocolNotAllowed": "\"Protocol\" はこのコンテキストでは使用できません",
|
"protocolNotAllowed": "\"Protocol\" はこのコンテキストでは使用できません",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "\"Protocol\" の型引数は型パラメーターである必要があります",
|
||||||
"protocolUnsafeOverlap": "クラスが安全でない方法で \"{name}\" と重複しており、実行時に一致する可能性があります",
|
"protocolUnsafeOverlap": "クラスが安全でない方法で \"{name}\" と重複しており、実行時に一致する可能性があります",
|
||||||
"protocolVarianceContravariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は反変である必要があります",
|
"protocolVarianceContravariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は反変である必要があります",
|
||||||
"protocolVarianceCovariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は共変である必要があります",
|
"protocolVarianceCovariant": "ジェネリック プロトコル \"{class}\" で使用される型変数 \"{variable}\" は共変である必要があります",
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
"enumMemberSet": "열거형 멤버 \"{name}\"을(를) 할당할 수 없음",
|
"enumMemberSet": "열거형 멤버 \"{name}\"을(를) 할당할 수 없음",
|
||||||
"enumMemberTypeAnnotation": "열거형 멤버에는 형식 주석을 사용할 수 없습니다.",
|
"enumMemberTypeAnnotation": "열거형 멤버에는 형식 주석을 사용할 수 없습니다.",
|
||||||
"exceptionGroupIncompatible": "예외 그룹 구문(\"except*\")에는 Python 3.11 이상이 필요합니다.",
|
"exceptionGroupIncompatible": "예외 그룹 구문(\"except*\")에는 Python 3.11 이상이 필요합니다.",
|
||||||
"exceptionGroupTypeIncorrect": "exception*의 예외 형식은 BaseGroupException에서 파생될 수 없습니다.",
|
"exceptionGroupTypeIncorrect": "except*의 예외 형식은 BaseGroupException에서 파생될 수 없습니다.",
|
||||||
"exceptionTypeIncorrect": "‘{type}’은 BaseException에서 파생되지 않습니다.",
|
"exceptionTypeIncorrect": "‘{type}’은 BaseException에서 파생되지 않습니다.",
|
||||||
"exceptionTypeNotClass": "\"{type}\"은(는) 올바른 예외 클래스가 아닙니다.",
|
"exceptionTypeNotClass": "\"{type}\"은(는) 올바른 예외 클래스가 아닙니다.",
|
||||||
"exceptionTypeNotInstantiable": "예외 형식 \"{type}\"에 대한 생성자에는 하나 이상의 인수가 필요합니다.",
|
"exceptionTypeNotInstantiable": "예외 형식 \"{type}\"에 대한 생성자에는 하나 이상의 인수가 필요합니다.",
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "형식 매개 변수 구문을 사용할 때는 Protocol 클래스에 형식 인수가 허용되지 않습니다.",
|
"protocolBaseClassWithTypeArgs": "형식 매개 변수 구문을 사용할 때는 Protocol 클래스에 형식 인수가 허용되지 않습니다.",
|
||||||
"protocolIllegal": "\"프로토콜\"을 사용하려면 Python 3.7 이상이 필요합니다.",
|
"protocolIllegal": "\"프로토콜\"을 사용하려면 Python 3.7 이상이 필요합니다.",
|
||||||
"protocolNotAllowed": "이 컨텍스트에서는 \"Protocol\"을 사용할 수 없습니다.",
|
"protocolNotAllowed": "이 컨텍스트에서는 \"Protocol\"을 사용할 수 없습니다.",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "\"Protocol\"의 형식 인수는 형식 매개 변수여야 합니다.",
|
||||||
"protocolUnsafeOverlap": "클래스가 \"{name}\"과(와) 안전하지 않게 겹치며 런타임에 일치 항목을 생성할 수 있습니다.",
|
"protocolUnsafeOverlap": "클래스가 \"{name}\"과(와) 안전하지 않게 겹치며 런타임에 일치 항목을 생성할 수 있습니다.",
|
||||||
"protocolVarianceContravariant": "‘{class}‘ 제네릭 프로토콜에서 사용되는 ’{variable}‘ 형식 변수는 반공변이어야 합니다.",
|
"protocolVarianceContravariant": "‘{class}‘ 제네릭 프로토콜에서 사용되는 ’{variable}‘ 형식 변수는 반공변이어야 합니다.",
|
||||||
"protocolVarianceCovariant": "‘{class}‘ 제네릭 프로토콜에서 사용되는 ’{variable}‘ 형식 변수는 공변이어야 합니다",
|
"protocolVarianceCovariant": "‘{class}‘ 제네릭 프로토콜에서 사용되는 ’{variable}‘ 형식 변수는 공변이어야 합니다",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Argumenty typu są niedozwolone w przypadku klasy protokołu, gdy jest używana składnia parametru typu",
|
"protocolBaseClassWithTypeArgs": "Argumenty typu są niedozwolone w przypadku klasy protokołu, gdy jest używana składnia parametru typu",
|
||||||
"protocolIllegal": "Użycie elementu „Protocol” wymaga języka Python w wersji 3.7 lub nowszej",
|
"protocolIllegal": "Użycie elementu „Protocol” wymaga języka Python w wersji 3.7 lub nowszej",
|
||||||
"protocolNotAllowed": "„Protokół” nie może być używany w tym kontekście",
|
"protocolNotAllowed": "„Protokół” nie może być używany w tym kontekście",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "Argument typu dla elementy „Protocol” musi być parametrem typu",
|
||||||
"protocolUnsafeOverlap": "Klasa nakłada się niebezpiecznie na element „{name}” i może utworzyć dopasowanie w czasie wykonywania",
|
"protocolUnsafeOverlap": "Klasa nakłada się niebezpiecznie na element „{name}” i może utworzyć dopasowanie w czasie wykonywania",
|
||||||
"protocolVarianceContravariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kontrawariantna",
|
"protocolVarianceContravariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kontrawariantna",
|
||||||
"protocolVarianceCovariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kowariantna",
|
"protocolVarianceCovariant": "Zmienna typu „{variable}” używana w klasie protokołu ogólnego „{class}” powinna być kowariantna",
|
||||||
|
@ -158,8 +158,8 @@
|
|||||||
"enumMemberDelete": "O membro enumerado \"{name}\" não pode ser excluído",
|
"enumMemberDelete": "O membro enumerado \"{name}\" não pode ser excluído",
|
||||||
"enumMemberSet": "O membro enumerado \"{name}\" não pode ser atribuído",
|
"enumMemberSet": "O membro enumerado \"{name}\" não pode ser atribuído",
|
||||||
"enumMemberTypeAnnotation": "Anotações de tipo não são permitidas para membros de enumeração",
|
"enumMemberTypeAnnotation": "Anotações de tipo não são permitidas para membros de enumeração",
|
||||||
"exceptionGroupIncompatible": "A sintaxe do grupo de exceção (\"exceto*\") requer o Python 3.11 ou mais recente",
|
"exceptionGroupIncompatible": "A sintaxe do grupo de exceção (\"except*\") requer o Python 3.11 ou mais recente",
|
||||||
"exceptionGroupTypeIncorrect": "O tipo de exceção em exceto* não pode derivar de BaseGroupException",
|
"exceptionGroupTypeIncorrect": "O tipo de exceção em except* não pode derivar de BaseGroupException",
|
||||||
"exceptionTypeIncorrect": "\"{type}\" não deriva de BaseException",
|
"exceptionTypeIncorrect": "\"{type}\" não deriva de BaseException",
|
||||||
"exceptionTypeNotClass": "\"{type}\" não é uma classe de exceção válida",
|
"exceptionTypeNotClass": "\"{type}\" não é uma classe de exceção válida",
|
||||||
"exceptionTypeNotInstantiable": "O construtor para o tipo de exceção \"{type}\" requer um ou mais argumentos",
|
"exceptionTypeNotInstantiable": "O construtor para o tipo de exceção \"{type}\" requer um ou mais argumentos",
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Argumentos de tipo não são permitidos com a classe Protocol ao usar a sintaxe de parâmetro de tipo",
|
"protocolBaseClassWithTypeArgs": "Argumentos de tipo não são permitidos com a classe Protocol ao usar a sintaxe de parâmetro de tipo",
|
||||||
"protocolIllegal": "O uso de \"Protocol\" requer o Python 3.7 ou mais recente",
|
"protocolIllegal": "O uso de \"Protocol\" requer o Python 3.7 ou mais recente",
|
||||||
"protocolNotAllowed": "\"Protocol\" não pode ser usado nesse contexto",
|
"protocolNotAllowed": "\"Protocol\" não pode ser usado nesse contexto",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "O argumento de tipo para o \"Protocolo\" deve ser um parâmetro de tipo",
|
||||||
"protocolUnsafeOverlap": "A classe se sobrepõe a \"{name}\" de forma não segura e pode produzir uma correspondência em runtime",
|
"protocolUnsafeOverlap": "A classe se sobrepõe a \"{name}\" de forma não segura e pode produzir uma correspondência em runtime",
|
||||||
"protocolVarianceContravariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser contravariante",
|
"protocolVarianceContravariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser contravariante",
|
||||||
"protocolVarianceCovariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser covariante",
|
"protocolVarianceCovariant": "A variável de tipo \"{variable}\" usada no protocolo genérico \"{class}\" deve ser covariante",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Аргументы типа не допускаются с классом протокола при использовании синтаксиса параметра типа",
|
"protocolBaseClassWithTypeArgs": "Аргументы типа не допускаются с классом протокола при использовании синтаксиса параметра типа",
|
||||||
"protocolIllegal": "Ключевое слово \"Protocol\" можно использовать в Python версии не ниже 3.7",
|
"protocolIllegal": "Ключевое слово \"Protocol\" можно использовать в Python версии не ниже 3.7",
|
||||||
"protocolNotAllowed": "Невозможно использовать \"Protocol\" в этом контексте",
|
"protocolNotAllowed": "Невозможно использовать \"Protocol\" в этом контексте",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "Аргумент типа для параметра \"Protocol\" должен быть параметром типа",
|
||||||
"protocolUnsafeOverlap": "Класс небезопасно перекрывает \"{name}\" и может вызвать совпадение во время выполнения",
|
"protocolUnsafeOverlap": "Класс небезопасно перекрывает \"{name}\" и может вызвать совпадение во время выполнения",
|
||||||
"protocolVarianceContravariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть контравариантной.",
|
"protocolVarianceContravariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть контравариантной.",
|
||||||
"protocolVarianceCovariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть ковариантной",
|
"protocolVarianceCovariant": "Переменная типа \"{variable}\", используемая в универсальном протоколе \"{class}\", должна быть ковариантной",
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
"enumMemberSet": "Sabit liste üyesi \"{name}\" atanamıyor",
|
"enumMemberSet": "Sabit liste üyesi \"{name}\" atanamıyor",
|
||||||
"enumMemberTypeAnnotation": "Sabit listesi üyeleri için tür ek açıklamalarına izin verilmiyor",
|
"enumMemberTypeAnnotation": "Sabit listesi üyeleri için tür ek açıklamalarına izin verilmiyor",
|
||||||
"exceptionGroupIncompatible": "Özel durum grubu söz dizimi (\"except*\") için Python 3.11 veya daha yeni bir sürümü gerekiyor",
|
"exceptionGroupIncompatible": "Özel durum grubu söz dizimi (\"except*\") için Python 3.11 veya daha yeni bir sürümü gerekiyor",
|
||||||
"exceptionGroupTypeIncorrect": "Except* altındaki özel durum türü BaseGroupException değerinden türetilemiyor",
|
"exceptionGroupTypeIncorrect": "except* altındaki özel durum türü BaseGroupException değerinden türetilemiyor",
|
||||||
"exceptionTypeIncorrect": "\"{type}\", BaseException türevi değil",
|
"exceptionTypeIncorrect": "\"{type}\", BaseException türevi değil",
|
||||||
"exceptionTypeNotClass": "\"{type}\" geçerli bir özel durum sınıfı değil",
|
"exceptionTypeNotClass": "\"{type}\" geçerli bir özel durum sınıfı değil",
|
||||||
"exceptionTypeNotInstantiable": "\"{type}\" özel durum türü oluşturucusu bir veya daha fazla bağımsız değişken gerektiriyor",
|
"exceptionTypeNotInstantiable": "\"{type}\" özel durum türü oluşturucusu bir veya daha fazla bağımsız değişken gerektiriyor",
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "Tür parametresi söz dizimi kullanılırken, tür bağımsız değişkenlerinin Protokol sınıfıyla kullanılmasına izin verilmez",
|
"protocolBaseClassWithTypeArgs": "Tür parametresi söz dizimi kullanılırken, tür bağımsız değişkenlerinin Protokol sınıfıyla kullanılmasına izin verilmez",
|
||||||
"protocolIllegal": "\"Protocol\" kullanımı için Python 3.7 veya daha yeni bir sürümü gerekiyor",
|
"protocolIllegal": "\"Protocol\" kullanımı için Python 3.7 veya daha yeni bir sürümü gerekiyor",
|
||||||
"protocolNotAllowed": "\"Protokol\" bu bağlamda kullanılamaz",
|
"protocolNotAllowed": "\"Protokol\" bu bağlamda kullanılamaz",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "“Protokol” için tür bağımsız değişkeni bir tür parametresi olmalıdır",
|
||||||
"protocolUnsafeOverlap": "Sınıf, \"{name}\" ile güvenli olmayan bir şekilde çakışıyor ve çalışma zamanında bir eşleşme üretebilir",
|
"protocolUnsafeOverlap": "Sınıf, \"{name}\" ile güvenli olmayan bir şekilde çakışıyor ve çalışma zamanında bir eşleşme üretebilir",
|
||||||
"protocolVarianceContravariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni, değişken karşıtı olmalıdır",
|
"protocolVarianceContravariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni, değişken karşıtı olmalıdır",
|
||||||
"protocolVarianceCovariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni birlikte değişen olmalıdır",
|
"protocolVarianceCovariant": "\"{class}\" genel protokolünde kullanılan \"{variable}\" tür değişkeni birlikte değişen olmalıdır",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "使用类型参数语法时,协议类不允许使用类型参数",
|
"protocolBaseClassWithTypeArgs": "使用类型参数语法时,协议类不允许使用类型参数",
|
||||||
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更高版本",
|
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更高版本",
|
||||||
"protocolNotAllowed": "\"Protocol\" 不能用于此上下文",
|
"protocolNotAllowed": "\"Protocol\" 不能用于此上下文",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "“协议”的类型参数必须是类型参数",
|
||||||
"protocolUnsafeOverlap": "类与“{name}”不安全地重叠,并且可能在运行时生成匹配项",
|
"protocolUnsafeOverlap": "类与“{name}”不安全地重叠,并且可能在运行时生成匹配项",
|
||||||
"protocolVarianceContravariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为逆变",
|
"protocolVarianceContravariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为逆变",
|
||||||
"protocolVarianceCovariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为协变",
|
"protocolVarianceCovariant": "泛型协议“{class}”中使用的类型变量“{variable}”应为协变",
|
||||||
|
@ -403,7 +403,7 @@
|
|||||||
"protocolBaseClassWithTypeArgs": "使用型別參數語法時,通訊協定類別不允許使用型別引數",
|
"protocolBaseClassWithTypeArgs": "使用型別參數語法時,通訊協定類別不允許使用型別引數",
|
||||||
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更新版本",
|
"protocolIllegal": "使用 \"Protocol\" 需要 Python 3.7 或更新版本",
|
||||||
"protocolNotAllowed": "\"Protocol\" 不能用在此內容中",
|
"protocolNotAllowed": "\"Protocol\" 不能用在此內容中",
|
||||||
"protocolTypeArgMustBeTypeParam": "Type argument for \"Protocol\" must be a type parameter",
|
"protocolTypeArgMustBeTypeParam": "“Protocol” 的型別引數必須是型別參數",
|
||||||
"protocolUnsafeOverlap": "類別以不安全方式重疊 \"{name}\",且可能會在運行時間產生相符專案",
|
"protocolUnsafeOverlap": "類別以不安全方式重疊 \"{name}\",且可能會在運行時間產生相符專案",
|
||||||
"protocolVarianceContravariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為逆變數",
|
"protocolVarianceContravariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為逆變數",
|
||||||
"protocolVarianceCovariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為共變數",
|
"protocolVarianceCovariant": "一般通訊協定 \"{class}\" 中使用的型別變數 \"{variable}\" 必須為共變數",
|
||||||
|
@ -1302,3 +1302,90 @@ test('import from completion for namespace package', async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('members off enum member', async () => {
|
||||||
|
const code = `
|
||||||
|
// @filename: test.py
|
||||||
|
//// from enum import Enum
|
||||||
|
//// class Planet(Enum):
|
||||||
|
//// MERCURY = (3.303e+23, 2.4397e6)
|
||||||
|
//// EARTH = (5.976e+24, 6.37814e6)
|
||||||
|
////
|
||||||
|
//// def __init__(self, mass, radius):
|
||||||
|
//// self.mass = mass # in kilograms
|
||||||
|
//// self.radius = radius # in meters
|
||||||
|
////
|
||||||
|
//// @property
|
||||||
|
//// def surface_gravity(self):
|
||||||
|
//// # universal gravitational constant (m3 kg-1 s-2)
|
||||||
|
//// G = 6.67300E-11
|
||||||
|
//// return G * self.mass / (self.radius * self.radius)
|
||||||
|
////
|
||||||
|
//// Planet.EARTH.[|/*marker*/|]
|
||||||
|
`;
|
||||||
|
|
||||||
|
const state = parseAndGetTestState(code).state;
|
||||||
|
|
||||||
|
await state.verifyCompletion('excluded', 'markdown', {
|
||||||
|
['marker']: {
|
||||||
|
completions: [
|
||||||
|
{
|
||||||
|
label: 'MERCURY',
|
||||||
|
kind: CompletionItemKind.EnumMember,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'EARTH',
|
||||||
|
kind: CompletionItemKind.EnumMember,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await state.verifyCompletion('included', 'markdown', {
|
||||||
|
['marker']: {
|
||||||
|
completions: [
|
||||||
|
{
|
||||||
|
label: 'mass',
|
||||||
|
kind: CompletionItemKind.Variable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'radius',
|
||||||
|
kind: CompletionItemKind.Variable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'surface_gravity',
|
||||||
|
kind: CompletionItemKind.Property,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('enum with regular base type', async () => {
|
||||||
|
const code = `
|
||||||
|
// @filename: test.py
|
||||||
|
//// from enum import Enum
|
||||||
|
//// from datetime import timedelta
|
||||||
|
//// class Period(timedelta, Enum):
|
||||||
|
//// Today = -1
|
||||||
|
////
|
||||||
|
//// Period.Today.[|/*marker*/|]
|
||||||
|
`;
|
||||||
|
|
||||||
|
const state = parseAndGetTestState(code).state;
|
||||||
|
|
||||||
|
await state.verifyCompletion('included', 'markdown', {
|
||||||
|
['marker']: {
|
||||||
|
completions: [
|
||||||
|
{
|
||||||
|
label: 'days',
|
||||||
|
kind: CompletionItemKind.Property,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'seconds',
|
||||||
|
kind: CompletionItemKind.Property,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -192,4 +192,47 @@ describe(`Basic language server tests`, () => {
|
|||||||
assert.equal(diagnostic.diagnostics[3].code, 'reportUnusedImport');
|
assert.equal(diagnostic.diagnostics[3].code, 'reportUnusedImport');
|
||||||
assert.equal(diagnostic.diagnostics[5].code, 'reportUnusedImport');
|
assert.equal(diagnostic.diagnostics[5].code, 'reportUnusedImport');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Diagnostic severity overrides test', async () => {
|
||||||
|
const code = `
|
||||||
|
// @filename: test.py
|
||||||
|
//// def test([|/*marker*/x|]): ...
|
||||||
|
////
|
||||||
|
// @filename: pyproject.toml
|
||||||
|
////
|
||||||
|
`;
|
||||||
|
const settings = [
|
||||||
|
{
|
||||||
|
item: {
|
||||||
|
scopeUri: `file://${normalizeSlashes(DEFAULT_WORKSPACE_ROOT, '/')}`,
|
||||||
|
section: 'python.analysis',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
diagnosticSeverityOverrides: {
|
||||||
|
reportUnknownParameterType: 'warning',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const info = await runLanguageServer(
|
||||||
|
DEFAULT_WORKSPACE_ROOT,
|
||||||
|
code,
|
||||||
|
/* callInitialize */ true,
|
||||||
|
settings,
|
||||||
|
undefined,
|
||||||
|
/* supportsBackgroundThread */ true
|
||||||
|
);
|
||||||
|
|
||||||
|
// get the file containing the marker that also contains our task list comments
|
||||||
|
await openFile(info, 'marker');
|
||||||
|
|
||||||
|
// Wait for the diagnostics to publish
|
||||||
|
const diagnostics = await waitForDiagnostics(info);
|
||||||
|
const diagnostic = diagnostics.find((d) => d.uri.includes('test.py'));
|
||||||
|
assert(diagnostic);
|
||||||
|
|
||||||
|
// Make sure the error has a special rule
|
||||||
|
assert.equal(diagnostic.diagnostics[0].code, 'reportUnknownParameterType');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -7,8 +7,7 @@ from abc import ABC, abstractmethod
|
|||||||
class A(ABC):
|
class A(ABC):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def method1() -> None:
|
def method1() -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -66,8 +65,7 @@ def func1(a: type[A]):
|
|||||||
a.method3()
|
a.method3()
|
||||||
|
|
||||||
|
|
||||||
class C(A):
|
class C(A): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
|
@ -18,8 +18,7 @@ class Foo(ABC):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def func1(self, a: str) -> str:
|
def func1(self, a: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
# This should generate an error because this overload is
|
# This should generate an error because this overload is
|
||||||
# missing an abstractmethod overload.
|
# missing an abstractmethod overload.
|
||||||
@ -27,8 +26,7 @@ class Foo(ABC):
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func2(self, a: str) -> str:
|
def func2(self, a: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -23,5 +23,4 @@ class Bar(Foo):
|
|||||||
@final
|
@final
|
||||||
# This should generate an error because Foo.foo, Bar.bar, and Bar.bar1
|
# This should generate an error because Foo.foo, Bar.bar, and Bar.bar1
|
||||||
# are abstract.
|
# are abstract.
|
||||||
class Baz(Bar):
|
class Baz(Bar): ...
|
||||||
...
|
|
||||||
|
@ -9,8 +9,7 @@ from typing import NamedTuple
|
|||||||
class ClassA(ABC):
|
class ClassA(ABC):
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def myproperty(self) -> str:
|
def myproperty(self) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
MixinB = NamedTuple("MixinB", [("myproperty", str)])
|
MixinB = NamedTuple("MixinB", [("myproperty", str)])
|
||||||
|
@ -10,9 +10,7 @@ v1: Annotated[str, ClassA, func1(), v2[0]] = ""
|
|||||||
v2 = [1, 2, 3]
|
v2 = [1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
class ClassA:
|
class ClassA: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1():
|
def func1(): ...
|
||||||
...
|
|
||||||
|
@ -64,8 +64,7 @@ class ClassD:
|
|||||||
|
|
||||||
str: "str"
|
str: "str"
|
||||||
|
|
||||||
def int(self):
|
def int(self): ...
|
||||||
...
|
|
||||||
|
|
||||||
foo: "int"
|
foo: "int"
|
||||||
|
|
||||||
@ -147,4 +146,3 @@ x12: b"int"
|
|||||||
|
|
||||||
# This should generate an error because format strings aren't allowed.
|
# This should generate an error because format strings aren't allowed.
|
||||||
x13: f"int"
|
x13: f"int"
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ class ClassB(ClassA):
|
|||||||
def func5(self, x: ClassA):
|
def func5(self, x: ClassA):
|
||||||
x.func0()
|
x.func0()
|
||||||
|
|
||||||
class ClassA:
|
class ClassA: ...
|
||||||
...
|
|
||||||
|
|
||||||
def func6(self, x: ClassC):
|
def func6(self, x: ClassC):
|
||||||
x.my_int
|
x.my_int
|
||||||
|
@ -53,8 +53,7 @@ e = [3]
|
|||||||
e: list[int]
|
e: list[int]
|
||||||
|
|
||||||
|
|
||||||
def register(fn: Callable[[], None]) -> None:
|
def register(fn: Callable[[], None]) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# These should be be fine because they use the "_" name.
|
# These should be be fine because they use the "_" name.
|
||||||
|
@ -11,12 +11,10 @@ v1 = cast(Any, 0)
|
|||||||
v2 = cast(typing.Any, 0)
|
v2 = cast(typing.Any, 0)
|
||||||
|
|
||||||
|
|
||||||
class A(Any):
|
class A(Any): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class B(typing.Any):
|
class B(typing.Any): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error because Any is not callable.
|
# This should generate an error because Any is not callable.
|
||||||
|
@ -20,8 +20,7 @@ class A:
|
|||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class B(Generic[T]):
|
class B(Generic[T]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(v1: list[Any | None], v2: list[int | str]):
|
def func1(v1: list[Any | None], v2: list[int | str]):
|
||||||
|
@ -38,8 +38,7 @@ d4: dict[str, tuple[int, Callable[[int], int]]] = {
|
|||||||
|
|
||||||
|
|
||||||
class Adder(Protocol):
|
class Adder(Protocol):
|
||||||
def __call__(self, x: int, y: dict[str, int]) -> int:
|
def __call__(self, x: int, y: dict[str, int]) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
v1: Adder = lambda x, y: x + y["hi"]
|
v1: Adder = lambda x, y: x + y["hi"]
|
||||||
|
@ -7,12 +7,10 @@ from typing import Any, TypeVar, overload
|
|||||||
|
|
||||||
class Foo:
|
class Foo:
|
||||||
@overload
|
@overload
|
||||||
def bar(self, obj: None) -> object:
|
def bar(self, obj: None) -> object: ...
|
||||||
...
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def bar(self, obj: object) -> Any:
|
def bar(self, obj: object) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
def bar(self, obj: object | None) -> Any:
|
def bar(self, obj: object | None) -> Any:
|
||||||
pass
|
pass
|
||||||
|
@ -17,8 +17,7 @@ def func1() -> Tuple[str, int]:
|
|||||||
return (a, y)
|
return (a, y)
|
||||||
|
|
||||||
|
|
||||||
def get_value(x: int) -> int:
|
def get_value(x: int) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
x = sum(max(value for x in range(10) if (value := get_value(x))) for _ in range(10))
|
x = sum(max(value for x in range(10) if (value := get_value(x))) for _ in range(10))
|
||||||
|
@ -7,8 +7,7 @@ from typing import Any, Callable, TypeVar, overload
|
|||||||
_T = TypeVar("_T")
|
_T = TypeVar("_T")
|
||||||
|
|
||||||
|
|
||||||
def decorator(*args: Any, **kwargs: Any) -> Callable[[_T], _T]:
|
def decorator(*args: Any, **kwargs: Any) -> Callable[[_T], _T]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@decorator(
|
@decorator(
|
||||||
@ -19,7 +18,7 @@ def decorator(*args: Any, **kwargs: Any) -> Callable[[_T], _T]:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def decorated(
|
def decorated(
|
||||||
x: list[str] = [x for x in ["a", "b"] if x in (walrus_target_2 := ["a", "b"])]
|
x: list[str] = [x for x in ["a", "b"] if x in (walrus_target_2 := ["a", "b"])],
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -29,13 +28,11 @@ reveal_type(walrus_target_2, expected_text="list[str]")
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(value: None = None) -> None:
|
def func1(value: None = None) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(value: str) -> str:
|
def func1(value: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(value: str | None = None) -> str | None:
|
def func1(value: str | None = None) -> str | None:
|
||||||
|
@ -19,15 +19,12 @@ class MyPartial[**P, R]:
|
|||||||
self.first = first
|
self.first = first
|
||||||
self.func = func
|
self.func = func
|
||||||
|
|
||||||
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackKeyed[*Ts](Protocol):
|
class CallbackKeyed[*Ts](Protocol):
|
||||||
def __call__(self, *args: *Ts, keyed: bool) -> tuple[*Ts]:
|
def __call__(self, *args: *Ts, keyed: bool) -> tuple[*Ts]: ...
|
||||||
...
|
|
||||||
|
|
||||||
def invoke_keyed[*Ts](fn: CallbackKeyed[*Ts], *args: *Ts) -> tuple[*Ts]:
|
def invoke_keyed[*Ts](fn: CallbackKeyed[*Ts], *args: *Ts) -> tuple[*Ts]:
|
||||||
return fn(*args, keyed=True)
|
return fn(*args, keyed=True)
|
||||||
|
|
||||||
|
|
@ -7,12 +7,15 @@ T = TypeVar("T")
|
|||||||
T_co = TypeVar("T_co", covariant=True)
|
T_co = TypeVar("T_co", covariant=True)
|
||||||
T_contra = TypeVar("T_contra", contravariant=True)
|
T_contra = TypeVar("T_contra", contravariant=True)
|
||||||
|
|
||||||
|
|
||||||
class Parent_Invariant(Generic[T]):
|
class Parent_Invariant(Generic[T]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ShouldBeInvariant[T](Parent_Invariant[T]):
|
class ShouldBeInvariant[T](Parent_Invariant[T]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
a1: ShouldBeInvariant[int] = ShouldBeInvariant[float]()
|
a1: ShouldBeInvariant[int] = ShouldBeInvariant[float]()
|
||||||
|
|
||||||
@ -23,9 +26,11 @@ a2: ShouldBeInvariant[float] = ShouldBeInvariant[int]()
|
|||||||
class Parent_Covariant(Generic[T_co]):
|
class Parent_Covariant(Generic[T_co]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ShouldBeCovariant[T](Parent_Covariant[T]):
|
class ShouldBeCovariant[T](Parent_Covariant[T]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
b1: ShouldBeCovariant[int] = ShouldBeCovariant[float]()
|
b1: ShouldBeCovariant[int] = ShouldBeCovariant[float]()
|
||||||
|
|
||||||
@ -35,11 +40,12 @@ b2: ShouldBeCovariant[float] = ShouldBeCovariant[int]()
|
|||||||
class Parent_Contravariant(Generic[T_contra]):
|
class Parent_Contravariant(Generic[T_contra]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ShouldBeContravariant[T](Parent_Contravariant[T]):
|
class ShouldBeContravariant[T](Parent_Contravariant[T]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
c1: ShouldBeContravariant[int] = ShouldBeContravariant[float]()
|
c1: ShouldBeContravariant[int] = ShouldBeContravariant[float]()
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
c2: ShouldBeContravariant[float] = ShouldBeContravariant[int]()
|
c2: ShouldBeContravariant[float] = ShouldBeContravariant[int]()
|
||||||
|
|
||||||
|
@ -4,12 +4,10 @@
|
|||||||
from typing import Any, Hashable, Mapping, Protocol
|
from typing import Any, Hashable, Mapping, Protocol
|
||||||
|
|
||||||
|
|
||||||
def requires_hashable_tuple(p1: tuple[Hashable, ...]):
|
def requires_hashable_tuple(p1: tuple[Hashable, ...]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def requires_hashable_dict(p1: dict[str, Hashable]):
|
def requires_hashable_dict(p1: dict[str, Hashable]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def test_args(*args: Hashable):
|
def test_args(*args: Hashable):
|
||||||
@ -24,8 +22,7 @@ def test_kwargs(**kwargs: Hashable):
|
|||||||
requires_hashable_dict(kwargs)
|
requires_hashable_dict(kwargs)
|
||||||
|
|
||||||
|
|
||||||
class StrSubclass(str):
|
class StrSubclass(str): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def test_kwargs2(
|
def test_kwargs2(
|
||||||
@ -51,30 +48,26 @@ def test_kwargs2(
|
|||||||
|
|
||||||
|
|
||||||
class Callback1(Protocol):
|
class Callback1(Protocol):
|
||||||
def __call__(self) -> None:
|
def __call__(self) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(
|
def func1(
|
||||||
value: str = ...,
|
value: str = ...,
|
||||||
*args: object,
|
*args: object,
|
||||||
) -> None:
|
) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(
|
def func2(
|
||||||
value: str = ...,
|
value: str = ...,
|
||||||
**kwargs: object,
|
**kwargs: object,
|
||||||
) -> None:
|
) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func3(
|
def func3(
|
||||||
value: str = ...,
|
value: str = ...,
|
||||||
*args: object,
|
*args: object,
|
||||||
**kwargs: object,
|
**kwargs: object,
|
||||||
) -> None:
|
) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
v1: Callback1 = func1
|
v1: Callback1 = func1
|
||||||
|
@ -71,8 +71,7 @@ for a, b in zip(*q6):
|
|||||||
reveal_type(b, expected_text="int")
|
reveal_type(b, expected_text="int")
|
||||||
|
|
||||||
|
|
||||||
def func1(a: list[str], c: list[int]):
|
def func1(a: list[str], c: list[int]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
func1(*q6)
|
func1(*q6)
|
||||||
|
@ -5,31 +5,25 @@
|
|||||||
from typing import Any, Generic, TypeVar, Mapping, KeysView
|
from typing import Any, Generic, TypeVar, Mapping, KeysView
|
||||||
|
|
||||||
|
|
||||||
class MyMapping(Mapping[str, Any]):
|
class MyMapping(Mapping[str, Any]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class StrRecord:
|
class StrRecord:
|
||||||
def __getitem__(self, __key: str) -> str:
|
def __getitem__(self, __key: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
def keys(self) -> KeysView[str]:
|
def keys(self) -> KeysView[str]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class GenericRecord(Generic[T]):
|
class GenericRecord(Generic[T]):
|
||||||
def __getitem__(self, __key: str) -> T:
|
def __getitem__(self, __key: str) -> T: ...
|
||||||
...
|
|
||||||
|
|
||||||
def keys(self) -> KeysView[T]:
|
def keys(self) -> KeysView[T]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(**kwargs: Any) -> None:
|
def func1(**kwargs: Any) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
m = MyMapping()
|
m = MyMapping()
|
||||||
|
@ -9,16 +9,14 @@ from typing import Any, Awaitable, Callable, Iterable, Sequence, TypeVar
|
|||||||
_T1 = TypeVar("_T1")
|
_T1 = TypeVar("_T1")
|
||||||
|
|
||||||
|
|
||||||
def func1(__iterable: Iterable[_T1]) -> _T1:
|
def func1(__iterable: Iterable[_T1]) -> _T1: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
a: Callable[[Sequence[float]], float] = func1
|
a: Callable[[Sequence[float]], float] = func1
|
||||||
b: Callable[[Sequence[Any]], Any] = func1
|
b: Callable[[Sequence[Any]], Any] = func1
|
||||||
|
|
||||||
|
|
||||||
def func2(__iterable: Sequence[_T1]) -> _T1:
|
def func2(__iterable: Sequence[_T1]) -> _T1: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error because an Iterable parameter
|
# This should generate an error because an Iterable parameter
|
||||||
@ -29,8 +27,7 @@ c: Callable[[Iterable[float]], float] = func2
|
|||||||
_T2 = TypeVar("_T2", bound=float)
|
_T2 = TypeVar("_T2", bound=float)
|
||||||
|
|
||||||
|
|
||||||
def func3(__iterable: Iterable[_T2]) -> _T2:
|
def func3(__iterable: Iterable[_T2]) -> _T2: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
d: Callable[[Sequence[int]], int] = func3
|
d: Callable[[Sequence[int]], int] = func3
|
||||||
|
@ -8,8 +8,7 @@ T = TypeVar("T")
|
|||||||
R = TypeVar("R")
|
R = TypeVar("R")
|
||||||
|
|
||||||
|
|
||||||
class ClassA(Generic[R]):
|
class ClassA(Generic[R]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ClassB(Generic[T]):
|
class ClassB(Generic[T]):
|
||||||
|
@ -8,17 +8,14 @@ T = TypeVar("T")
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(real: float):
|
def func1(real: float): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(real: str):
|
def func1(real: str): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(real: float | str) -> None:
|
def func1(real: float | str) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(f: Callable[[T], Any], p: T):
|
def func2(f: Callable[[T], Any], p: T):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# This sample tests the handling of the `__call__` attribute.
|
# This sample tests the handling of the `__call__` attribute.
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__call__ = self.method1
|
self.__call__ = self.method1
|
||||||
|
@ -140,7 +140,7 @@ class TestClass7:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_func7(*args: * tuple[int, *tuple[int, ...]]) -> int:
|
def test_func7(*args: *tuple[int, *tuple[int, ...]]) -> int:
|
||||||
return 123
|
return 123
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,8 +9,7 @@ OutputT = TypeVar("OutputT", covariant=True)
|
|||||||
|
|
||||||
|
|
||||||
class MyCallable(Protocol[InputT, OutputT]):
|
class MyCallable(Protocol[InputT, OutputT]):
|
||||||
def __call__(self, inputs: InputT) -> OutputT:
|
def __call__(self, inputs: InputT) -> OutputT: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class Class1:
|
class Class1:
|
||||||
|
@ -7,17 +7,14 @@ TE = TypeVar("TE", bound=Exception)
|
|||||||
|
|
||||||
|
|
||||||
class CallbackProtocol1(Protocol[TE]):
|
class CallbackProtocol1(Protocol[TE]):
|
||||||
def __call__(self, s_exc: Exception, t_exc_class: Type[TE]) -> TE:
|
def __call__(self, s_exc: Exception, t_exc_class: Type[TE]) -> TE: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(s_exc: Exception, t_exc_class: Type[TE]) -> TE:
|
def func1(s_exc: Exception, t_exc_class: Type[TE]) -> TE: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(
|
def func2(
|
||||||
s_exc_class: Exception,
|
s_exc_class: Exception,
|
||||||
t_exc_class: Type[TE],
|
t_exc_class: Type[TE],
|
||||||
mapper: CallbackProtocol1[TE] = func1,
|
mapper: CallbackProtocol1[TE] = func1,
|
||||||
):
|
): ...
|
||||||
...
|
|
||||||
|
@ -6,15 +6,12 @@ from typing import Any, Protocol, overload
|
|||||||
|
|
||||||
class P1(Protocol):
|
class P1(Protocol):
|
||||||
@overload
|
@overload
|
||||||
def __call__(self, x: int) -> int:
|
def __call__(self, x: int) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __call__(self, x: str) -> str:
|
def __call__(self, x: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
def __call__(self, x: Any) -> Any:
|
def __call__(self, x: Any) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func0(x: Any) -> Any:
|
def func0(x: Any) -> Any:
|
||||||
@ -32,13 +29,11 @@ a1: P1 = func1
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def of1(x: int) -> int:
|
def of1(x: int) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def of1(x: str) -> str:
|
def of1(x: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def of1(x: Any) -> Any:
|
def of1(x: Any) -> Any:
|
||||||
@ -46,13 +41,11 @@ def of1(x: Any) -> Any:
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def of2(x: int) -> complex:
|
def of2(x: int) -> complex: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def of2(x: str) -> str:
|
def of2(x: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def of2(x: Any) -> Any:
|
def of2(x: Any) -> Any:
|
||||||
@ -66,8 +59,7 @@ b1: P1 = of2
|
|||||||
|
|
||||||
|
|
||||||
class P2(Protocol):
|
class P2(Protocol):
|
||||||
def __call__(self, *args: int) -> Any:
|
def __call__(self, *args: int) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
a: P2 = lambda *args: map(lambda arg: arg + 0, args)
|
a: P2 = lambda *args: map(lambda arg: arg + 0, args)
|
||||||
|
@ -6,22 +6,18 @@ from typing import Protocol
|
|||||||
|
|
||||||
# Callback with positional parameter with default arg value.
|
# Callback with positional parameter with default arg value.
|
||||||
class Callback1(Protocol):
|
class Callback1(Protocol):
|
||||||
def __call__(self, path: str = ...) -> str:
|
def __call__(self, path: str = ...) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Callback with positional parameter without default arg value.
|
# Callback with positional parameter without default arg value.
|
||||||
class Callback2(Protocol):
|
class Callback2(Protocol):
|
||||||
def __call__(self, path: str) -> str:
|
def __call__(self, path: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1_1(path: str = "") -> str:
|
def func1_1(path: str = "") -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1_2(path: str) -> str:
|
def func1_2(path: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
val1_1: Callback1 = func1_1
|
val1_1: Callback1 = func1_1
|
||||||
@ -36,22 +32,18 @@ val2_2: Callback2 = func1_2
|
|||||||
|
|
||||||
# Callback with keyword parameter with default arg value.
|
# Callback with keyword parameter with default arg value.
|
||||||
class Callback3(Protocol):
|
class Callback3(Protocol):
|
||||||
def __call__(self, *, path: str = ...) -> str:
|
def __call__(self, *, path: str = ...) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Callback with keyword parameter without default arg value.
|
# Callback with keyword parameter without default arg value.
|
||||||
class Callback4(Protocol):
|
class Callback4(Protocol):
|
||||||
def __call__(self, *, path: str) -> str:
|
def __call__(self, *, path: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func3_1(*, path: str = "") -> str:
|
def func3_1(*, path: str = "") -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func3_2(*, path: str) -> str:
|
def func3_2(*, path: str) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
val3_1: Callback3 = func3_1
|
val3_1: Callback3 = func3_1
|
||||||
|
@ -5,11 +5,10 @@ from typing import Any, Protocol
|
|||||||
|
|
||||||
|
|
||||||
class X(Protocol):
|
class X(Protocol):
|
||||||
def __call__(self, x: int, /, y: str) -> Any:
|
def __call__(self, x: int, /, y: str) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
def f1(x: int, /, y: str, z: None = None) -> Any:
|
|
||||||
...
|
def f1(x: int, /, y: str, z: None = None) -> Any: ...
|
||||||
|
|
||||||
|
|
||||||
x: X = f1
|
x: X = f1
|
||||||
|
@ -5,12 +5,10 @@ from typing import Any, Protocol
|
|||||||
|
|
||||||
|
|
||||||
class P(Protocol):
|
class P(Protocol):
|
||||||
def __call__(self, *args: Any, kwarg0: Any, kwarg1: Any) -> None:
|
def __call__(self, *args: Any, kwarg0: Any, kwarg1: Any) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def f(*args: Any, kwarg0: Any, kwarg1: Any) -> None:
|
def f(*args: Any, kwarg0: Any, kwarg1: Any) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
p: P = f
|
p: P = f
|
||||||
|
@ -15,8 +15,7 @@ class A:
|
|||||||
_T = TypeVar("_T", bound=A)
|
_T = TypeVar("_T", bound=A)
|
||||||
|
|
||||||
|
|
||||||
class B(Generic[_T]):
|
class B(Generic[_T]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class C(A):
|
class C(A):
|
||||||
|
@ -9,8 +9,7 @@ class ClassA:
|
|||||||
# This should generate a warning because __class_getitem__
|
# This should generate a warning because __class_getitem__
|
||||||
# is implicitly a classmethod and should use cls rather than
|
# is implicitly a classmethod and should use cls rather than
|
||||||
# self.
|
# self.
|
||||||
def __class_getitem__(self, args: tuple[int, ...]) -> None:
|
def __class_getitem__(self, args: tuple[int, ...]) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
reveal_type(ClassA[10, 63], expected_text="type[ClassA]")
|
reveal_type(ClassA[10, 63], expected_text="type[ClassA]")
|
||||||
@ -23,8 +22,7 @@ _S = TypeVar("_S")
|
|||||||
class ClassB(Generic[_T, _S]):
|
class ClassB(Generic[_T, _S]):
|
||||||
# Even though this class has a __class_getitem__ method,
|
# Even though this class has a __class_getitem__ method,
|
||||||
# it will be assumed to follow normal generic class semantics.
|
# it will be assumed to follow normal generic class semantics.
|
||||||
def __class_getitem__(cls, args: tuple[int, ...]) -> None:
|
def __class_getitem__(cls, args: tuple[int, ...]) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
reveal_type(ClassB[int, str], expected_text="type[ClassB[int, str]]")
|
reveal_type(ClassB[int, str], expected_text="type[ClassB[int, str]]")
|
||||||
|
@ -19,7 +19,6 @@ def dynamic_subclass1(cls: type[T_A]):
|
|||||||
|
|
||||||
|
|
||||||
def dynamic_subclass2(base: type[A] | None):
|
def dynamic_subclass2(base: type[A] | None):
|
||||||
class SubClass(base or A):
|
class SubClass(base or A): ...
|
||||||
...
|
|
||||||
|
|
||||||
return SubClass
|
return SubClass
|
||||||
|
@ -6,34 +6,27 @@ from typing import Collection, Iterator, Mapping, Sequence, TypeVar
|
|||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
class A(Mapping[str, int], Collection[int]):
|
class A(Mapping[str, int], Collection[int]):
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
def __iter__(self) -> Iterator[str]:
|
def __iter__(self) -> Iterator[str]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
class B(Mapping[str, int], Sequence[int]):
|
class B(Mapping[str, int], Sequence[int]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
class C(Sequence[int], Mapping[str, int]):
|
class C(Sequence[int], Mapping[str, int]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class D(Sequence[float], Mapping[float, int]):
|
class D(Sequence[float], Mapping[float, int]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class E(Sequence[float], Mapping[int, int]):
|
class E(Sequence[float], Mapping[int, int]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
class F(Mapping[int, int], Sequence[float]):
|
class F(Mapping[int, int], Sequence[float]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
@ -41,16 +34,13 @@ S = TypeVar("S")
|
|||||||
|
|
||||||
|
|
||||||
class G(Mapping[T, S], Collection[T]):
|
class G(Mapping[T, S], Collection[T]):
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int: ...
|
||||||
...
|
|
||||||
|
def __iter__(self) -> Iterator[T]: ...
|
||||||
|
|
||||||
def __iter__(self) -> Iterator[T]:
|
|
||||||
...
|
|
||||||
|
|
||||||
# This should generate an error.
|
# This should generate an error.
|
||||||
class H(Mapping[T, S], Collection[S]):
|
class H(Mapping[T, S], Collection[S]):
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
def __iter__(self) -> Iterator[T]:
|
def __iter__(self) -> Iterator[T]: ...
|
||||||
...
|
|
||||||
|
@ -215,8 +215,7 @@ class SubclassTuple2(ParentClass2):
|
|||||||
cv_decl_1, cv_decl_2, cv_decl_3 = (3, 4.5, None)
|
cv_decl_1, cv_decl_2, cv_decl_3 = (3, 4.5, None)
|
||||||
|
|
||||||
|
|
||||||
class ConfigBase:
|
class ConfigBase: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ParentClass3(Protocol):
|
class ParentClass3(Protocol):
|
||||||
@ -225,13 +224,11 @@ class ParentClass3(Protocol):
|
|||||||
|
|
||||||
|
|
||||||
class ChildClass3(ParentClass3):
|
class ChildClass3(ParentClass3):
|
||||||
class Config1(ConfigBase):
|
class Config1(ConfigBase): ...
|
||||||
...
|
|
||||||
|
|
||||||
# This should generate an error if reportIncompatibleVariableOverride
|
# This should generate an error if reportIncompatibleVariableOverride
|
||||||
# is enabled.
|
# is enabled.
|
||||||
class Config2:
|
class Config2: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class PeerClass1:
|
class PeerClass1:
|
||||||
|
@ -66,5 +66,4 @@ class TD_A2(TypedDict):
|
|||||||
|
|
||||||
|
|
||||||
# This should generate an error for x but not y.
|
# This should generate an error for x but not y.
|
||||||
class TD_A(TD_A1, TD_A2):
|
class TD_A(TD_A1, TD_A2): ...
|
||||||
...
|
|
||||||
|
@ -5,31 +5,25 @@
|
|||||||
from typing import Any, Callable, overload
|
from typing import Any, Callable, overload
|
||||||
|
|
||||||
|
|
||||||
class C:
|
class C: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(v: Callable[[], int]) -> int:
|
def func1(v: Callable[[], int]) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(v: Callable[[], list[C]]) -> list[C]:
|
def func1(v: Callable[[], list[C]]) -> list[C]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(v: Any) -> Any:
|
def func1(v: Any) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(v: list[C]):
|
def func2(v: list[C]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
t = func1(lambda: func3())
|
t = func1(lambda: func3())
|
||||||
t.append(C())
|
t.append(C())
|
||||||
|
|
||||||
|
|
||||||
def func3() -> list[C]:
|
def func3() -> list[C]: ...
|
||||||
...
|
|
||||||
|
@ -5,31 +5,25 @@
|
|||||||
from typing import Any, Callable, overload
|
from typing import Any, Callable, overload
|
||||||
|
|
||||||
|
|
||||||
class C:
|
class C: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(v: Callable[[], int]) -> int:
|
def func1(v: Callable[[], int]) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def func1(v: Callable[[], list[C]]) -> list[C]:
|
def func1(v: Callable[[], list[C]]) -> list[C]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func1(v: Any) -> Any:
|
def func1(v: Any) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(v: list[C]):
|
def func2(v: list[C]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
t = func1(lambda: func3())
|
t = func1(lambda: func3())
|
||||||
t.append(C())
|
t.append(C())
|
||||||
|
|
||||||
|
|
||||||
def func3() -> list[C]:
|
def func3() -> list[C]: ...
|
||||||
...
|
|
||||||
|
@ -30,12 +30,10 @@ def func1(os: OS, val: Literal[1, "linux"]):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ClassA:
|
class ClassA: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ClassB:
|
class ClassB: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
_T1 = TypeVar("_T1")
|
_T1 = TypeVar("_T1")
|
||||||
|
@ -8,8 +8,7 @@ b = a + 4
|
|||||||
c = 1.2 * a
|
c = 1.2 * a
|
||||||
|
|
||||||
|
|
||||||
def requires_complex(val: complex):
|
def requires_complex(val: complex): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
requires_complex(a)
|
requires_complex(a)
|
||||||
|
@ -18,8 +18,7 @@ def add1(value: _T1) -> _T1:
|
|||||||
|
|
||||||
|
|
||||||
class IntSubclass2(int):
|
class IntSubclass2(int):
|
||||||
def __add__(self, value: object) -> "IntSubclass2":
|
def __add__(self, value: object) -> "IntSubclass2": ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
_T2 = TypeVar("_T2", int, IntSubclass2)
|
_T2 = TypeVar("_T2", int, IntSubclass2)
|
||||||
|
@ -6,8 +6,7 @@ from os import PathLike
|
|||||||
from typing import AnyStr
|
from typing import AnyStr
|
||||||
|
|
||||||
|
|
||||||
def func1(path: AnyStr | PathLike[AnyStr]) -> AnyStr:
|
def func1(path: AnyStr | PathLike[AnyStr]) -> AnyStr: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(value: AnyStr) -> AnyStr:
|
def func2(value: AnyStr) -> AnyStr:
|
||||||
|
@ -5,16 +5,13 @@
|
|||||||
from typing import TypeVar, Generic
|
from typing import TypeVar, Generic
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class B:
|
class B: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class A2(A):
|
class A2(A): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T", A, B)
|
T = TypeVar("T", A, B)
|
||||||
|
@ -5,8 +5,7 @@ from typing import AnyStr, Iterable, TypeVar, Generic
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
class ClassA:
|
class ClassA: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
_T = TypeVar("_T", int | float, ClassA)
|
_T = TypeVar("_T", int | float, ClassA)
|
||||||
|
@ -13,12 +13,10 @@ _T1 = TypeVar("_T1")
|
|||||||
AnyStr = TypeVar("AnyStr", str, bytes)
|
AnyStr = TypeVar("AnyStr", str, bytes)
|
||||||
|
|
||||||
|
|
||||||
def exists2(path: AnyStr) -> bool:
|
def exists2(path: AnyStr) -> bool: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def filter2(f: Callable[[_T1], Any], i: Iterable[_T1]) -> Iterator[_T1]:
|
def filter2(f: Callable[[_T1], Any], i: Iterable[_T1]) -> Iterator[_T1]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
result = filter2(exists2, ["hello", "world"])
|
result = filter2(exists2, ["hello", "world"])
|
||||||
|
@ -8,12 +8,10 @@
|
|||||||
from typing import Any, AnyStr, Optional, Protocol, TypeVar, Union
|
from typing import Any, AnyStr, Optional, Protocol, TypeVar, Union
|
||||||
|
|
||||||
|
|
||||||
class Array:
|
class Array: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class MMap:
|
class MMap: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Note that this union contains types that are not compatible
|
# Note that this union contains types that are not compatible
|
||||||
@ -25,29 +23,24 @@ _T_co = TypeVar("_T_co", covariant=True)
|
|||||||
|
|
||||||
|
|
||||||
class BufferedWriter:
|
class BufferedWriter:
|
||||||
def write(self, __buffer: ReadableBuffer) -> int:
|
def write(self, __buffer: ReadableBuffer) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class SupportsWrite(Protocol[_T_contra]):
|
class SupportsWrite(Protocol[_T_contra]):
|
||||||
def write(self, __s: _T_contra) -> Any:
|
def write(self, __s: _T_contra) -> Any: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class SupportsRead(Protocol[_T_co]):
|
class SupportsRead(Protocol[_T_co]):
|
||||||
def read(self, __length: int = ...) -> _T_co:
|
def read(self, __length: int = ...) -> _T_co: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class BufferedReader:
|
class BufferedReader:
|
||||||
def read(self, __size: Optional[int] = ...) -> bytes:
|
def read(self, __size: Optional[int] = ...) -> bytes: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def copyfileobj(
|
def copyfileobj(
|
||||||
fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = ...
|
fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = ...
|
||||||
) -> AnyStr:
|
) -> AnyStr: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def f(fr: BufferedReader, fw: BufferedWriter):
|
def f(fr: BufferedReader, fw: BufferedWriter):
|
||||||
|
@ -9,13 +9,11 @@ T = TypeVar("T")
|
|||||||
|
|
||||||
|
|
||||||
class Async:
|
class Async:
|
||||||
def fn(self, returnable: T) -> Awaitable[T]:
|
def fn(self, returnable: T) -> Awaitable[T]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class Sync:
|
class Sync:
|
||||||
def fn(self, returnable: T) -> T:
|
def fn(self, returnable: T) -> T: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar("T", Async, Sync)
|
T = TypeVar("T", Async, Sync)
|
||||||
|
@ -42,8 +42,7 @@ archive_path = data_dir / "hello"
|
|||||||
shutil.rmtree(archive_path)
|
shutil.rmtree(archive_path)
|
||||||
|
|
||||||
|
|
||||||
def func1(a: AnyStr, b: AnyStr) -> None:
|
def func1(a: AnyStr, b: AnyStr) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(a: Union[str, bytes], b: Union[str, bytes]):
|
def func2(a: Union[str, bytes], b: Union[str, bytes]):
|
||||||
@ -51,27 +50,22 @@ def func2(a: Union[str, bytes], b: Union[str, bytes]):
|
|||||||
func1(a, b)
|
func1(a, b)
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class B:
|
class B: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class C:
|
class C: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class D:
|
class D: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T3 = TypeVar("T3", A, B, Union[C, D])
|
T3 = TypeVar("T3", A, B, Union[C, D])
|
||||||
|
|
||||||
|
|
||||||
def do_something(value: T3) -> T3:
|
def do_something(value: T3) -> T3: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func10(value: Union[C, D]):
|
def func10(value: Union[C, D]):
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
from typing import Iterator, Optional, Sequence, TypeVar, Union
|
from typing import Iterator, Optional, Sequence, TypeVar, Union
|
||||||
|
|
||||||
|
|
||||||
def func0(a: Union[int, float]):
|
def func0(a: Union[int, float]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
_T1 = TypeVar("_T1", int, float)
|
_T1 = TypeVar("_T1", int, float)
|
||||||
@ -39,12 +38,10 @@ def func5(xs: Sequence[Optional[_T2]]) -> Iterator[_T2]:
|
|||||||
return func3(xs)
|
return func3(xs)
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class B(A):
|
class B(A): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
_T4 = TypeVar("_T4", A, B)
|
_T4 = TypeVar("_T4", A, B)
|
||||||
|
@ -10,8 +10,7 @@ _T = TypeVar("_T")
|
|||||||
|
|
||||||
|
|
||||||
class A(Iterator[_T_co]):
|
class A(Iterator[_T_co]):
|
||||||
def __new__(cls, __iterable: Iterable[_T]) -> "A[tuple[_T, _T]]":
|
def __new__(cls, __iterable: Iterable[_T]) -> "A[tuple[_T, _T]]": ...
|
||||||
...
|
|
||||||
|
|
||||||
def __next__(self) -> _T_co: ...
|
def __next__(self) -> _T_co: ...
|
||||||
|
|
||||||
@ -22,8 +21,7 @@ def func1(iterable: Iterable[_T]) -> Iterator[tuple[_T, _T, _T]]:
|
|||||||
|
|
||||||
|
|
||||||
class B(Generic[_T_co]):
|
class B(Generic[_T_co]):
|
||||||
def __new__(cls, __iter1: Iterable[_T]) -> "B[_T]":
|
def __new__(cls, __iter1: Iterable[_T]) -> "B[_T]": ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(p1: list[dict]):
|
def func2(p1: list[dict]):
|
||||||
|
@ -9,38 +9,32 @@ _M = TypeVar("_M")
|
|||||||
|
|
||||||
|
|
||||||
class A(Generic[_M, _N]):
|
class A(Generic[_M, _N]):
|
||||||
def __new__(cls, m: _M, n: _N) -> "A[_M, _N]":
|
def __new__(cls, m: _M, n: _N) -> "A[_M, _N]": ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
a: A[Literal[3], Literal[4]] = A(3, 4)
|
a: A[Literal[3], Literal[4]] = A(3, 4)
|
||||||
|
|
||||||
|
|
||||||
class B(Generic[_M, _N]):
|
class B(Generic[_M, _N]):
|
||||||
def __new__(cls, m: _M, n: _N) -> "B[_M, _N]":
|
def __new__(cls, m: _M, n: _N) -> "B[_M, _N]": ...
|
||||||
...
|
|
||||||
|
|
||||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
b: B[Literal[3], Literal[4]] = B(3, 4)
|
b: B[Literal[3], Literal[4]] = B(3, 4)
|
||||||
|
|
||||||
|
|
||||||
class C(Generic[_M, _N]):
|
class C(Generic[_M, _N]):
|
||||||
def __new__(cls, m: _M, n: _N) -> "C[_M, _N]":
|
def __new__(cls, m: _M, n: _N) -> "C[_M, _N]": ...
|
||||||
...
|
|
||||||
|
|
||||||
def __init__(self, m: _M, n: _N) -> None:
|
def __init__(self, m: _M, n: _N) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
c: C[Literal[3], Literal[4]] = C(3, 4)
|
c: C[Literal[3], Literal[4]] = C(3, 4)
|
||||||
|
|
||||||
|
|
||||||
class D(Generic[_M, _N]):
|
class D(Generic[_M, _N]):
|
||||||
def __new__(cls, m: _M, n: _N) -> Self:
|
def __new__(cls, m: _M, n: _N) -> Self: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
d: D[Literal[3], Literal[4]] = D(3, 4)
|
d: D[Literal[3], Literal[4]] = D(3, 4)
|
||||||
|
@ -13,24 +13,21 @@ class A(Generic[T]):
|
|||||||
|
|
||||||
|
|
||||||
class B(Generic[T]):
|
class B(Generic[T]):
|
||||||
def __init__(self):
|
def __init__(self): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class C(Generic[T]):
|
class C(Generic[T]):
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
return super().__new__(cls, *args, **kwargs)
|
return super().__new__(cls, *args, **kwargs)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class D(Generic[T]):
|
class D(Generic[T]):
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
return super().__new__(cls, *args, **kwargs)
|
return super().__new__(cls, *args, **kwargs)
|
||||||
|
|
||||||
def __init__(self, a: T):
|
def __init__(self, a: T): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class E(Generic[T]):
|
class E(Generic[T]):
|
||||||
|
@ -178,8 +178,7 @@ def s18():
|
|||||||
|
|
||||||
|
|
||||||
class Plant(Generic[_T1]):
|
class Plant(Generic[_T1]):
|
||||||
def __new__(cls, o: _T1) -> Self:
|
def __new__(cls, o: _T1) -> Self: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
plant: Plant[float] = Plant(0)
|
plant: Plant[float] = Plant(0)
|
||||||
|
@ -9,14 +9,11 @@ T = TypeVar("T", covariant=True)
|
|||||||
|
|
||||||
|
|
||||||
class A(Protocol[T]):
|
class A(Protocol[T]):
|
||||||
def a(self) -> "A[Tuple[T]]":
|
def a(self) -> "A[Tuple[T]]": ...
|
||||||
...
|
|
||||||
|
|
||||||
def b(self) -> "A[Tuple[T]]":
|
def b(self) -> "A[Tuple[T]]": ...
|
||||||
...
|
|
||||||
|
|
||||||
def c(self) -> "T":
|
def c(self) -> "T": ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class B(Generic[T]):
|
class B(Generic[T]):
|
||||||
|
@ -72,20 +72,17 @@ def func1(obv: Container[T], default_value: T = None) -> None:
|
|||||||
obv.on_next(default_value)
|
obv.on_next(default_value)
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
T_A = TypeVar("T_A", bound=A)
|
T_A = TypeVar("T_A", bound=A)
|
||||||
|
|
||||||
|
|
||||||
class B(Generic[T]):
|
class B(Generic[T]):
|
||||||
def __init__(self, c: Callable[[], T]):
|
def __init__(self, c: Callable[[], T]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def func2(cls: type[T_A] = A) -> Callable[[], T_A]:
|
def func2(cls: type[T_A] = A) -> Callable[[], T_A]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
B(func2())
|
B(func2())
|
||||||
|
@ -11,22 +11,18 @@ T = TypeVar("T", contravariant=True)
|
|||||||
S = TypeVar("S", contravariant=True)
|
S = TypeVar("S", contravariant=True)
|
||||||
|
|
||||||
|
|
||||||
class ClassA(Generic[T]):
|
class ClassA(Generic[T]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ClassB(Generic[S, T], ClassA[T]):
|
class ClassB(Generic[S, T], ClassA[T]): ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ClassC(ClassB[S, T]):
|
class ClassC(ClassB[S, T]):
|
||||||
def __new__(cls, subcon: ClassA[S]) -> ClassC[S, list[S]]:
|
def __new__(cls, subcon: ClassA[S]) -> ClassC[S, list[S]]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class ClassD(ClassB[S, T]):
|
class ClassD(ClassB[S, T]):
|
||||||
def __new__(cls, subcon: ClassA[S]) -> ClassD[S, list[S]]:
|
def __new__(cls, subcon: ClassA[S]) -> ClassD[S, list[S]]: ...
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
c = ClassA[int]()
|
c = ClassA[int]()
|
||||||
|
@ -29,3 +29,11 @@ def func1(t: type[TA]) -> TA: ...
|
|||||||
|
|
||||||
b = B(func1, A)
|
b = B(func1, A)
|
||||||
reveal_type(b, expected_text="B[(t: type[A]), A]")
|
reveal_type(b, expected_text="B[(t: type[A]), A]")
|
||||||
|
|
||||||
|
|
||||||
|
class C(Generic[TA]):
|
||||||
|
def __init__(self, _type: type[TA]) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
c = B(C, A)
|
||||||
|
reveal_type(c, expected_text="B[(_type: type[A]), C[A]]")
|
||||||
|
@ -9,8 +9,7 @@ T_A = TypeVar("T_A", bound="A")
|
|||||||
|
|
||||||
class A(ABC):
|
class A(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def some_method(self) -> str:
|
def some_method(self) -> str: ...
|
||||||
...
|
|
||||||
|
|
||||||
def some_factory_method_1(self):
|
def some_factory_method_1(self):
|
||||||
return type(self)()
|
return type(self)()
|
||||||
|
17
packages/pyright-internal/src/tests/samples/coroutines4.py
Normal file
17
packages/pyright-internal/src/tests/samples/coroutines4.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# This sample tests the case where an inner coroutine with an inferred
|
||||||
|
# return type is referenced in a manner that results in recursion.
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
|
def func1(replace_inner: bool) -> None:
|
||||||
|
inner = lambda: None
|
||||||
|
|
||||||
|
async def wrapper():
|
||||||
|
inner()
|
||||||
|
|
||||||
|
wrapped_fn = wrapper()
|
||||||
|
asyncio.create_task(wrapped_fn)
|
||||||
|
|
||||||
|
if replace_inner:
|
||||||
|
inner = lambda: None
|
@ -12,8 +12,9 @@ class IsDataclass(Protocol):
|
|||||||
__dataclass_fields__: ClassVar[dict[str, Any]]
|
__dataclass_fields__: ClassVar[dict[str, Any]]
|
||||||
|
|
||||||
|
|
||||||
def dataclass_only(x: IsDataclass):
|
def dataclass_only(
|
||||||
... # do something that only makes sense with a dataclass
|
x: IsDataclass,
|
||||||
|
): ... # do something that only makes sense with a dataclass
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -7,12 +7,10 @@ from typing import Any, cast, overload
|
|||||||
|
|
||||||
class MyDescriptor:
|
class MyDescriptor:
|
||||||
@overload
|
@overload
|
||||||
def __get__(self, __obj: None, __owner: Any) -> "MyDescriptor":
|
def __get__(self, __obj: None, __owner: Any) -> "MyDescriptor": ...
|
||||||
...
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __get__(self, __obj: object, __owner: Any) -> int:
|
def __get__(self, __obj: object, __owner: Any) -> int: ...
|
||||||
...
|
|
||||||
|
|
||||||
def __get__(self, __obj: object | None, __owner: Any) -> "int | MyDescriptor":
|
def __get__(self, __obj: object | None, __owner: Any) -> "int | MyDescriptor":
|
||||||
if __obj is None:
|
if __obj is None:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user