Home › Python

TypeError: takes 0 positional arguments but 1 was given — how to fix

Traceback (most recent call last):
  File "app.py", line 9, in <module>
    c.greet()
TypeError: Greeter.greet() takes 0 positional arguments but 1 was given

Quick fix: Add self as the first parameter of the method: def greet(self):. If the method really doesn't need the instance, decorate it with @staticmethod. For callbacks (Tkinter, signal handlers, map), accept the argument the caller passes, e.g. def on_click(event):.

What it means

The function signature accepts fewer positional arguments than the call supplies. The numbers tell you how many: "takes 0 ... but 1 was given" means the function has no parameters but received one. "takes 1 positional argument but 2 were given" is the same bug with one parameter.

If the extra argument isn't visible in your call, something is passing it implicitly. Usually that's Python passing self.

Cause 1: a method without self

class Greeter:
    def greet():            # no self
        print("hi")

Greeter().greet()           # TypeError: takes 0 positional arguments but 1 was given

obj.greet() is really Greeter.greet(obj), so the instance is passed as the first argument.

Fix:

class Greeter:
    def greet(self):
        print("hi")

The same applies to methods with other parameters: def add(x, y) called as obj.add(1, 2) gives "takes 2 positional arguments but 3 were given". Write def add(self, x, y).

Cause 2: the method doesn't need the instance

Use @staticmethod (no implicit argument) or @classmethod (receives the class as cls):

class MathUtil:
    @staticmethod
    def square(x):
        return x * x

    @classmethod
    def create(cls):
        return cls()

MathUtil.square(3)
MathUtil().square(3)    # also fine

Cause 3: a callback receives an argument you didn't expect

Many frameworks call your function with an argument:

# Tkinter bind() passes an event object
button.bind("<Button-1>", on_click)
def on_click():         # TypeError: on_click() takes 0 positional arguments but 1 was given
    ...

Fix: accept it (and ignore it if unused), or give it a default so the function works both ways:

def on_click(event=None):
    ...

Other common cases:

Cause 4: you passed arguments positionally that should be keywords

Functions with keyword-only parameters (after *) reject positional arguments:

def connect(*, host, port):
    ...

connect("localhost", 5432)            # TypeError: takes 0 positional arguments but 2 were given
connect(host="localhost", port=5432)  # OK

Check the library's signature with help(func) or inspect.signature(func), especially after an upgrade that made parameters keyword-only.

Cause 5: name shadowing

You defined a function with the same name as one you meant to call (or imported), so the call hits your zero-argument version. Rename your function, or check print(func, func.__module__) to see which object you're really calling.

For the opposite error, where an argument is missing instead of extra, see missing 1 required positional argument: 'self'.

Last updated 2026-11-08.