Attached is an update for debian/patches/jelmer-python-bindings that
includes the fix for the memory leak.

-- 
#! /bin/sh /usr/share/dpatch/dpatch-run
## jelmer-python-bindings by <[EMAIL PROTECTED]>
##
## DP: Updates to python bindings from Jelmer Vernooij.  This is stuff
## DP: he needs for his svn<->bzr bridge, backported from trunk.
## DP:
## DP: Patch was pulled from Ubuntu edgy, then edited rather heavily:
## DP: (a) ported to 1.4.2, (b) removed lots of indentation fixing
## DP: noise, (c) reverted some duplicate adds.

@DPATCH@
Index: subversion/bindings/swig/include/apr.swg
--- a/subversion/bindings/swig/include/apr.swg
+++ b/subversion/bindings/swig/include/apr.swg
@@ -146,14 +146,24 @@
 
 /* -----------------------------------------------------------------------
    create an OUTPUT argument defn for an apr_hash_t ** which is storing
+   dirent values
+*/
+%typemap(python,in,numinputs=0) apr_hash_t **DIRENTHASH = apr_hash_t **OUTPUT;
+%typemap(python,argout,fragment="t_output_helper") apr_hash_t **DIRENTHASH {
+    $result = t_output_helper($result,
+                              svn_swig_py_convert_hash(*$1, 
+                                                       SWIGTYPE_p_svn_dirent_t,
+                                                       NULL));
+}
+
+/* -----------------------------------------------------------------------
+   create an OUTPUT argument defn for an apr_hash_t ** which is storing
    property values
 */
 
 %typemap(python,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT;
-%typemap(python,argout) apr_hash_t **PROPHASH {
-    /* toss prior result, get new result from the hash */
-    Py_DECREF($result);
-    $result = svn_swig_py_prophash_to_dict(*$1);
+%typemap(python,argout,fragment="t_output_helper") apr_hash_t **PROPHASH {
+    $result = t_output_helper($result, svn_swig_py_prophash_to_dict(*$1));
 }
 
 %typemap(perl5,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT;
--- a/subversion/bindings/swig/include/proxy_apr.swg
+++ b/subversion/bindings/swig/include/proxy_apr.swg
@@ -159,6 +159,28 @@
           del self._parent_pool
         if hasattr(self, "_is_valid"):
           del self._is_valid
+        
+        # Clear out any pool-owned references inserted by typemaps
+        if hasattr(self, "_owned_refs"):
+          del self._owned_refs
+
+      def _add_owned_ref(self, ref):
+        """Add a new 'owned' reference -- i.e. a Python object contained in a C
+           structure allocated in this pool.  Used by the typemaps to manage
+           reference counting semantics."""
+        if not hasattr(self, "_owned_refs"):
+          self._owned_refs = {}
+        if self._owned_refs.has_key(ref):
+          self._owned_refs[ref] += 1
+        else:
+          self._owned_refs[ref] = 1
+      
+      def _remove_owned_ref(self, ref):
+        """Remove an existing 'owned' reference.  Also used by typemaps."""
+        if hasattr(self, "_owned_refs") and self._owned_refs.has_key(ref):
+          self._owned_refs[ref] -= 1
+          if self._owned_refs[ref] == 0:
+            del self._owned_refs[ref]
   
       def __del__(self):
         """Automatically destroy memory pools, if necessary"""
--- a/subversion/bindings/swig/include/svn_types.swg
+++ b/subversion/bindings/swig/include/svn_types.swg
@@ -444,6 +444,12 @@
   svn_swig_rb_set_baton($result, (VALUE)$2);
 };
 
+%typemap(python, in) (svn_commit_callback2_t callback, void *callback_baton)
+{
+  $1 = svn_swig_py_commit_callback2;
+  $2 = (void *)$input;
+}
+
 /* -----------------------------------------------------------------------
    Callback: svn_cancel_func_t
 */
@@ -519,6 +525,29 @@
   $1 = svn_swig_rb_make_stream($input);
 }
 
+%typemap(python, in) (svn_commit_callback_t callback, void *callback_baton)
+{
+  $1 = svn_swig_py_commit_callback;
+  $2 = (void *)$input;
+}
+
+/* -----------------------------------------------------------------------
+   Mapper to automatically turn Python objects into void* batons on assignment
+*/
+
+%typemap(python, in) void *PY_AS_VOID (PyObject *newRef) {
+  newRef = $input;
+  if ($input == Py_None) {
+    $1 = newRef = NULL;
+  } else {
+    newRef = $input;
+    $1 = (void *)$input;
+  }
+  if (svn_swig_py_pool_set_owned_ref(obj0, (PyObject *)arg1->$1_name, newRef)) 
{
+    SWIG_fail;
+  }
+}
+
 /* -----------------------------------------------------------------------
    Wrap the digest output for functions populating digests.
 */
--- a/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
+++ b/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
@@ -104,6 +104,8 @@
 static PyObject *_global_svn_swig_py_pool = NULL;
 static char assertValid[] = "assert_valid";
 static char parentPool[] = "_parent_pool";
+static char addOwnedRef[] = "_add_owned_ref";
+static char removeOwnedRef[] = "_remove_owned_ref";
 static char wrap[] = "_wrap";
 static char unwrap[] = "_unwrap";
 static char setParentPool[] = "set_parent_pool";
@@ -166,6 +168,51 @@
 
   return 0;
 }
+
+/* Get the parent pool of a proxy object, or return the global application
+ * pool if one is not set.  Returns a BORROWED reference! */
+static PyObject *proxy_get_pool(PyObject *proxy)
+{
+  PyObject *result;
+  if (PyObject_HasAttrString(proxy, parentPool))
+    {
+      result = PyObject_GetAttrString(proxy, parentPool);
+      Py_DECREF(result);
+    }
+  else
+    {
+      result = _global_svn_swig_py_pool;
+    }
+  return result;
+}
+
+/* Change an 'owned reference' allocated in a pool from oldRef to newRef.
+ * If oldRef is non-NULL and present in the parent pool of proxy, it is 
removed.
+ */
+int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef,
+                                   PyObject *newRef)
+{
+  PyObject *temp;
+  PyObject *py_pool = proxy_get_pool(proxy);
+
+  if (oldRef != NULL)
+    {
+      temp = PyObject_CallMethod(py_pool, removeOwnedRef, objectTuple, oldRef);
+      if (temp == NULL)
+        return 1;
+      else
+        Py_DECREF(temp);
+    }
+  if (newRef != NULL)
+    {
+      temp = PyObject_CallMethod(py_pool, addOwnedRef, objectTuple, newRef);
+      if (temp == NULL)
+        return 1;
+      else
+        Py_DECREF(temp);
+    }
+  return 0;
+}
 
 /* Wrapper for SWIG_TypeQuery */
 #define svn_swig_TypeQuery(x) SWIG_TypeQuery(x)
@@ -239,14 +286,9 @@
     }
     Py_DECREF(result);
   }
-  if (py_pool != NULL) {
-    if (PyObject_HasAttrString(input, parentPool)) {
-      *py_pool = PyObject_GetAttrString(input, parentPool);
-      Py_DECREF(*py_pool);
-    } else {
-      *py_pool = _global_svn_swig_py_pool;
-    }
-  }
+  if (py_pool != NULL)
+    *py_pool = proxy_get_pool((PyObject *) input);
+
   if (PyObject_HasAttrString(input, unwrap)) {
     input = PyObject_CallMethod(input, unwrap, emptyTuple);
     if (input == NULL) {
@@ -486,6 +528,52 @@
   return convert_hash(hash, convert_svn_string_t, NULL, NULL);
 }
 
+static PyObject *proparray_to_dict(const apr_array_header_t *array)
+{
+    PyObject *dict = PyDict_New();
+    int i;
+
+    if (dict == NULL)
+      return NULL;
+
+    for (i = 0; i < array->nelts; ++i)
+      {
+        svn_prop_t prop;
+        PyObject *py_key, *py_value;
+
+        prop = APR_ARRAY_IDX(array, i, svn_prop_t);
+
+        py_key = PyString_FromString(prop.name);
+        if (py_key == NULL)
+          goto error;
+
+        if (prop.value == NULL)
+          {
+             py_value = Py_None;
+             Py_INCREF(Py_None);
+          }
+        else
+          {
+             py_value = PyString_FromStringAndSize((void *)prop.value->data,
+                                                   prop.value->len);
+             if (py_value == NULL)
+               {
+                 Py_DECREF(py_key);
+                  goto error;
+               }
+          }
+
+        PyDict_SetItem(dict, py_key, py_value);
+    }
+
+    return dict;
+
+  error:
+    Py_DECREF(dict);
+    return NULL;
+
+}
+
 
 PyObject *svn_swig_py_locationhash_to_dict(apr_hash_t *hash)
 {
@@ -780,8 +780,10 @@
   PyObject *new_py_pool = svn_swig_NewPointerObj(new_pool, \
     svn_swig_TypeQuery("apr_pool_t *"), application_py_pool, NULL); \
   svn_##type##_t *new_value = dup(value, new_pool); \
-  return svn_swig_NewPointerObjString(new_value, "svn_" #type "_t *", \
-      new_py_pool); \
+  PyObject *obj = svn_swig_NewPointerObjString(new_value, "svn_" #type "_t *", 
\
+                                               new_py_pool); \
+  Py_XDECREF(new_py_pool); \
+  return obj; \
 }
 
 DECLARE_SWIG_CONSTRUCTOR(txdelta_window, svn_txdelta_window_dup)
@@ -552,6 +642,8 @@
 DECLARE_SWIG_CONSTRUCTOR(auth_ssl_server_cert_info,
     svn_auth_ssl_server_cert_info_dup)
 DECLARE_SWIG_CONSTRUCTOR(info, svn_info_dup)
+DECLARE_SWIG_CONSTRUCTOR(commit_info, svn_commit_info_dup)
+DECLARE_SWIG_CONSTRUCTOR(wc_notify, svn_wc_dup_notify)
 
 static PyObject *convert_log_changed_path(void *value, void *ctx,
                                           PyObject *py_pool)
@@ -1444,6 +1534,15 @@
   return err;
 }
 
+static svn_error_t *
+close_handler_pyio(void *baton)
+{
+  PyObject *py_io = baton;
+  Py_DECREF(py_io);
+  return SVN_NO_ERROR;
+}
+
+
 svn_stream_t *
 svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool)
 {
@@ -1454,9 +1553,11 @@
    * bindings, and we will be finished with the py_io object before we return
    * to python. I.e. DO NOT STORE AWAY THE RESULTING svn_stream_t * for use
    * over multiple calls into the bindings. */
+  Py_INCREF(py_io);
   stream = svn_stream_create(py_io, pool);
   svn_stream_set_read(stream, read_handler_pyio);
   svn_stream_set_write(stream, write_handler_pyio);
+  svn_stream_set_close(stream, close_handler_pyio);
 
   return stream;
 }
@@ -1504,6 +1605,41 @@
 }
 
 
+void svn_swig_py_notify_func2(void *baton,
+                              const svn_wc_notify_t *notify,
+                              apr_pool_t *pool)
+{
+  PyObject *function = baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  if (function == NULL || function == Py_None)
+    return;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallFunction(function,
+                                      (char *)"(O&O&)",
+                                      make_ob_wc_notify, notify,
+                                      make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      /* The callback shouldn't be returning anything. */
+      if (result != Py_None)
+        err = callback_bad_return_error("Not None");
+      Py_DECREF(result);
+    }
+
+  /* Our error has no place to go. :-( */
+  if (err)
+    svn_error_clear(err);
+
+  svn_swig_py_release_py_lock();
+}
+
 void svn_swig_py_status_func(void *baton,
                              const char *path,
                              svn_wc_status_t *status)
@@ -2138,3 +2274,377 @@
   *cred = creds;
   return err;
 }
+
+/* svn_ra_callbacks_t */
+static svn_error_t *
+ra_callbacks_open_tmp_file(apr_file_t **fp,
+                           void *callback_baton,
+                           apr_pool_t *pool)
+{
+  PyObject *callbacks = (PyObject *)callback_baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(callbacks, 
+                                    "open_tmp_file",
+                                    (char *)"O&", 
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result == Py_None)
+    {
+      *fp = NULL;
+    }
+  else 
+    {
+      *fp = svn_swig_py_make_file(result, pool);
+      if (*fp == NULL)
+       {
+         err = callback_exception_error();
+       }
+    }
+
+  Py_XDECREF(result);
+  svn_swig_py_release_py_lock();
+  return err;
+}
+
+void
+svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks,
+                               void **baton,
+                               PyObject *py_callbacks,
+                               apr_pool_t *pool)
+{
+  svn_error_t *err = svn_ra_create_callbacks(callbacks, pool);
+  PyObject *py_auth_baton;
+
+  if (err)
+    {
+      svn_swig_py_svn_exception(err);
+      return;
+    }
+
+  (*callbacks)->open_tmp_file = ra_callbacks_open_tmp_file;
+
+  py_auth_baton = PyObject_GetAttrString(py_callbacks, "auth_baton");
+
+  if (svn_swig_ConvertPtrString(py_auth_baton, 
+                                (void **)&((*callbacks)->auth_baton),
+                                "svn_auth_baton_t *")) 
+    {
+      err = type_conversion_error("svn_auth_baton_t *");
+      svn_swig_py_svn_exception(err);
+      Py_DECREF(py_auth_baton);
+      return;
+    }
+  
+  Py_XDECREF(py_auth_baton);
+
+  *baton = py_callbacks;
+}
+
+svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info,
+                                          void *baton,
+                                          apr_pool_t *pool)
+{
+  PyObject *receiver = baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  if ((receiver == NULL) || (receiver == Py_None))
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallFunction(receiver,
+                                      (char *)"O&O&",
+                                      make_ob_commit_info, commit_info,
+                                      make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      if (result != Py_None)
+        err = callback_bad_return_error("Not None");
+      Py_DECREF(result);
+    }
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision,
+                                         const char *date,
+                                         const char *author,
+                                         void *baton)
+{
+  PyObject *receiver = baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  if ((receiver == NULL) || (receiver == Py_None))
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallFunction(receiver,
+                                      (char *)"lss",
+                                      new_revision, date, author)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      if (result != Py_None)
+        err = callback_bad_return_error("Not None");
+      Py_DECREF(result);
+    }
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+svn_error_t *svn_swig_py_ra_file_rev_handler_func(
+                    void *baton,
+                    const char *path,
+                    svn_revnum_t rev,
+                    apr_hash_t *rev_props,
+                    svn_txdelta_window_handler_t *delta_handler,
+                    void **delta_baton,
+                    apr_array_header_t *prop_diffs,
+                    apr_pool_t *pool)
+{
+  PyObject *handler = baton;
+  PyObject *result, *py_rev_props = NULL, *py_prop_diffs = NULL;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  if ((handler == NULL) || (handler == Py_None))
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  py_rev_props = svn_swig_py_prophash_to_dict(rev_props);
+  if (py_rev_props == NULL)
+    {
+      err = type_conversion_error("apr_hash_t *");
+      goto error;
+    }
+
+  py_prop_diffs = proparray_to_dict(prop_diffs);
+
+  if (py_prop_diffs == NULL)
+    {
+      err = type_conversion_error("apr_array_header_t *");
+      goto error;
+    }
+
+  if ((result = PyObject_CallFunction(handler,
+                                      (char *)"slOOO&",
+                                      path, rev, py_rev_props, py_prop_diffs,
+                                      make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      if (result != Py_None)
+        err = callback_bad_return_error("Not None");
+
+      /* FIXME: Support returned TxDeltaWindow object and
+       * set delta_handler and delta_baton */
+      *delta_handler = NULL;
+      *delta_baton = NULL;
+
+      Py_XDECREF(result);
+    }
+
+error:
+
+  Py_XDECREF(py_rev_props);
+  Py_XDECREF(py_prop_diffs);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+static svn_error_t *reporter_set_path(void *report_baton,
+                           const char *path,
+                           svn_revnum_t revision,
+                           svn_boolean_t start_empty,
+                           const char *lock_token,
+                           apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+  PyObject *py_reporter = report_baton, *result;
+
+  if (py_reporter == NULL || py_reporter == Py_None)
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(py_reporter,
+                                    (char *)"set_path",
+                                    (char *)"slbsO&",
+                                    path, revision,
+                                    start_empty, lock_token,
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result != Py_None)
+    {
+      err = callback_bad_return_error("Not None");
+    }
+
+  Py_XDECREF(result);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+static svn_error_t *reporter_delete_path(void *report_baton,
+                         const char *path,
+                        apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+  PyObject *py_reporter = report_baton, *result;
+
+  if (py_reporter == NULL || py_reporter == Py_None)
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(py_reporter,
+                                    (char *)"delete_path",
+                                    (char *)"sO&",
+                                    path, 
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result != Py_None)
+    {
+      err = callback_bad_return_error("Not None");
+    }
+
+  Py_XDECREF(result);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+    
+static svn_error_t *reporter_link_path(void *report_baton,
+                            const char *path,
+                            const char *url,
+                            svn_revnum_t revision,
+                            svn_boolean_t start_empty,
+                            const char *lock_token,
+                            apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+  PyObject *py_reporter = report_baton, *result;
+
+  if (py_reporter == NULL || py_reporter == Py_None)
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(py_reporter,
+                                    (char *)"link_path",
+                                    (char *)"sslbsO&",
+                                    path, url, revision,
+                                    start_empty, lock_token,
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result != Py_None)
+    {
+      err = callback_bad_return_error("Not None");
+    }
+
+  Py_XDECREF(result);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+static svn_error_t *reporter_finish_report(void *report_baton,
+                                apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+
+  PyObject *py_reporter = report_baton, *result;
+
+  if (py_reporter == NULL || py_reporter == Py_None)
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(py_reporter,
+                                    (char *)"finish_report",
+                                    (char *)"O&",
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result != Py_None)
+    {
+      err = callback_bad_return_error("Not None");
+    }
+
+  Py_XDECREF(result);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+static svn_error_t *reporter_abort_report(void *report_baton,
+                               apr_pool_t *pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+
+  PyObject *py_reporter = report_baton, *result;
+
+  if (py_reporter == NULL || py_reporter == Py_None)
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallMethod(py_reporter,
+                                    (char *)"abort_report",
+                                    (char *)"O&",
+                                    make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else if (result != Py_None)
+    {
+      err = callback_bad_return_error("Not None");
+    }
+
+  Py_XDECREF(result);
+
+  svn_swig_py_release_py_lock();
+
+  return err;
+}
+
+const svn_ra_reporter2_t swig_py_ra_reporter2 = {
+    reporter_set_path,
+    reporter_delete_path,
+    reporter_link_path,
+    reporter_finish_report,
+    reporter_abort_report
+};
--- a/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
+++ b/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
@@ -79,6 +79,9 @@
 SVN_SWIG_SWIGUTIL_EXPORT
 void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool);
 
+/* Set a Python 'owned' reference on the pool of the given proxy object */
+int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef, PyObject 
*newRef);
+
 
 /*** SWIG Wrappers ***/
 
@@ -198,6 +201,11 @@
                              svn_wc_notify_state_t prop_state,
                              svn_revnum_t revision);
 
+SVN_SWIG_SWIGUTIL_EXPORT
+void svn_swig_py_notify_func2(void *baton,
+                              const svn_wc_notify_t *notify,
+                              apr_pool_t *pool);
+
 /* a status function that executes a Python function that is passed in
    via the baton argument */
 SVN_SWIG_SWIGUTIL_EXPORT
@@ -256,6 +264,13 @@
                                             const svn_info_t *info,
                                             apr_pool_t *pool);
 
+/* thunked info receiver function */
+SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t *svn_swig_py_info_receiver_func(void *py_receiver,
+                                            const char *path,
+                                            const svn_info_t *info,
+                                            apr_pool_t *pool);
+
 /* thunked blame receiver function */
 SVN_SWIG_SWIGUTIL_EXPORT
 svn_error_t *svn_swig_py_client_blame_receiver_func(void *baton,
@@ -310,6 +325,45 @@
     svn_boolean_t may_save,
     apr_pool_t *pool);
 
+SVN_SWIG_SWIGUTIL_EXPORT
+void
+svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks,
+                               void **baton,
+                               PyObject *py_callbacks,
+                               apr_pool_t *pool);
+SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info,
+                                          void *baton,
+                                          apr_pool_t *pool);
+
+SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision,
+                                         const char *date,
+                                         const char *author,
+                                         void *baton);
+
+
+SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t *svn_swig_py_ra_file_rev_handler_func(
+                    void *baton,
+                    const char *path,
+                    svn_revnum_t rev,
+                    apr_hash_t *rev_props,
+                    svn_txdelta_window_handler_t *delta_handler,
+                    void **delta_baton,
+                    apr_array_header_t *prop_diffs,
+                    apr_pool_t *pool);
+
+SVN_SWIG_SWIGUTIL_EXPORT
+extern const svn_ra_reporter2_t swig_py_ra_reporter2;
+
+SVN_SWIG_SWIGUTIL_EXPORT
+void
+svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks,
+                               void **baton,
+                               PyObject *py_callbacks,
+                               apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/subversion/bindings/swig/python/tests/client.py
+++ b/subversion/bindings/swig/python/tests/client.py
@@ -1,9 +1,9 @@
-import unittest, os
+import unittest, os, tempfile, types
 
-from svn import core, repos, fs, delta, client
+from svn import core, repos, fs, delta, client, wc
 
 from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
-  REPOS_PATH, REPOS_URL
+  REPOS_PATH
 from urllib import pathname2url
 
 class SubversionRepositoryTestCase(unittest.TestCase):
@@ -19,6 +19,7 @@
     ]
 
     self.client_ctx.auth_baton = core.svn_auth_open(providers)
+    self.repos_url = "file://" + pathname2url(REPOS_PATH)
 
   def info_receiver(self, path, info, pool):
     """Squirrel away the output from 'svn info' so that the unit tests
@@ -26,22 +27,80 @@
     self.path = path
     self.info = info
 
+  def test_checkout(self):
+    """Test svn_client_checkout2."""
+
+    rev = core.svn_opt_revision_t()
+    rev.kind = core.svn_opt_revision_head
+
+    path = os.path.join(tempfile.gettempdir(), 'checkout')
+
+    self.assertRaises(ValueError, client.checkout2, 
+                      self.repos_url, path, None, None, True, True, 
+                      self.client_ctx)
+
+    client.checkout2(self.repos_url, path, rev, rev, True, True, 
+            self.client_ctx)
+
   def test_info(self):
     """Test scope of get_logs callbacks"""
 
     # Run info
     revt = core.svn_opt_revision_t()
     revt.kind = core.svn_opt_revision_head
-    client.info(REPOS_URL, revt, revt, self.info_receiver,
+    repos_url = "file://" + pathname2url(REPOS_PATH)
+    client.info(repos_url, revt, revt, self.info_receiver,
                 False, self.client_ctx)
 
     # Check output from running info. This also serves to verify that
     # the internal 'info' object is still valid
     self.assertEqual(self.path, os.path.basename(REPOS_PATH))
     self.info.assert_valid()
-    self.assertEqual(self.info.URL, REPOS_URL)
-    self.assertEqual(self.info.repos_root_URL, REPOS_URL)
+    self.assertEqual(self.info.URL, repos_url)
+    self.assertEqual(self.info.repos_root_URL, repos_url)
+
+
+  def test_uuid_from_url(self):
+    """Test svn_client_uuid_from_url on a file:// URL"""
+    self.assert_(isinstance(
+                 client.uuid_from_url(self.repos_url, self.client_ctx),
+                 types.StringTypes))
 
+  def test_url_from_path(self):
+    """Test svn_client_url_from_path for a file:// URL"""
+    self.assertEquals(client.url_from_path(self.repos_url), self.repos_url)
+
+    rev = core.svn_opt_revision_t()
+    rev.kind = core.svn_opt_revision_head
+
+    path = os.path.join(tempfile.gettempdir(), 'url_from_path')
+
+    client.checkout2(self.repos_url, path, rev, rev, True, True, 
+                     self.client_ctx)
+
+    self.assertEquals(client.url_from_path(path), self.repos_url)
+
+  def test_uuid_from_path(self):
+    """Test svn_client_uuid_from_path."""
+    rev = core.svn_opt_revision_t()
+    rev.kind = core.svn_opt_revision_head
+
+    path = os.path.join(tempfile.gettempdir(), 'uuid_from_path')
+
+    client.checkout2(self.repos_url, path, rev, rev, True, True, 
+                     self.client_ctx)
+
+    wc_adm = wc.adm_open3(None, path, False, 0, None)
+
+    self.assertEquals(client.uuid_from_path(path, wc_adm, self.client_ctx), 
+                      client.uuid_from_url(self.repos_url, self.client_ctx))
+
+    self.assert_(isinstance(client.uuid_from_path(path, wc_adm, 
+                            self.client_ctx), types.StringTypes))
+
+  def test_open_ra_session(self):
+      """Test svn_client_open_ra_session()."""
+      client.open_ra_session(self.repos_url, self.client_ctx)
 
 def suite():
     return unittest.makeSuite(SubversionRepositoryTestCase, 'test',
--- a/subversion/bindings/swig/python/tests/ra.py
+++ b/subversion/bindings/swig/python/tests/ra.py
@@ -0,0 +1,136 @@
+import unittest, os
+
+from svn import core, repos, fs, delta, client, ra
+
+from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
+  REPOS_PATH
+from urllib import pathname2url
+
+class SubversionRepositoryTestCase(unittest.TestCase):
+  """Test cases for the Subversion repository layer"""
+
+  def setUp(self):
+    """Load a Subversion repository"""
+
+    ra.initialize()
+
+    self.repos_url = "file://" + pathname2url(REPOS_PATH)
+    
+    # Open repository directly for cross-checking
+    self.repos = repos.open(REPOS_PATH)
+    self.fs = repos.fs(self.repos)
+
+    callbacks = ra.callbacks2_t()
+
+    self.ra_ctx = ra.open2(self.repos_url, callbacks, None, None)
+
+  def test_get_repos_root(self):
+    root = ra.get_repos_root(self.ra_ctx)
+    self.assertEqual(root,self.repos_url)
+
+  def test_get_uuid(self):
+    ra_uuid = ra.get_uuid(self.ra_ctx)
+    fs_uuid = fs.get_uuid(self.fs)
+    self.assertEqual(ra_uuid,fs_uuid)
+
+  def test_get_lastest_revnum(self):
+    ra_revnum = ra.get_latest_revnum(self.ra_ctx)
+    fs_revnum = fs.youngest_rev(self.fs)
+    self.assertEqual(ra_revnum,fs_revnum)
+
+  def test_get_dir(self):
+    (dirents,_,props) = ra.get_dir(self.ra_ctx, '', 1)
+    self.assert_(dirents.has_key('trunk'))
+    self.assert_(dirents.has_key('branches'))
+    self.assert_(dirents.has_key('tags'))
+    self.assertEqual(dirents['trunk'].kind, core.svn_node_dir)
+    self.assertEqual(dirents['branches'].kind, core.svn_node_dir)
+    self.assertEqual(dirents['tags'].kind, core.svn_node_dir)
+    self.assert_(props.has_key(core.SVN_PROP_ENTRY_UUID))
+    self.assert_(props.has_key(core.SVN_PROP_ENTRY_LAST_AUTHOR))
+
+    (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 1)
+
+    self.assertEqual(dirents, {})
+
+    (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 10)
+
+    self.assert_(dirents.has_key('README2.txt'))
+    self.assertEqual(dirents['README2.txt'].kind,core.svn_node_file)
+
+  def test_commit(self):
+    def my_callback(revision, date, author, baton):
+        self.assertEqual(info.revision, fs.youngest_rev(self.fs))
+
+    editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", 
my_callback, None, False)
+    root = delta.editor_invoke_open_root(editor, edit_baton, 4)
+    child = delta.editor_invoke_add_directory(editor, "bla", root, None, 0)
+    delta.editor_invoke_close_edit(editor, edit_baton)
+
+  def test_commit(self):
+    def my_callback(revision, date, author):
+        self.assertEqual(revision, fs.youngest_rev(self.fs))
+
+    editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", 
my_callback, None, False)
+    root = delta.editor_invoke_open_root(editor, edit_baton, 4)
+    child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0)
+    delta.editor_invoke_close_edit(editor, edit_baton)
+
+  def test_commit(self):
+    def my_callback(revision, date, author):
+        self.assertEqual(revision, fs.youngest_rev(self.fs))
+
+    editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", 
my_callback, None, False)
+    root = delta.editor_invoke_open_root(editor, edit_baton, 4)
+    child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0)
+    delta.editor_invoke_close_edit(editor, edit_baton)
+
+  def test_get_locations(self):
+    locations = ra.get_locations(self.ra_ctx, "/trunk/README.txt", 2, 
range(1,5))
+    self.assertEqual(locations, {
+        2: '/trunk/README.txt', 
+        3: '/trunk/README.txt', 
+        4: '/trunk/README.txt'})
+
+  def test_get_file_revs(self):
+    def rev_handler(path, rev, rev_props, prop_diffs, pool):
+        self.assert_(rev == 2 or rev == 3)
+        self.assertEqual(path, "/trunk/README.txt")
+        if rev == 2:
+            self.assertEqual(rev_props, {
+              'svn:log': 'Added README.',
+              'svn:author': 'john',
+              'svn:date': '2005-04-01T13:12:18.216267Z'
+            })
+            self.assertEqual(prop_diffs, {})
+        elif rev == 3:
+            self.assertEqual(rev_props, {
+              'svn:log': 'Fixed README.\n',
+              'svn:author': 'kate',
+              'svn:date': '2005-04-01T13:24:58.234643Z'
+            })
+            self.assertEqual(prop_diffs, {'svn:mime-type': 'text/plain', 
'svn:eol-style': 'native'})
+
+    ra.get_file_revs(self.ra_ctx, "trunk/README.txt", 0, 10, rev_handler)
+
+  def test_update(self):
+    class TestEditor(delta.Editor):
+        pass
+
+    editor = TestEditor()
+
+    e_ptr, e_baton = delta.make_editor(editor)
+    
+    reporter, reporter_baton = ra.do_update(self.ra_ctx, 10, "", True, e_ptr, 
e_baton)
+
+    ra.reporter2_invoke_set_path(reporter, reporter_baton, "", 0, True, None)
+
+    ra.reporter2_invoke_finish_report(reporter, reporter_baton)
+
+def suite():
+    return unittest.makeSuite(SubversionRepositoryTestCase, 'test',
+                              suiteClass=SubversionRepositoryTestSetup)
+
+if __name__ == '__main__':
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
--- a/subversion/bindings/swig/python/tests/run_all.py
+++ b/subversion/bindings/swig/python/tests/run_all.py
@@ -18,6 +18,8 @@
 import pool
 import repository
 import client
+import ra
+import wc
 import trac.versioncontrol.tests
 
 # Run all tests
@@ -27,6 +29,8 @@
   suite = unittest.TestSuite()
   suite.addTest(client.suite())
   suite.addTest(pool.suite())
+  suite.addTest(ra.suite())
+  suite.addTest(wc.suite())
   suite.addTest(repository.suite())
   suite.addTest(trac.versioncontrol.tests.suite());
   return suite
--- a/subversion/bindings/swig/python/tests/wc.py
+++ b/subversion/bindings/swig/python/tests/wc.py
@@ -0,0 +1,175 @@
+import unittest, os, tempfile
+import shutil
+
+from svn import core, repos, wc, client
+from libsvn.core import SubversionException
+
+from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
+  REPOS_PATH
+from urllib import pathname2url
+
+class SubversionRepositoryTestCase(unittest.TestCase):
+  """Test cases for the Subversion working copy layer"""
+
+  def setUp(self):
+    """Load a Subversion repository"""
+
+    self.repos_url = "file://" + pathname2url(REPOS_PATH)
+    
+    # Open repository directly for cross-checking
+    self.repos = repos.open(REPOS_PATH)
+    self.fs = repos.fs(self.repos)
+
+    self.path = tempfile.mktemp()
+
+    client_ctx = client.create_context()
+    
+    rev = core.svn_opt_revision_t()
+    rev.kind = core.svn_opt_revision_head
+
+    client.checkout2(self.repos_url, self.path, rev, rev, True, True, 
+            client_ctx)
+
+    self.wc = wc.adm_open3(None, self.path, True, -1, None)
+
+  def test_entry(self):
+      wc_entry = wc.entry(self.path, self.wc, True)
+
+  def test_lock(self):
+      lock = wc.add_lock(self.path, core.svn_lock_create(core.Pool()), self.wc)
+      self.assertEqual(True, wc.adm_locked(self.wc))
+      self.assertEqual(True, wc.locked(self.path))
+      wc.remove_lock(self.path, self.wc)
+
+  def test_version(self):
+      wc.version()
+
+  def test_access_path(self):
+      self.assertEqual(self.path, wc.adm_access_path(self.wc))
+
+  def test_is_adm_dir(self):
+      self.assert_(wc.is_adm_dir(".svn"))
+      self.assert_(not wc.is_adm_dir(".foosvn"))
+
+  def test_get_adm_dir(self):
+      self.assert_(isinstance(wc.get_adm_dir(), basestring))
+
+  def test_set_adm_dir(self):
+      self.assertRaises(SubversionException, wc.set_adm_dir, ".foobar")
+      self.assert_(wc.is_adm_dir(".svn"))
+      self.assert_(not wc.is_adm_dir("_svn"))
+      self.assert_(not wc.is_adm_dir(".foobar"))
+      wc.set_adm_dir("_svn")
+      self.assert_(wc.is_adm_dir("_svn"))
+      self.assertEqual("_svn", wc.get_adm_dir())
+      wc.set_adm_dir(".svn")
+      self.assert_(not wc.is_adm_dir("_svn"))
+      self.assertEqual(".svn", wc.get_adm_dir())
+
+  def test_init_traversal_info(self):
+      wc.init_traversal_info()
+
+  def test_crawl_revisions2(self):
+      infos = []
+      set_paths = []
+
+      def notify(info, pool):
+          infos.append(info)
+
+      class MyReporter:
+          def __init__(self):
+              self._finished_report = False
+
+          def abort_report(self, pool):
+              pass
+
+          def finish_report(self, pool):
+              self._finished_report = True
+
+          def set_path(self, path, revision, start_empty, lock_token, pool):
+              set_paths.append(path)
+
+          def link_path(self, path, url, revision, start_empty, lock_token,
+                        pool):
+              pass
+
+          def delete_path(self, path, pool):
+              pass
+
+      # Remove trunk/README.txt
+      readme_path = os.path.join(self.path, "trunk", "README.txt")
+      self.assert_(os.path.exists(readme_path))
+      os.remove(readme_path)
+
+      # Restore trunk/README.txt using crawl_revision2
+      info = wc.init_traversal_info()
+      reporter = MyReporter()
+      wc.crawl_revisions2(self.path, self.wc, reporter,
+                          True, True, False, notify, info)
+
+      # Check that the report finished
+      self.assert_(reporter._finished_report)
+      self.assertEqual([''], set_paths)
+      self.assertEqual(1, len(infos))
+
+      # Check content of infos object
+      [info] = infos
+      self.assertEqual(readme_path, info.path)
+      self.assertEqual(core.svn_node_file, info.kind)
+      self.assertEqual(-1, info.revision)
+
+  def test_create_notify(self):
+      wc.create_notify(self.path, wc.notify_add)
+
+  def test_check_wc(self):
+      self.assert_(wc.check_wc(self.path) > 0)
+
+  def test_get_ancestry(self):
+      self.assertEqual([self.repos_url, 12], 
+                       wc.get_ancestry(self.path, self.wc))
+
+  def test_status(self):
+      wc.status2(self.path, self.wc)
+
+  def test_is_normal_prop(self):
+      self.failIf(wc.is_normal_prop('svn:wc:foo:bar'))
+      self.failIf(wc.is_normal_prop('svn:entry:foo:bar'))
+      self.assert_(wc.is_normal_prop('svn:foo:bar'))
+      self.assert_(wc.is_normal_prop('foreign:foo:bar'))
+
+  def test_is_wc_prop(self):
+      self.assert_(wc.is_wc_prop('svn:wc:foo:bar'))
+      self.failIf(wc.is_wc_prop('svn:entry:foo:bar'))
+      self.failIf(wc.is_wc_prop('svn:foo:bar'))
+      self.failIf(wc.is_wc_prop('foreign:foo:bar'))
+
+  def test_is_entry_prop(self):
+      self.assert_(wc.is_entry_prop('svn:entry:foo:bar'))
+      self.failIf(wc.is_entry_prop('svn:wc:foo:bar'))
+      self.failIf(wc.is_entry_prop('svn:foo:bar'))
+      self.failIf(wc.is_entry_prop('foreign:foo:bar'))
+
+  def test_get_pristine_copy_path(self):
+      self.assertEqual(
+        wc.get_pristine_copy_path(os.path.join(self.path, 'foo')),
+        os.path.join(self.path, wc.get_adm_dir(), 'text-base', 'foo.svn-base'))
+
+  def test_get_ignores(self):
+      self.assert_(isinstance(wc.get_ignores(None, self.wc), list))
+
+  def test_entries_read(self):
+      entries = wc.entries_read(self.wc, True)
+        
+      self.assertEqual(['', 'tags', 'branches', 'trunk'], entries.keys())
+
+  def tearDown(self):
+      wc.adm_close(self.wc)
+      shutil.rmtree(self.path)
+
+def suite():
+    return unittest.makeSuite(SubversionRepositoryTestCase, 'test',
+                              suiteClass=SubversionRepositoryTestSetup)
+
+if __name__ == '__main__':
+    runner = unittest.TextTestRunner()
+    runner.run(suite())
--- a/subversion/bindings/swig/svn_client.i
+++ b/subversion/bindings/swig/svn_client.i
@@ -25,6 +25,7 @@
 #endif
 
 %include typemaps.i
+%include constraints.i
 
 %include svn_global.swg
 %import core.i
@@ -49,6 +50,11 @@
   svn_client_ctx_t **
 };
 
+%apply Pointer NONNULL { 
+  const svn_opt_revision_t *revision,
+  const svn_opt_revision_t *peg_revision
+};
+
 %apply const apr_array_header_t *STRINGLIST {
     const apr_array_header_t *targets,
     const apr_array_header_t *diff_options
@@ -71,6 +77,16 @@
 
 #ifdef SWIGPYTHON
 %apply svn_stream_t *WRAPPED_STREAM { svn_stream_t * };
+
+/* members of svn_client_ctx_t */
+%apply void *PY_AS_VOID {
+    void *notify_baton,
+    void *log_msg_baton,
+    void *cancel_baton,
+    void *notify_baton2,
+    void *log_msg_baton2,
+    void *progress_baton
+};
 #endif
 
 /* -----------------------------------------------------------------------
@@ -240,6 +256,18 @@
 }
 
 /* -----------------------------------------------------------------------
+   Callback: svn_info_receiver_t
+   svn_client_info()
+*/
+
+%typemap(python, in) (svn_info_receiver_t receiver, 
+                      void *receiver_baton) {
+    $1 = svn_swig_py_info_receiver_func;
+    $2 = (void *)$input;
+}
+
+
+/* -----------------------------------------------------------------------
    We use 'svn_wc_status_t *' in some custom code, but it isn't in the
    API anywhere. Thus, SWIG doesn't generate a typemap entry for it. by
    adding a simple declaration here, SWIG will insert a name for it.
@@ -498,6 +526,15 @@
 %include svn_time_h.swg
 %include svn_client_h.swg
 
+#ifdef SWIGPYTHON
+
+/* provide Python with access to some thunks. */
+%constant svn_cancel_func_t svn_swig_py_cancel_func;
+%constant svn_client_get_commit_log2_t svn_swig_py_get_commit_log_func;
+%constant svn_wc_notify_func2_t svn_swig_py_notify_func;
+
+#endif
+
 #ifdef SWIGRUBY
 %inline %{
 static VALUE
--- a/subversion/bindings/swig/svn_delta.i
+++ b/subversion/bindings/swig/svn_delta.i
@@ -47,7 +47,8 @@
     const char *error_info,
     const char *copyfrom_path,
     const char *copy_path,
-    const char *base_checksum
+    const char *base_checksum,
+    const char *text_checksum
 };
 
 #ifdef SWIGPYTHON
@@ -148,6 +149,17 @@
 #endif
 %}
 
+#ifdef SWIGPYTHON
+%inline %{
+svn_error_t *svn_delta_invoke_txdelta_window_handler (
+  svn_txdelta_window_handler_t handler,
+  svn_txdelta_window_t *window, void *baton) {
+  return handler(window, baton);
+}
+%}
+#endif
+
+
 /* -----------------------------------------------------------------------
    handle svn_txdelta_window_t::ops
 */
--- a/subversion/bindings/swig/svn_ra.i
+++ b/subversion/bindings/swig/svn_ra.i
@@ -25,6 +25,7 @@
 #endif
 
 %include typemaps.i
+%include constraints.i
 
 %include svn_global.swg
 %import apr.swg
@@ -49,10 +50,12 @@
     const svn_ra_reporter2_t **reporter,
     void **report_baton,
     svn_dirent_t **dirent,
-    svn_lock_t **lock
+    svn_lock_t **lock,
+    const svn_delta_editor_t **
 };
 
 %apply apr_hash_t **PROPHASH { apr_hash_t **props };
+%apply apr_hash_t **DIRENTHASH { apr_hash_t **dirents };
 
 %apply const char *MAY_BE_NULL {
     const char *comment,
@@ -120,6 +123,11 @@
   svn_swig_rb_setup_ra_callbacks(&$1, &$2, $input, _global_pool);
 }
 
+%typemap(python, in) (const svn_ra_callbacks2_t *callbacks, 
+                      void *callback_baton) {
+  svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool);
+}
+
 %typemap(perl5, in) apr_hash_t *config {
     $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *",
                                           _global_pool);
@@ -142,6 +150,18 @@
   $1 = svn_swig_rb_hash_to_apr_hash_revnum($input, _global_pool);
 }
 
+%typemap(python, in) (svn_ra_file_rev_handler_t handler, void *handler_baton)
+{
+   $1 = svn_swig_py_ra_file_rev_handler_func;
+   $2 = (void *)$input;
+}
+
+%typemap(python, in) (const svn_ra_reporter2_t *reporter, void *report_baton)
+{
+  $1 = (svn_ra_reporter2_t *)&swig_py_ra_reporter2;
+  $2 = (void *)$input;
+}
+
 /* ----------------------------------------------------------------------- */
 
 %{
--- a/subversion/bindings/swig/svn_wc.i
+++ b/subversion/bindings/swig/svn_wc.i
@@ -226,6 +226,18 @@
   }
 }
 
+%typemap(python, in, numinputs=0)
+     apr_array_header_t **patterns (apr_array_header_t *temp)
+{
+  $1 = &temp;
+}
+%typemap(python, argout, fragment="t_output_helper")
+     apr_array_header_t **patterns
+{
+  $result = t_output_helper($result,
+                          svn_swig_py_array_to_list(*$1));
+}
+
 /* -----------------------------------------------------------------------
    Callback: svn_wc_notify_func_t
    svn_client_ctx_t
@@ -272,6 +284,11 @@
   $2 = $input; /* our function is the baton. */
 }
 
+%typemap(python,in) (svn_wc_notify_func2_t notify_func, void *notify_baton) {
+   $1 = svn_swig_py_notify_func2;
+   $2 = $input; /* our function is the baton. */
+}
+
 %typemap(perl5,in) (svn_wc_status_func_t status_func, void *status_baton) {
   $1 = svn_swig_pl_status_func;
   $2 = $input; /* our function is the baton. */

Reply via email to