Python: fix TypeError: NamedTuple() got an unexpected keyword argument

Take this code, defining a small NamedTuple with a keyword argument per field:
from typing import NamedTuple
Point = NamedTuple("Point", x=int, y=int)
Run it on Python 3.13 or 3.14, and you’ll see:
$ python3.14 example.py
/.../example.py:3: DeprecationWarning: Creating NamedTuple classes using keyword arguments is deprecated and will be disallowed in Python 3.15. Use the class-based or functional syntax instead.
Point = NamedTuple("Point", x=int, y=int)
And on Python 3.15+, it’s broken:
$ python3.15 example.py
Traceback (most recent call last):
...
TypeError: NamedTuple() got an unexpected keyword argument 'x'
What’s up with that?
NamedTuple has always had two documented ways to define fields: the class-based syntax, and a functional syntax taking a list of (name, type) pairs. The keyword-argument style above was never one of them, it worked only as a side effect of the old implementation happening to accept **kwargs. This form was therefore deprecated and removed in Python 3.15, with NamedTuple’s signature now locked to positional-only.
From the release notes:
The undocumented keyword argument syntax for creatingNamedTupleclasses (for example,Point = NamedTuple("Point", x=int, y=int)) is no longer supported. Use the class-based syntax or the functional syntax instead. (Contributed by Bénédikt Tran in gh-133817.)
The fix
Switch to the class-based syntax, which is the more readable option, and gives you a normal class body to add methods or docstrings to later:
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
Or, if you’d rather keep a one-liner, use the documented functional syntax, a list of (name, type) pairs, instead of keyword arguments:
from typing import NamedTuple
Point = NamedTuple("Point", [("x", int), ("y", int)])
Auto-fix this problem with Ruff
Ruff’s pyupgrade-derived rule convert-named-tuple-functional-to-class (UP014) rewrites both functional forms, the list-of-tuples version and this keyword-argument version, to class syntax automatically. As of Ruff 0.16, released July 2026, UP014 is one of the hundreds of rules Ruff now enables by default, so there’s nothing to switch on, just run:
$ ruff check --fix example.py
Found 2 errors (2 fixed, 0 remaining).
(If you’re on an older Ruff, add --select UP014, or the broader --select UP, to opt in explicitly.)
…turning our original example straight into:
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
Read my book Boost Your Git DX to Git better.
One summary email a week, no spam, I pinky promise.
Related posts:
- Python: fix
SyntaxWarning: 'return' in a 'finally' block - Python type hints: How to Use TypedDict
- Python type hints: upgrade syntax with pyupgrade
Tags: python