agronholm / typeguard

Run-time type checker for Python
Other
1.52k stars 114 forks source link

Checking `typing.NamedTuple` against a `Protocol` fails with missing `__weakref__` #469

Closed sth closed 3 months ago

sth commented 3 months ago

Things to check first

Typeguard version

4.3.0

Python version

3.11

What happened?

Checking an instance of typing.NamedTuple against a typing.Protocol fails, complaining about a missing __weakref__ attribute. This seems to happen irrespective of the protocol's contents.

How can we reproduce the bug?

This code demonstrates the problem:

from typing import Protocol, NamedTuple
from typeguard import typechecked

class Prot(Protocol):
    pass

class Tup(NamedTuple):
    x: int

@typechecked
def f() -> None:
    value: Prot = Tup(x=1)

f()

This results in this error:

Traceback (most recent call last):
  File "/tmp/tst.py", line 14, in <module>
    f()
  File "/tmp/tst.py", line 12, in f
    value: Prot = Tup(x=1)
  File "/usr/local/lib/python3.11/site-packages/typeguard/_functions.py", line 251, in check_variable_assignment
    check_type_internal(value, annotation, memo)
  File "/usr/local/lib/python3.11/site-packages/typeguard/_checkers.py", line 861, in check_type_internal
    checker(value, origin_type, args, memo)
  File "/usr/local/lib/python3.11/site-packages/typeguard/_checkers.py", line 738, in check_protocol
    raise TypeCheckError(
typeguard.TypeCheckError: value assigned to value (__main__.Tup) is not compatible with the Prot protocol because it has no attribute named '__weakref__'
agronholm commented 3 months ago

This is basically a duplicate of #465.