[Zodb-checkins] SVN: ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/ Deprecate beforeCommitHook().

Tim Peters tim.one at comcast.net
Fri Aug 12 19:10:39 EDT 2005


Log message for revision 37907:
  Deprecate beforeCommitHook().
  
  Test that it is deprecated, and restore non-trivial tests
  of it.
  

Changed:
  U   ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/_transaction.py
  U   ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/interfaces.py
  U   ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/tests/test_transaction.py

-=-
Modified: ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/_transaction.py
===================================================================
--- ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/_transaction.py	2005-08-12 22:51:41 UTC (rev 37906)
+++ ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/_transaction.py	2005-08-12 23:10:38 UTC (rev 37907)
@@ -430,6 +430,9 @@
         self._before_commit_index += 1
 
     def beforeCommitHook(self, hook, *args, **kws):
+        from ZODB.utils import deprecated37
+
+        deprecated37("Use addBeforeCommitHook instead of beforeCommitHook.")
         # Default order is zero.
         self.addBeforeCommitHook(hook, args, kws, order=0)
 

Modified: ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/interfaces.py
===================================================================
--- ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/interfaces.py	2005-08-12 22:51:41 UTC (rev 37906)
+++ ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/interfaces.py	2005-08-12 23:10:38 UTC (rev 37907)
@@ -167,6 +167,7 @@
         raise an exception, or remove `<name, value>` pairs).
         """
 
+    # deprecated37
     def beforeCommitHook(__hook, *args, **kws):
         """Register a hook to call before the transaction is committed.
 

Modified: ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/tests/test_transaction.py
===================================================================
--- ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/tests/test_transaction.py	2005-08-12 22:51:41 UTC (rev 37906)
+++ ZODB/branches/anguenot-ordering-beforecommitsubscribers/src/transaction/tests/test_transaction.py	2005-08-12 23:10:38 UTC (rev 37907)
@@ -44,6 +44,7 @@
 
 import transaction
 from ZODB.utils import positive_id
+from ZODB.tests.warnhook import WarningsHook
 
 # deprecated37  remove when subtransactions go away
 # Don't complain about subtxns in these tests.
@@ -435,6 +436,182 @@
         self.assertRaises(ValueError, t.addBeforeCommitHook,
                           hook, order=foo())
 
+# deprecated37; remove this then
+def test_beforeCommitHook():
+    """Test beforeCommitHook.
+
+    Let's define a hook to call, and a way to see that it was called.
+
+      >>> log = []
+      >>> def reset_log():
+      ...     del log[:]
+
+      >>> def hook(arg='no_arg', kw1='no_kw1', kw2='no_kw2'):
+      ...     log.append("arg %r kw1 %r kw2 %r" % (arg, kw1, kw2))
+
+    beforeCommitHook is deprecated, so we need cruft to suppress the
+    warnings.
+
+      >>> whook = WarningsHook()
+      >>> whook.install()
+
+    Fool the warnings module into delivering the warnings despite that
+    they've been seen before; this is needed in case this test is run
+    more than once.
+
+      >>> import warnings
+      >>> warnings.filterwarnings("always", category=DeprecationWarning)
+
+    Now register the hook with a transaction.
+
+      >>> import transaction
+      >>> t = transaction.begin()
+      >>> t.beforeCommitHook(hook, '1')
+
+    Make sure it triggered a deprecation warning:
+
+      >>> len(whook.warnings)
+      1
+      >>> message, category, filename, lineno = whook.warnings[0]
+      >>> print message
+      This will be removed in ZODB 3.7:
+      Use addBeforeCommitHook instead of beforeCommitHook.
+      >>> category.__name__
+      'DeprecationWarning'
+      >>> whook.clear()
+
+    We can see that the hook is indeed registered.
+
+      >>> [(hook.func_name, args, kws)
+      ...  for hook, args, kws in t.getBeforeCommitHooks()]
+      [('hook', ('1',), {})]
+
+    When transaction commit starts, the hook is called, with its
+    arguments.
+
+      >>> log
+      []
+      >>> t.commit()
+      >>> log
+      ["arg '1' kw1 'no_kw1' kw2 'no_kw2'"]
+      >>> reset_log()
+
+    A hook's registration is consumed whenever the hook is called.  Since
+    the hook above was called, it's no longer registered:
+
+      >>> len(list(t.getBeforeCommitHooks()))
+      0
+      >>> transaction.commit()
+      >>> log
+      []
+
+    The hook is only called for a full commit, not for a savepoint or
+    subtransaction.
+
+      >>> t = transaction.begin()
+      >>> t.beforeCommitHook(hook, 'A', kw1='B')
+      >>> dummy = t.savepoint()
+      >>> log
+      []
+      >>> t.commit(subtransaction=True)
+      >>> log
+      []
+      >>> t.commit()
+      >>> log
+      ["arg 'A' kw1 'B' kw2 'no_kw2'"]
+      >>> reset_log()
+
+    If a transaction is aborted, no hook is called.
+
+      >>> t = transaction.begin()
+      >>> t.beforeCommitHook(hook, "OOPS!")
+      >>> transaction.abort()
+      >>> log
+      []
+      >>> transaction.commit()
+      >>> log
+      []
+
+    The hook is called before the commit does anything, so even if the
+    commit fails the hook will have been called.  To provoke failures in
+    commit, we'll add failing resource manager to the transaction.
+
+      >>> class CommitFailure(Exception):
+      ...     pass
+      >>> class FailingDataManager:
+      ...     def tpc_begin(self, txn, sub=False):
+      ...         raise CommitFailure
+      ...     def abort(self, txn):
+      ...         pass
+
+      >>> t = transaction.begin()
+      >>> t.join(FailingDataManager())
+
+      >>> t.beforeCommitHook(hook, '2')
+      >>> t.commit()
+      Traceback (most recent call last):
+      ...
+      CommitFailure
+      >>> log
+      ["arg '2' kw1 'no_kw1' kw2 'no_kw2'"]
+      >>> reset_log()
+
+    Let's register several hooks.
+
+      >>> t = transaction.begin()
+      >>> t.beforeCommitHook(hook, '4', kw1='4.1')
+      >>> t.beforeCommitHook(hook, '5', kw2='5.2')
+
+    They are returned in the same order by getBeforeCommitHooks.
+
+      >>> [(hook.func_name, args, kws)     #doctest: +NORMALIZE_WHITESPACE
+      ...  for hook, args, kws in t.getBeforeCommitHooks()]
+      [('hook', ('4',), {'kw1': '4.1'}),
+       ('hook', ('5',), {'kw2': '5.2'})]
+
+    And commit also calls them in this order.
+
+      >>> t.commit()
+      >>> len(log)
+      2
+      >>> log  #doctest: +NORMALIZE_WHITESPACE
+      ["arg '4' kw1 '4.1' kw2 'no_kw2'",
+       "arg '5' kw1 'no_kw1' kw2 '5.2'"]
+      >>> reset_log()
+
+    While executing, a hook can itself add more hooks, and they will all
+    be called before the real commit starts.
+
+      >>> def recurse(txn, arg):
+      ...     log.append('rec' + str(arg))
+      ...     if arg:
+      ...         txn.beforeCommitHook(hook, '-')
+      ...         txn.beforeCommitHook(recurse, txn, arg-1)
+
+      >>> t = transaction.begin()
+      >>> t.beforeCommitHook(recurse, t, 3)
+      >>> transaction.commit()
+      >>> log  #doctest: +NORMALIZE_WHITESPACE
+      ['rec3',
+               "arg '-' kw1 'no_kw1' kw2 'no_kw2'",
+       'rec2',
+               "arg '-' kw1 'no_kw1' kw2 'no_kw2'",
+       'rec1',
+               "arg '-' kw1 'no_kw1' kw2 'no_kw2'",
+       'rec0']
+      >>> reset_log()
+
+    We have to uninstall the warnings hook so that other warnings don't get
+    lost.
+
+      >>> whook.uninstall()
+
+    Obscure:  There is no API call for removing the filter we added, but
+    filters appears to be a public variable.
+
+      >>> del warnings.filters[0]
+    """
+
 def test_addBeforeCommitHook():
     """Test addBeforeCommitHook, without order arguments.
 



More information about the Zodb-checkins mailing list