Skip to content

Dataclass field that contains a descriptor object isn't handled correctly #3245

Closed
@erictraut

Description

@erictraut

If a @dataclass field is initialized with a descriptor as a default value, pyright should use the value type of the __set__ method for the descriptor when determining the type of the corresponding parameter within the synthesized __init__ method.

Types are also evaluated incorrectly in this case.

Note that mypy also exhibits these same bugs.

from dataclasses import dataclass
from typing import Any, cast


class MyDescriptor:
    def __get__(self, __obj: object | None, __owner: Any) -> "int | MyDescriptor":
        if __obj is None:
            return self
        return cast(Any, __obj)._x

    def __set__(self, __obj: object | None, __value: int) -> None:
        if __obj is not None:
            cast(Any, __obj)._x = __value


@dataclass
class Foo:
    y: MyDescriptor = MyDescriptor()


f = Foo(3)  # Currently a false positive error in pyright (and mypy)

print(f.y)  # 3
f.y = 4
print(f.y)  # 4
print(Foo.y)  # MyDescriptor object

reveal_type(f.y) # int | MyDescriptor, which is wrong
reveal_type(Foo.y) # int | MyDescriptor, which is wrong

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions