python/cpython · error · TypeError

() takes no arguments

Error message

{cls.__name__}() takes no arguments

What it means

Raised by the __new__ wrapper that warnings.deprecated installs when it decorates a class. When the class inherits object.__new__ and object.__init__ (i.e. the decorator must synthesize instantiation), passing any arguments to the constructor hits this TypeError, mirroring object.__new__'s own check. The deprecation wrapper cannot know which __init__ signature is legal, so it applies the same rule as the interpreter for argless classes.

Solutions

  1. Remove the arguments at call sites of the deprecated class (the class defines no __init__, so args were always invalid)
  2. Define an explicit __init__ on the class (or its undecorated base) accepting the arguments before applying @deprecated
  3. Apply @deprecated to a factory function instead of the argless class, so instantiation signature stays controlled

Example fix

// before
@warnings.deprecated('use New')
class Old: pass
Old(42)  # TypeError

# after
@warnings.deprecated('use New')
class Old:
    def __init__(self, value=None): self.value = value
Old(42)
Defensive patterns

Strategy: validation

Validate before calling

@warnings.deprecated('use New')
class Old:
    def __init__(self, value=None):
        self.value = value
Old(42)  # now legal

Prevention

When it happens

Trigger: @warnings.deprecated('...') class Legacy: pass followed by Legacy(1) or Legacy(x=2); decorating a dataclass-like class that defines only class attributes and instantiating with args; subclasses that call super().__new__(cls, *args) with args while inheriting the wrapper.

Common situations: Deprecating a marker/empty class and forgetting call sites still pass arguments; deprecating a class whose real __init__ lives on a base that itself is decorated; copy/paste of instantiation call sites during migration off the deprecated class.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/98362515cdc860bc. Report an issue: GitHub.

Appendix: source

Thrown at Lib/_py_warnings.py:821

        stacklevel = self.stacklevel
        if category is None:
            arg.__deprecated__ = msg
            return arg
        elif isinstance(arg, type):
            import functools
            from types import MethodType

            original_new = arg.__new__

            @functools.wraps(original_new)
            def __new__(cls, /, *args, **kwargs):
                if cls is arg:
                    _wm.warn(msg, category=category, stacklevel=stacklevel + 1)
                if original_new is not object.__new__:
                    return original_new(cls, *args, **kwargs)
                # Mirrors a similar check in object.__new__.
                elif cls.__init__ is object.__init__ and (args or kwargs):
                    raise TypeError(f"{cls.__name__}() takes no arguments")
                else:
                    return original_new(cls)

            arg.__new__ = staticmethod(__new__)

            if "__init_subclass__" in arg.__dict__:
                # __init_subclass__ is directly present on the decorated class.
                # Synthesize a wrapper that calls this method directly.
                original_init_subclass = arg.__init_subclass__
                # We need slightly different behavior if __init_subclass__
                # is a bound method (likely if it was implemented in Python).
                # Otherwise, it likely means it's a builtin such as
                # object's implementation of __init_subclass__.
                if isinstance(original_init_subclass, MethodType):
                    original_init_subclass = original_init_subclass.__func__

                @functools.wraps(original_init_subclass)
                def __init_subclass__(*args, **kwargs):

View on GitHub (pinned to bc6749cc3b)