python/cpython · error · TypeError

{cls.__name__}() 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.

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)

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.