
The Problem Link to heading
You are using NamedTuple to create your data classes and decide to add a field called count or index. Everything works perfectly at runtime, but when you run mypy or another type checker, you get strange errors. What is going on?
| |
Running mypy:
$ mypy example.py
example.py:7: error: Cannot assign to a method
example.py:9: error: "int" not callable
Why does this happen? Link to heading
NamedTuple inherits from tuple, and tuples have built-in methods called count() and index():
| |
When you create a field with those names in a NamedTuple, there is a name collision. At runtime, Python gives priority to the attributes created by the NamedTuple, but static type checkers get confused, because they see both the method and the attribute under the same name.
Demonstrating the Problem Link to heading
Here is a more complete example:
| |
mypy detects the conflict because:
tuple.countis a method that takes a value and returns an integer- You are trying to define
countas an integer attribute - The same goes for
index
The Solution Link to heading
There are a few ways to solve this problem:
1. Rename the fields (Recommended) Link to heading
The simplest and clearest solution is to use different names:
| |
2. Use a dataclass Link to heading
If you really need those specific names, consider using dataclass instead of NamedTuple:
| |
The downside is that dataclass does not inherit from tuple, so you lose some features such as index access and positional unpacking. On the other hand, you gain more flexibility and avoid name collisions.
3. Use type: ignore (Not recommended) Link to heading
As a last resort, you can suppress the mypy warnings:
| |
This approach is not recommended because you are hiding a real problem and may miss other important warnings.
Final Thoughts Link to heading
This is a classic example of how static type analysis can reveal subtle problems that work at runtime but can cause confusion and hard-to-spot bugs. Always run mypy or another type checker on your code to catch these problems early!
The rule of thumb is: if you are using NamedTuple, avoid names that are also tuple methods. When you need those specific names, dataclass is usually a better choice.
That’s it, folks!
See you next time!
{}’s