[tor-commits] [bridgedb/master] Use contextlib's context manager.

phw at torproject.org phw at torproject.org
Wed May 27 17:14:43 UTC 2020


commit 2abd54a1b979c11153c41a51b884386fbd4635c4
Author: Philipp Winter <phw at 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





More information about the tor-commits mailing list