[Checkins] SVN: zc.ngi/trunk/ Bugs Fixed:

Jim Fulton jim at zope.com
Wed Aug 18 18:11:42 EDT 2010


Log message for revision 115765:
  Bugs Fixed:
  
  - The zc.ngi.async connections' ``write`` and ``writelines`` methods
    didn't raise errors when called on closed connections.
  
  - The built-in connection adapters and handy adapter base class
    didn't implement __nonzero__.
  

Changed:
  U   zc.ngi/trunk/README.txt
  U   zc.ngi/trunk/src/zc/ngi/adapters.py
  U   zc.ngi/trunk/src/zc/ngi/adapters.test
  U   zc.ngi/trunk/src/zc/ngi/async.py
  U   zc.ngi/trunk/src/zc/ngi/tests.py

-=-
Modified: zc.ngi/trunk/README.txt
===================================================================
--- zc.ngi/trunk/README.txt	2010-08-18 16:48:28 UTC (rev 115764)
+++ zc.ngi/trunk/README.txt	2010-08-18 22:11:41 UTC (rev 115765)
@@ -20,7 +20,7 @@
 *******
 
 ====================
-2.0.0a5 (2010-08-18)
+2.0.0a5 (2010-08-19)
 ====================
 
 New Features:
@@ -35,6 +35,12 @@
 - When testing listeners were closed, handle_close, rather than close,
   was called on server connections.
 
+- The zc.ngi.async connections' ``write`` and ``writelines`` methods
+  didn't raise errors when called on closed connections.
+
+- The built-in connection adapters and handy adapter base class
+  didn't implement __nonzero__.
+
 ====================
 2.0.0a4 (2010-07-27)
 ====================

Modified: zc.ngi/trunk/src/zc/ngi/adapters.py
===================================================================
--- zc.ngi/trunk/src/zc/ngi/adapters.py	2010-08-18 16:48:28 UTC (rev 115764)
+++ zc.ngi/trunk/src/zc/ngi/adapters.py	2010-08-18 22:11:41 UTC (rev 115765)
@@ -65,6 +65,9 @@
     def peer_address(self):
         return self.connection.peer_address
 
+    def __nonzero__(self):
+        return bool(self.connection)
+
 class Lines(Base):
 
     input = ''

Modified: zc.ngi/trunk/src/zc/ngi/adapters.test
===================================================================
--- zc.ngi/trunk/src/zc/ngi/adapters.test	2010-08-18 16:48:28 UTC (rev 115764)
+++ zc.ngi/trunk/src/zc/ngi/adapters.test	2010-08-18 22:11:41 UTC (rev 115765)
@@ -144,3 +144,17 @@
 
     >>> connection.test_close('test')
     -> CLOSE test
+
+Booleanness
+===========
+
+    >>> connection = zc.ngi.testing.Connection()
+    >>> adapter = zc.ngi.adapters.Lines(connection)
+    >>> bool(adapter)
+    True
+
+    >>> adapter.close()
+    -> CLOSE
+
+    >>> bool(adapter)
+    False

Modified: zc.ngi/trunk/src/zc/ngi/async.py
===================================================================
--- zc.ngi/trunk/src/zc/ngi/async.py	2010-08-18 16:48:28 UTC (rev 115764)
+++ zc.ngi/trunk/src/zc/ngi/async.py	2010-08-18 22:11:41 UTC (rev 115765)
@@ -224,7 +224,6 @@
 
 class _ConnectionDispatcher(dispatcher):
 
-    __connected = True
     __closed = None
     __handler = None
     __iterator_exception = None
@@ -236,7 +235,7 @@
         self.logger = logger
 
     def __nonzero__(self):
-        return self.__connected
+        return self.__output is not None
 
     def set_handler(self, handler):
         if self.__handler is not None:
@@ -269,23 +268,37 @@
         if __debug__:
             self.logger.debug('write %r', data)
         assert isinstance(data, str) or (data is zc.ngi.END_OF_DATA)
-        self.__output.append(data)
+        try:
+            self.__output.append(data)
+        except AttributeError:
+            if self.__output is None:
+                raise ValueError("write called on closed connection")
+            raise
         self.implementation.notify_select()
 
     def writelines(self, data):
         if __debug__:
             self.logger.debug('writelines %r', data)
         assert not isinstance(data, str), "writelines does not accept strings"
-        self.__output.append(iter(data))
+        try:
+            self.__output.append(iter(data))
+        except AttributeError:
+            if self.__output is None:
+                raise ValueError("writelines called on closed connection")
+            raise
         self.implementation.notify_select()
 
     def close_after_write(self):
-        self.__output.append(zc.ngi.END_OF_DATA)
+        try:
+            self.__output.append(zc.ngi.END_OF_DATA)
+        except AttributeError:
+            if self.__output is None:
+                return # already closed
+            raise
         self.implementation.notify_select()
 
     def close(self):
-        self.__connected = False
-        self.__output[:] = []
+        self.__output = None
         dispatcher.close(self)
         self.implementation.notify_select()
 

Modified: zc.ngi/trunk/src/zc/ngi/tests.py
===================================================================
--- zc.ngi/trunk/src/zc/ngi/tests.py	2010-08-18 16:48:28 UTC (rev 115764)
+++ zc.ngi/trunk/src/zc/ngi/tests.py	2010-08-18 22:11:41 UTC (rev 115765)
@@ -50,6 +50,14 @@
 else:
     del blocking_warns
 
+def wait_until(func, timeout=30):
+    deadline = time.time()+timeout
+    while 1:
+        if func():
+            break
+        if time.time() > deadline:
+            raise ValueError("Timeout")
+        time.sleep(.01)
 
 
 def test_async_cannot_connect():
@@ -203,17 +211,10 @@
     """
 If a connection is closed, we need to make sure write calls generate errors.
 
-    >>> logger = logging.getLogger('zc.ngi')
-    >>> log_handler = logging.StreamHandler(sys.stdout)
-    >>> logger.addHandler(log_handler)
-    >>> logger.setLevel(logging.WARNING)
-
-    >>> server_event = threading.Event()
     >>> @zc.ngi.generator.handler
     ... def server(conn):
-    ...     data = yield
-    ...     print data
-    ...     server_event.set()
+    ...     while 1:
+    ...        print (yield)
 
     >>> listener = zc.ngi.async.listener(None, server)
 
@@ -222,6 +223,7 @@
     ...         self.event = threading.Event()
     ...     def connected(self, conn):
     ...         self.conn = conn
+    ...         conn.set_handler(self)
     ...         self.event.set()
 
     >>> connector = Connector()
@@ -231,27 +233,19 @@
 OK, we've connected.  If we close the connection, we won't be able to write:
 
     >>> connector.conn.close()
-    >>> connector.conn.write('xxx')
 
-    >>> connector.conn.writelines(['xxx', 'yyy'])
+    >>> wait_until(lambda : not connector.conn)
 
-Similarly if the server closes the connection:
-
-    >>> connector = Connector()
-    >>> zc.ngi.async.connect(listener.address, connector)
-    >>> _ = connector.event.wait(1)
-
-    >>> connector.conn.write('aaa'); _ = server_event.wait(1)
-    aaa
-
     >>> connector.conn.write('xxx')
+    Traceback (most recent call last):
+    ...
+    ValueError: write called on closed connection
 
     >>> connector.conn.writelines(['xxx', 'yyy'])
+    Traceback (most recent call last):
+    ...
+    ValueError: writelines called on closed connection
 
-
-    >>> logger.removeHandler(log_handler)
-    >>> logger.setLevel(logging.NOTSET)
-
     >>> listener.close()
     """
 



More information about the checkins mailing list