Describe the bug
When matching a Protocol with mutable special (class) attribute __name__, a NamedTuple/dataclass class is rejected as immutable even though the (class) attribute is actually writeable. This seems to only affect __name__; the __module__ and __qualname__ attributes are considered r/w.
This seems to only trigger when matching against a Protocol. When directly working with the class attribute (e.g. my_tup.__name__ = "something"), PyRight does not complain.
Code or Screenshots
Consider a decorator that patches the name of classes. With recent PyRight versions, this only works for regular classes, not NamedTuple/dataclass classes.
from typing import Protocol, NamedTuple
from dataclasses import dataclass
class Named(Protocol):
__name__: str
def transform[N: Named](n: N) -> N:
n.__name__ = f"transfomed_{n.__name__}"
return n
@transform
class Working: ...
@transform
class BrokenT(NamedTuple): ...
@transform
@dataclass(frozen=True)
class BrokenD: ...
/Users/maxfischer/vscode/snippets/playground.py:19:2 - error: Argument of type "type[BrokenT]" cannot be assigned to parameter "n" of type "N@transform" in function "transform"
Type "type[BrokenT]" is incompatible with type "Named"
"__name__" is not read-only in protocol (reportArgumentType)
/Users/maxfischer/vscode/snippets/playground.py:23:2 - error: Argument of type "type[BrokenD]" cannot be assigned to parameter "n" of type "N@transform" in function "transform"
Type "type[BrokenD]" is incompatible with type "Named"
"__name__" is not read-only in protocol (reportArgumentType)
Notably, there are no runtime errors. The __name__ attribute is writeable on both BrokenT and BrokenD at runtime.
VS Code extension or command-line
Tested with the python -m pyright CLI on version pyright 1.1.377. Testing this in the PyRight Playground, the code was accepted up to PyRight 1.1.375.
Describe the bug When matching a
Protocol
with mutable special (class) attribute__name__
, aNamedTuple
/dataclass
class is rejected as immutable even though the (class) attribute is actually writeable. This seems to only affect__name__
; the__module__
and__qualname__
attributes are considered r/w.This seems to only trigger when matching against a
Protocol
. When directly working with the class attribute (e.g.my_tup.__name__ = "something"
), PyRight does not complain.Code or Screenshots Consider a decorator that patches the name of classes. With recent PyRight versions, this only works for regular classes, not
NamedTuple
/dataclass
classes.Notably, there are no runtime errors. The
__name__
attribute is writeable on bothBrokenT
andBrokenD
at runtime.VS Code extension or command-line Tested with the
python -m pyright
CLI on versionpyright 1.1.377
. Testing this in the PyRight Playground, the code was accepted up to PyRight 1.1.375.