commit 2abd54a1b979c11153c41a51b884386fbd4635c4 Author: Philipp Winter phw@nymity.ch Date: Wed May 6 17:54:59 2020 -0700
Use contextlib's context manager.
So far, the email autoresponder fails after a while, raising the following exception:
File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite why = selectable.doRead() File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/internet/tcp.py", line 243, in doRead return self._dataReceived(data) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/internet/tcp.py", line 249, in _dataReceived rval = self.protocol.dataReceived(data) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/protocols/basic.py", line 454, in dataReceived self.lineReceived(line) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/mail/smtp.py", line 445, in lineReceived return getattr(self, 'state_' + self.mode)(line) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/mail/smtp.py", line 705, in dataLineReceived m.eomReceived() for m in self.__messages File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/twisted/mail/smtp.py", line 705, in <listcomp> m.eomReceived() for m in self.__messages File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/distributors/email/server.py", line 230, in eomReceived self.responder.reply() File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/distributors/email/autoresponder.py", line 574, in reply response = self.getMailData() File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/distributors/email/autoresponder.py", line 392, in getMailData client, lang) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/distributors/email/autoresponder.py", line 101, in createResponseBody bridges = context.distributor.getBridges(bridgeRequest, interval) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/distributors/email/distributor.py", line 145, in getBridges with bridgedb.Storage.getDB() as db: File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/Storage.py", line 352, in __enter__ return next(self.gen) File "/home/bridgedb/virtualenvs/bridgedb/lib/python3.7/site-packages/bridgedb-0.10.0+11.g4cdd6a61.dirty-py3.7.egg/bridgedb/Storage.py", line 472, in getDB assert _REFCOUNT == 0 builtins.AssertionError:
It's not clear what caused this regression but it may have been introduced in commit c1a48d1, as part of our conversion to Python 3.
This fixes https://bugs.torproject.org/33945. --- CHANGELOG | 4 ++++ bridgedb/Storage.py | 63 +---------------------------------------------------- 2 files changed, 5 insertions(+), 62 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG index 80d3afa..aad33f2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ + * FIXES https://bugs.torproject.org/33945 + This patch fixes a bug that caused the email autoresponder to fail after + a while. + * FIXES https://bugs.torproject.org/34154 Add new fields to the SQLite table BlockedBridges in preparation for taking into account OONI's bridge measurement results. diff --git a/bridgedb/Storage.py b/bridgedb/Storage.py index 0fe8851..2859cf1 100644 --- a/bridgedb/Storage.py +++ b/bridgedb/Storage.py @@ -10,6 +10,7 @@ import time import hashlib from functools import wraps from ipaddr import IPAddress +from contextlib import contextmanager import sys
from bridgedb.Stability import BridgeHistory @@ -345,68 +346,6 @@ def openDatabase(sqlite_file): return conn
-class DBGeneratorContextManager(object): - """Helper for @contextmanager decorator. - - Overload __exit__() so we can call the generator many times - """ - - def __init__(self, gen): - self.gen = gen - - def __enter__(self): - return next(self.gen) - - def __exit__(self, type, value, traceback): - """Handle exiting a with statement block - - Progress generator or throw exception - - Significantly based on contextlib.py - - :throws: `RuntimeError` if the generator doesn't stop after - exception is thrown - """ - if type is None: - try: - next(self.gen) - except StopIteration: - return - return - else: - if value is None: - # Need to force instantiation so we can reliably - # tell if we get the same exception back - value = type() - try: - self.gen.throw(type, value, traceback) - raise RuntimeError("generator didn't stop after throw()") - except StopIteration as exc: - # Suppress the exception *unless* it's the same exception that - # was passed to throw(). This prevents a StopIteration - # raised inside the "with" statement from being suppressed - return exc is not value - except: - # only re-raise if it's *not* the exception that was - # passed to throw(), because __exit__() must not raise - # an exception unless __exit__() itself failed. But throw() - # has to raise the exception to signal propagation, so this - # fixes the impedance mismatch between the throw() protocol - # and the __exit__() protocol. - # - if sys.exc_info()[1] is not value: - raise - -def contextmanager(func): - """Decorator to for :func:`Storage.getDB()` - - Define getDB() for use by with statement content manager - """ - @wraps(func) - def helper(*args, **kwds): - return DBGeneratorContextManager(func(*args, **kwds)) - return helper - _DB_FNAME = None _LOCK = None _LOCKED = 0
tor-commits@lists.torproject.org