diff --git a/CHANGES.rst b/CHANGES.rst index dea491f..448013f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,9 @@ 5.2 (unreleased) ================ +- Add minimal savepoint support, so we do not fail if any code tries to create a savepoint. + (`#35 `_). + - Fix TypeError: 'error' object is not subscriptable during error handling on Windows (`#33 `_). diff --git a/src/zope/sendmail/delivery.py b/src/zope/sendmail/delivery.py index a0395e9..3d20b7c 100644 --- a/src/zope/sendmail/delivery.py +++ b/src/zope/sendmail/delivery.py @@ -25,7 +25,8 @@ from time import strftime from socket import gethostname -from transaction.interfaces import IDataManager +from transaction.interfaces import ISavepointDataManager +from transaction.interfaces import IDataManagerSavepoint import transaction from zope.interface import implementer @@ -41,7 +42,14 @@ log = logging.getLogger("MailDataManager") -@implementer(IDataManager) +@implementer(IDataManagerSavepoint) +class _NoOpSavepoint(object): + + def rollback(self): + return + + +@implementer(ISavepointDataManager) class MailDataManager(object): def __init__(self, callable, args=(), vote=None, onAbort=None): @@ -62,6 +70,12 @@ def abort(self, txn): def sortKey(self): return str(id(self)) + def savepoint(self): + # We do not need savepoint/rollback, but some code (like CMFEditions) + # uses savepoints, and breaks when one datamanager does not have this. + # So provide a dummy implementation. + return _NoOpSavepoint() + # No subtransaction support. def abort_sub(self, txn): "This object does not do anything with subtransactions" diff --git a/src/zope/sendmail/tests/test_delivery.py b/src/zope/sendmail/tests/test_delivery.py index d4843ef..5c90ef0 100644 --- a/src/zope/sendmail/tests/test_delivery.py +++ b/src/zope/sendmail/tests/test_delivery.py @@ -256,6 +256,35 @@ def send(self): self.assertEqual(1, len(w)) self.assertIn("does not provide a vote method", str(w[0])) + def testSavepoint(self): + mailer = MailerStub() + delivery = DirectMailDelivery(mailer) + fromaddr = 'Jim ', + 'Steve ') + opt_headers = (b'From: Jim \n' + b'To: some-zope-coders:;\n' + b'Date: Mon, 19 May 2003 10:17:36 -0400\n' + b'Message-Id: <20030519.1234@example.org>\n') + message = (b'Subject: example\n' + b'\n' + b'This is just an example\n') + + message_bytes = message + opt_headers_bytes = opt_headers + + msgid = delivery.send(fromaddr, toaddrs, opt_headers + message) + self.assertEqual(msgid, '20030519.1234@example.org') + self.assertEqual(mailer.sent_messages, []) + savepoint = transaction.savepoint() + self.assertEqual(mailer.sent_messages, []) + savepoint.rollback() + self.assertEqual(mailer.sent_messages, []) + transaction.commit() + self.assertEqual(mailer.sent_messages, + [(fromaddr, toaddrs, + opt_headers_bytes + message_bytes)]) + class MaildirWriterStub(object):