Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NamedTuple/dataclass special attribute __name__ incorrectly treated as immutable for matching protocols #8829

Closed
maxfischer2781 opened this issue Aug 25, 2024 · 1 comment
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working

Comments

@maxfischer2781
Copy link

maxfischer2781 commented Aug 25, 2024

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.

@maxfischer2781 maxfischer2781 added the bug Something isn't working label Aug 25, 2024
erictraut added a commit that referenced this issue Sep 4, 2024
…tching because writable class variables defined in a named tuple or a frozen dataclass were considered read-only. This addresses #8829.
erictraut added a commit that referenced this issue Sep 4, 2024
…tching because writable class variables defined in a named tuple or a frozen dataclass were considered read-only. This addresses #8829. (#8896)
@erictraut erictraut added the addressed in next version Issue is fixed and will appear in next published version label Sep 4, 2024
@erictraut
Copy link
Collaborator

This is addressed in pyright 1.1.380.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addressed in next version Issue is fixed and will appear in next published version bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants