This one gets uncaught errors in isolation:

C:\Code\Zope3>\python23\python.exe -vvf . testNotFound
Configuration file found.
Running FUNCTIONAL tests at level 1
Running FUNCTIONAL tests from C:\Code\Zope3
Parsing ftesting.zcml
testNotFound ( ...
Exception ZODB.POSException.ConnectionStateError:
<ZODB.POSException.ConnectionStateError instance at 0x03418490> in
<bound method Cleanup.__del__ of
< object at 0x0340F9B0>>
Exception ZODB.POSException.ConnectionStateError:
<ZODB.POSException.ConnectionStateError instance at 0x020875A8> in
<bound method Cleanup.__del__ of
< object at 0x03419110>>
testNotFound ( ... ok

Ran 2 tests in 0.547s


I don't know whether this is new, but I have a vague memory of bumping
into this some weeks ago.  The switch to using ZODB 3.4a2 definitely
isn't relevant.

ConnectionStateError is raised by ZODB when:

1. An attempt to commit a transaction T (or subtransaction) fails.
2. T isn't explicitly aborted.
3. An attempt is made to close a Connection involved in the failing T.

unittest doesn't notice the failures because the exceptions are raised
in a __del__ method, and Python can't raise exceptions that occur in
__del__ methods (Python just prints info about such exceptions).

This patch makes the exceptions go away, but I don't know whether it's
the right thing to do -- ZODB raises ConnectionStateError precisely
because it's impossible to guess what the user's intent was when they
try to close a connection with a transaction still in a damaged state.
 Best guess is that this patch isn't the right solution, and that the
publication machinery should be explicitly aborting transactions that
fail; for that matter, relying on a __del__ method for *anything* here
just doesn't smell right:

Index: src/zope/app/publication/
--- src/zope/app/publication/ (revision 29848)
+++ src/zope/app/publication/ (working copy)
@@ -137,7 +137,11 @@
         version = request.get(self.version_cookie, '')
         conn =

-        cleanup = Cleanup(conn.close)
+        def close_connection():
+            transaction.abort()
+            conn.close()
+        cleanup = Cleanup(close_connection)
         request.hold(cleanup)  # Close the connection on request.close()

Zope3-dev mailing list

Reply via email to