Hi all
<div><br></div><div>I have recently started switching to trial.unittest from python&#39;s own. The trouble I&#39;m experiencing is when a timeout occurs in my test, it errbacks(). Then the @inlineCallbacks decorator sees the error and errbacks(). But then a second @inlineCallback in the chain subsequently sees <i>that</i> errback and tries to errback itself. This results in AlreadyCalledError.</div>
<div><br></div><div>In the test setup, various services are started. These are tracked and then shutdown again in the teardown. Also, there is some polling that happens as part of the tests (waiting on db activities, for example). These use deferLater calls, which are also tracked and torn down in the teardown. </div>
<div><br></div><div>I&#39;ve tried _suppressAlreadyCalled in various places to no avail.</div><div><br></div><div>Below is a simple example that shows the problem.</div><div><br></div><div>Many thanks</div><div>Brad</div>
<div><br></div><div><br></div><div>&lt;code&gt;</div><div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #4700ff">from</span> twisted.trial.unittest <span style="color: #4700ff">import</span> TestCase</p>

<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #4700ff">from</span> twisted.internet <span style="color: #4700ff">import</span> task, reactor</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #4700ff">from</span> twisted.internet.defer <span style="color: #4700ff">import</span> inlineCallbacks</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #cc38c4">#import twisted</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #cc38c4">#twisted.internet.base.DelayedCall.debug = True</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #cc38c4">#twisted.internet.defer.setDebugging(True)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #4700ff">class</span> Test1(TestCase):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px">    </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">def</span> setUp(self):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #cc38c4"><span style="color: #000000">        </span># timeout test in 1 second</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        self.timeout = <span style="color: #9b0000">1</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <a href="http://self.jobs">self.jobs</a> = []</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        self.addCleanup(self._tearDown)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px">        </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">def</span> _tearDown(self):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span style="color: #4700ff">for</span> d <span style="color: #4700ff">in</span> <a href="http://self.jobs">self.jobs</a>:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">            <span style="color: #4700ff">if</span> d <span style="color: #4700ff">and</span> <span style="color: #4700ff">not</span> d.called:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">                d.cancel()</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px">                </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #909090"><span style="color: #000000">    </span>@inlineCallbacks</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">def</span> _waitForChange(self):</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span class="Apple-style-span" style="color: rgb(204, 56, 196); "># do stuff</span></p>

<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        d = task.deferLater(reactor, <span style="color: #9b0000">0.5</span>, <span style="color: #4700ff">lambda</span> : <span style="color: #4700ff">None</span>)</p>

<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        self.jobs.append(d)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span style="color: #4700ff">yield</span> d</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        self.jobs.remove(d)</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span class="Apple-style-span" style="color: rgb(204, 56, 196); "># do more stuff</span></p>

<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px">    </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #909090"><span style="color: #000000">    </span>@inlineCallbacks</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">def</span> testHere(self):</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span class="Apple-style-span" style="color: rgb(204, 56, 196); "># do stuff</span></p>

<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span style="color: #4700ff">yield</span> self._waitForChange()</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">        <span class="Apple-style-span" style="color: rgb(204, 56, 196); "># do more stuff</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span" style="color: rgb(204, 56, 196); "><br></span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span" style="color: rgb(204, 56, 196); ">    # This one passes OK</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span" style="color: rgb(204, 56, 196); ">    #def testHere(self):</span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
<span class="Apple-style-span" style="color: rgb(204, 56, 196); ">    #   return self._waitForChange()</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #4700ff">if</span> __name__ == <span style="color: #00bf00">&quot;__main__&quot;</span>:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">import</span> sys</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    <span style="color: #4700ff">from</span> twisted.scripts <span style="color: #4700ff">import</span> trial</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    sys.argv.extend([sys.argv[<span style="color: #9b0000">0</span>]])</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">    trial.run()</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">&lt;/code&gt;</p></div>