Frankenstein's `__init__`

https://news.ycombinator.com/rss Hits: 6
Summary

Inspired by a recent post about the woes of __init__ methods in Python, I thought I’d share the untold story of the absolute craziest __init__ I’ve come across in a production codebase.It all started when I tried to add a failing test to a Python service.The test was indeed failing, but every now and then it would fail on something unexpected.The Evidence of the TestAfter some minimization, this was the test I had:def test_foobar(): f = FooBarWidget() with contextlib.closing(f): assert False which sometimes failed with this error:self = <foobar.FooBarWidget object at 0x10512ed80> def close(self): > if self.should_exit is False: E AttributeError: 'FooBarWidget' object has no attribute 'should_exit' foo.py:28: AttributeError And not (only) the expected AssertionError.Searching for self.should_exit = yielded FooWidget.__init__ in foo.py:class AbstractWidget: def __init__(self): self.config = Path("config.json").read_text() class FooWidget(AbstractWidget): def __init__(self): super().__init__() self.ctx = zmq.Context.instance() self.consumer: zmq.Socket = self.ctx.socket(zmq.PULL) self.should_exit = False def run(self): while self.should_exit is False: ... self.consumer.close() def close(self): if self.should_exit is False: self.should_exit = True Which didn’t make sense at all: assuming none of these lines fail, how can the should_exit attribute sometimes not be to set?The __init__The impossible could not have happened,therefore the impossible must be possible in spite of appearances.~ Hercule Poirot, Murder on the Orient ExpressThe only other clue we have is that self is a FooBarWidget, not a FooWidget. So, to the class FooBarWidget(FooWidget) definition I went, which is where I found it.The craziest __init__ I’ve ever seen:class FooBarWidget(FooWidget): def __init__(self): self.publisher: zmq.Socket = zmq.Context.instance().socket(zmq.PUSH) self._init() def _init(self): def worker_thread_start(): FooWidget.__init__(self) self.run() worker_thread = Thread(target=worke...

First seen: 2025-04-19 13:20

Last seen: 2025-04-19 18:21