no-named-tuple

Prefer dataclasses.dataclass over NamedTuple when tuple compatibility is not required. Dataclasses are not tuple-compatible, so converting public NamedTuple APIs can break unpacking, indexing, equality, and callers that expect tuple instances.

Message

NamedTuple can often be replaced with @dataclass, but dataclasses are not tuple-compatible; check callers before converting.

References

Valid examples

@dataclass(frozen=True)
class Foo:
    pass
@dataclass(frozen=False)
class Foo:
    pass
Show more
class Foo:
    pass
class Foo(SomeOtherBase):
    pass
@some_other_decorator
class Foo:
    pass
@some_other_decorator
class Foo(SomeOtherBase):
    pass
from typing import NamedTuple as NT

Other = NT

Invalid examples

from typing import NamedTuple

class Foo(NamedTuple):
    pass
Show more
from typing_extensions import NamedTuple

class Foo(NamedTuple):
    pass
from typing import NamedTuple as NT

class Foo(NT):
    pass
import typing as typ

class Foo(typ.NamedTuple):
    pass
from typing import NamedTuple

class Foo(NamedTuple, AnotherBase, YetAnotherBase):
    pass
from typing import NamedTuple

class OuterClass(SomeBase):
    class InnerClass(NamedTuple):
        pass
from typing import NamedTuple

@some_other_decorator
class Foo(NamedTuple):
    pass
from dataclasses import dataclass
from typing import NamedTuple

class Foo(NamedTuple):
    pass
import dataclasses as dc
from typing import NamedTuple

class Foo(NamedTuple):
    pass
from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
from typing import NamedTuple

Point = NamedTuple("Point", [("x", int), ("y", int)])
from typing_extensions import NamedTuple

Point = NamedTuple("Point", [("x", int), ("y", int)])
from typing import NamedTuple as NT

Point = NT("Point", [("x", int), ("y", int)])
import typing

Point = typing.NamedTuple("Point", [("x", int), ("y", int)])
import typing as typ

Point = typ.NamedTuple("Point", [("x", int), ("y", int)])
from typing import *

Point = NamedTuple("Point", [("x", int), ("y", int)])
from typing import *

class Foo(NamedTuple):
    pass
from typing_extensions import *

class Foo(NamedTuple):
    pass
from typing import NamedTuple

NT = NamedTuple

class Foo(NT):
    pass
from typing import NamedTuple as NT

class Foo(NT):
    pass

Other = NT
from typing import NamedTuple

A = B = NamedTuple

class Foo(A):
    pass