TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
1 · The lesson
readWhat this error means
You tried to add a number to None. Python has no rule for None + 5, so it stops. The message tells you which side was None: 'NoneType' and 'int' means the left side, 'int' and 'NoneType' means the right.
The + is rarely where the bug lives. Somewhere earlier, a value you expected to be a number turned out to be None, and the + is just the first line that cared.
When you see it
Traceback (most recent call last): File "main.py", line 7, in <module> grand_total = subtotal(basket) + 5 ~~~~~~~~~~~~~~~~~^~~ TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
Traceback (most recent call last): File "main.py", line 4, in <module> total += stock.get(item) TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
Same bug, different operator. You'll also see -, * and / versions.
Why it happens
None is what you get when nothing was returned. The usual sources:
1. The function forgot to return. A function that falls off the end returns None, even if it computed the right answer along the way.
2. It prints instead of returning. The number appears on screen, which looks like success, but the caller gets None.
3. A method that changes things in place. list.sort(), list.append(), random.shuffle() and dict.update() all return None. Assigning their result throws the list away.
4. dict.get() with no default. A missing key gives None, not 0.
def subtotal(basket): total = sum(item["price"] for item in basket) print(f"Subtotal: {total}") # shows the right number... basket = [{"price": 12.5}, {"price": 7.5}] grand_total = subtotal(basket) + 5 # ...but returns None
How to fix it
Return the value. Keep the print if you like, but the function has to hand the number back:
def subtotal(basket): total = sum(item["price"] for item in basket) return total basket = [{"price": 12.5}, {"price": 7.5}] grand_total = subtotal(basket) + 5 # delivery print(grand_total) # 25.0
If a function has several branches, check that every one of them returns. A single if with no else is enough to leak a None out of the other path.
Don't assign the result of an in-place method. Call it, then use the original — or use the version that returns a new object:
scores = [72, 91, 64] scores.sort() # sorts scores; returns None print(scores + [100]) # [64, 72, 91, 100] ranked = sorted(scores, reverse=True) # sorted() returns a new list print(ranked) # [91, 72, 64]
Give dict.get() a default that makes sense for the arithmetic:
stock = {"earl grey": 14, "oat milk": 6}
order = ["earl grey", "oat milk", "matcha"]
total = 0
for item in order:
total += stock.get(item, 0) # matcha isn't stocked: counts as 0
print(total) # 20Only use 0 when zero is genuinely the right answer. If a missing price means the data is broken, let it fail — but fail with a message that names the item, not a NoneType error three lines later.
Skip missing values deliberately when they come from data, such as blank cells in a CSV:
amounts = [19.99, None, 45.00, None, 8.50] print(sum(a for a in amounts if a is not None)) # 73.49
When you'd actually see this in real code
- A helper that started life as a debugging script, full of
print()calls, and later got called from other code. sum(row["amount"] for row in rows)where one row parsed from JSON had"amount": null. That one surfaces as'int' and 'NoneType', becausesumstarts from0.- A recursive function where the base case returns a number but the recursive branch forgets
returnin front of the call. config.get("retries") + 1when the setting was never written to the file.
Related errors
- AttributeError: 'NoneType' object has no attribute 'X' — the same stray
None, used with a dot instead of a+. - TypeError: 'NoneType' object is not subscriptable — the same
None, used with[ ]. - TypeError: 'NoneType' object is not iterable
- TypeError: can only concatenate str (not "int") to str —
+with two types that don't mix.
See Also
- All Python errors — the full index, by type and by when it happens.
- Functions (tutorial) —
returnvsprint. - Lists (tutorial) — which methods change the list in place.
- Dictionary cheat sheet
Found this useful? Share it with a friend who’s learning Python.