зеркало из https://github.com/microsoft/pyright.git
Allow `Final` and `ClassVar` to be combined in both directions within a dataclass. Previously, the `Final` qualifier needed to be the outermost. This addresses #8676. (#8678)
This commit is contained in:
Родитель
08e02e450b
Коммит
c285825dea
|
@ -7607,24 +7607,30 @@ export function createTypeEvaluator(
|
|||
const typeArgs: TypeResultWithNode[] = [];
|
||||
let adjFlags = flags | EvalFlags.NoConvertSpecialForm;
|
||||
|
||||
if (options?.isFinalAnnotation) {
|
||||
adjFlags |= EvalFlags.NoClassVar | EvalFlags.NoFinal;
|
||||
} else if (options?.isClassVarAnnotation) {
|
||||
adjFlags |= EvalFlags.NoClassVar;
|
||||
|
||||
const allowFinalClassVar = () => {
|
||||
// If the annotation is a variable within the body of a dataclass, a
|
||||
// Final is allowed within the ClassVar annotation. In all other cases,
|
||||
// Final is allowed with a ClassVar annotation. In all other cases,
|
||||
// it's disallowed.
|
||||
let disallowFinal = true;
|
||||
const enclosingClassNode = ParseTreeUtils.getEnclosingClass(node, /* stopeAtFunction */ true);
|
||||
if (enclosingClassNode) {
|
||||
const classTypeInfo = getTypeOfClass(enclosingClassNode);
|
||||
if (classTypeInfo && ClassType.isDataClass(classTypeInfo.classType)) {
|
||||
disallowFinal = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (disallowFinal) {
|
||||
if (options?.isFinalAnnotation) {
|
||||
adjFlags |= EvalFlags.NoFinal;
|
||||
|
||||
if (!allowFinalClassVar()) {
|
||||
adjFlags |= EvalFlags.NoClassVar;
|
||||
}
|
||||
} else if (options?.isClassVarAnnotation) {
|
||||
adjFlags |= EvalFlags.NoClassVar;
|
||||
|
||||
if (!allowFinalClassVar()) {
|
||||
adjFlags |= EvalFlags.NoFinal;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -11,6 +11,7 @@ class A:
|
|||
b: Final[str] = ""
|
||||
c: ClassVar[Final[int]] = 0
|
||||
d: ClassVar[Final] = 0
|
||||
e: Final[ClassVar[int]] = 0
|
||||
|
||||
|
||||
a = A(1)
|
||||
|
@ -29,3 +30,6 @@ A.c = 0
|
|||
|
||||
# This should generate an error.
|
||||
A.d = 0
|
||||
|
||||
# This should generate an error.
|
||||
A.e = 0
|
||||
|
|
|
@ -363,7 +363,7 @@ test('DataClass16', () => {
|
|||
test('DataClass17', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dataclass17.py']);
|
||||
|
||||
TestUtils.validateResults(analysisResults, 5);
|
||||
TestUtils.validateResults(analysisResults, 6);
|
||||
});
|
||||
|
||||
test('DataClassReplace1', () => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче