subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From futat...@apache.org
Subject svn commit: r1852967 - /subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
Date Tue, 05 Feb 2019 07:05:40 GMT
Author: futatuki
Date: Tue Feb  5 07:05:40 2019
New Revision: 1852967

URL: http://svn.apache.org/viewvc?rev=1852967&view=rev
Log:
On branch swig-py3: A follow up r1851888: Save/restore Python error indicator

For all callback APIs which don't return svn_error_t * cannot notify
Python exception their caller, and as exceptions chain in Python 3,
exception conext should be detached from caller. 

* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
 (svn_swig_py_notify_func, svn_swig_py_notify_func2,
  svn_swig_py_status_func, svn_swig_py_client_status_func,
  svn_swig_py_status_func2, ra_callbacks_progress_func,
  svn_swig_py_config_enumerator2, svn_swig_py_config_section_enumerator2):
  Save error indicator before Python function call and then restore it
  after call

Modified:
    subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1852967&r1=1852966&r2=1852967&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
(original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
Tue Feb  5 07:05:40 2019
@@ -2767,11 +2767,18 @@ void svn_swig_py_notify_func(void *baton
   PyObject *function = baton;
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   if (function == NULL || function == Py_None)
     return;
 
   svn_swig_py_acquire_py_lock();
+
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
 #if IS_PY3
                                       (char *)"(yiiyiii)",
@@ -2796,6 +2803,9 @@ void svn_swig_py_notify_func(void *baton
   /* Our error has no place to go. :-( */
   svn_error_clear(err);
 
+  /* Also, restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
   svn_swig_py_release_py_lock();
 }
 
@@ -2807,12 +2817,18 @@ void svn_swig_py_notify_func2(void *bato
   PyObject *function = baton;
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   if (function == NULL || function == Py_None)
     return;
 
   svn_swig_py_acquire_py_lock();
 
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
                                       (char *)"(O&O&)",
                                       make_ob_wc_notify, notify,
@@ -2831,6 +2847,9 @@ void svn_swig_py_notify_func2(void *bato
   /* Our error has no place to go. :-( */
   svn_error_clear(err);
 
+  /* Also, restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
   svn_swig_py_release_py_lock();
 }
 
@@ -2841,11 +2860,18 @@ void svn_swig_py_status_func(void *baton
   PyObject *function = baton;
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   if (function == NULL || function == Py_None)
     return;
 
   svn_swig_py_acquire_py_lock();
+
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
                                       (char *)SVN_SWIG_BYTES_FMT "O&", path,
                                       make_ob_wc_status, status)) == NULL)
@@ -2863,6 +2889,9 @@ void svn_swig_py_status_func(void *baton
   /* Our error has no place to go. :-( */
   svn_error_clear(err);
 
+  /* Also, restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
   svn_swig_py_release_py_lock();
 }
 
@@ -2874,11 +2903,18 @@ void svn_swig_py_client_status_func(void
   PyObject *function = baton;
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   if (function == NULL || function == Py_None)
     return;
 
   svn_swig_py_acquire_py_lock();
+
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
 #if IS_PY3
                                       (char *)"yO&O&",
@@ -2902,6 +2938,9 @@ void svn_swig_py_client_status_func(void
   /* Our error has no place to go. :-( */
   svn_error_clear(err);
 
+  /* Also, restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
   svn_swig_py_release_py_lock();
 }
 
@@ -2965,11 +3004,18 @@ void svn_swig_py_status_func2(void *bato
   PyObject *function = baton;
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   if (function == NULL || function == Py_None)
     return;
 
   svn_swig_py_acquire_py_lock();
+
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
                                       (char *)SVN_SWIG_BYTES_FMT "O&", path,
                                       make_ob_wc_status, status)) == NULL)
@@ -2985,11 +3031,10 @@ void svn_swig_py_status_func2(void *bato
     }
 
   /* Our error has no place to go. :-( */
-  if (err)
-    {
-      svn_error_clear(err);
-      PyErr_Clear();
-    }
+  svn_error_clear(err);
+
+  /* Also, restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
 
   svn_swig_py_release_py_lock();
 }
@@ -4230,11 +4275,17 @@ ra_callbacks_progress_func(apr_off_t pro
 {
   PyObject *callbacks = (PyObject *)baton;
   PyObject *py_callback, *py_progress, *py_total, *result;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   py_progress = py_total = NULL;
 
   svn_swig_py_acquire_py_lock();
 
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   py_callback = PyObject_GetAttrString(callbacks,
                                        (char *)"progress_func");
   if (py_callback == NULL)
@@ -4274,6 +4325,9 @@ ra_callbacks_progress_func(apr_off_t pro
 
   Py_XDECREF(result);
 finished:
+  /* Restore error indicator */
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
   Py_XDECREF(py_callback);
   Py_XDECREF(py_progress);
   Py_XDECREF(py_total);
@@ -5134,9 +5188,15 @@ svn_swig_py_config_enumerator2(const cha
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
   svn_boolean_t c_result;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   svn_swig_py_acquire_py_lock();
 
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
 #if IS_PY3
                                       (char *)"yyO&",
@@ -5158,7 +5218,7 @@ svn_swig_py_config_enumerator2(const cha
   /* Any Python exception we might have pending must be cleared,
      because the SWIG wrapper will not check for it, and return a value with
      the exception still set. */
-  PyErr_Clear();
+  PyErr_Restore(exc_type, exc, exc_traceback);
 
   if (err)
     {
@@ -5186,9 +5246,15 @@ svn_swig_py_config_section_enumerator2(c
   PyObject *result;
   svn_error_t *err = SVN_NO_ERROR;
   svn_boolean_t c_result;
+  PyObject *exc, *exc_type, *exc_traceback;
 
   svn_swig_py_acquire_py_lock();
 
+  /* As caller can't understand Python context and we can't notify if
+     Python call back function raise exception to caller, we must catch it
+     if it is occurred, and restore error indicator */
+  PyErr_Fetch(&exc_type, &exc, &exc_traceback);
+
   if ((result = PyObject_CallFunction(function,
                                       (char *)SVN_SWIG_BYTES_FMT "O&",
                                       name,
@@ -5205,7 +5271,8 @@ svn_swig_py_config_section_enumerator2(c
   /* Any Python exception we might have pending must be cleared,
      because the SWIG wrapper will not check for it, and return a value with
      the exception still set. */
-  PyErr_Clear();
+  PyErr_Restore(exc_type, exc, exc_traceback);
+
 
   if (err)
     {



Mime
View raw message