Skip to content

Commit

Permalink
Fixed bug that results in incorrect evaluation of a generic dataclass…
Browse files Browse the repository at this point in the history
… entry when the entry is defined by a generic subclass. This addresses #9545.
  • Loading branch information
erictraut committed Dec 10, 2024
1 parent e19106a commit f32c0b6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
7 changes: 6 additions & 1 deletion packages/pyright-internal/src/analyzer/dataClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,11 @@ export function synthesizeDataClassMethods(
});

defaultType = makeTypeVarsFree(defaultType, liveTypeVars);

if (entry.mroClass && requiresSpecialization(defaultType)) {
const solution = buildSolutionFromSpecializedClass(entry.mroClass);
defaultType = applySolvedTypeVars(defaultType, solution);
}
}
}
}
Expand Down Expand Up @@ -1135,7 +1140,7 @@ export function addInheritedDataClassEntries(classType: ClassType, entries: Data

// If the type from the parent class is generic, we need to convert
// to the type parameter namespace of child class.
const updatedEntry = { ...entry };
const updatedEntry = { ...entry, mroClass };
updatedEntry.type = applySolvedTypeVars(updatedEntry.type, solution);

if (entry.isClassVar) {
Expand Down
1 change: 1 addition & 0 deletions packages/pyright-internal/src/analyzer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ export namespace ModuleType {
export interface DataClassEntry {
name: string;
classType: ClassType;
mroClass?: ClassType;
isClassVar: boolean;
isKeywordOnly: boolean;
alias?: string | undefined;
Expand Down
31 changes: 27 additions & 4 deletions packages/pyright-internal/src/tests/samples/dataclass10.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,38 @@


@dataclass
class Foo(Generic[T]):
class ABase(Generic[T]):
value: Union[str, T]


reveal_type(Foo(""), expected_text="Foo[Unknown]")
reveal_type(ABase(""), expected_text="ABase[Unknown]")


class Bar(Foo[int]):
class AChild(ABase[int]):
pass


reveal_type(Bar(123), expected_text="Bar")
reveal_type(AChild(123), expected_text="AChild")


class B(Generic[T]):
pass


@dataclass
class CBase(Generic[T]):
x: B[T] = B[T]()


@dataclass
class CChild(CBase[T]):
pass


c1 = CBase[int]()
reveal_type(c1, expected_text="CBase[int]")
reveal_type(c1.x, expected_text="B[int]")

c2 = CChild[int]()
reveal_type(c2, expected_text="CChild[int]")
reveal_type(c2.x, expected_text="B[int]")

0 comments on commit f32c0b6

Please sign in to comment.