microsoft / pyright

Static Type Checker for Python
Other
13.12k stars 1.4k forks source link

Accessing attribute of a Generic class defined by type parameters #8832

Closed Lotram closed 2 weeks ago

Lotram commented 2 weeks ago

Hi,

If I'm not mistaken, the new syntax to declare a generic class, is to do MyClass[T]: instead of MyClass(Generic[T]). However the following code does not give the same pyright output:

from typing import Generic, TypeVar

class TaskParameters:
    field: str

Params = TypeVar("Params", bound="TaskParameters")

class NewStyleTask[Params]:
    parameters: Params

    @property
    def field(self) -> str:
        return self.parameters.field

class OldStyleTask(Generic[Params]):
    parameters: Params

    @property
    def field(self) -> str:
        return self.parameters.field

Using pyright 1.1.377, I get:

  generics.py:16:32 - error: Cannot access attribute "field" for class "object*"
    Attribute "field" is unknown (reportAttributeAccessIssue)
1 error, 0 warnings, 0 informations 

The first class raises an error while the second does not.

erictraut commented 2 weeks ago

In your code sample, you've defined the old-style TypeVar with an upper bound, but you've omitted the upper bound for the new-style type parameter. If no upper bound is provided, the default upper bound is object.

If you want to make the new-style type parameter equivalent, you'd need to do this:

class NewStyleTask[Params: TaskParameters]: ...
Lotram commented 2 weeks ago

Ok so I did miss something in the doc, thanks.