Skip to content

Commit

Permalink
Improved isinstance and issubclass narrowing in the case where an…
Browse files Browse the repository at this point in the history
… intersection type is created and one of the two subclasses has a custom metaclass. This is related to mypy issue python/mypy#8705.
  • Loading branch information
msfterictraut committed Aug 24, 2023
1 parent c83dd9d commit ae62d7c
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion packages/pyright-internal/src/analyzer/typeGuards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,18 @@ function narrowTypeForIsInstance(
// the two types.
const className = `<subclass of ${varType.details.name} and ${concreteFilterType.details.name}>`;
const fileInfo = getFileInfo(errorNode);

// The effective metaclass of the intersection is the narrower of the two metaclasses.
let effectiveMetaclass = varType.details.effectiveMetaclass;
if (concreteFilterType.details.effectiveMetaclass) {
if (
!effectiveMetaclass ||
evaluator.assignType(effectiveMetaclass, concreteFilterType.details.effectiveMetaclass)
) {
effectiveMetaclass = concreteFilterType.details.effectiveMetaclass;
}
}

let newClassType = ClassType.createInstantiable(
className,
ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className),
Expand All @@ -1356,7 +1368,7 @@ function narrowTypeForIsInstance(
ClassTypeFlags.None,
ParseTreeUtils.getTypeSourceId(errorNode),
/* declaredMetaclass */ undefined,
varType.details.effectiveMetaclass,
effectiveMetaclass,
varType.details.docString
);
newClassType.details.baseClasses = [ClassType.cloneAsInstantiable(varType), concreteFilterType];
Expand Down

0 comments on commit ae62d7c

Please sign in to comment.