Glyph Lefkowitz email@example.com writes:
Yes. Unfortunately, lots of places do import the reactor directly today, but we have long since decided that this is a bad way to do things. This is why e.g. react https://twistedmatrix.com/documents/16.2.0/api/twisted.internet.task.h tml#react passes the reactor to your function as a parameter, so you can pass it on down to any other code that needs it.
As a "casual" user of Twisted, I was somewhat skeptical of this "pass the reactor everywhere" approach -- but I did try to follow this advice in txtorcon, and was rewarded with easy-to-write tests regarding timing, which are (usually) a horror-show *and* I was rewarded with having to think about "do I *really* need the reactor here?".
Now, sometimes you can compromise. For example, see my AddrMap class which assigns a "self.scheduler" which is usually just gotten by importing from twisted.internet.reactor -- *but* critically, the tests can re-assign this:
Ideally, this would have been passed-in via the __init__ but, *shruggy-face*. The point being, you can incrementally upgrade to "the better way".
Overall, I'm very sold on accessing "the reactor" via "self dot something" rather than via imports *even if* the only reason ends up being "because testing". It's pretty likely that some random user you've never heard of has a similar use-case to that thing you needed to do in that one test... (I've read this elsewhere, not my idea)
If nothing else, it will cause you to pause and consider "how will this thing access the reactor", which will cause you to think about concurrency issues... (Or, contrary-wise, classes which *don't* have a self._reactor definitely do *not* need any thinking about concurrency -- which is also a big win).
In any case, my concurrency-hackles raise when I see ".. import reactor". Best to localize these fears to "self._reactor".