Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed4a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'clause': 0.09; 'cleanup': 0.09; 'etc).': 0.09; 'mess': 0.09; 'okay': 0.09; 'seemed': 0.09; 'statements': 0.09; 'try:': 0.09; 'wrapped': 0.09; 'runs': 0.10; 'def': 0.12; '"break"': 0.16; 'circumvent': 0.16; 'clause.': 0.16; 'exceptions,': 0.16; 'exiting': 0.16; 'expect)': 0.16; 'left,': 0.16; 'mode,': 0.16; 'modules,': 0.16; 'pygtk,': 0.16; 'statements,': 0.16; 'true:': 0.16; 'folks': 0.16; 'bit': 0.19; 'skip:g 40': 0.19; 'meant': 0.20; 'skip': 0.24; 'switched': 0.24; 'looks': 0.24; "i've": 0.25; 'switch': 0.26; 'this:': 0.26; 'function': 0.29; 'skip:p 30': 0.29; 'mode': 0.30; 'statement': 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'work.': 0.31; 'code': 0.31; 'complete,': 0.31; 'raised': 0.31; 'subject:that': 0.31; 'figure': 0.32; 'handled': 0.32; 'stuff': 0.32; 'another': 0.32; 'running': 0.33; 'except': 0.35; 'problem.': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'data,': 0.36; 'false': 0.36; 'yield': 0.36; 'responsible': 0.36; 'needed': 0.38; 'to:addr:python-list': 0.38; 'delete': 0.39; 'to:addr:python.org': 0.39; 'changed': 0.39; 'break': 0.61; 'took': 0.61; 'back': 0.62; 'decided': 0.64; 'finally': 0.65; 'kept': 0.65; 'sole': 0.78; 'awhile': 0.84; 'that),': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=lHSWQjzef0E+CXw1PK66rsUoqr2Wn6Gi1h6wB6jppsU=; b=lXU7t+s1YznBGjSteaKChfrsVv/kfJwX3jgxjpeWvn1suKtOr4mCtfC5eIdFJFYT7M mFKeA3Lp4nGxbaUPHMPFsSBOUD6OKwZlKJf9GAT4bcGlrAQkCPuLB77SVNJM5rw2vuNi JsNpo5gTGKEDCS2JwLbfnO45qdZEQsTn/DqkvdYJ3rn/FTh4Tm7uxCrPDL+NOvcyVXS9 KEcKmU2bLFFHBUnRztr2DGINmpT90VhmY5Y5GX7GfQbHKyO5UqkZhVYlhv61z8UCRXUT ni8mzOK6Q2gkPDh/lhpK++Q/qbnffKCzO9sZu7OGS/ey7w5TSfRfJEDAnHJBa1boZL0a LJRg== MIME-Version: 1.0 X-Received: by 10.182.251.138 with SMTP id zk10mr8436734obc.72.1424712224930; Mon, 23 Feb 2015 09:23:44 -0800 (PST) Date: Mon, 23 Feb 2015 11:23:44 -0600 Subject: Well, that was a head scratcher... From: Skip Montanaro To: Python Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 50 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1424712227 news.xs4all.nl 2864 [2001:888:2000:d::a6]:53001 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:86242 I've been reworking some of the code in the platform I use at work. I'm the sole developer/maintainer/hard-core user left, so I can pretty much do what I want with it (convert modules to Cython, delete no longer used modules, etc). The platform uses PyGtk, so we use signals and other features of that system heavily. In one place, I register a generator function with gobject.idle_add: self.chunk_id = gobject.idle_add(self.read_chunk().next, priority=gobject.PRIORITY_LOW) read_chunk is (as you might expect) a generator function. Structurally, it looks like this: def read_chunk(self): count = 0 while True: try: x = other_stuff() except StopIteration: yield False else: if some other condition holds: yield False self.distribute(x) count += 1 if count % 1000 == 0: # Let other folks have the CPU... yield True I decided I needed to clean up that idle_add stuff when complete, so instead of duplicating that bit before both "yield False" statements, I wrapped the whole mess in a try/finally statement and did my cleanup in the finally clause. Thinking the "yield False" might circumvent the finally clause (silly me), I changed those statements to break statements. Everything seemed to work okay for awhile, as long as I was running in one (historical) mode, where the system only runs from historical data (read_chunk above is responsible for much of that), exiting when the historical data were exhausted. When I switched to live mode (initialize from historical data, then switch to listen for live data), the system kept crashing with a StopIteration before switching to live mode. I thought I had handled all the StopIteration exceptions, but the switch from "yield False" to "break" meant another one was raised which I wasn't catching. Switching back to the yield statement solved the problem. Took awhile to figure out what was going on. Skip