You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2022/01/14 14:01:51 UTC
svn commit: r1897034 [8/37] - in /subversion/branches/multi-wc-format: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contrib/hook-scripts/ contrib/se...
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Fri Jan 14 14:01:45 2022
@@ -23,9 +23,18 @@
/* Tell swigutil_py.h that we're inside the implementation */
#define SVN_SWIG_SWIGUTIL_PY_C
+/* Avoid deprecation warnings about PY_SSIZE_T_CLEAN since Python 3.8 */
+#define PY_SSIZE_T_CLEAN
+
+#if defined(_MSC_VER)
+/* Prevent "non-constant aggregate initializer" errors from Python.h in
+ * Python 3.9 */
+# pragma warning(default : 4204)
+#endif
#include <Python.h>
+
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -46,10 +55,23 @@
#include "svn_mergeinfo.h"
#include "svn_types.h"
-#include "svn_private_config.h" /* for SVN_APR_INT64_T_PYCFMT */
+#include "svn_private_config.h"
#include "swig_python_external_runtime.swg"
#include "swigutil_py.h"
+#include "swigutil_py3c.h"
+
+#if IS_PY3
+
+/* In Python 3 use the bytes format character for raw data */
+#define SVN_SWIG_BYTES_FMT "y"
+
+#else
+
+/* In Python 2 use the string format character for raw data */
+#define SVN_SWIG_BYTES_FMT "s"
+
+#endif
/* Py_ssize_t for old Pythons */
/* This code is as recommended by: */
@@ -142,6 +164,35 @@ apr_status_t svn_swig_py_initialize(void
return APR_SUCCESS;
}
+FILE *svn_swig_py_as_file(PyObject *pyfile)
+{
+#if IS_PY3
+ FILE *fp = NULL;
+ int fd = PyObject_AsFileDescriptor(pyfile);
+ if (fd >= 0)
+ {
+ PyObject *mode_obj;
+ PyObject *mode_byte_obj = NULL;
+ char *mode = NULL;
+
+ /* If any Python API returns NULL, then the Python exception is set and
+ this function will return NULL signifying to the caller that an error
+ occurred. */
+ if ( NULL != (mode_obj = PyObject_GetAttrString(pyfile, "mode"))
+ && NULL != (mode_byte_obj = PyUnicode_AsUTF8String(mode_obj))
+ && NULL != (mode = PyBytes_AsString(mode_byte_obj)))
+ fp = fdopen(fd, mode);
+
+ Py_XDECREF(mode_obj);
+ Py_XDECREF(mode_byte_obj);
+ }
+
+ return fp;
+#else
+ return PyFile_AsFile(pyfile);
+#endif
+}
+
int svn_swig_py_get_pool_arg(PyObject *args, swig_type_info *type,
PyObject **py_pool, apr_pool_t **pool)
{
@@ -150,14 +201,25 @@ int svn_swig_py_get_pool_arg(PyObject *a
if (argnum >= 0)
{
PyObject *input = PyTuple_GET_ITEM(args, argnum);
- if (input != Py_None && PyObject_HasAttrString(input, markValid))
+ if (input != Py_None)
{
- *pool = svn_swig_py_must_get_ptr(input, type, argnum+1);
- if (*pool == NULL)
- return 1;
- *py_pool = input;
- Py_INCREF(input);
- return 0;
+ PyObject *fn;
+ if (NULL != (fn = PyObject_GetAttrString(input, markValid)))
+ {
+ Py_DECREF(fn);
+
+ *pool = svn_swig_py_must_get_ptr(input, type, argnum+1);
+ if (*pool == NULL)
+ return 1;
+ *py_pool = input;
+ Py_INCREF(input);
+ return 0;
+ }
+ else
+ {
+ /* Clear any getattr() error, it isn't needed. */
+ PyErr_Clear();
+ }
}
}
@@ -221,13 +283,20 @@ static int proxy_set_pool(PyObject **pro
{
if (pool == NULL)
{
- if (PyObject_HasAttrString(*proxy, setParentPool))
+ PyObject *setFn;
+ if (NULL != (setFn = PyObject_GetAttrString(*proxy, setParentPool)))
{
- result = PyObject_CallMethod(*proxy, setParentPool, emptyTuple);
+ result = PyObject_CallObject(setFn, NULL);
+ Py_DECREF(setFn);
if (result == NULL)
return 1;
Py_DECREF(result);
}
+ else
+ {
+ /* Clear any getattr() error, it isn't needed. */
+ PyErr_Clear();
+ }
}
else
{
@@ -285,23 +354,45 @@ static PyObject *svn_swig_NewPointerObjS
return svn_swig_py_new_pointer_obj(ptr, typeinfo, py_pool, NULL);
}
-/** Wrapper for SWIG_ConvertPtr */
-int svn_swig_py_convert_ptr(PyObject *input, void **obj, swig_type_info *type)
+static int svn_swig_ensure_valid_swig_wrapper(PyObject *input)
{
- if (PyObject_HasAttrString(input, assertValid))
+ PyObject *assertFn;
+ PyObject *unwrapFn;
+ if (NULL != (assertFn = PyObject_GetAttrString(input, assertValid)))
{
- PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple);
+ PyObject *result = PyObject_CallObject(assertFn, NULL);
+ Py_DECREF(assertFn);
if (result == NULL)
return 1;
Py_DECREF(result);
}
- if (PyObject_HasAttrString(input, unwrap))
+ else
+ {
+ /* Clear any getattr() error, it isn't needed. */
+ PyErr_Clear();
+ }
+ if (NULL != (unwrapFn = PyObject_GetAttrString(input, unwrap)))
{
- input = PyObject_CallMethod(input, unwrap, emptyTuple);
+ input = PyObject_CallObject(unwrapFn, NULL);
+ Py_DECREF(unwrapFn);
if (input == NULL)
return 1;
Py_DECREF(input);
}
+ else
+ {
+ /* Clear any getattr() error, it isn't needed. */
+ PyErr_Clear();
+ }
+
+ return 0;
+}
+
+/** Wrapper for SWIG_ConvertPtr */
+int svn_swig_py_convert_ptr(PyObject *input, void **obj, swig_type_info *type)
+{
+ if (svn_swig_ensure_valid_swig_wrapper(input))
+ return 1;
return SWIG_ConvertPtr(input, obj, type, SWIG_POINTER_EXCEPTION | 0);
}
@@ -316,21 +407,8 @@ static int svn_swig_ConvertPtrString(PyO
/** Wrapper for SWIG_MustGetPtr */
void *svn_swig_py_must_get_ptr(void *input, swig_type_info *type, int argnum)
{
- if (PyObject_HasAttrString(input, assertValid))
- {
- PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple);
- if (result == NULL)
- return NULL;
- Py_DECREF(result);
- }
-
- if (PyObject_HasAttrString(input, unwrap))
- {
- input = PyObject_CallMethod(input, unwrap, emptyTuple);
- if (input == NULL)
- return NULL;
- Py_DECREF((PyObject *) input);
- }
+ if (svn_swig_ensure_valid_swig_wrapper(input))
+ return NULL;
return SWIG_MustGetPtr(input, type, argnum, SWIG_POINTER_EXCEPTION | 0);
}
@@ -339,10 +417,12 @@ void *svn_swig_py_must_get_ptr(void *inp
/*** Custom SubversionException stuffs. ***/
-void svn_swig_py_svn_exception(svn_error_t *error_chain)
+void svn_swig_py_build_svn_exception(PyObject **exc_class,
+ PyObject **exc_ob,
+ svn_error_t *error_chain)
{
PyObject *args_list, *args, *apr_err_ob, *message_ob, *file_ob, *line_ob;
- PyObject *svn_module, *exc_class, *exc_ob;
+ PyObject *svn_module;
svn_error_t *err;
if (error_chain == NULL)
@@ -350,7 +430,7 @@ void svn_swig_py_svn_exception(svn_error
/* Start with no references. */
args_list = args = apr_err_ob = message_ob = file_ob = line_ob = NULL;
- svn_module = exc_class = exc_ob = NULL;
+ svn_module = *exc_class = *exc_ob = NULL;
if ((args_list = PyList_New(0)) == NULL)
goto finished;
@@ -370,14 +450,14 @@ void svn_swig_py_svn_exception(svn_error
Py_INCREF(Py_None);
message_ob = Py_None;
}
- else if ((message_ob = PyString_FromString(err->message)) == NULL)
+ else if ((message_ob = PyStr_FromString(err->message)) == NULL)
goto finished;
if (err->file == NULL)
{
Py_INCREF(Py_None);
file_ob = Py_None;
}
- else if ((file_ob = PyString_FromString(err->file)) == NULL)
+ else if ((file_ob = PyStr_FromString(err->file)) == NULL)
goto finished;
if ((line_ob = PyInt_FromLong(err->line)) == NULL)
goto finished;
@@ -409,15 +489,12 @@ void svn_swig_py_svn_exception(svn_error
/* Create the exception object chain. */
if ((svn_module = PyImport_ImportModule((char *)"svn.core")) == NULL)
goto finished;
- if ((exc_class = PyObject_GetAttrString(svn_module,
- (char *)"SubversionException")) == NULL)
- goto finished;
- if ((exc_ob = PyObject_CallMethod(exc_class, (char *)"_new_from_err_list",
- (char *)"O", args_list)) == NULL)
- goto finished;
-
- /* Raise the exception. */
- PyErr_SetObject(exc_class, exc_ob);
+ if ((*exc_class = PyObject_GetAttrString(svn_module,
+ (char *)"SubversionException")) != NULL)
+ {
+ *exc_ob = PyObject_CallMethod(*exc_class, (char *)"_new_from_err_list",
+ (char *)"O", args_list);
+ }
finished:
/* Release any references. */
@@ -428,14 +505,66 @@ void svn_swig_py_svn_exception(svn_error
Py_XDECREF(file_ob);
Py_XDECREF(line_ob);
Py_XDECREF(svn_module);
- Py_XDECREF(exc_class);
- Py_XDECREF(exc_ob);
+}
+
+void svn_swig_py_svn_exception(svn_error_t *error_chain)
+{
+ PyObject *exc_class, *exc_ob;
+
+ /* First, we create the exception... */
+ svn_swig_py_build_svn_exception(&exc_class, &exc_ob, error_chain);
+
+ /* ...then, we raise it. If got only an exception class but no
+ instance, we'll raise the class without an instance. */
+ if (exc_class != NULL)
+ {
+ if (exc_ob != NULL)
+ {
+ PyErr_SetObject(exc_class, exc_ob);
+ Py_DECREF(exc_ob);
+ }
+ else
+ {
+ PyErr_SetNone(exc_class);
+ }
+ Py_DECREF(exc_class);
+ }
}
/*** Helper/Conversion Routines ***/
+/* Function to get char * representation of bytes/str object. This is
+ the replacement of typemap(in, parse="s") and typemap(in, parse="z")
+ to accept both of bytes object and str object, and it assumes to be
+ used from those typemaps only.
+ Note: type of return value should be char const *, however, as SWIG
+ produces variables for C function without 'const' modifier, to avoid
+ ton of cast in SWIG produced C code we drop it from return value
+ types as well */
+char *svn_swig_py_string_to_cstring(PyObject *input, int maybe_null,
+ const char * funcsym, const char * argsym)
+{
+ char *retval = NULL;
+ if (PyBytes_Check(input))
+ {
+ retval = PyBytes_AsString(input);
+ }
+ else if (PyUnicode_Check(input))
+ {
+ retval = (char *)PyStr_AsUTF8(input);
+ }
+ else if (input != Py_None || ! maybe_null)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s() argument %s must be bytes or str%s, not %s",
+ funcsym, argsym, maybe_null?" or None":"",
+ Py_TYPE(input)->tp_name);
+ }
+ return retval;
+}
+
/* Functions for making Python wrappers around Subversion structs */
static PyObject *make_ob_pool(void *pool)
{
@@ -470,32 +599,89 @@ static PyObject *make_ob_error(svn_error
/***/
+static void svn_swig_py_string_type_exception(int maybe_null)
+{
+ PyErr_Format(PyExc_TypeError, "not a bytes or a str%s",
+ maybe_null?" or None":"");
+}
+
/* Conversion from Python single objects (not hashes/lists/etc.) to
Subversion types. */
static char *make_string_from_ob(PyObject *ob, apr_pool_t *pool)
{
+ /* caller should not expect to raise TypeError: check return value
+ whether it is NULL or not, if needed */
+ if (PyBytes_Check(ob))
+ {
+ return apr_pstrdup(pool, PyBytes_AsString(ob));
+ }
+ if (PyUnicode_Check(ob))
+ {
+ /* PyStr_AsUTF8() may cause UnicodeEncodeError,
+ but apr_pstrdup() allows NULL for s */
+ return apr_pstrdup(pool, PyStr_AsUTF8(ob));
+ }
+ return NULL;
+}
+
+static char *make_string_from_ob_maybe_null(PyObject *ob, apr_pool_t *pool)
+{
+ char * retval;
if (ob == Py_None)
- return NULL;
- if (! PyString_Check(ob))
{
- PyErr_SetString(PyExc_TypeError, "not a string");
return NULL;
}
- return apr_pstrdup(pool, PyString_AS_STRING(ob));
+ retval = make_string_from_ob(ob, pool);
+ if (!retval)
+ {
+ if (!PyErr_Occurred())
+ {
+ svn_swig_py_string_type_exception(TRUE);
+ }
+ }
+ return retval;
}
+
static svn_string_t *make_svn_string_from_ob(PyObject *ob, apr_pool_t *pool)
{
+ /* caller should not expect to raise TypeError: check return value
+ whether it is NULL or not, if needed */
+ if (PyBytes_Check(ob))
+ {
+ return svn_string_create(PyBytes_AsString(ob), pool);
+ }
+ if (PyUnicode_Check(ob))
+ {
+ /* PyStr_AsUTF8() may cause UnicodeEncodeError,
+ and svn_string_create() does not allows NULL for cstring */
+ const char *obstr = PyStr_AsUTF8(ob);
+ if (obstr)
+ {
+ return svn_string_create(obstr, pool);
+ }
+ }
+ return NULL;
+}
+
+static svn_string_t *make_svn_string_from_ob_maybe_null(PyObject *ob,
+ apr_pool_t *pool)
+{
+ svn_string_t * retval;
if (ob == Py_None)
- return NULL;
- if (! PyString_Check(ob))
{
- PyErr_SetString(PyExc_TypeError, "not a string");
return NULL;
}
- return svn_string_create(PyString_AS_STRING(ob), pool);
+ retval = make_svn_string_from_ob(ob, pool);
+ if (!retval)
+ {
+ if (!PyErr_Occurred())
+ {
+ svn_swig_py_string_type_exception(TRUE);
+ }
+ }
+ return retval;
}
-
/***/
static PyObject *convert_hash(apr_hash_t *hash,
@@ -527,7 +713,7 @@ static PyObject *convert_hash(apr_hash_t
return NULL;
}
/* ### gotta cast this thing cuz Python doesn't use "const" */
- if (PyDict_SetItemString(dict, (char *)key, value) == -1)
+ if (PyDict_SetItem(dict, PyBytes_FromString((char *)key), value) == -1)
{
Py_DECREF(value);
Py_DECREF(dict);
@@ -552,11 +738,10 @@ static PyObject *convert_svn_string_t(vo
const svn_string_t *s = value;
- /* ### gotta cast this thing cuz Python doesn't use "const" */
- return PyString_FromStringAndSize((void *)s->data, s->len);
+ return PyBytes_FromStringAndSize(s->data, s->len);
}
-/* Convert a C string into a Python String object (or a reference to
+/* Convert a C string into a Python Bytes object (or a reference to
Py_None if CSTRING is NULL). */
static PyObject *cstring_to_pystring(const char *cstring)
{
@@ -566,7 +751,7 @@ static PyObject *cstring_to_pystring(con
Py_INCREF(Py_None);
return retval;
}
- return PyString_FromString(cstring);
+ return PyBytes_FromString(cstring);
}
static PyObject *convert_svn_client_commit_item3_t(void *value, void *ctx)
@@ -642,8 +827,7 @@ PyObject *svn_swig_py_prophash_to_dict(a
static PyObject *convert_string(void *value, void *ctx,
PyObject *py_pool)
{
- /* ### gotta cast this thing cuz Python doesn't use "const" */
- return PyString_FromString((const char *)value);
+ return PyBytes_FromString((const char *)value);
}
PyObject *svn_swig_py_stringhash_to_dict(apr_hash_t *hash)
@@ -725,7 +909,7 @@ svn_swig_py_propinheriteditemarray_to_di
apr_hash_t *prop_hash = prop_inherited_item->prop_hash;
PyObject *py_key, *py_value;
- py_key = PyString_FromString(prop_inherited_item->path_or_url);
+ py_key = PyBytes_FromString(prop_inherited_item->path_or_url);
if (py_key == NULL)
goto error;
@@ -769,7 +953,7 @@ PyObject *svn_swig_py_proparray_to_dict(
prop = APR_ARRAY_IDX(array, i, svn_prop_t);
- py_key = PyString_FromString(prop.name);
+ py_key = PyBytes_FromString(prop.name);
if (py_key == NULL)
goto error;
@@ -780,8 +964,8 @@ PyObject *svn_swig_py_proparray_to_dict(
}
else
{
- py_value = PyString_FromStringAndSize((void *)prop.value->data,
- prop.value->len);
+ py_value = PyBytes_FromStringAndSize(prop.value->data,
+ prop.value->len);
if (py_value == NULL)
{
Py_DECREF(py_key);
@@ -831,7 +1015,7 @@ PyObject *svn_swig_py_locationhash_to_di
Py_DECREF(dict);
return NULL;
}
- value = PyString_FromString((char *)v);
+ value = PyBytes_FromString((const char *)v);
if (value == NULL)
{
Py_DECREF(key);
@@ -881,6 +1065,7 @@ DECLARE_SWIG_CONSTRUCTOR(info, svn_info_
DECLARE_SWIG_CONSTRUCTOR(location_segment, svn_location_segment_dup)
DECLARE_SWIG_CONSTRUCTOR(commit_info, svn_commit_info_dup)
DECLARE_SWIG_CONSTRUCTOR(wc_notify, svn_wc_dup_notify)
+DECLARE_SWIG_CONSTRUCTOR(client_status, svn_client_status_dup)
static PyObject *convert_log_changed_path(void *value, void *ctx,
PyObject *py_pool)
@@ -895,7 +1080,7 @@ PyObject *svn_swig_py_c_strings_to_list(
while ((s = *strings++) != NULL)
{
- PyObject *ob = PyString_FromString(s);
+ PyObject *ob = PyBytes_FromString(s);
if (ob == NULL)
goto error;
@@ -938,7 +1123,7 @@ PyObject *svn_swig_py_changed_path_hash_
Py_DECREF(dict);
return NULL;
}
- if (PyDict_SetItemString(dict, (char *)key, value) == -1)
+ if (PyDict_SetItem(dict, PyBytes_FromString((char *)key), value) == -1)
{
Py_DECREF(value);
Py_DECREF(dict);
@@ -974,7 +1159,7 @@ PyObject *svn_swig_py_changed_path2_hash
Py_DECREF(dict);
return NULL;
}
- if (PyDict_SetItemString(dict, (char *)key, value) == -1)
+ if (PyDict_SetItem(dict, PyBytes_FromString((char *)key), value) == -1)
{
Py_DECREF(value);
Py_DECREF(dict);
@@ -986,6 +1171,9 @@ PyObject *svn_swig_py_changed_path2_hash
return dict;
}
+#define TYPE_ERROR_DICT_STRING_KEY \
+ "dictionary keys aren't bytes or str objects"
+
apr_hash_t *svn_swig_py_stringhash_from_dict(PyObject *dict,
apr_pool_t *pool)
{
@@ -1010,11 +1198,19 @@ apr_hash_t *svn_swig_py_stringhash_from_
PyObject *key = PyList_GetItem(keys, i);
PyObject *value = PyDict_GetItem(dict, key);
const char *propname = make_string_from_ob(key, pool);
- const char *propval = make_string_from_ob(value, pool);
- if (! (propname && propval))
+ const char *propval;
+ if (!propname)
+ {
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
+ Py_DECREF(keys);
+ return NULL;
+ }
+ propval = make_string_from_ob_maybe_null(value, pool);
+ if (PyErr_Occurred())
{
- PyErr_SetString(PyExc_TypeError,
- "dictionary keys/values aren't strings");
Py_DECREF(keys);
return NULL;
}
@@ -1047,17 +1243,27 @@ apr_hash_t *svn_swig_py_mergeinfo_from_d
PyObject *key = PyList_GetItem(keys, i);
PyObject *value = PyDict_GetItem(dict, key);
const char *pathname = make_string_from_ob(key, pool);
- const svn_rangelist_t *ranges = svn_swig_py_seq_to_array(value,
+ const svn_rangelist_t *ranges;
+ if (!pathname)
+ {
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
+ Py_DECREF(keys);
+ return NULL;
+ }
+ ranges = svn_swig_py_seq_to_array(value,
sizeof(const svn_merge_range_t *),
svn_swig_py_unwrap_struct_ptr,
svn_swig_TypeQuery("svn_merge_range_t *"),
pool
);
- if (! (pathname && ranges))
+ if (!ranges)
{
PyErr_SetString(PyExc_TypeError,
- "dictionary keys aren't strings or values aren't svn_merge_range_t *'s");
+ "dictionary values aren't svn_merge_range_t *'s");
Py_DECREF(keys);
return NULL;
}
@@ -1092,11 +1298,18 @@ apr_array_header_t *svn_swig_py_proparra
PyObject *value = PyDict_GetItem(dict, key);
svn_prop_t *prop = apr_palloc(pool, sizeof(*prop));
prop->name = make_string_from_ob(key, pool);
- prop->value = make_svn_string_from_ob(value, pool);
- if (! (prop->name && prop->value))
+ if (! prop->name)
+ {
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
+ Py_DECREF(keys);
+ return NULL;
+ }
+ prop->value = make_svn_string_from_ob_maybe_null(value, pool);
+ if (PyErr_Occurred())
{
- PyErr_SetString(PyExc_TypeError,
- "dictionary keys/values aren't strings");
Py_DECREF(keys);
return NULL;
}
@@ -1130,11 +1343,19 @@ apr_hash_t *svn_swig_py_prophash_from_di
PyObject *key = PyList_GetItem(keys, i);
PyObject *value = PyDict_GetItem(dict, key);
const char *propname = make_string_from_ob(key, pool);
- svn_string_t *propval = make_svn_string_from_ob(value, pool);
- if (! (propname && propval))
+ svn_string_t *propval;
+ if (!propname)
+ {
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
+ Py_DECREF(keys);
+ return NULL;
+ }
+ propval = make_svn_string_from_ob_maybe_null(value, pool);
+ if (PyErr_Occurred())
{
- PyErr_SetString(PyExc_TypeError,
- "dictionary keys/values aren't strings");
Py_DECREF(keys);
return NULL;
}
@@ -1172,8 +1393,10 @@ apr_hash_t *svn_swig_py_path_revs_hash_f
if (!(path))
{
- PyErr_SetString(PyExc_TypeError,
- "dictionary keys aren't strings");
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
Py_DECREF(keys);
return NULL;
}
@@ -1227,8 +1450,10 @@ apr_hash_t *svn_swig_py_struct_ptr_hash_
if (!c_key)
{
- PyErr_SetString(PyExc_TypeError,
- "dictionary keys aren't strings");
+ if (!PyErr_Occurred())
+ {
+ PyErr_SetString(PyExc_TypeError, TYPE_ERROR_DICT_STRING_KEY);
+ }
Py_DECREF(keys);
return NULL;
}
@@ -1252,8 +1477,21 @@ svn_swig_py_unwrap_string(PyObject *sour
void *baton)
{
const char **ptr_dest = destination;
- *ptr_dest = PyString_AsString(source);
-
+ if (PyBytes_Check(source))
+ {
+ *ptr_dest = PyBytes_AsString(source);
+ }
+ else if (PyUnicode_Check(source))
+ {
+ *ptr_dest = PyStr_AsUTF8(source);
+ }
+ else
+ {
+ PyErr_Format(PyExc_TypeError,
+ "Expected bytes or str object, %s found",
+ Py_TYPE(source)->tp_name);
+ *ptr_dest = NULL;
+ }
if (*ptr_dest != NULL)
return 0;
else
@@ -1371,7 +1609,7 @@ PyObject *svn_swig_py_array_to_list(cons
for (i = 0; i < array->nelts; ++i)
{
PyObject *ob =
- PyString_FromString(APR_ARRAY_IDX(array, i, const char *));
+ PyBytes_FromString(APR_ARRAY_IDX(array, i, const char *));
if (ob == NULL)
goto error;
PyList_SET_ITEM(list, i, ob);
@@ -1425,7 +1663,7 @@ commit_item_array_to_list(const apr_arra
}
-
+
/*** Errors ***/
/* Convert a given SubversionException to an svn_error_t. On failure returns
@@ -1446,13 +1684,13 @@ static svn_error_t *exception_to_error(P
if ((message_ob = PyObject_GetAttrString(exc, "message")) == NULL)
goto finished;
- message = PyString_AsString(message_ob);
+ message = PyStr_AsString(message_ob);
if (PyErr_Occurred()) goto finished;
if ((file_ob = PyObject_GetAttrString(exc, "file")) == NULL)
goto finished;
if (file_ob != Py_None)
- file = PyString_AsString(file_ob);
+ file = PyStr_AsString(file_ob);
if (PyErr_Occurred()) goto finished;
if ((line_ob = PyObject_GetAttrString(exc, "line")) == NULL)
@@ -1679,7 +1917,8 @@ static svn_error_t *delete_entry(const c
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_entry",
- (char *)"slOO&", path, revision, ib->baton,
+ (char *)SVN_SWIG_BYTES_FMT "lOO&",
+ path, revision, ib->baton,
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -1710,7 +1949,12 @@ static svn_error_t *add_directory(const
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"add_directory",
- (char *)"sOslO&", path, ib->baton,
+#if IS_PY3
+ (char *)"yOylO&",
+#else
+ (char *)"sOslO&",
+#endif
+ path, ib->baton,
copyfrom_path, copyfrom_revision,
make_ob_pool, dir_pool)) == NULL)
{
@@ -1741,8 +1985,8 @@ static svn_error_t *open_directory(const
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"open_directory",
- (char *)"sOlO&", path, ib->baton,
- base_revision,
+ (char *)SVN_SWIG_BYTES_FMT "OlO&",
+ path, ib->baton, base_revision,
make_ob_pool, dir_pool)) == NULL)
{
err = callback_exception_error();
@@ -1771,9 +2015,14 @@ static svn_error_t *change_dir_prop(void
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop",
- (char *)"Oss#O&", ib->baton, name,
+#if IS_PY3
+ (char *)"Oyy#O&",
+#else
+ (char *)"Oss#O&",
+#endif
+ ib->baton, name,
value ? value->data : NULL,
- value ? value->len : 0,
+ (Py_ssize_t) (value ? value->len : 0),
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -1810,7 +2059,12 @@ static svn_error_t *add_file(const char
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"add_file",
- (char *)"sOslO&", path, ib->baton,
+#if IS_PY3
+ (char *)"yOylO&",
+#else
+ (char *)"sOslO&",
+#endif
+ path, ib->baton,
copyfrom_path, copyfrom_revision,
make_ob_pool, file_pool)) == NULL)
{
@@ -1842,8 +2096,8 @@ static svn_error_t *open_file(const char
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"open_file",
- (char *)"sOlO&", path, ib->baton,
- base_revision,
+ (char *)SVN_SWIG_BYTES_FMT "OlO&",
+ path, ib->baton, base_revision,
make_ob_pool, file_pool)) == NULL)
{
err = callback_exception_error();
@@ -1916,7 +2170,12 @@ static svn_error_t *apply_textdelta(void
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"apply_textdelta",
- (char *)"(Os)", ib->baton,
+#if IS_PY3
+ (char *)"(Oy)",
+#else
+ (char *)"(Os)",
+#endif
+ ib->baton,
base_checksum)) == NULL)
{
err = callback_exception_error();
@@ -1961,9 +2220,14 @@ static svn_error_t *change_file_prop(voi
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop",
- (char *)"Oss#O&", ib->baton, name,
+#if IS_PY3
+ (char *)"Oyy#O&",
+#else
+ (char *)"Oss#O&",
+#endif
+ ib->baton, name,
value ? value->data : NULL,
- value ? value->len : 0,
+ (Py_ssize_t) (value ? value->len : 0),
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -1991,7 +2255,12 @@ static svn_error_t *close_file(void *fil
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"close_file",
- (char *)"(Os)", ib->baton,
+#if IS_PY3
+ (char *)"(Oy)",
+#else
+ (char *)"(Os)",
+#endif
+ ib->baton,
text_checksum)) == NULL)
{
err = callback_exception_error();
@@ -2099,7 +2368,7 @@ static svn_error_t *parse_fn3_uuid_recor
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"uuid_record",
- (char *)"sO&", uuid,
+ (char *)SVN_SWIG_BYTES_FMT "O&", uuid,
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -2188,9 +2457,15 @@ static svn_error_t *parse_fn3_set_revisi
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"set_revision_property",
- (char *)"Oss#", ib->baton, name,
+#if IS_PY3
+ (char *)"Oyy#",
+#else
+ (char *)"Oss#",
+#endif
+ ib->baton, name,
value ? value->data : NULL,
- value ? value->len : 0)) == NULL)
+ (Py_ssize_t) (value ? value->len : 0)))
+ == NULL)
{
err = callback_exception_error();
goto finished;
@@ -2218,9 +2493,15 @@ static svn_error_t *parse_fn3_set_node_p
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"set_node_property",
- (char *)"Oss#", ib->baton, name,
+#if IS_PY3
+ (char *)"Oyy#",
+#else
+ (char *)"Oss#",
+#endif
+ ib->baton, name,
value ? value->data : NULL,
- value ? value->len : 0)) == NULL)
+ (Py_ssize_t) (value ? value->len : 0)))
+ == NULL)
{
err = callback_exception_error();
goto finished;
@@ -2247,7 +2528,8 @@ static svn_error_t *parse_fn3_delete_nod
/* ### python doesn't have 'const' on the method name and format */
if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_node_property",
- (char *)"Os", ib->baton, name)) == NULL)
+ (char *)"O" SVN_SWIG_BYTES_FMT,
+ ib->baton, name)) == NULL)
{
err = callback_exception_error();
goto finished;
@@ -2293,8 +2575,8 @@ static svn_error_t *parse_fn3_set_fullte
void *node_baton)
{
item_baton *ib = node_baton;
- PyObject *result;
- svn_error_t *err;
+ PyObject *result = NULL;
+ svn_error_t *err = SVN_NO_ERROR;
svn_swig_py_acquire_py_lock();
@@ -2316,14 +2598,17 @@ static svn_error_t *parse_fn3_set_fullte
/* create a stream from the IO object. it will increment the
reference on the 'result'. */
*stream = svn_swig_py_make_stream(result, ib->pool);
+ if (*stream == NULL)
+ {
+ err = callback_exception_error();
+ goto finished;
+ }
}
/* if the handler returned an IO object, svn_swig_py_make_stream() has
incremented its reference counter. If it was None, it is discarded. */
- Py_DECREF(result);
- err = SVN_NO_ERROR;
-
- finished:
+finished:
+ Py_XDECREF(result);
svn_swig_py_release_py_lock();
return err;
}
@@ -2432,14 +2717,23 @@ apr_file_t *svn_swig_py_make_file(PyObje
{
apr_file_t *apr_file = NULL;
apr_status_t apr_err;
+ const char* fname = NULL;
if (py_file == NULL || py_file == Py_None)
return NULL;
- if (PyString_Check(py_file))
+ /* check if input is a path */
+ if (PyBytes_Check(py_file))
+ {
+ fname = PyBytes_AsString(py_file);
+ }
+ else if (PyUnicode_Check(py_file))
+ {
+ fname = PyStr_AsUTF8(py_file);
+ }
+ if (fname)
{
/* input is a path -- just open an apr_file_t */
- char* fname = PyString_AS_STRING(py_file);
apr_err = apr_file_open(&apr_file, fname,
APR_CREATE | APR_READ | APR_WRITE,
APR_OS_DEFAULT, pool);
@@ -2452,25 +2746,26 @@ apr_file_t *svn_swig_py_make_file(PyObje
return NULL;
}
}
- else if (PyFile_Check(py_file))
+ else
{
- FILE *file;
- apr_os_file_t osfile;
+ FILE *file = svn_swig_py_as_file(py_file);
/* input is a file object -- convert to apr_file_t */
- file = PyFile_AsFile(py_file);
+ if (file != NULL)
+ {
#ifdef WIN32
- osfile = (apr_os_file_t)_get_osfhandle(_fileno(file));
+ apr_os_file_t osfile = (apr_os_file_t)_get_osfhandle(_fileno(file));
#else
- osfile = (apr_os_file_t)fileno(file);
+ apr_os_file_t osfile = (apr_os_file_t)fileno(file);
#endif
- apr_err = apr_os_file_put(&apr_file, &osfile, O_CREAT | O_WRONLY, pool);
- if (apr_err)
- {
- char buf[256];
- apr_strerror(apr_err, buf, sizeof(buf));
- PyErr_Format(PyExc_IOError, "apr_os_file_put failed: %s", buf);
- return NULL;
+ apr_err = apr_os_file_put(&apr_file, &osfile, O_CREAT | O_WRONLY, pool);
+ if (apr_err)
+ {
+ char buf[256];
+ apr_strerror(apr_err, buf, sizeof(buf));
+ PyErr_Format(PyExc_IOError, "apr_os_file_put failed: %s", buf);
+ return NULL;
+ }
}
}
return apr_file;
@@ -2482,7 +2777,6 @@ read_handler_pyio(void *baton, char *buf
{
PyObject *result;
PyObject *py_io = baton;
- apr_size_t bytes;
svn_error_t *err = SVN_NO_ERROR;
if (py_io == Py_None)
@@ -2499,10 +2793,17 @@ read_handler_pyio(void *baton, char *buf
{
err = callback_exception_error();
}
- else if (PyString_Check(result))
+ else if (PyBytes_Check(result))
{
- bytes = PyString_GET_SIZE(result);
- if (bytes > *len)
+ Py_ssize_t bytes;
+ char *result_str;
+
+ if ( -1 == PyBytes_AsStringAndSize(result, &result_str, &bytes)
+ || result_str == NULL)
+ {
+ err = callback_exception_error();
+ }
+ else if (bytes > *len)
{
err = callback_bad_return_error("Too many bytes");
}
@@ -2510,12 +2811,12 @@ read_handler_pyio(void *baton, char *buf
{
/* Writeback, in case this was a short read, indicating EOF */
*len = bytes;
- memcpy(buffer, PyString_AS_STRING(result), *len);
+ memcpy(buffer, result_str, *len);
}
}
else
{
- err = callback_bad_return_error("Not a string");
+ err = callback_bad_return_error("Not a bytes object");
}
Py_XDECREF(result);
svn_swig_py_release_py_lock();
@@ -2534,7 +2835,8 @@ write_handler_pyio(void *baton, const ch
{
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallMethod(py_io, (char *)"write",
- (char *)"s#", data, *len)) == NULL)
+ (char *) SVN_SWIG_BYTES_FMT "#",
+ data, (Py_ssize_t) *len)) == NULL)
{
err = callback_exception_error();
}
@@ -2575,17 +2877,39 @@ svn_swig_py_stream_destroy(void *py_io)
svn_stream_t *
svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool)
{
- svn_stream_t *stream;
+ PyObject *_stream = NULL;
+ void *result = NULL;
+ swig_type_info *typeinfo = svn_swig_TypeQuery("svn_stream_t *");
+
+ if (svn_swig_py_convert_ptr(py_io, &result, typeinfo) != 0) {
+ PyErr_Clear();
+ if (PyObject_HasAttrString(py_io, "_stream")) {
+ _stream = PyObject_GetAttrString(py_io, "_stream");
+ if (svn_swig_py_convert_ptr(_stream, &result, typeinfo) != 0) {
+ PyErr_Clear();
+ }
+ }
+ }
+ if (result == NULL) {
+ if (!PyObject_HasAttrString(py_io, "read")
+ && !PyObject_HasAttrString(py_io, "write")) {
+ PyErr_SetString(PyExc_TypeError,
+ "expecting a svn_stream_t or file like object");
+ goto finished;
+ }
+ result = svn_stream_create(py_io, pool);
+ svn_stream_set_read2(result, read_handler_pyio, NULL);
+ svn_stream_set_write(result, write_handler_pyio);
+ svn_stream_set_close(result, close_handler_pyio);
+ apr_pool_cleanup_register(pool, py_io, svn_swig_py_stream_destroy,
+ apr_pool_cleanup_null);
+ Py_INCREF(py_io);
+ }
- stream = svn_stream_create(py_io, pool);
- svn_stream_set_read2(stream, read_handler_pyio, NULL);
- svn_stream_set_write(stream, write_handler_pyio);
- svn_stream_set_close(stream, close_handler_pyio);
- apr_pool_cleanup_register(pool, py_io, svn_swig_py_stream_destroy,
- apr_pool_cleanup_null);
- Py_INCREF(py_io);
+finished:
+ Py_XDECREF(_stream);
- return stream;
+ return result;
}
PyObject *
@@ -2619,13 +2943,24 @@ 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)",
+#else
(char *)"(siisiii)",
+#endif
path, action, kind,
mime_type,
content_state, prop_state,
@@ -2644,6 +2979,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();
}
@@ -2655,12 +2993,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,
@@ -2679,6 +3023,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();
}
@@ -2689,12 +3036,20 @@ 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();
- if ((result = PyObject_CallFunction(function, (char *)"sO&", path,
+
+ /* 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)
{
err = callback_exception_error();
@@ -2710,7 +3065,64 @@ 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();
+}
+
+svn_error_t *svn_swig_py_client_status_func(void *baton,
+ const char *path,
+ const svn_client_status_t *status,
+ apr_pool_t *scratch_pool)
+{
+ 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 err;
+
+ svn_swig_py_acquire_py_lock();
+
+ if (status == NULL)
+ {
+ result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"yOO&",
+#else
+ (char *)"sOO&",
+#endif
+ path, Py_None,
+ make_ob_pool, scratch_pool);
+ }
+ else
+ {
+ result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"yO&O&",
+#else
+ (char *)"sO&O&",
+#endif
+ path,
+ make_ob_client_status, status,
+ make_ob_pool, scratch_pool);
+ }
+ if (result == 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);
+ }
+
svn_swig_py_release_py_lock();
+ return err;
}
@@ -2733,7 +3145,12 @@ svn_error_t *svn_swig_py_delta_path_driv
"void *",
NULL);
- result = PyObject_CallFunction(function, (char *)"OsO&",
+ result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"OyO&",
+#else
+ (char *)"OsO&",
+#endif
py_parent_baton,
path, make_ob_pool, pool);
@@ -2768,12 +3185,20 @@ 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();
- if ((result = PyObject_CallFunction(function, (char *)"sO&", path,
+
+ /* 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)
{
err = callback_exception_error();
@@ -2787,8 +3212,10 @@ void svn_swig_py_status_func2(void *bato
}
/* Our error has no place to go. :-( */
- if (err)
- svn_error_clear(err);
+ svn_error_clear(err);
+
+ /* Also, restore error indicator */
+ PyErr_Restore(exc_type, exc, exc_traceback);
svn_swig_py_release_py_lock();
}
@@ -2877,7 +3304,7 @@ svn_error_t *svn_swig_py_fs_lock_callbac
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(py_callback,
- (char *)"sO&O&O&",
+ (char *)SVN_SWIG_BYTES_FMT "O&O&O&",
path,
make_ob_lock, lock,
make_ob_error, fs_err,
@@ -2943,23 +3370,34 @@ svn_error_t *svn_swig_py_get_commit_log_
if (result == Py_None)
{
- Py_DECREF(result);
*log_msg = NULL;
err = SVN_NO_ERROR;
}
- else if (PyString_Check(result))
+ else if (PyBytes_Check(result))
{
- *log_msg = apr_pstrdup(pool, PyString_AS_STRING(result));
- Py_DECREF(result);
+ *log_msg = apr_pstrdup(pool, PyBytes_AsString(result));
err = SVN_NO_ERROR;
}
+ else if (PyUnicode_Check(result))
+ {
+ /* PyStr_AsUTF8() may cause UnicodeEncodeError,
+ but apr_pstrdup() allows NULL for s */
+ if ((*log_msg = apr_pstrdup(pool, PyStr_AsUTF8(result))) == NULL)
+ {
+ err = callback_exception_error();
+ }
+ else
+ {
+ err = SVN_NO_ERROR;
+ }
+ }
else
{
- Py_DECREF(result);
- err = callback_bad_return_error("Not a string");
+ err = callback_bad_return_error("Not a bytes or str object");
}
+ Py_DECREF(result);
- finished:
+finished:
svn_swig_py_release_py_lock();
return err;
}
@@ -2998,7 +3436,11 @@ svn_error_t *svn_swig_py_repos_authz_fun
}
if ((result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"OyO",
+#else
(char *)"OsO",
+#endif
py_root, path, py_pool)) == NULL)
{
err = callback_exception_error();
@@ -3035,7 +3477,7 @@ svn_error_t *svn_swig_py_repos_history_f
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
- (char *)"slO&",
+ (char *)SVN_SWIG_BYTES_FMT "lO&",
path, revision,
make_ob_pool, pool)) == NULL)
{
@@ -3162,7 +3604,7 @@ svn_error_t *svn_swig_py_proplist_receiv
}
result = PyObject_CallFunction(receiver,
- (char *)"sOOO",
+ (char *)SVN_SWIG_BYTES_FMT "OOO",
path, py_props, py_iprops, py_pool);
if (result == NULL)
{
@@ -3222,7 +3664,11 @@ svn_error_t *svn_swig_py_log_receiver(vo
}
if ((result = PyObject_CallFunction(receiver,
+#if IS_PY3
+ (char *)"OlyyyO",
+#else
(char *)"OlsssO",
+#endif
chpaths, rev, author, date, msg,
py_pool)) == NULL)
{
@@ -3300,7 +3746,7 @@ svn_error_t *svn_swig_py_info_receiver_f
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(receiver,
- (char *)"sO&O&",
+ (char *)SVN_SWIG_BYTES_FMT "O&O&",
path, make_ob_info, info,
make_ob_pool, pool)) == NULL)
{
@@ -3370,9 +3816,13 @@ svn_error_t *svn_swig_py_client_blame_re
if ((result = PyObject_CallFunction(receiver,
(char *)
- (SVN_APR_INT64_T_PYCFMT "lsssO&"),
- line_no, revision, author, date, line,
- make_ob_pool, pool)) == NULL)
+#if IS_PY3
+ "LlyyyO&",
+#else
+ "LlsssO&",
+#endif
+ (PY_LONG_LONG)line_no, revision, author,
+ date, line, make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
}
@@ -3402,7 +3852,11 @@ svn_error_t *svn_swig_py_changelist_rece
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(receiver,
+#if IS_PY3
+ (char *)"yyO&",
+#else
(char *)"ssO&",
+#endif
path, changelist,
make_ob_pool, pool)) == NULL)
{
@@ -3437,7 +3891,7 @@ svn_swig_py_auth_gnome_keyring_unlock_pr
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
- (char *)"sO&",
+ (char *)SVN_SWIG_BYTES_FMT "O&",
keyring_name,
make_ob_pool, pool)) == NULL)
{
@@ -3445,7 +3899,11 @@ svn_swig_py_auth_gnome_keyring_unlock_pr
}
else
{
- *keyring_passwd = make_string_from_ob(result, pool);
+ *keyring_passwd = make_string_from_ob_maybe_null(result, pool);
+ if (PyErr_Occurred())
+ {
+ err = callback_exception_error();
+ }
Py_DECREF(result);
}
@@ -3473,7 +3931,11 @@ svn_swig_py_auth_simple_prompt_func(svn_
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"yylO&",
+#else
(char *)"sslO&",
+#endif
realm, username, may_save,
make_ob_pool, pool)) == NULL)
{
@@ -3524,7 +3986,7 @@ svn_swig_py_auth_username_prompt_func(sv
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
- (char *)"slO&",
+ (char *)SVN_SWIG_BYTES_FMT "lO&",
realm, may_save,
make_ob_pool, pool)) == NULL)
{
@@ -3576,7 +4038,8 @@ svn_swig_py_auth_ssl_server_trust_prompt
svn_swig_py_acquire_py_lock();
- if ((result = PyObject_CallFunction(function, (char *)"slO&lO&",
+ if ((result = PyObject_CallFunction(function,
+ (char *)SVN_SWIG_BYTES_FMT "lO&lO&",
realm, failures, make_ob_auth_ssl_server_cert_info,
cert_info, may_save, make_ob_pool, pool)) == NULL)
{
@@ -3627,7 +4090,7 @@ svn_swig_py_auth_ssl_client_cert_prompt_
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
- (char *)"slO&",
+ (char *)SVN_SWIG_BYTES_FMT "lO&",
realm, may_save,
make_ob_pool, pool)) == NULL)
{
@@ -3678,7 +4141,7 @@ svn_swig_py_auth_ssl_client_cert_pw_prom
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(function,
- (char *)"slO&",
+ (char *)SVN_SWIG_BYTES_FMT "lO&",
realm, may_save,
make_ob_pool, pool)) == NULL)
{
@@ -3745,7 +4208,12 @@ svn_swig_py_config_auth_walk_func(svn_bo
goto finished;
}
- if ((result = PyObject_CallFunction(function, (char *)"ssOO",
+ if ((result = PyObject_CallFunction(function,
+#if IS_PY3
+ (char *)"yyOO",
+#else
+ (char *)"ssOO",
+#endif
cred_kind, realmstring,
py_hash, py_scratch_pool)) == NULL)
{
@@ -3844,16 +4312,21 @@ ra_callbacks_get_wc_prop(void *baton,
}
if ((result = PyObject_CallFunction(py_callback,
- (char *)"ssO&", path, name,
+#if IS_PY3
+ (char *)"yyO&",
+#else
+ (char *)"ssO&",
+#endif
+ path, name,
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
}
else if (result != Py_None)
{
- char *buf;
Py_ssize_t len;
- if (PyString_AsStringAndSize(result, &buf, &len) == -1)
+ char *buf;
+ if (PyBytes_AsStringAndSize(result, &buf, &len) == -1)
{
err = callback_exception_error();
}
@@ -3896,14 +4369,19 @@ ra_callbacks_push_or_set_wc_prop(const c
goto finished;
}
- if ((py_value = PyString_FromStringAndSize(value->data, value->len)) == NULL)
+ if ((py_value = PyBytes_FromStringAndSize(value->data, value->len)) == NULL)
{
err = callback_exception_error();
goto finished;
}
if ((result = PyObject_CallFunction(py_callback,
- (char *)"ssOO&", path, name, py_value,
+#if IS_PY3
+ (char *)"yyOO&",
+#else
+ (char *)"ssOO&",
+#endif
+ path, name, py_value,
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -3966,7 +4444,12 @@ ra_callbacks_invalidate_wc_props(void *b
}
if ((result = PyObject_CallFunction(py_callback,
- (char *)"ssO&", path, name,
+#if IS_PY3
+ (char *)"yyO&",
+#else
+ (char *)"ssO&",
+#endif
+ path, name,
make_ob_pool, pool)) == NULL)
{
err = callback_exception_error();
@@ -3988,11 +4471,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)
@@ -4032,6 +4521,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);
@@ -4095,7 +4587,7 @@ ra_callbacks_get_client_string(void *bat
}
else if (result != Py_None)
{
- if ((*name = PyString_AsString(result)) == NULL)
+ if ((*name = PyBytes_AsString(result)) == NULL)
{
err = callback_exception_error();
}
@@ -4198,7 +4690,11 @@ svn_error_t *svn_swig_py_commit_callback
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(receiver,
+#if IS_PY3
+ (char *)"lyy",
+#else
(char *)"lss",
+#endif
new_revision, date, author)) == NULL)
{
err = callback_exception_error();
@@ -4250,7 +4746,7 @@ svn_error_t *svn_swig_py_ra_file_rev_han
}
if ((result = PyObject_CallFunction(handler,
- (char *)"slOOO&",
+ (char *)SVN_SWIG_BYTES_FMT "lOOO&",
path, rev, py_rev_props, py_prop_diffs,
make_ob_pool, pool)) == NULL)
{
@@ -4296,7 +4792,7 @@ svn_error_t *svn_swig_py_ra_lock_callbac
svn_swig_py_acquire_py_lock();
if ((result = PyObject_CallFunction(py_callback,
- (char *)"sbO&O&O&",
+ (char *)SVN_SWIG_BYTES_FMT "bO&O&O&",
path, do_lock,
make_ob_lock, lock,
make_ob_error, ra_err,
@@ -4333,7 +4829,11 @@ static svn_error_t *reporter_set_path(vo
if ((result = PyObject_CallMethod(py_reporter,
(char *)"set_path",
+#if IS_PY3
+ (char *)"ylbyO&",
+#else
(char *)"slbsO&",
+#endif
path, revision,
start_empty, lock_token,
make_ob_pool, pool)) == NULL)
@@ -4366,7 +4866,7 @@ static svn_error_t *reporter_delete_path
if ((result = PyObject_CallMethod(py_reporter,
(char *)"delete_path",
- (char *)"sO&",
+ (char *)SVN_SWIG_BYTES_FMT "O&",
path,
make_ob_pool, pool)) == NULL)
{
@@ -4402,7 +4902,11 @@ static svn_error_t *reporter_link_path(v
if ((result = PyObject_CallMethod(py_reporter,
(char *)"link_path",
+#if IS_PY3
+ (char *)"yylbsO&",
+#else
(char *)"sslbsO&",
+#endif
path, url, revision,
start_empty, lock_token,
make_ob_pool, pool)) == NULL)
@@ -4533,7 +5037,11 @@ wc_diff_callbacks2_file_changed_or_added
}
result = PyObject_CallFunction(py_callback,
+#if IS_PY3
+ (char *)"O&yyyllyyO&O&",
+#else
(char *)"O&sssllssO&O&",
+#endif
make_ob_wc_adm_access, adm_access,
path,
tmpfile1, tmpfile2,
@@ -4656,7 +5164,11 @@ wc_diff_callbacks2_file_deleted(svn_wc_a
}
result = PyObject_CallFunction(py_callback,
+#if IS_PY3
+ (char *)"O&yyyyyO&",
+#else
(char *)"O&sssssO&",
+#endif
make_ob_wc_adm_access, adm_access,
path,
tmpfile1, tmpfile2,
@@ -4710,7 +5222,11 @@ wc_diff_callbacks2_dir_added(svn_wc_adm_
}
result = PyObject_CallFunction(py_callback,
+#if IS_PY3
+ (char *)"O&yl",
+#else
(char *)"O&sl",
+#endif
make_ob_wc_adm_access, adm_access,
path, rev);
if (result == NULL)
@@ -4760,7 +5276,7 @@ wc_diff_callbacks2_dir_deleted(svn_wc_ad
}
result = PyObject_CallFunction(py_callback,
- (char *)"O&s",
+ (char *)"O&" SVN_SWIG_BYTES_FMT,
make_ob_wc_adm_access, adm_access, path);
if (result == NULL)
{
@@ -4812,7 +5328,11 @@ wc_diff_callbacks2_dir_props_changed(svn
}
result = PyObject_CallFunction(py_callback,
+#if IS_PY3
+ (char *)"O&yO&O&",
+#else
(char *)"O&sO&O&",
+#endif
make_ob_wc_adm_access, adm_access,
path,
svn_swig_py_proparray_to_dict, propchanges,
@@ -4864,11 +5384,21 @@ 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&",
+#else
(char *)"ssO&",
+#endif
name,
value,
make_ob_pool, pool)) == NULL)
@@ -4884,7 +5414,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)
{
@@ -4912,11 +5442,17 @@ 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 *)"sO&",
+ (char *)SVN_SWIG_BYTES_FMT "O&",
name,
make_ob_pool, pool)) == NULL)
{
@@ -4931,7 +5467,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)
{
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h Fri Jan 14 14:01:45 2022
@@ -50,6 +50,12 @@ extern "C" {
apr_status_t svn_swig_py_initialize(void);
+/* Returns the provided python object as a FILE *object.
+ * Return the underlying FILE or NULL if the object is not a File instance.
+ */
+FILE *svn_swig_py_as_file(PyObject *pyfile);
+
+
/* Functions to manage python's global interpreter lock */
void svn_swig_py_release_py_lock(void);
@@ -92,15 +98,33 @@ int svn_swig_py_convert_ptr(PyObject *in
/* Wrapper for SWIG_MustGetPtr */
void *svn_swig_py_must_get_ptr(void *input, swig_type_info *type, int argnum);
+
/*** Functions to expose a custom SubversionException ***/
-/* raise a subversion exception, created from a normal subversion
- error. consume the error. */
+/* Get a SubversionException class object and its instance built from
+ error_chain, but do not raise it immediately. Consume the
+ error_chain. */
+void svn_swig_py_build_svn_exception(
+ PyObject **exc_class, PyObject **exc_ob, svn_error_t *error_chain);
+
+/* Raise a SubversionException, created from a normal subversion
+ error. Consume the error. */
void svn_swig_py_svn_exception(svn_error_t *err);
+/* Function to get char * representation of bytes/str object. This is
+ the replacement of typemap(in, parse="s") and typemap(in, parse="z")
+ to accept both of bytes object and str object, and it assumes to be
+ used from those typemaps only.
+ Note: type of return value should be char const *, however, as SWIG
+ produces variables for C function without 'const' modifier, to avoid
+ ton of cast in SWIG produced C code we drop it from return value
+ types as well */
+char *svn_swig_py_string_to_cstring(PyObject *input, int maybe_null,
+ const char * funcsym, const char * argsym);
+
/* helper function to convert an apr_hash_t* (char* -> svnstring_t*) to
a Python dict */
PyObject *svn_swig_py_prophash_to_dict(apr_hash_t *hash);
@@ -226,7 +250,10 @@ svn_swig_py_seq_to_array(PyObject *seq,
apr_pool_t *pool);
/* An svn_swig_py_object_unwrap_t that extracts a char pointer from a Python
- string. */
+ string.
+
+ Note the lifetime of the returned string is tied to the provided Python
+ object. */
int
svn_swig_py_unwrap_string(PyObject *source,
void *destination,
@@ -293,6 +320,13 @@ void svn_swig_py_status_func(void *baton
const char *path,
svn_wc_status_t *status);
+/* a client status function that executes a Python function that is passed in
+ via the baton argument */
+svn_error_t *svn_swig_py_client_status_func(void *baton,
+ const char *path,
+ const svn_client_status_t *status,
+ apr_pool_t *scratch_pool);
+
/* a svn_delta_path_driver callback that executes a Python function
that is passed in via the baton argument */
svn_error_t *svn_swig_py_delta_path_driver_cb_func(void **dir_baton,
Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Jan 14 14:01:45 2022
@@ -1 +1,2 @@
*.pyc
+__pycache__
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/client.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/client.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/client.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/client.py Fri Jan 14 14:01:45 2022
@@ -24,8 +24,8 @@
######################################################################
from libsvn.client import *
-from svn.core import _unprefix_names
+from svn.core import _unprefix_names, _as_list
_unprefix_names(locals(), 'svn_client_')
_unprefix_names(locals(), 'SVN_CLIENT_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/core.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/core.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/core.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/core.py Fri Jan 14 14:01:45 2022
@@ -27,8 +27,8 @@ from libsvn.core import *
import libsvn.core as _libsvncore
import atexit as _atexit
import sys
-# __all__ is defined later, since some svn_* functions are implemented below.
+# __all__ is defined later, since some svn_* functions are implemented below.
class SubversionException(Exception):
@@ -89,6 +89,20 @@ class SubversionException(Exception):
child = cls(message, apr_err, child, file, line)
return child
+# This function is useful for common Python 2/3 code. It prevents the double
+# memory hit of simply wrapping values/keys/items calls on dictionaries on
+# python 2, but ensuring an independent list is returned in Python 3.
+def _as_list(seq):
+ """Returns the given sequence or iterator as a list.
+
+ If already a list, simply returns the list, otherwise a list is constructed
+ using the given object.
+ """
+ if isinstance(seq, list):
+ return seq
+
+ return list(seq)
+
def _cleanup_application_pool():
"""Cleanup the application pool before exiting"""
if application_pool and application_pool.valid():
@@ -96,7 +110,7 @@ def _cleanup_application_pool():
_atexit.register(_cleanup_application_pool)
def _unprefix_names(symbol_dict, from_prefix, to_prefix = ''):
- for name, value in symbol_dict.items():
+ for name, value in _as_list(symbol_dict.items()):
if name.startswith(from_prefix):
symbol_dict[to_prefix + name[len(from_prefix):]] = value
@@ -141,7 +155,7 @@ def svn_path_compare_paths(path1, path2)
# Common prefix was skipped above, next character is compared to
# determine order
- return cmp(char1, char2)
+ return (char1 > char2) - (char1 < char2)
def svn_mergeinfo_merge(mergeinfo, changes):
return _libsvncore.svn_swig_mergeinfo_merge(mergeinfo, changes)
@@ -171,7 +185,7 @@ class Stream:
if not data:
break
chunks.append(data)
- return ''.join(chunks)
+ return b''.join(chunks)
# read the amount specified
return svn_stream_read(self._stream, int(amt))
@@ -194,7 +208,7 @@ def secs_from_timestr(svn_datetime, pool
# ### convert to a time_t; this requires intimate knowledge of
# ### the apr_time_t type
# ### aprtime is microseconds; turn it into seconds
- return aprtime / 1000000
+ return aprtime // 1000000
# ============================================================================
@@ -317,12 +331,12 @@ def run_app(func, *args, **kw):
# 'apr_pool_clear' 'apr_pool_destroy' 'apr_pool_t'
# 'apr_time_ansi_put'
# 'run_app'
-# 'svn_relpath__internal_style' 'svn_uri__is_ancestor'
+# 'svn_uri__is_ancestor'
# 'svn_tristate__from_word' 'svn_tristate__to_word'
-__all__ = filter(lambda s: (s.startswith('svn_')
- or s.startswith('SVN_')
- or s.startswith('SVNSYNC_')
- or s in ('Pool', 'SubversionException'))
- and '__' not in s,
- locals())
+__all__ = [s for s in _as_list(locals())
+ if (s.startswith('svn_')
+ or s.startswith('SVN_')
+ or s.startswith('SVNSYNC_')
+ or s in ('Pool', 'SubversionException'))
+ and '__' not in s]
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/delta.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/delta.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/delta.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/delta.py Fri Jan 14 14:01:45 2022
@@ -24,10 +24,10 @@
######################################################################
from libsvn.delta import *
-from svn.core import _unprefix_names
+from svn.core import _unprefix_names, _as_list
_unprefix_names(locals(), 'svn_delta_')
_unprefix_names(locals(), 'svn_txdelta_', 'tx_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
class Editor:
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/diff.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/diff.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/diff.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/diff.py Fri Jan 14 14:01:45 2022
@@ -24,7 +24,7 @@
######################################################################
from libsvn.diff import *
-from svn.core import _unprefix_names
+from svn.core import _unprefix_names, _as_list
_unprefix_names(locals(), 'svn_diff_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/fs.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/fs.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/fs.py Fri Jan 14 14:01:45 2022
@@ -24,10 +24,38 @@
######################################################################
from libsvn.fs import *
-from svn.core import _unprefix_names, Pool
+
+######################################################################
+# Any adjustment of SWIG generated wrapper functions on svn.fs module
+# should be placed before adding alternative names for them.
+
+# fs.commit_txn() should return a 2-tupple of conflict_p and new_rev.
+# However if conflict_p is None, SWIG generated wrapper function
+# libsvn.fs.svn_fs_commit_txn returns an integer value of new_rev.
+# This is a bug of SWIG generated wrapper function, so we fix it here.
+#
+# (There was discussion about this behavior because C API
+# svn_fs_commit_txn() always set NULL to conflict_p if it returns
+# SVN_NO_ERROR and so it seems to be reasonable that fs.commit_txn()
+# returns only rev_new value. However for compatibility, we decided
+# that fs.commit_txn always returns 2-tuple if it does not raises
+# an exception.)
+
+_svn_fs_commit_txn = svn_fs_commit_txn
+
+def svn_fs_commit_txn(*args):
+ r"""svn_fs_commit_txn(svn_fs_txn_t txn, apr_pool_t pool) -> svn_error_t"""
+ ret = _svn_fs_commit_txn(*args)
+ if not isinstance(ret, tuple):
+ ret = (None, ret)
+ return ret
+
+######################################################################
+
+from svn.core import _unprefix_names, Pool, _as_list
_unprefix_names(locals(), 'svn_fs_')
_unprefix_names(locals(), 'SVN_FS_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
@@ -48,10 +76,30 @@ import svn.diff as _svndiff
def entries(root, path, pool=None):
"Call dir_entries returning a dictionary mappings names to IDs."
e = dir_entries(root, path, pool)
- for name, entry in e.items():
+ for name, entry in _as_list(e.items()):
e[name] = dirent_t_id_get(entry)
return e
+class _PopenStdoutWrapper(object):
+ "Private wrapper object of _subprocess.Popen.stdout to clean up sub process"
+ def __init__(self, pobject):
+ self._pobject = pobject
+ def __getattr__(self, name):
+ return getattr(self._pobject.stdout, name)
+ def close(self):
+ self._pobject.stdout.close()
+ if self._pobject.poll() is None:
+ self._pobject.terminate()
+ def __del__(self):
+ if not self.closed:
+ self.close()
+ if self._pobject.poll() is None:
+ self._pobject.terminate()
+ if _sys.hexversion >= 0x030300F0:
+ try:
+ self._pobject.wait(10)
+ except _subprocess.TimeoutExpired:
+ self._pobject.kill()
class FileDiff:
def __init__(self, root1, path1, root2, path2, pool=None, diffoptions=[]):
@@ -124,7 +172,7 @@ class FileDiff:
# open the pipe, and return the file object for reading from the child.
p = _subprocess.Popen(cmd, stdout=_subprocess.PIPE, bufsize=-1,
close_fds=_sys.platform != "win32")
- return p.stdout
+ return _PopenStdoutWrapper(p)
else:
if self.difftemp is None:
@@ -132,16 +180,16 @@ class FileDiff:
with builtins.open(self.difftemp, "wb") as fp:
diffopt = _svndiff.file_options_create()
- diffobj = _svndiff.file_diff_2(self.tempfile1,
- self.tempfile2,
+ diffobj = _svndiff.file_diff_2(self.tempfile1.encode('UTF-8'),
+ self.tempfile2.encode('UTF-8'),
diffopt)
_svndiff.file_output_unified4(fp,
diffobj,
- self.tempfile1,
- self.tempfile2,
+ self.tempfile1.encode('UTF-8'),
+ self.tempfile2.encode('UTF-8'),
None, None,
- "utf8",
+ b"utf8",
None,
diffopt.show_c_function,
diffopt.context_size,
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/ra.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/ra.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/ra.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/ra.py Fri Jan 14 14:01:45 2022
@@ -24,10 +24,10 @@
######################################################################
from libsvn.ra import *
-from svn.core import _unprefix_names
+from svn.core import _unprefix_names, _as_list
_unprefix_names(locals(), 'svn_ra_')
_unprefix_names(locals(), 'SVN_RA_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
class Callbacks:
@@ -58,7 +58,7 @@ class Callbacks:
svn.core.SVN_AUTH_PARAM_DEFAULT_PASSWORD,
password)
def open_tmp_file(self, pool):
- path = '/'.join([self.wc, svn.wc.get_adm_dir(pool), 'tmp'])
+ path = b'/'.join([self.wc, svn.wc.get_adm_dir(pool), b'tmp'])
(fd, fn) = tempfile.mkstemp(dir=path)
os.close(fd)
return fn
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/repos.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/repos.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/repos.py Fri Jan 14 14:01:45 2022
@@ -24,10 +24,10 @@
######################################################################
from libsvn.repos import *
-from svn.core import _unprefix_names, Pool
+from svn.core import _unprefix_names, Pool, _as_list
_unprefix_names(locals(), 'svn_repos_')
_unprefix_names(locals(), 'SVN_REPOS_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
@@ -126,9 +126,9 @@ class ChangeCollector(_svndelta.Editor):
self.notify_cb(change)
def _make_base_path(self, parent_path, path):
- idx = path.rfind('/')
+ idx = path.rfind(b'/')
if parent_path:
- parent_path = parent_path + '/'
+ parent_path = parent_path + b'/'
if idx == -1:
return parent_path + path
return parent_path + path[idx+1:]
@@ -142,7 +142,7 @@ class ChangeCollector(_svndelta.Editor):
return root
def open_root(self, base_revision, dir_pool=None):
- return ('', '', self.base_rev) # dir_baton
+ return (b'', b'', self.base_rev) # dir_baton
def delete_entry(self, path, revision, parent_baton, pool=None):
base_path = self._make_base_path(parent_baton[1], path)
@@ -281,9 +281,9 @@ class RevisionChangeCollector(ChangeColl
ChangeCollector.__init__(self, fs_ptr, root, pool, notify_cb)
def _make_base_path(self, parent_path, path):
- idx = path.rfind('/')
+ idx = path.rfind(b'/')
if idx == -1:
- return parent_path + '/' + path
+ return parent_path + b'/' + path
return parent_path + path[idx:]
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/wc.py?rev=1897034&r1=1897033&r2=1897034&view=diff
==============================================================================
--- subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/wc.py (original)
+++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/svn/wc.py Fri Jan 14 14:01:45 2022
@@ -24,10 +24,10 @@
######################################################################
from libsvn.wc import *
-from svn.core import _unprefix_names
+from svn.core import _unprefix_names, _as_list
_unprefix_names(locals(), 'svn_wc_')
_unprefix_names(locals(), 'SVN_WC_')
-__all__ = filter(lambda x: x.lower().startswith('svn_'), locals().keys())
+__all__ = [x for x in _as_list(locals()) if x.lower().startswith('svn_')]
del _unprefix_names
Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Jan 14 14:01:45 2022
@@ -1,2 +1,3 @@
*.pyc
+__pycache__
.gdb_history