<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Jan 23, 2017 at 7:08 PM, Craig Rodrigues <span dir="ltr"><<a href="mailto:rodrigc@crodrigues.org" target="_blank">rodrigc@crodrigues.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="gmail-h5">On Sat, Jan 21, 2017 at 8:06 PM, Glyph Lefkowitz <span dir="ltr"><<a href="mailto:glyph@twistedmatrix.com" target="_blank">glyph@twistedmatrix.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><span class="gmail-m_920830734858214402gmail-"><br><div><blockquote type="cite"><div>On Jan 21, 2017, at 6:15 PM, Craig Rodrigues <<a href="mailto:rodrigc@crodrigues.org" target="_blank">rodrigc@crodrigues.org</a>> wrote:</div><br class="gmail-m_920830734858214402gmail-m_1103198121470315311Apple-interchange-newline"><div><div style="font-family:menlo-regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">If I run the test on Python 2, I don't get the error, and on line 93, brdicts is a dict.</div><div style="font-family:menlo-regular;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">However, if I run the test on Python 3, brdicts is a Deferred, thus the error.</div></div></blockquote><br></div></span><div>This really ought to be impossible.  If I were seeing this, single-stepping through inlineCallbacks in pudb would probably be my next step.  Have you made any attempts to simplify it down to remove some of the buildbot-specific code?</div><span class="gmail-m_920830734858214402gmail-HOEnZb"><font color="#888888"><br><div>-glyph</div></font></span></div><br></blockquote><div><br></div><div><br></div></div></div>I did some more debugging.  The callstack is quite deep. :/<br>I used this command to trigger the error:<br><br>trial  buildbot.test.unit.test_<wbr>process_<wbr>buildrequestdistributor.<wbr>TestMaybeStartBuilds.test_<wbr>slow_db<br><br>I found in this function in buildbot's BuildRequestsEndpoint.get() function ( <a href="https://github.com/buildbot/buildbot/blob/master/master/buildbot/data/buildrequests.py#L146" target="_blank">https://github.com/buildbot/<wbr>buildbot/blob/master/master/<wbr>buildbot/data/buildrequests.<wbr>py#L146</a> ) there is this line:<br><br><b>        defer.returnValue(<br>            [(yield self.db2data(br)) for br in buildrequests])<br></b><br>On Python 2, this line returns:</div><div class="gmail_quote">  an object list</div><div class="gmail_quote">  each list entry is a dictionary of name/value pairs that looks like:</div><div class="gmail_quote">







<p class="gmail-m_920830734858214402gmail-p1"><span class="gmail-m_920830734858214402gmail-s1">[{'buildrequestid': 10, 'complete': False, 'waited_for': False, 'claimed_at': None, 'results': -1, 'claimed': False, 'buildsetid': 11, 'complete_at': None, 'submitted_at': datetime.datetime(1970, 1, 2, 12, 6, 40, tzinfo=tzutc()), 'builderid': 77, 'claimed_by_masterid': None, 'priority': 0}, {'buildrequestid': 11, 'complete': False, 'waited_for': False, 'claimed_at': None, 'results': -1, 'claimed': False, 'buildsetid': 11, 'complete_at': None, 'submitted_at': datetime.datetime(1970, 1, 2, 13, 30, tzinfo=tzutc()), 'builderid': 77, 'claimed_by_masterid': None, 'priority': 0}]</span></p></div><div class="gmail_quote"><br></div><div class="gmail_quote">On Python 3, this returns:</div><div class="gmail_quote">  an object <generator object BuildRequestsEndpoint.get.<<wbr>locals>.<listcomp></div><div class="gmail_quote">  of type <class 'generator'><br><br></div></div></div></blockquote><div><br></div><div>Yep.</div><div><br></div><div>On Python 2, [(yield self.db2data(br)) for br in buildrequests] is a list comprehension.  It will have len(buildrequests) elements and each will be the value sent back in to the generator via the yield expression.</div><div><br></div><div>On Python 3, the same expression is a list of one element which is a generator expression.</div><div><br></div><div>This form is much clearer, I think, and behaves as intended on both versions of Python:</div><div><br></div><div>    results = []</div><div>    for br in buildrequests:</div><div>        results.append((yield self.db2data(br)))</div><div>    defer.returnValue(results)</div><div><br></div><div>Jean-Paul</div><div><br></div></div></div></div>