Description
When a class declares an instance attribute with an explicit type annotation, and that type is a class with __getattr__, basedpyright incorrectly reports the attribute as Unknown when accessed. Standard pyright does not have this issue.
The type is explicitly declared, and the assignment is type-checked. There's no code path where the attribute could be anything other than the declared type.
Reproduction
from __future__ import annotations
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from gitlab.v4.objects import Project # Has __getattr__ via RESTObject base class
class Handler:
_project: Project # Explicitly declared type
def __init__(self, project: Project) -> None:
self._project = project # Assignment is type-checked
def get_project(self) -> Project:
return self._project # Warning: Return type is unknown
Playground link - uses a simplified example since gitlab isn't available in playground.
Expected Behavior
self._project should have type Project because:
- The attribute is explicitly declared as
_project: Project
- The assignment
self._project = project is type-checked to ensure type safety
- There's no code path where
_project could be anything other than Project
The __getattr__ on Project is irrelevant - it affects attribute access on Project instances, not how other classes store Project as their own attribute.
Actual Behavior
basedpyright reports:
warning: Return type is unknown (reportUnknownVariableType)
Comparison with pyright
Standard pyright (tested with pyright 1.1.x via uv run --with pyright pyright) reports no warnings for the same code.
Environment
- basedpyright 1.37.2
- Python 3.14
- The issue occurs with python-gitlab's
Project class, which inherits from RESTObject that has __getattr__(self, name: str) -> Any
Workaround
Using __slots__ on the holder class makes basedpyright correctly recognize the type:
class Handler:
__slots__ = ("_project",)
_project: Project
# ... now _project is correctly typed as Project
But this shouldn't be necessary - the explicit type declaration should be sufficient.
Description
When a class declares an instance attribute with an explicit type annotation, and that type is a class with
__getattr__, basedpyright incorrectly reports the attribute asUnknownwhen accessed. Standard pyright does not have this issue.The type is explicitly declared, and the assignment is type-checked. There's no code path where the attribute could be anything other than the declared type.
Reproduction
Playground link - uses a simplified example since gitlab isn't available in playground.
Expected Behavior
self._projectshould have typeProjectbecause:_project: Projectself._project = projectis type-checked to ensure type safety_projectcould be anything other thanProjectThe
__getattr__onProjectis irrelevant - it affects attribute access onProjectinstances, not how other classes storeProjectas their own attribute.Actual Behavior
basedpyright reports:
Comparison with pyright
Standard pyright (tested with
pyright 1.1.xviauv run --with pyright pyright) reports no warnings for the same code.Environment
Projectclass, which inherits fromRESTObjectthat has__getattr__(self, name: str) -> AnyWorkaround
Using
__slots__on the holder class makes basedpyright correctly recognize the type:But this shouldn't be necessary - the explicit type declaration should be sufficient.