Why does Python log a SyntaxWarning saying "object is not callable"?2020-06-16
Take this code, which we want to return a list of shopping items with desired quantities:
If we import it in Python 3.8+, we’ll see a warning message on line 3:
This is a new warning added in Python 3.8. From the release notes:
When a comma is missed in code such as
[(10, 20) (30, 40)], the compiler displays a
SyntaxWarningwith a helpful suggestion. This improves on just having a
TypeErrorindicating that the first tuple was not callable. (Contributed by Serhiy Storchaka in bpo-15248.)
Indeed, if we run the function, it raises a
Python emits the
SyntaxWarning at import time because it can predict that the code will raise this
So why does the error occur?
Some objects in Python are callable, such as functions or classes.
You normally call them with the syntax:
some_object(an_argument, another_argument), but you can also spread a function call over multiple lines, for example:
If this happens within parentheses or square brackets, you can also put the call parentheses on a new line:
This looks odd, and is very rare in Python code, but it’s valid.
get_shopping_list() function follows this pattern, unintentionally.
We could replace
("bananas", 5), and
(an_argument, another_argument) with
So the second line,
("pears", 3), is not interpreted as another tuple, but as arguments to a call to the first line.
The first line is the tuple
("bananas", 5), and tuple objects aren’t callable, so it raises a
The fix is to add a comma after the
("bananas", 5) tuple:
This comma separated the two tuples, so our function can return them in a list, as intended.
Note there’s now also a comma after
("pears", 3) tuple.
You should form a habit to always end each item in a multi-line list with a comma, even when it’s the last one.
Then you can never encounter the error.
Python raises this
SyntaxWarning for more types than just tuples.
It also raises them for most of the built-in literal types:
- Numbers -
- Container types -
dict, plus their comprehension versions
- Generator expressions
- Strings, including f-strings
You can see this on the console, for example with an f-string:
I hope this helps you understand and fix this error,
Are your Django project's tests slow? Read Speed Up Your Django Tests now!
One summary email a week, no spam, I pinky promise.
- Why does Python log a SyntaxWarning for 'is' with literals?
- Why does Python log a SyntaxWarning saying "object is not subscriptable"?
- Why does Python log a SyntaxWarning saying "assertion is always true"?
- Why does Python log a SyntaxWarning saying "list indices must be integers or slices"?
© 2020 All rights reserved.