RustPython/RustPython · error · TypeError

Initialization arguments are not supported

Error message

Initialization arguments are not supported

What it means

Raised by threading.local.__new__ when you instantiate threading.local (or a subclass) with positional or keyword arguments while the class still uses object.__init__. Thread-local setup happens entirely in __new__, so there is no __init__ to receive the arguments; CPython rejects them to match object's own behavior for argumentless constructors.

Source

Thrown at Lib/_threading_local.py:87

def _patch(self):
    impl = object.__getattribute__(self, '_local__impl')
    try:
        dct = impl.get_dict()
    except KeyError:
        dct = impl.create_dict()
        args, kw = impl.localargs
        self.__init__(*args, **kw)
    with impl.locallock:
        object.__setattr__(self, '__dict__', dct)
        yield


class local:
    __slots__ = '_local__impl', '__dict__'

    def __new__(cls, /, *args, **kw):
        if (args or kw) and (cls.__init__ is object.__init__):
            raise TypeError("Initialization arguments are not supported")
        self = object.__new__(cls)
        impl = _localimpl()
        impl.localargs = (args, kw)
        impl.locallock = RLock()
        object.__setattr__(self, '_local__impl', impl)
        # We need to create the thread dict in anticipation of
        # __init__ being called, to make sure we don't call it
        # again ourselves.
        impl.create_dict()
        return self

    def __getattribute__(self, name):
        with _patch(self):
            return object.__getattribute__(self, name)

    def __setattr__(self, name, value):
        if name == '__dict__':
            raise AttributeError(

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Define an __init__ on the local subclass that accepts the arguments (it runs per-thread on first attribute access)
  2. Instantiate with no arguments and set attributes afterwards: ctx = Ctx(); ctx.user = 'alice'
  3. If a base local class must stay argument-less, funnel construction through a factory function that sets defaults

Example fix

// before
class Ctx(threading.local):
    pass
ctx = Ctx(user='alice')  # TypeError

// after
class Ctx(threading.local):
    def __init__(self, user=None):
        self.user = user
ctx = Ctx(user='alice')
Defensive patterns

Strategy: validation

Validate before calling

import threading

def make_local(cls, /, *args, **kw):
    if (args or kw) and cls.__init__ is object.__init__:
        raise TypeError(f'{cls.__name__} takes no arguments; define __init__ to accept them')
    return cls(*args, **kw)

Type guard

def accepts_init_args(cls) -> bool:
    return cls.__init__ is not object.__init__

Try / catch

try:
    ctx = Ctx(user='alice')
except TypeError as e:
    if 'Initialization arguments' in str(e):
        ctx = Ctx(); ctx.user = 'alice'
    else:
        raise

Prevention

When it happens

Trigger: `class Ctx(threading.local): pass` followed by `Ctx('a')` or `Ctx(user='alice')`. Also a subclass that overrides __new__ but not __init__ and is then called with arguments.

Common situations: Developers porting a config/context class to threading.local and passing initial state in the constructor; metaclass or decorator code that forwards *args/**kw to every class it creates.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/d3ac7a9ba51ca689. Report an issue: GitHub.