RussBaz / enforce

Python 3.5+ runtime type checking for integration testing and data validation
543 stars 21 forks source link

`AttributeError: can't set attribute` with namedtuple #77

Closed SamuelMarks closed 4 years ago

SamuelMarks commented 4 years ago

Been debugging this issue for a while, can't seem to resolve it, this line:

enforce/enforce/decorators.py", line 145, in universal
    result = wrapped(*_args, **_kwargs)
  File "<string>", line 6, in __init__
AttributeError: can't set attribute
from typing import NamedTuple, Any
from dataclass.dataclasses import dataclass

from enforce import runtime_validation

class C(NamedTuple):
    c: Any = None
# Also tried `C = namedtuple('C', ('c',))(None)`

@runtime_validation
@dataclass(init=True, repr=False, eq=False, order=False, unsafe_hash=True)
class A(object):
    b: Any = C.c

if __name__ == "__main__":
    A()

I even tried copying over the stdlib dataclass and modifying it to output what it's getting, and it's getting, for the value of b, this:

<_collections._tuplegetter object at 0x103778ca0>

It looks like it's caused by C.c; as C works.

Any ideas how to fix?

habnabit commented 4 years ago

Yes: don't assign a _collections._tuplegetter instance as a class attribute.