NoNamedTupleRule

Enforce the use of dataclasses.dataclass decorator instead of NamedTuple for cleaner customization and inheritance. It supports default value, combining fields for inheritance, and omitting optional fields at instantiation. See PEP 557. @dataclass is faster at reading an object’s nested properties and executing its methods. (benchmark)

Message

Instead of NamedTuple, consider using the @dataclass decorator from dataclasses instead for simplicity, efficiency and consistency.

Has Autofix: Yes

VALID Code Examples

# 1:

@dataclass(frozen=True)
class Foo:
    pass

# 2:

@dataclass(frozen=False)
class Foo:
    pass

# 3:

class Foo:
    pass

# 4:

class Foo(SomeOtherBase):
    pass

# 5:

@some_other_decorator
class Foo:
    pass

# 6:

@some_other_decorator
class Foo(SomeOtherBase):
    pass

INVALID Code Examples

# 1:

from typing import NamedTuple

class Foo(NamedTuple):
    pass

Autofix:

---
+++
@@ -1,5 +1,6 @@

 from typing import NamedTuple

-class Foo(NamedTuple):
+@dataclass(frozen=True)
+class Foo:
     pass

# 2:

from typing import NamedTuple as NT

class Foo(NT):
    pass

Autofix:

---
+++
@@ -1,5 +1,6 @@

 from typing import NamedTuple as NT

-class Foo(NT):
+@dataclass(frozen=True)
+class Foo:
     pass

# 3:

import typing as typ

class Foo(typ.NamedTuple):
    pass

Autofix:

---
+++
@@ -1,5 +1,6 @@

 import typing as typ

-class Foo(typ.NamedTuple):
+@dataclass(frozen=True)
+class Foo:
     pass

# 4:

from typing import NamedTuple

class Foo(NamedTuple, AnotherBase, YetAnotherBase):
    pass

Autofix:

---
+++
@@ -1,5 +1,6 @@

 from typing import NamedTuple

-class Foo(NamedTuple, AnotherBase, YetAnotherBase):
+@dataclass(frozen=True)
+class Foo(AnotherBase, YetAnotherBase):
     pass

# 5:

from typing import NamedTuple

class OuterClass(SomeBase):
    class InnerClass(NamedTuple):
        pass

Autofix:

---
+++
@@ -2,5 +2,6 @@
 from typing import NamedTuple

 class OuterClass(SomeBase):
-    class InnerClass(NamedTuple):
+    @dataclass(frozen=True)
+    class InnerClass:
         pass

# 6:

from typing import NamedTuple

@some_other_decorator
class Foo(NamedTuple):
    pass

Autofix:

---
+++
@@ -2,5 +2,6 @@
 from typing import NamedTuple

 @some_other_decorator
-class Foo(NamedTuple):
+@dataclass(frozen=True)
+class Foo:
     pass