mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Fixed a bug that led to a false negative when a non-Generic class has a metaclass that defines a __getitem__
method. Such a class should not be indexable within a type annotation, but pyright was not flagging this error. This addresses https://github.com/microsoft/pyright/discussions/4766#discussioncomment-5291138.
This commit is contained in:
parent
a28fb5d560
commit
ce66cc21bb
@ -6608,7 +6608,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
if (
|
||||
concreteSubtype.details.effectiveMetaclass &&
|
||||
isInstantiableClass(concreteSubtype.details.effectiveMetaclass) &&
|
||||
!ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta'])
|
||||
!ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
|
||||
!concreteSubtype.details.mro.some(
|
||||
(mroClass) => isClass(mroClass) && ClassType.isBuiltIn(mroClass, 'Generic')
|
||||
)
|
||||
) {
|
||||
const itemMethodType = getTypeOfClassMember(
|
||||
node,
|
||||
@ -6618,6 +6621,19 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
/* diag */ undefined,
|
||||
MemberAccessFlags.SkipAttributeAccessOverride | MemberAccessFlags.ConsiderMetaclassOnly
|
||||
);
|
||||
|
||||
if (flags & EvaluatorFlags.ExpectingTypeAnnotation) {
|
||||
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
||||
addDiagnostic(
|
||||
AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues,
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
Localizer.Diagnostic.typeArgsExpectingNone().format({
|
||||
name: printType(ClassType.cloneAsInstance(concreteSubtype)),
|
||||
}),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
if (itemMethodType) {
|
||||
return getTypeOfIndexedObjectOrClass(node, concreteSubtype, usage).type;
|
||||
}
|
||||
|
@ -1,7 +1,26 @@
|
||||
# This sample tests pyright's ability to use metaclasses.
|
||||
|
||||
from ctypes import Array, c_uint64
|
||||
from typing import Any, Generic, TypeVar
|
||||
|
||||
myArray1 = (c_uint64 * 5)()
|
||||
|
||||
myArray2: Array[c_uint64] = (c_uint64 * 5)()
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class CustomMeta(type):
|
||||
def __getitem__(self, key: Any) -> "type[int]":
|
||||
...
|
||||
|
||||
|
||||
class Custom(metaclass=CustomMeta):
|
||||
...
|
||||
|
||||
|
||||
# This should generate an errro because the class isn't
|
||||
# Generic even though it supports a metaclass with a
|
||||
# __getitem__.
|
||||
y: Custom[int]
|
||||
|
@ -43,7 +43,7 @@ test('Required3', () => {
|
||||
|
||||
test('Metaclass1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['metaclass1.py']);
|
||||
TestUtils.validateResults(analysisResults, 0);
|
||||
TestUtils.validateResults(analysisResults, 1);
|
||||
});
|
||||
|
||||
test('Metaclass2', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user