You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by tr...@apache.org on 2018/12/27 03:42:52 UTC

svn commit: r1849784 [1/2] - in /subversion/branches/swig-py3: build/ac-macros/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversion/bindings/swig/python/libsvn_swig_py/ subversion/bindings/swig/python/svn/ subversion/bindings/swig/py...

Author: troycurtisjr
Date: Thu Dec 27 03:42:52 2018
New Revision: 1849784

URL: http://svn.apache.org/viewvc?rev=1849784&view=rev
Log:
On branch swig-py3: Use bytes for all API string parameters.

Since many string like arguments in the API can contain arbitrary bytes, use the
Python Bytes interface in Python 3, while still using Str in Python 2, to ensure
full compatibility with all possible input data.

Build system change:

* build/ac-macros/swig.m4:
  Add "-DPY3" option to SWIG_PY_OPTS for py3 build to define symbol to switch
  typemap between py2 and py3.

Typemap changes:

* subversion/bindings/swig/core.i
  (%typemap(argout) (char *buffer, apr_size_t *len):
    Map buffer arg to Bytes insted of Str.
  (%typemap(in) (const char *data, apr_size_t *len) ($*2_type temp):
    Map data arg to Bytes instead of Str and pass Py_ssize_t variable as length
    argment of PyBytes_AsStringAndSize for for explicit type conversion.
  (%typemap(in) const void *value):
    Map value arg to Bytes instead of Str for svn_auth_set_parameter().

* subversion/bindings/swig/include/svn_global.swg:
  - Define SWIG_PYTHON_STRICT_BYTE_CHAR symbol for swig context for
    Python3.
  - Switch "in" type typemap for char *, char const *, char * const,
    and char const * const "", to use parse parameter "y" for py3 and
    "s" for py2.

* subversion/bindings/swig/include/svn_string.swg
  (%typemap(argout) RET_STRING, %typemap(in) svn_stringbuf_t *,
    %typemap(out) svn_stringbuf_t *, %typemap(in) const svn_string_t *,
    %typemap(out) svn_string_t *, %typemap(argout) const char **OUTPUT):
    Map args to Bytes instead of Str.

* subversion/bindings/swig/include/svn_swigcompat.swg
  (%set_constant(name, value): Use PyDict_SetItem and PyBytes_FromString
    instead of PyDict_SetItemString, for SWIG <= 1.3.27 (not tested).

* subversion/bindings/swig/include/svn_types.swg
  (%typemap(in) const char *MAY_BE_NULL): Don't use "z" conversion
    format and convert to Bytes if it is not NULL.
  (%typemap(in) (const char *PTR, apr_size_t LEN): Use PyBytes_Check and
    PyBytes_AsStringAndSize instead of PyStr_Check and PyStr_AsUTF8AndSize.

* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
  (make_string_from_ob(), make_svn_string_from_ob(),
   svn_swig_py_make_file(), svn_swig_py_get_commit_log_func()):
    Use PyBytes_Check and PyBytes_AsString instead of PyStr_Check and
    PyStr_AsString.
  (convert_hash()): Use Dict_SetItem and PyBytes_FromString instead of
    DictItemString.
  (convert_svn_string_t(), svn_swig_py_proparray_to_dict(),
   ra_callbacks_get_wc_prop()):
    Use PyBytes_AsStringAndSize instead of PyStr_AsUTF8AndSize.
   (cstring_to_pystring(), convert_string(),
    svn_swig_py_propinheriteditemarray_to_dict(),
    svn_swig_py_proparray_to_dict(),
    svn_swig_py_locationhash_to_dict(),
    svn_swig_py_c_strings_to_list(),
    svn_swig_py_changed_path_hash_to_dict(),
    svn_swig_py_changed_path2_hash_to_dict(),
    svn_swig_py_unwrap_string(),
    svn_swig_py_array_to_list()): Use PyBytes_FromString instead of
     PyStr_FromString.
  (delete_entry(), add_directory(), open_directory(), change_dir_prop(),
    add_file(), open_file(), apply_textdelta(), change_file_prop(),
    close_file(), parse_fn3_uuid_record(), parse_fn3_set_revision_property(),
    parse_fn3_set_node_property(), parse_fn3_delete_node_property(),
    svn_swig_py_notify_func(), svn_swig_py_status_func(),
    svn_swig_py_delta_path_driver_cb_func(), svn_swig_py_status_func2(),
    svn_swig_py_fs_lock_callback(), svn_swig_py_repos_authz_func(),
    svn_swig_py_repos_history_func(), svn_swig_py_proplist_receiver2(),
    svn_swig_py_log_receiver(), svn_swig_py_info_receiver_func(),
    svn_swig_py_client_blame_receiver_func(),
    svn_swig_py_changelist_receiver_func(),
    svn_swig_py_auth_gnome_keyring_unlock_prompt_func(),
    svn_swig_py_auth_simple_prompt_func(),
    svn_swig_py_auth_username_prompt_func(),
    svn_swig_py_auth_ssl_server_trust_prompt_func(),
    svn_swig_py_auth_ssl_client_cert_prompt_func(),
    svn_swig_py_auth_ssl_client_cert_pw_prompt_func(),
    svn_swig_py_config_auth_walk_func(), ra_callbacks_get_wc_prop(),
    ra_callbacks_push_or_set_wc_prop(), ra_callbacks_invalidate_wc_props(),
    svn_swig_py_commit_callback(), svn_swig_py_ra_file_rev_handler_func(),
    svn_swig_py_ra_lock_callback(), reporter_set_path(),
    reporter_delete_path(), reporter_link_path(),
    wc_diff_callbacks2_file_changed_or_added(),
    wc_diff_callbacks2_file_deleted(), wc_diff_callbacks2_dir_added(),
    wc_diff_callbacks2_dir_deleted(),
    wc_diff_callbacks2_dir_props_changed(),
    svn_swig_py_config_enumerator2(),
    svn_swig_py_config_section_enumerator2()): Use 's' for py2 and use 'y'
     for py3 in argment format string.
  (ra_callbacks_push_or_set_wc_prop()): Use PyBytes_FromStringAndSize
    instead of PyStr_FromStringAndSize.
  (ra_callbacks_get_client_string()): Use PyBytes_FromString instaed of
    PyStr_AsString.

* subversion/bindings/swig/svn_client.i
  (%typemap(argout) apr_array_header_t **props):
   Use PyBytes_FromStringAndSize() instead of PyStr_FromStringAndSize.

Helper python code changes:

* subversion/bindings/swig/python/svn/core.py
  (svn_path_compare_paths): Do not use cmp, for py3 compatibility.
  (Stream.read()): Chunks is now list of bytes, not list of str.

* subversion/bindings/swig/python/svn/fs.py
  (FileDiff.get_pipe()):
   - Make sure self.tempfile1 and self.self.tempfile2 are bytes.
   - Pass bytes to header_encoding arg in _svndiff.file_output_unified4().

* subversion/bindings/swig/python/svn/ra.py
  (Callbacks..__doc__):
    Treat path as bytes in sample code.

* subversion/bindings/swig/python/svn/repos.py
  (ChangeCollector._make_base_path()): Treat path as bytes.
  (ChangeCollector.open_root(): Path and basepath should be bytes in
    dir_baton.
  (RevisionChangeCollector._make_base_path()): Treat path as bytes.

Unit test changes:

* subversion/bindings/swig/python/tests/auth.py:
  Replace all str literals with bytes literals except docstring and module name.

* subversion/bindings/swig/python/tests/checksum.py
  (ChecksumTestCases.test_checksum()): Check if type of check_val is
   bytes instead of str.

* subversion/bindings/swig/python/tests/client.py:
  Replace all str literals with bytes literals except for the mode arg of open(),
    arguments to utils.Temper methods, docstrings, and module names.
  (SubversionClientTestCase.test_uuid_from_url): Check if return value
    type client.uuid_from_url() is bytes instead of str.
  (SubversionClientTestCase.test_uuid_from_path): Check if return value
    type client.uuid_from_path() is bytes instead of str.
  (SubversionClientTestCase.test_merge_peg3()): Open the result file in
    raw mode.
  (SubversionClientTestCase.test_update4()): Convert os.path.sep into
    bytes if it is str in py3.

* subversion/bindings/swig/python/tests/core.py:
  Replace all str literals with bytes literals except for exception messages,
    arguments to utils.Temper methods, docstrigs, and module names.
  Add new tests for svn_stream_*()
  (SubversionCoreTestCase.test_stream_from_stringbuf()): New test method.
  (SubversionCoreTestCase.test_stream_read_full()): New test method.
  (SubversionCoreTestCase.test_stream_read2()): New test method.
  (SubversionCoreTestCase.test_stream_write_exception()): New test method.
  (SubversionCoreTestCase.test_stream_write()): New test method.
  (SubversionCoreTestCase.test_stream_readline()): New test method.

* subversion/bindings/swig/python/tests/delta.py
 (DeltaTestCase.estTxWindowHandler_stream_IF(),
  DeltaTestCase.estTxWindowHandler_Stream_IF()):
  Use bytes literals to make stream when using
   svn.core.svn_stream_from_stringbuf().
  Use bytes file name to make stream when using
   svn.core.svn_stream_from_aprfile2().

* subversion/bindings/swig/python/tests/fs.py
  (SubversionFSTestCase.log_message_func(): log_msg_func3 callback now
    expects bytes to return.
  (SubversionFSTestCase.setUp()): Pass bytes path and url to client.import2().
  (SubversionFSTestCase.test_diff_repos_paths_internal(),
   SubversionFSTestCase.test_diff_repos_paths_external()): Use bytes for
    path1 argument to fs.FileDiff.__init__().

* subversion/bindings/swig/python/tests/mergeinfo.py
  (SubversionMergeinfoTestCase.TEXT_MERGEINFO1,
   SubversionMergeinfoTestCase.TEXT_MERGEINFO2,
   SubversionMergeinfoTestCase.MERGEINFO_SRC): Use bytes instead of str.
  (SubversionMergeinfoTestCase.test_mergeinfo_get()):
   - Pass list of bytes for paths arg to repos.fs_get_mergeinfo().
   - Replace str in expected_mergeinfo with bytes.

* subversion/bindings/swig/python/tests/ra.py
  Replace all str literals with bytes literals except assertion message,
  arguments to utils.Temper methods, docstrings, and module names.
  (SubversionRepositoryAccessTestCase.test_get_file): Compare file
   content as bytes.

* subversion/bindings/swig/python/tests/repository.py
  Replace all str literals with bytes literals when passed into or returned from
    the Subversion API, except exception messages.
  (SubversionRepositoryTestCase.test_dump_fs2()): Treat dump and
   feedback as bytes and compose expected_feedback as bytes.

* subversion/bindings/swig/python/tests/utils.py
  (Temper.alloc_empty_dir(),
   Temper.alloc_empty_repo): Convert return value of tempfile.mkdtemp() into
    bytes.
  (Temper.file_uri_for_path()): Return URI as bytes.

* subversion/bindings/swig/python/tests/wc.py
  Replace all str literals with bytes literals when passed into or returned from
    the Subversion API, except exception messages.
  (SubversionWorkingCopyTestCase.test_get_adm_dir()): Check type as
    bytes.
  (SubversionWorkingCopyTestCase.test_get_pristine_copy_path(),
   SubversionWorkingCopyTestCase.test_diff_editor4()): Open file in raw mode.
  (SubversionWorkingCopyTestCase.test_commit()): Use bytes literals
    instead of str.

* subversion/bindings/swig/python/tests/trac/versioncontrol/main.py
  (Node.DIRECTORY, Node.FILE): Replace str with bytes.
  (Node.__init__): Do not convert path to str.
  (Node.get_name): Treat self.path as bytes.
  (Changeset.ADD, Changeset.COPY, Changeset.DELETE, Changeset.EDIT,
   Changeset.MOVE): Replace str with bytes.

* subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py
  (SubversionRepository.__init__(),
   SubversionRepository.get_oldest_rev(),
   SubversionRepository.youngest_rev(),
   SubversionRepository.next_rev()): Treat self.path and self.scope as bytes.
  (SubversionRepository.normalize_path(),
   SubversionRepository.get_node()): Treat path as bytes.
  (SubversionRepository.get_path_history()): Replace 'unknown' Changeset value
    with bytes.
  (SubversionRepository.get_deltas()): Replace str 'entry' arg to
    repos.svn_repos_dir_delta() with bytes.
  (SubversionNode.__init__()):
   - Treat self.path and self.scope as bytes.
   - Decode path into str for exception message on py3.
  (SubversionNode.get_entries()): Treat self.path as bytes.
  (SubversionNode.get_properties()): Property values are bytes, not str.
  (DiffChangeEditor.open_root()): Return bytes value.

* subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py
  Replace all str literals with bytes literals when passed into or returned from
    the Subversion API, except exception messages.
  (REPOS_URL) Build REPOS_URL as bytes.

Patch By: Yasuhito FUTATSUKI <fu...@poem.co.jp>


Modified:
    subversion/branches/swig-py3/build/ac-macros/swig.m4
    subversion/branches/swig-py3/subversion/bindings/swig/core.i
    subversion/branches/swig-py3/subversion/bindings/swig/include/svn_global.swg
    subversion/branches/swig-py3/subversion/bindings/swig/include/svn_string.swg
    subversion/branches/swig-py3/subversion/bindings/swig/include/svn_swigcompat.swg
    subversion/branches/swig-py3/subversion/bindings/swig/include/svn_types.swg
    subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/branches/swig-py3/subversion/bindings/swig/python/svn/core.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/svn/fs.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/svn/ra.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/svn/repos.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/auth.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/checksum.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/core.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/delta.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/fs.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/mergeinfo.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/ra.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/repository.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/trac/versioncontrol/main.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/utils.py
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/wc.py
    subversion/branches/swig-py3/subversion/bindings/swig/svn_client.i

Modified: subversion/branches/swig-py3/build/ac-macros/swig.m4
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/build/ac-macros/swig.m4?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/build/ac-macros/swig.m4 (original)
+++ subversion/branches/swig-py3/build/ac-macros/swig.m4 Thu Dec 27 03:42:52 2018
@@ -154,7 +154,7 @@ AC_DEFUN(SVN_FIND_SWIG,
           ])
 
           if test "$ac_cv_python_is_py3" = "yes"; then
-             SWIG_PY_OPTS="-python -py3"
+             SWIG_PY_OPTS="-python -py3 -DPY3"
           else
              SWIG_PY_OPTS="-python -classic"
           fi

Modified: subversion/branches/swig-py3/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/core.i?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/core.i (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/core.i Thu Dec 27 03:42:52 2018
@@ -420,7 +420,7 @@
 
 #ifdef SWIGPYTHON
 %typemap(argout) (char *buffer, apr_size_t *len) {
-  %append_output(PyStr_FromStringAndSize($1, *$2));
+  %append_output(PyBytes_FromStringAndSize($1, *$2));
   free($1);
 }
 #endif
@@ -442,16 +442,18 @@
 */
 #ifdef SWIGPYTHON
 %typemap(in) (const char *data, apr_size_t *len) ($*2_type temp) {
-    if (!PyStr_Check($input)) {
+    char *tmpdata;
+    Py_ssize_t length;
+    if (!PyBytes_Check($input)) {
         PyErr_SetString(PyExc_TypeError,
-                        "expecting a string for the buffer");
+                        "expecting a bytes object for the buffer");
         SWIG_fail;
     }
-    /* Explicitly cast away const from PyStr_AsUTF8AndSize (in Python 3). The
-       swig generated argument ($1) here will be "char *", but since its only
-       use is to pass directly into the "const char *" argument of the wrapped
-       function, this is safe to do. */
-    $1 = (char *)PyStr_AsUTF8AndSize($input, &temp);
+    if (PyBytes_AsStringAndSize($input, &tmpdata, &length) == -1) {
+        SWIG_fail;
+    }
+    temp = ($*2_type)length;
+    $1 = tmpdata;
     $2 = ($2_ltype)&temp;
 }
 #endif
@@ -504,8 +506,8 @@
        SWIG_fail;
     }
 
-    if (PyStr_Check($input)) {
-        const char *value = PyStr_AsString($input);
+    if (PyBytes_Check($input)) {
+        const char *value = PyBytes_AsString($input);
         $1 = apr_pstrdup(_global_pool, value);
     }
     else if (PyLong_Check($input)) {

Modified: subversion/branches/swig-py3/subversion/bindings/swig/include/svn_global.swg
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/include/svn_global.swg?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/include/svn_global.swg (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/include/svn_global.swg Thu Dec 27 03:42:52 2018
@@ -31,6 +31,12 @@
 #define SVN_DEPRECATED
 #endif
 
+#ifdef SWIGPYTHON
+%begin %{
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
+%}
+#endif
+
 %include typemaps.i
 %include constraints.i
 %include exception.i
@@ -136,9 +142,15 @@ static PyObject * _global_py_pool = NULL
 /* Python format specifiers. Use Python instead of SWIG to parse
    these basic types, because Python reports better error messages
    (with correct argument numbers). */
+#if defined(PY3)
+%typemap (in, parse="y")
+  char *, char const *, char * const, char const * const "";
+#else
 %typemap (in, parse="s")
   char *, char const *, char * const, char const * const "";
+#endif
 %typemap (in, parse="c") char "";
+
 %typemap (in, fragment=SWIG_As_frag(long)) long
 {
   $1 = ($1_ltype)SWIG_As(long)($input);

Modified: subversion/branches/swig-py3/subversion/bindings/swig/include/svn_string.swg
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/include/svn_string.swg?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/include/svn_string.swg (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/include/svn_string.swg Thu Dec 27 03:42:52 2018
@@ -31,15 +31,13 @@ typedef struct svn_string_t svn_string_t
    because we only refer to the ->data and ->len values.
 */
 #ifdef SWIGPYTHON
-
 %typemap(argout) RET_STRING {
     PyObject *s;
     if (*$1 == NULL) {
         Py_INCREF(Py_None);
         s = Py_None;
-    }
-    else {
-        s = PyStr_FromStringAndSize((*$1)->data, (*$1)->len);
+    } else {
+        s = PyBytes_FromStringAndSize((*$1)->data, (*$1)->len);
         if (s == NULL)
             SWIG_fail;
     }
@@ -76,13 +74,16 @@ typedef struct svn_string_t svn_string_t
 
 #ifdef SWIGPYTHON
 %typemap(in) svn_stringbuf_t * {
-    if (!PyStr_Check($input)) {
-        PyErr_SetString(PyExc_TypeError, "not a string");
+    if (!PyBytes_Check($input)) {
+        PyErr_SetString(PyExc_TypeError, "not a bytes object");
         SWIG_fail;
     }
     {
       Py_ssize_t strBufLen;
-      const char *strBufChar = PyStr_AsUTF8AndSize($input, &strBufLen);
+      char *strBufChar;
+      if (-1 == PyBytes_AsStringAndSize($input, &strBufChar, &strBufLen)) {
+        SWIG_fail;
+      }
       $1 = svn_stringbuf_ncreate(strBufChar, strBufLen,
                                  /* ### gah... what pool to use? */
                                  _global_pool);
@@ -143,7 +144,7 @@ typedef struct svn_string_t svn_string_t
 
 #ifdef SWIGPYTHON
 %typemap(out) svn_stringbuf_t * {
-    $result = PyStr_FromStringAndSize($1->data, $1->len);
+    $result = PyBytes_FromStringAndSize($1->data, (Py_ssize_t)($1->len));
 }
 #endif
 
@@ -179,11 +180,14 @@ typedef struct svn_string_t svn_string_t
         $1 = NULL;
     else {
         Py_ssize_t pyStrLen;
-        if (!PyStr_Check($input)) {
-            PyErr_SetString(PyExc_TypeError, "not a string");
+        if (!PyBytes_Check($input)) {
+            PyErr_SetString(PyExc_TypeError, "not a bytes object");
+            SWIG_fail;
+        }
+        if (PyBytes_AsStringAndSize($input, (char **)&(value.data),
+                                    &pyStrLen) == -1) {
             SWIG_fail;
         }
-        value.data = PyStr_AsUTF8AndSize($input, &pyStrLen);
         value.len = pyStrLen;
         $1 = &value;
     }
@@ -228,7 +232,7 @@ typedef struct svn_string_t svn_string_t
 
 #ifdef SWIGPYTHON
 %typemap(out) svn_string_t * {
-    $result = PyStr_FromStringAndSize($1->data, $1->len);
+    $result = PyBytes_FromStringAndSize($1->data, $1->len);
 }
 #endif
 #ifdef SWIGPERL
@@ -258,7 +262,7 @@ typedef struct svn_string_t svn_string_t
         s = Py_None;
     }
     else {
-        s = PyStr_FromString(*$1);
+        s = PyBytes_FromString(*$1);
         if (s == NULL)
             SWIG_fail;
     }

Modified: subversion/branches/swig-py3/subversion/bindings/swig/include/svn_swigcompat.swg
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/include/svn_swigcompat.swg?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/include/svn_swigcompat.swg (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/include/svn_swigcompat.swg Thu Dec 27 03:42:52 2018
@@ -45,7 +45,7 @@
 #if SWIG_VERSION <= 0x010327
 #ifdef SWIGPYTHON
 %define %set_constant(name, value)
-PyDict_SetItemString(d, name, value);
+PyDict_SetItem(d, PyBytes_FromString(name), value);
 %enddef
 #endif
 #endif

Modified: subversion/branches/swig-py3/subversion/bindings/swig/include/svn_types.swg
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/include/svn_types.swg?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/include/svn_types.swg (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/include/svn_types.swg Thu Dec 27 03:42:52 2018
@@ -346,7 +346,15 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
    Create a typemap for specifying string args that may be NULL.
 */
 #ifdef SWIGPYTHON
-%typemap(in, parse="z") const char *MAY_BE_NULL "";
+%typemap(in) const char *MAY_BE_NULL
+{
+    if ($input == Py_None) {
+        $1 = NULL;
+    } else {
+        $1 = PyBytes_AsString($input);
+        if ($1 == NULL) SWIG_fail;
+    }
+}
 #endif
 
 #ifdef SWIGPERL
@@ -476,15 +484,13 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
 #ifdef SWIGPYTHON
 %typemap(in) (const char *PTR, apr_size_t LEN) {
     Py_ssize_t pyStrLen;
-    if (!PyStr_Check($input)) {
-        PyErr_SetString(PyExc_TypeError, "expecting a string");
+    if (!PyBytes_Check($input)) {
+        PyErr_SetString(PyExc_TypeError, "expecting a bytes");
+        SWIG_fail;
+    }
+    if (PyBytes_AsStringAndSize($input, &$1, &pyStrLen) == -1) {
         SWIG_fail;
     }
-    /* Explicitly cast away const from PyStr_AsUTF8AndSize (in Python 3). The
-       swig generated argument ($1) here will be "char *", but since its only
-       use is to pass directly into the "const char *" argument of the wrapped
-       function, this is safe to do. */
-    $1 = (char *)PyStr_AsUTF8AndSize($input, &pyStrLen);
     $2 = pyStrLen;
 }
 #endif

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=1849784&r1=1849783&r2=1849784&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 Thu Dec 27 03:42:52 2018
@@ -547,23 +547,23 @@ static char *make_string_from_ob(PyObjec
 {
   if (ob == Py_None)
     return NULL;
-  if (! PyStr_Check(ob))
+  if (! PyBytes_Check(ob))
     {
-      PyErr_SetString(PyExc_TypeError, "not a string");
+      PyErr_SetString(PyExc_TypeError, "not a bytes object");
       return NULL;
     }
-  return apr_pstrdup(pool, PyStr_AsString(ob));
+  return apr_pstrdup(pool, PyBytes_AsString(ob));
 }
 static svn_string_t *make_svn_string_from_ob(PyObject *ob, apr_pool_t *pool)
 {
   if (ob == Py_None)
     return NULL;
-  if (! PyStr_Check(ob))
+  if (! PyBytes_Check(ob))
     {
-      PyErr_SetString(PyExc_TypeError, "not a string");
+      PyErr_SetString(PyExc_TypeError, "not a bytes object");
       return NULL;
     }
-  return svn_string_create(PyStr_AsString(ob), pool);
+  return svn_string_create(PyBytes_AsString(ob), pool);
 }
 
 
@@ -598,7 +598,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);
@@ -623,10 +623,10 @@ static PyObject *convert_svn_string_t(vo
 
   const svn_string_t *s = value;
 
-  return PyStr_FromStringAndSize(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)
 {
@@ -636,7 +636,7 @@ static PyObject *cstring_to_pystring(con
       Py_INCREF(Py_None);
       return retval;
     }
-  return PyStr_FromString(cstring);
+  return PyBytes_FromString(cstring);
 }
 
 static PyObject *convert_svn_client_commit_item3_t(void *value, void *ctx)
@@ -712,7 +712,7 @@ PyObject *svn_swig_py_prophash_to_dict(a
 static PyObject *convert_string(void *value, void *ctx,
                                 PyObject *py_pool)
 {
-  return PyStr_FromString((const char *)value);
+  return PyBytes_FromString((const char *)value);
 }
 
 PyObject *svn_swig_py_stringhash_to_dict(apr_hash_t *hash)
@@ -794,7 +794,7 @@ svn_swig_py_propinheriteditemarray_to_di
         apr_hash_t *prop_hash = prop_inherited_item->prop_hash;
         PyObject *py_key, *py_value;
 
-        py_key = PyStr_FromString(prop_inherited_item->path_or_url);
+        py_key = PyBytes_FromString(prop_inherited_item->path_or_url);
         if (py_key == NULL)
           goto error;
 
@@ -838,7 +838,7 @@ PyObject *svn_swig_py_proparray_to_dict(
 
         prop = APR_ARRAY_IDX(array, i, svn_prop_t);
 
-        py_key = PyStr_FromString(prop.name);
+        py_key = PyBytes_FromString(prop.name);
         if (py_key == NULL)
           goto error;
 
@@ -849,8 +849,8 @@ PyObject *svn_swig_py_proparray_to_dict(
           }
         else
           {
-             py_value = PyStr_FromStringAndSize(prop.value->data,
-                                                prop.value->len);
+             py_value = PyBytes_FromStringAndSize(prop.value->data,
+                                                  prop.value->len);
              if (py_value == NULL)
                {
                  Py_DECREF(py_key);
@@ -900,7 +900,7 @@ PyObject *svn_swig_py_locationhash_to_di
             Py_DECREF(dict);
             return NULL;
           }
-        value = PyStr_FromString((const char *)v);
+        value = PyBytes_FromString((const char *)v);
         if (value == NULL)
           {
             Py_DECREF(key);
@@ -965,7 +965,7 @@ PyObject *svn_swig_py_c_strings_to_list(
 
     while ((s = *strings++) != NULL)
       {
-        PyObject *ob = PyStr_FromString(s);
+        PyObject *ob = PyBytes_FromString(s);
 
         if (ob == NULL)
             goto error;
@@ -1008,7 +1008,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);
@@ -1044,7 +1044,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);
@@ -1322,7 +1322,7 @@ svn_swig_py_unwrap_string(PyObject *sour
                           void *baton)
 {
     const char **ptr_dest = destination;
-    *ptr_dest = PyStr_AsString(source);
+    *ptr_dest = PyBytes_AsString(source);
 
     if (*ptr_dest != NULL)
         return 0;
@@ -1441,7 +1441,7 @@ PyObject *svn_swig_py_array_to_list(cons
     for (i = 0; i < array->nelts; ++i)
       {
         PyObject *ob =
-          PyStr_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);
@@ -1749,7 +1749,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();
@@ -1780,7 +1781,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"yOylO&", path, ib->baton,
+#else
                                     (char *)"sOslO&", path, ib->baton,
+#endif
                                     copyfrom_path, copyfrom_revision,
                                     make_ob_pool, dir_pool)) == NULL)
     {
@@ -1811,8 +1816,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();
@@ -1841,7 +1846,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"Oyy#O&", ib->baton, name,
+#else
                                     (char *)"Oss#O&", ib->baton, name,
+#endif
                                     value ? value->data : NULL,
                                     value ? value->len : 0,
                                     make_ob_pool, pool)) == NULL)
@@ -1880,7 +1889,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"yOylO&", path, ib->baton,
+#else
                                     (char *)"sOslO&", path, ib->baton,
+#endif
                                     copyfrom_path, copyfrom_revision,
                                     make_ob_pool, file_pool)) == NULL)
     {
@@ -1912,8 +1925,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();
@@ -1986,7 +1999,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"(Oy)", ib->baton,
+#else
                                     (char *)"(Os)", ib->baton,
+#endif
                                     base_checksum)) == NULL)
     {
       err = callback_exception_error();
@@ -2031,7 +2048,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"Oyy#O&", ib->baton, name,
+#else
                                     (char *)"Oss#O&", ib->baton, name,
+#endif
                                     value ? value->data : NULL,
                                     value ? value->len : 0,
                                     make_ob_pool, pool)) == NULL)
@@ -2061,7 +2082,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"(Oy)", ib->baton,
+#else
                                     (char *)"(Os)", ib->baton,
+#endif
                                     text_checksum)) == NULL)
     {
       err = callback_exception_error();
@@ -2169,7 +2194,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();
@@ -2258,7 +2283,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"Oyy#", ib->baton, name,
+#else
                                     (char *)"Oss#", ib->baton, name,
+#endif
                                     value ? value->data : NULL,
                                     value ? value->len : 0)) == NULL)
     {
@@ -2288,7 +2317,11 @@ 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",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"Oyy#", ib->baton, name,
+#else
                                     (char *)"Oss#", ib->baton, name,
+#endif
                                     value ? value->data : NULL,
                                     value ? value->len : 0)) == NULL)
     {
@@ -2317,7 +2350,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;
@@ -2509,10 +2543,10 @@ apr_file_t *svn_swig_py_make_file(PyObje
   if (py_file == NULL || py_file == Py_None)
     return NULL;
 
-  if (PyStr_Check(py_file))
+  if (PyBytes_Check(py_file))
     {
       /* input is a path -- just open an apr_file_t */
-      const char* fname = PyStr_AsString(py_file);
+      const char* fname = PyBytes_AsString(py_file);
       apr_err = apr_file_open(&apr_file, fname,
                               APR_CREATE | APR_READ | APR_WRITE,
                               APR_OS_DEFAULT, pool);
@@ -2732,7 +2766,11 @@ void svn_swig_py_notify_func(void *baton
 
   svn_swig_py_acquire_py_lock();
   if ((result = PyObject_CallFunction(function,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"(yiiyiii)",
+#else
                                       (char *)"(siisiii)",
+#endif
                                       path, action, kind,
                                       mime_type,
                                       content_state, prop_state,
@@ -2801,7 +2839,8 @@ void svn_swig_py_status_func(void *baton
     return;
 
   svn_swig_py_acquire_py_lock();
-  if ((result = PyObject_CallFunction(function, (char *)"sO&", path,
+  if ((result = PyObject_CallFunction(function,
+                                      (char *)SVN_SWIG_BYTES_FMT "O&", path,
                                       make_ob_wc_status, status)) == NULL)
     {
       err = callback_exception_error();
@@ -2873,7 +2912,12 @@ svn_error_t *svn_swig_py_delta_path_driv
                                                  "void *",
                                                  NULL);
 
-  result = PyObject_CallFunction(function, (char *)"OsO&",
+  result = PyObject_CallFunction(function,
+#if PY_VERSION_HEX >= 0x03000000
+                                 (char *)"OyO&",
+#else
+                                 (char *)"OsO&",
+#endif
                                  py_parent_baton,
                                  path, make_ob_pool, pool);
 
@@ -2913,7 +2957,8 @@ void svn_swig_py_status_func2(void *bato
     return;
 
   svn_swig_py_acquire_py_lock();
-  if ((result = PyObject_CallFunction(function, (char *)"sO&", path,
+  if ((result = PyObject_CallFunction(function,
+                                      (char *)SVN_SWIG_BYTES_FMT "O&", path,
                                       make_ob_wc_status, status)) == NULL)
     {
       err = callback_exception_error();
@@ -3017,7 +3062,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,
@@ -3087,16 +3132,16 @@ svn_error_t *svn_swig_py_get_commit_log_
       *log_msg = NULL;
       err = SVN_NO_ERROR;
     }
-  else if (PyStr_Check(result))
+  else if (PyBytes_Check(result))
     {
-      *log_msg = apr_pstrdup(pool, PyStr_AsString(result));
+      *log_msg = apr_pstrdup(pool, PyBytes_AsString(result));
       Py_DECREF(result);
       err = SVN_NO_ERROR;
     }
   else
     {
       Py_DECREF(result);
-      err = callback_bad_return_error("Not a string");
+      err = callback_bad_return_error("Not a bytes object");
     }
 
  finished:
@@ -3138,7 +3183,11 @@ svn_error_t *svn_swig_py_repos_authz_fun
     }
 
   if ((result = PyObject_CallFunction(function,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"OyO",
+#else
                                       (char *)"OsO",
+#endif
                                       py_root, path, py_pool)) == NULL)
     {
       err = callback_exception_error();
@@ -3175,7 +3224,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)
     {
@@ -3302,7 +3351,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)
     {
@@ -3362,7 +3411,11 @@ svn_error_t *svn_swig_py_log_receiver(vo
     }
 
   if ((result = PyObject_CallFunction(receiver,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"OlyyyO",
+#else
                                       (char *)"OlsssO",
+#endif
                                       chpaths, rev, author, date, msg,
                                       py_pool)) == NULL)
     {
@@ -3440,7 +3493,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)
     {
@@ -3510,7 +3563,11 @@ svn_error_t *svn_swig_py_client_blame_re
 
   if ((result = PyObject_CallFunction(receiver,
                                       (char *)
+#if PY_VERSION_HEX >= 0x03000000
+                                      (SVN_APR_INT64_T_PYCFMT "lyyyO&"),
+#else
                                       (SVN_APR_INT64_T_PYCFMT "lsssO&"),
+#endif
                                       line_no, revision, author, date, line,
                                       make_ob_pool, pool)) == NULL)
     {
@@ -3542,7 +3599,11 @@ svn_error_t *svn_swig_py_changelist_rece
   svn_swig_py_acquire_py_lock();
 
   if ((result = PyObject_CallFunction(receiver,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyO&",
+#else
                                       (char *)"ssO&",
+#endif
                                       path, changelist,
                                       make_ob_pool, pool)) == NULL)
     {
@@ -3577,7 +3638,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)
     {
@@ -3613,7 +3674,11 @@ svn_swig_py_auth_simple_prompt_func(svn_
   svn_swig_py_acquire_py_lock();
 
   if ((result = PyObject_CallFunction(function,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yylO&",
+#else
                                       (char *)"sslO&",
+#endif
                                       realm, username, may_save,
                                       make_ob_pool, pool)) == NULL)
     {
@@ -3664,7 +3729,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)
     {
@@ -3716,7 +3781,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)
     {
@@ -3767,7 +3833,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)
     {
@@ -3818,7 +3884,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)
     {
@@ -3885,7 +3951,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 PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyOO",
+#else
+                                      (char *)"ssOO",
+#endif
                                       cred_kind, realmstring,
                                       py_hash, py_scratch_pool)) == NULL)
     {
@@ -3984,7 +4055,11 @@ ra_callbacks_get_wc_prop(void *baton,
     }
 
   if ((result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyO&", path, name,
+#else
                                       (char *)"ssO&", path, name,
+#endif
                                       make_ob_pool, pool)) == NULL)
     {
       err = callback_exception_error();
@@ -3992,8 +4067,8 @@ ra_callbacks_get_wc_prop(void *baton,
   else if (result != Py_None)
     {
       Py_ssize_t len;
-      const char *buf = PyStr_AsUTF8AndSize(result, &len);
-      if (buf == NULL)
+      char *buf;
+      if (PyBytes_AsStringAndSize(result, &buf, &len) == -1)
         {
           err = callback_exception_error();
         }
@@ -4036,14 +4111,18 @@ ra_callbacks_push_or_set_wc_prop(const c
       goto finished;
     }
 
-  if ((py_value = PyStr_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,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyOO&", path, name, py_value,
+#else
                                       (char *)"ssOO&", path, name, py_value,
+#endif
                                       make_ob_pool, pool)) == NULL)
     {
       err = callback_exception_error();
@@ -4106,7 +4185,11 @@ ra_callbacks_invalidate_wc_props(void *b
     }
 
   if ((result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyO&", path, name,
+#else
                                       (char *)"ssO&", path, name,
+#endif
                                       make_ob_pool, pool)) == NULL)
     {
       err = callback_exception_error();
@@ -4235,7 +4318,7 @@ ra_callbacks_get_client_string(void *bat
     }
   else if (result != Py_None)
     {
-      if ((*name = PyStr_AsString(result)) == NULL)
+      if ((*name = PyBytes_AsString(result)) == NULL)
         {
           err = callback_exception_error();
         }
@@ -4338,7 +4421,11 @@ svn_error_t *svn_swig_py_commit_callback
   svn_swig_py_acquire_py_lock();
 
   if ((result = PyObject_CallFunction(receiver,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"lyy",
+#else
                                       (char *)"lss",
+#endif
                                       new_revision, date, author)) == NULL)
     {
       err = callback_exception_error();
@@ -4390,7 +4477,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)
     {
@@ -4436,7 +4523,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,
@@ -4473,7 +4560,11 @@ static svn_error_t *reporter_set_path(vo
 
   if ((result = PyObject_CallMethod(py_reporter,
                                     (char *)"set_path",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"ylbyO&",
+#else
                                     (char *)"slbsO&",
+#endif
                                     path, revision,
                                     start_empty, lock_token,
                                     make_ob_pool, pool)) == NULL)
@@ -4506,7 +4597,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)
     {
@@ -4542,7 +4633,11 @@ static svn_error_t *reporter_link_path(v
 
   if ((result = PyObject_CallMethod(py_reporter,
                                     (char *)"link_path",
+#if PY_VERSION_HEX >= 0x03000000
+                                    (char *)"yylbsO&",
+#else
                                     (char *)"sslbsO&",
+#endif
                                     path, url, revision,
                                     start_empty, lock_token,
                                     make_ob_pool, pool)) == NULL)
@@ -4673,7 +4768,11 @@ wc_diff_callbacks2_file_changed_or_added
     }
 
   result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                 (char *)"O&yyyllyyO&O&",
+#else
                                  (char *)"O&sssllssO&O&",
+#endif
                                  make_ob_wc_adm_access, adm_access,
                                  path,
                                  tmpfile1, tmpfile2,
@@ -4796,7 +4895,11 @@ wc_diff_callbacks2_file_deleted(svn_wc_a
     }
 
   result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                 (char *)"O&yyyyyO&",
+#else
                                  (char *)"O&sssssO&",
+#endif
                                  make_ob_wc_adm_access, adm_access,
                                  path,
                                  tmpfile1, tmpfile2,
@@ -4850,7 +4953,11 @@ wc_diff_callbacks2_dir_added(svn_wc_adm_
     }
 
   result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                 (char *)"O&yl",
+#else
                                  (char *)"O&sl",
+#endif
                                  make_ob_wc_adm_access, adm_access,
                                  path, rev);
   if (result == NULL)
@@ -4900,7 +5007,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)
     {
@@ -4952,7 +5059,11 @@ wc_diff_callbacks2_dir_props_changed(svn
     }
 
   result = PyObject_CallFunction(py_callback,
+#if PY_VERSION_HEX >= 0x03000000
+                                 (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,
@@ -5008,7 +5119,11 @@ svn_swig_py_config_enumerator2(const cha
   svn_swig_py_acquire_py_lock();
 
   if ((result = PyObject_CallFunction(function,
+#if PY_VERSION_HEX >= 0x03000000
+                                      (char *)"yyO&",
+#else
                                       (char *)"ssO&",
+#endif
                                       name,
                                       value,
                                       make_ob_pool, pool)) == NULL)
@@ -5056,7 +5171,7 @@ svn_swig_py_config_section_enumerator2(c
   svn_swig_py_acquire_py_lock();
 
   if ((result = PyObject_CallFunction(function,
-                                      (char *)"sO&",
+                                      (char *)SVN_SWIG_BYTES_FMT "O&",
                                       name,
                                       make_ob_pool, pool)) == NULL)
     {

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/svn/core.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/svn/core.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/svn/core.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/svn/core.py Thu Dec 27 03:42:52 2018
@@ -155,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)
@@ -185,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))

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/svn/fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/svn/fs.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/svn/fs.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/svn/fs.py Thu Dec 27 03:42:52 2018
@@ -132,16 +132,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/swig-py3/subversion/bindings/swig/python/svn/ra.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/svn/ra.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/svn/ra.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/svn/ra.py Thu Dec 27 03:42:52 2018
@@ -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/swig-py3/subversion/bindings/swig/python/svn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/svn/repos.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/svn/repos.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/svn/repos.py Thu Dec 27 03:42:52 2018
@@ -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/swig-py3/subversion/bindings/swig/python/tests/auth.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/auth.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/auth.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/auth.py Thu Dec 27 03:42:52 2018
@@ -31,82 +31,82 @@ class SubversionAuthTestCase(unittest.Te
 
   def test_set_parameter(self):
     baton = core.svn_auth_open([])
-    core.svn_auth_set_parameter(baton, "name", "somedata")
-    core.svn_auth_set_parameter(baton, "name", None)
-    core.svn_auth_set_parameter(baton, "name", 2)
-    core.svn_auth_set_parameter(baton, "name",
+    core.svn_auth_set_parameter(baton, b"name", b"somedata")
+    core.svn_auth_set_parameter(baton, b"name", None)
+    core.svn_auth_set_parameter(baton, b"name", 2)
+    core.svn_auth_set_parameter(baton, b"name",
                                 core.svn_auth_ssl_server_cert_info_t())
 
   def test_invalid_cred_kind(self):
     baton = core.svn_auth_open([])
     self.assertRaises(core.SubversionException,
             lambda: core.svn_auth_first_credentials(
-                "unknown", "somerealm", baton))
+                b"unknown", b"somerealm", baton))
 
   def test_credentials_get_username(self):
     def myfunc(realm, maysave, pool):
-      self.assertEqual("somerealm", realm)
+      self.assertEqual(b"somerealm", realm)
       username_cred = core.svn_auth_cred_username_t()
-      username_cred.username = "bar"
+      username_cred.username = b"bar"
       username_cred.may_save = False
       return username_cred
     baton = core.svn_auth_open([core.svn_auth_get_username_prompt_provider(myfunc, 1)])
     creds = core.svn_auth_first_credentials(
-                core.SVN_AUTH_CRED_USERNAME, "somerealm", baton)
+                core.SVN_AUTH_CRED_USERNAME, b"somerealm", baton)
     self.assertTrue(creds is not None)
 
   def test_credentials_get_simple(self):
     def myfunc(realm, username, may_save, pool):
-      self.assertEqual("somerealm", realm)
+      self.assertEqual(b"somerealm", realm)
       simple_cred = core.svn_auth_cred_simple_t()
-      simple_cred.username = "mijnnaam"
-      simple_cred.password = "geheim"
+      simple_cred.username = b"mijnnaam"
+      simple_cred.password = b"geheim"
       simple_cred.may_save = False
       return simple_cred
     baton = core.svn_auth_open([core.svn_auth_get_simple_prompt_provider(myfunc, 1)])
     creds = core.svn_auth_first_credentials(
-                core.SVN_AUTH_CRED_SIMPLE, "somerealm", baton)
+                core.SVN_AUTH_CRED_SIMPLE, b"somerealm", baton)
     self.assertTrue(creds is not None)
 
   def test_credentials_get_ssl_client_cert(self):
     def myfunc(realm, may_save, pool):
-      self.assertEqual("somerealm", realm)
+      self.assertEqual(b"somerealm", realm)
       ssl_cred = core.svn_auth_cred_ssl_client_cert_t()
-      ssl_cred.cert_file = "my-certs-file"
+      ssl_cred.cert_file = b"my-certs-file"
       ssl_cred.may_save = False
       return ssl_cred
     baton = core.svn_auth_open([core.svn_auth_get_ssl_client_cert_prompt_provider(myfunc, 1)])
     creds = core.svn_auth_first_credentials(
-                core.SVN_AUTH_CRED_SSL_CLIENT_CERT, "somerealm", baton)
+                core.SVN_AUTH_CRED_SSL_CLIENT_CERT, b"somerealm", baton)
     self.assertTrue(creds is not None)
 
   def test_credentials_get_ssl_client_cert_pw(self):
     def myfunc(realm, may_save, pool):
-      self.assertEqual("somerealm", realm)
+      self.assertEqual(b"somerealm", realm)
       ssl_cred_pw = core.svn_auth_cred_ssl_client_cert_pw_t()
-      ssl_cred_pw.password = "supergeheim"
+      ssl_cred_pw.password = b"supergeheim"
       ssl_cred_pw.may_save = False
       return ssl_cred_pw
     baton = core.svn_auth_open([core.svn_auth_get_ssl_client_cert_pw_prompt_provider(myfunc, 1)])
     creds = core.svn_auth_first_credentials(
-                core.SVN_AUTH_CRED_SSL_CLIENT_CERT_PW, "somerealm", baton)
+                core.SVN_AUTH_CRED_SSL_CLIENT_CERT_PW, b"somerealm", baton)
     self.assertTrue(creds is not None)
 
   def test_credentials_get_ssl_server_trust(self):
     def myfunc(realm, failures, cert_info, may_save, pool):
-      self.assertEqual("somerealm", realm)
+      self.assertEqual(b"somerealm", realm)
       ssl_trust = core.svn_auth_cred_ssl_server_trust_t()
       ssl_trust.accepted_failures = 0
       ssl_trust.may_save = False
       return ssl_trust
     baton = core.svn_auth_open([core.svn_auth_get_ssl_server_trust_prompt_provider(myfunc)])
     core.svn_auth_set_parameter(baton, core.SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
-                                "2")
+                                b"2")
     cert_info = core.svn_auth_ssl_server_cert_info_t()
     core.svn_auth_set_parameter(baton, core.SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
                 cert_info)
     creds = core.svn_auth_first_credentials(
-                core.SVN_AUTH_CRED_SSL_SERVER_TRUST, "somerealm", baton)
+                core.SVN_AUTH_CRED_SSL_SERVER_TRUST, b"somerealm", baton)
     self.assertTrue(creds is not None)
 
 def suite():

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/checksum.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/checksum.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/checksum.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/checksum.py Thu Dec 27 03:42:52 2018
@@ -29,7 +29,7 @@ class ChecksumTestCases(unittest.TestCas
         val = svn.core.svn_checksum_create(kind)
         check_val = svn.core.svn_checksum_to_cstring_display(val)
 
-        self.assertTrue(isinstance(check_val, str),
+        self.assertTrue(isinstance(check_val, bytes),
                               "Type of digest not string")
         self.assertEqual(len(check_val), 2*expected_length,
                          "Length of digest does not match kind")

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py Thu Dec 27 03:42:52 2018
@@ -40,7 +40,7 @@ class SubversionClientTestCase(unittest.
   def log_message_func(self, items, pool):
     """ Simple log message provider for unit tests. """
     self.log_message_func_calls += 1
-    return "Test log message"
+    return b"Test log message"
 
   def log_receiver(self, changed_paths, revision, author, date, message, pool):
     """ Function to receive log messages retrieved by client.log3(). """
@@ -134,8 +134,8 @@ class SubversionClientTestCase(unittest.
 
     # We keep track of these objects in separate variables here
     # because you can't get a PyObject back out of a PY_AS_VOID field
-    test_object1 = lambda *args: "message 1"
-    test_object2 = lambda *args: "message 2"
+    test_object1 = lambda *args: b"message 1"
+    test_object2 = lambda *args: b"message 2"
 
     # Verify that the refcount of a Python object is incremented when
     # you insert it into a PY_AS_VOID field.
@@ -191,7 +191,7 @@ class SubversionClientTestCase(unittest.
 
   def test_mkdir_url(self):
     """Test svn_client_mkdir2 on a file:// URL"""
-    directory = urljoin(self.repos_uri+"/", "dir1")
+    directory = urljoin(self.repos_uri+b"/", b"dir1")
 
     commit_info = client.mkdir2((directory,), self.client_ctx)
     self.assertEqual(commit_info.revision, 13)
@@ -199,28 +199,28 @@ class SubversionClientTestCase(unittest.
 
   def test_mkdir_url_with_revprops(self):
     """Test svn_client_mkdir3 on a file:// URL, with added revprops"""
-    directory = urljoin(self.repos_uri+"/", "some/deep/subdir")
+    directory = urljoin(self.repos_uri+b"/", b"some/deep/subdir")
 
-    commit_info = client.mkdir3((directory,), 1, {'customprop':'value'},
+    commit_info = client.mkdir3((directory,), 1, {b'customprop':b'value'},
                                 self.client_ctx)
     self.assertEqual(commit_info.revision, 13)
     self.assertEqual(self.log_message_func_calls, 1)
 
   def test_log3_url(self):
     """Test svn_client_log3 on a file:// URL"""
-    directory = urljoin(self.repos_uri+"/", "trunk/dir1")
+    directory = urljoin(self.repos_uri+b"/", b"trunk/dir1")
 
     start = core.svn_opt_revision_t()
     end = core.svn_opt_revision_t()
-    core.svn_opt_parse_revision(start, end, "4:0")
+    core.svn_opt_parse_revision(start, end, b"4:0")
     client.log3((directory,), start, start, end, 1, True, False,
         self.log_receiver, self.client_ctx)
-    self.assertEqual(self.change_author, "john")
-    self.assertEqual(self.log_message, "More directories.")
+    self.assertEqual(self.change_author, b"john")
+    self.assertEqual(self.log_message, b"More directories.")
     self.assertEqual(len(self.changed_paths), 3)
-    for dir in ('/trunk/dir1', '/trunk/dir2', '/trunk/dir3'):
+    for dir in (b'/trunk/dir1', b'/trunk/dir2', b'/trunk/dir3'):
       self.assertTrue(dir in self.changed_paths)
-      self.assertEqual(self.changed_paths[dir].action, 'A')
+      self.assertEqual(self.changed_paths[dir].action, b'A')
 
   def test_log5(self):
     """Test svn_client_log5."""
@@ -247,7 +247,7 @@ class SubversionClientTestCase(unittest.
     """Test svn_client_uuid_from_url on a file:// URL"""
     self.assertTrue(isinstance(
                  client.uuid_from_url(self.repos_uri, self.client_ctx),
-                 str))
+                 bytes))
 
   def test_url_from_path(self):
     """Test svn_client_url_from_path for a file:// URL"""
@@ -279,7 +279,7 @@ class SubversionClientTestCase(unittest.
                       client.uuid_from_url(self.repos_uri, self.client_ctx))
 
     self.assertTrue(isinstance(client.uuid_from_path(path, wc_adm,
-                            self.client_ctx), str))
+                            self.client_ctx), bytes))
 
   def test_open_ra_session(self):
       """Test svn_client_open_ra_session()."""
@@ -302,8 +302,8 @@ class SubversionClientTestCase(unittest.
     try:
       # Test 1: Run info -r BASE. We expect the size value to be filled in.
       rev.kind = core.svn_opt_revision_base
-      readme_path = '%s/trunk/README.txt' % wc_path
-      readme_url = '%s/trunk/README.txt' % self.repos_uri
+      readme_path = b'%s/trunk/README.txt' % wc_path
+      readme_url = b'%s/trunk/README.txt' % self.repos_uri
       client.info(readme_path, rev, rev, self.info_receiver,
                   False, self.client_ctx)
 
@@ -349,8 +349,8 @@ class SubversionClientTestCase(unittest.
                      True, False, self.client_ctx)
 
     # Let's try to backport a change from the v1x branch
-    trunk_path = core.svn_dirent_join(wc_path, 'trunk')
-    v1x_path = core.svn_dirent_join(wc_path, 'branches/v1x')
+    trunk_path = core.svn_dirent_join(wc_path, b'trunk')
+    v1x_path = core.svn_dirent_join(wc_path, b'branches/v1x')
 
     start = core.svn_opt_revision_t()
     start.kind = core.svn_opt_revision_number
@@ -370,14 +370,14 @@ class SubversionClientTestCase(unittest.
 
     # Did it take effect?
     readme_path_native = core.svn_dirent_local_style(
-      core.svn_dirent_join(trunk_path, 'README.txt')
+      core.svn_dirent_join(trunk_path, b'README.txt')
     )
 
-    readme = open(readme_path_native, 'r')
+    readme = open(readme_path_native, 'rb')
     readme_text = readme.read()
     readme.close()
 
-    self.assertEqual(readme_text, 'This is a test.\n')
+    self.assertEqual(readme_text, b'This is a test.\n')
 
   def test_platform_providers(self):
     providers = core.svn_auth_get_platform_specific_client_providers(None, None)
@@ -396,38 +396,38 @@ class SubversionClientTestCase(unittest.
     # just test if this doesn't error out, there's not even a return
     # value to test.
     def prompt_func(realm_string, pool):
-      return "Foo"
+      return b"Foo"
 
     core.svn_auth_set_gnome_keyring_unlock_prompt_func(self.client_ctx.auth_baton, prompt_func)
 
   def proplist_receiver_trunk(self, path, props, iprops, pool):
-    self.assertEqual(props['svn:global-ignores'], '*.q\n')
+    self.assertEqual(props[b'svn:global-ignores'], b'*.q\n')
     self.proplist_receiver_trunk_calls += 1
 
   def proplist_receiver_dir1(self, path, props, iprops, pool):
     self.assertEqual(iprops[self.proplist_receiver_dir1_key],
-                      {'svn:global-ignores':'*.q\n'})
+                      {b'svn:global-ignores':b'*.q\n'})
     self.proplist_receiver_dir1_calls += 1
 
   def test_inherited_props(self):
     """Test inherited props"""
 
-    trunk_url = self.repos_uri + '/trunk'
-    client.propset_remote('svn:global-ignores', '*.q', trunk_url,
+    trunk_url = self.repos_uri + b'/trunk'
+    client.propset_remote(b'svn:global-ignores', b'*.q', trunk_url,
                           False, 12, {}, None, self.client_ctx)
 
     head = core.svn_opt_revision_t()
     head.kind = core.svn_opt_revision_head
-    props, iprops, rev = client.propget5('svn:global-ignores', trunk_url,
+    props, iprops, rev = client.propget5(b'svn:global-ignores', trunk_url,
                                          head, head, core.svn_depth_infinity,
                                          None, self.client_ctx)
-    self.assertEqual(props[trunk_url], '*.q\n')
+    self.assertEqual(props[trunk_url], b'*.q\n')
 
-    dir1_url = trunk_url + '/dir1'
-    props, iprops, rev = client.propget5('svn:global-ignores', dir1_url,
+    dir1_url = trunk_url + b'/dir1'
+    props, iprops, rev = client.propget5(b'svn:global-ignores', dir1_url,
                                          head, head, core.svn_depth_infinity,
                                          None, self.client_ctx)
-    self.assertEqual(iprops[trunk_url], {'svn:global-ignores':'*.q\n'})
+    self.assertEqual(iprops[trunk_url], {b'svn:global-ignores':b'*.q\n'})
 
     self.proplist_receiver_trunk_calls = 0
     client.proplist4(trunk_url, head, head, core.svn_depth_empty, None, True,
@@ -467,15 +467,15 @@ class SubversionClientTestCase(unittest.
                    False, False, self.client_ctx)
     expected_paths = [
         path,
-        os.path.join(path, 'branches'),
-        os.path.join(path, 'tags'),
-        os.path.join(path, 'trunk'),
+        os.path.join(path, b'branches'),
+        os.path.join(path, b'tags'),
+        os.path.join(path, b'trunk'),
         path,
         path
     ]
     # All normal subversion apis process paths in Subversion's canonical format,
     # which isn't the platform specific format
-    expected_paths = [x.replace(os.path.sep, '/') for x in expected_paths]
+    expected_paths = [x.replace(os.path.sep.encode('UTF-8'), b'/') for x in expected_paths]
     self.notified_paths.sort()
     expected_paths.sort()
 
@@ -490,12 +490,12 @@ class SubversionClientTestCase(unittest.
     self.notified_paths = []
     expected_paths = [
         path,
-        os.path.join(path, 'trunk', 'README.txt'),
-        os.path.join(path, 'trunk'),
+        os.path.join(path, b'trunk', b'README.txt'),
+        os.path.join(path, b'trunk'),
         path,
         path
     ]
-    expected_paths = [x.replace(os.path.sep, '/') for x in expected_paths]
+    expected_paths = [x.replace(os.path.sep.encode('UTF-8'), b'/') for x in expected_paths]
     client.update4((path,), rev, core.svn_depth_unknown, True, False, False,
                    False, False, self.client_ctx)
     self.notified_paths.sort()

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/core.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/core.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/core.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/core.py Thu Dec 27 03:42:52 2018
@@ -19,6 +19,8 @@
 #
 #
 import unittest
+import os
+import tempfile
 
 import svn.core, svn.client
 import utils
@@ -40,13 +42,13 @@ class SubversionCoreTestCase(unittest.Te
                      'error message')
 
   def test_mime_type_is_binary(self):
-    self.assertEqual(0, svn.core.svn_mime_type_is_binary("text/plain"))
-    self.assertEqual(1, svn.core.svn_mime_type_is_binary("image/png"))
+    self.assertEqual(0, svn.core.svn_mime_type_is_binary(b"text/plain"))
+    self.assertEqual(1, svn.core.svn_mime_type_is_binary(b"image/png"))
 
   def test_mime_type_validate(self):
     self.assertRaises(svn.core.SubversionException,
-            svn.core.svn_mime_type_validate, "this\nis\ninvalid\n")
-    svn.core.svn_mime_type_validate("unknown/but-valid; charset=utf8")
+            svn.core.svn_mime_type_validate, b"this\nis\ninvalid\n")
+    svn.core.svn_mime_type_validate(b"unknown/but-valid; charset=utf8")
 
   def test_exception_interoperability(self):
     """Test if SubversionException is correctly converted into svn_error_t
@@ -109,20 +111,20 @@ class SubversionCoreTestCase(unittest.Te
   def test_config_enumerate2(self):
     cfg = svn.core.svn_config_create(False)
     entries = {
-      'one': 'one-value',
-      'two': 'two-value',
-      'three': 'three-value'
+      b'one': b'one-value',
+      b'two': b'two-value',
+      b'three': b'three-value'
     }
 
     for (name, value) in entries.items():
-      svn.core.svn_config_set(cfg, "section", name, value)
+      svn.core.svn_config_set(cfg, b"section", name, value)
 
     received_entries = {}
     def enumerator(name, value, pool):
       received_entries[name] = value
       return len(received_entries) < 2
 
-    svn.core.svn_config_enumerate2(cfg, "section", enumerator)
+    svn.core.svn_config_enumerate2(cfg, b"section", enumerator)
 
     self.assertEqual(len(received_entries), 2)
     for (name, value) in received_entries.items():
@@ -131,22 +133,22 @@ class SubversionCoreTestCase(unittest.Te
 
   def test_config_enumerate2_exception(self):
     cfg = svn.core.svn_config_create(False)
-    svn.core.svn_config_set(cfg, "section", "one", "one-value")
-    svn.core.svn_config_set(cfg, "section", "two", "two-value")
+    svn.core.svn_config_set(cfg, b"section", b"one", b"one-value")
+    svn.core.svn_config_set(cfg, b"section", b"two", b"two-value")
 
     def enumerator(name, value, pool):
       raise Exception
 
     # the exception will be swallowed, but enumeration must be stopped
     self.assertEqual(
-      svn.core.svn_config_enumerate2(cfg, "section", enumerator), 1)
+      svn.core.svn_config_enumerate2(cfg, b"section", enumerator), 1)
 
   def test_config_enumerate_sections2(self):
     cfg = svn.core.svn_config_create(False)
-    sections = ['section-one', 'section-two', 'section-three']
+    sections = [b'section-one', b'section-two', b'section-three']
 
     for section in sections:
-      svn.core.svn_config_set(cfg, section, "name", "value")
+      svn.core.svn_config_set(cfg, section, b"name", b"value")
 
     received_sections = []
     def enumerator(section, pool):
@@ -161,8 +163,8 @@ class SubversionCoreTestCase(unittest.Te
 
   def test_config_enumerate_sections2_exception(self):
     cfg = svn.core.svn_config_create(False)
-    svn.core.svn_config_set(cfg, "section-one", "name", "value")
-    svn.core.svn_config_set(cfg, "section-two", "name", "value")
+    svn.core.svn_config_set(cfg, b"section-one", b"name", b"value")
+    svn.core.svn_config_set(cfg, b"section-two", b"name", b"value")
 
     def enumerator(section, pool):
       raise Exception
@@ -171,6 +173,120 @@ class SubversionCoreTestCase(unittest.Te
     self.assertEqual(
       svn.core.svn_config_enumerate_sections2(cfg, enumerator), 1)
 
+  def test_stream_from_stringbuf(self):
+    stream = svn.core.svn_stream_from_stringbuf(b'')
+    svn.core.svn_stream_close(stream)
+    with self.assertRaises(TypeError):
+        stream = svn.core.svn_stream_from_stringbuf(b''.decode())
+        svn.core.svn_stream_close(stream)
+
+  def test_stream_read_full(self):
+    in_str = (b'Python\x00'
+              b'\xa4\xd1\xa4\xa4\xa4\xbd\xa4\xf3\r\n'
+              b'Subversion\x00'
+              b'\xa4\xb5\xa4\xd6\xa4\xd0\xa1\xbc\xa4\xb8\xa4\xe7\xa4\xf3\n'
+              b'swig\x00'
+              b'\xa4\xb9\xa4\xa6\xa4\xa3\xa4\xb0\r'
+              b'end')
+    stream = svn.core.svn_stream_from_stringbuf(in_str)
+    self.assertEqual(svn.core.svn_stream_read_full(stream, 4096), in_str)
+    svn.core.svn_stream_seek(stream, None)
+    self.assertEqual(svn.core.svn_stream_read_full(stream, 10), in_str[0:10])
+    svn.core.svn_stream_seek(stream, None)
+    svn.core.svn_stream_skip(stream, 20)
+    self.assertEqual(svn.core.svn_stream_read_full(stream, 4096), in_str[20:])
+    self.assertEqual(svn.core.svn_stream_read_full(stream, 4096), b'')
+    svn.core.svn_stream_close(stream)
+
+  def test_stream_read2(self):
+    # as we can't create non block stream by using swig-py API directly,
+    # we only test svn_stream_read2() behaves just same as
+    # svn_stream_read_full()
+    in_str = (b'Python\x00'
+              b'\xa4\xd1\xa4\xa4\xa4\xbd\xa4\xf3\r\n'
+              b'Subversion\x00'
+              b'\xa4\xb5\xa4\xd6\xa4\xd0\xa1\xbc\xa4\xb8\xa4\xe7\xa4\xf3\n'
+              b'swig\x00'
+              b'\xa4\xb9\xa4\xa6\xa4\xa3\xa4\xb0\r'
+              b'end')
+    stream = svn.core.svn_stream_from_stringbuf(in_str)
+    self.assertEqual(svn.core.svn_stream_read2(stream, 4096), in_str)
+    svn.core.svn_stream_seek(stream, None)
+    self.assertEqual(svn.core.svn_stream_read2(stream, 10), in_str[0:10])
+    svn.core.svn_stream_seek(stream, None)
+    svn.core.svn_stream_skip(stream, 20)
+    self.assertEqual(svn.core.svn_stream_read2(stream, 4096), in_str[20:])
+    self.assertEqual(svn.core.svn_stream_read2(stream, 4096), b'')
+    svn.core.svn_stream_close(stream)
+
+  def test_stream_write_exception(self):
+    ostr_unicode = b'Python'.decode()
+    stream = svn.core.svn_stream_empty()
+    with self.assertRaises(TypeError):
+        svn.core.svn_stream_write(stream, ostr_unicode)
+    svn.core.svn_stream_close(stream)
+
+  def test_stream_write(self):
+    o1_str = b'Python\x00\xa4\xd1\xa4\xa4\xa4\xbd\xa4\xf3\r\n'
+    o2_str = (b'subVersioN\x00'
+              b'\xa4\xb5\xa4\xd6\xa4\xd0\xa1\xbc\xa4\xb8\xa4\xe7\xa4\xf3\n')
+    o3_str =  b'swig\x00\xa4\xb9\xa4\xa6\xa4\xa3\xa4\xb0\rend'
+    out_str = o1_str + o2_str + o3_str
+    rewrite_str = b'Subversion'
+    fd, fname = tempfile.mkstemp()
+    os.close(fd)
+    try:
+      stream = svn.core.svn_stream_from_aprfile2(fname.encode('UTF-8'), False)
+      self.assertEqual(svn.core.svn_stream_write(stream, out_str),
+                       len(out_str))
+      svn.core.svn_stream_seek(stream, None)
+      self.assertEqual(svn.core.svn_stream_read_full(stream, 4096), out_str)
+      svn.core.svn_stream_seek(stream, None)
+      svn.core.svn_stream_skip(stream, len(o1_str))
+      self.assertEqual(svn.core.svn_stream_write(stream, rewrite_str),
+                       len(rewrite_str))
+      svn.core.svn_stream_seek(stream, None)
+      self.assertEqual(
+                svn.core.svn_stream_read_full(stream, 4096),
+                o1_str + rewrite_str + o2_str[len(rewrite_str):] + o3_str)
+      svn.core.svn_stream_close(stream)
+    finally:
+      try:
+        os.remove(fname)
+      except OSError:
+        pass
+
+  def test_stream_readline(self):
+    o1_str = b'Python\t\xa4\xd1\xa4\xa4\xa4\xbd\xa4\xf3\r\n'
+    o2_str = (b'Subversion\t'
+              b'\xa4\xb5\xa4\xd6\xa4\xd0\xa1\xbc\xa4\xb8\xa4\xe7\xa4\xf3\n')
+    o3_str =  b'swig\t\xa4\xb9\xa4\xa6\xa4\xa3\xa4\xb0\rend'
+    in_str = o1_str + o2_str + o3_str
+    stream = svn.core.svn_stream_from_stringbuf(in_str)
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\n'),
+                     [o1_str[:-1], 0])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\n'),
+                     [o2_str[:-1], 0])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\n'),
+                     [o3_str, 1])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\n'),
+                     [b'', 1])
+    svn.core.svn_stream_seek(stream, None)
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\r\n'),
+                     [o1_str[:-2], 0])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\r\n'),
+                     [o2_str + o3_str, 1])
+    svn.core.svn_stream_write(stream, b'\r\n')
+    svn.core.svn_stream_seek(stream, None)
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\r\n'),
+                     [o1_str[:-2], 0])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\r\n'),
+                     [o2_str + o3_str, 0])
+    self.assertEqual(svn.core.svn_stream_readline(stream, b'\r\n'),
+                     [b'', 1])
+    svn.core.svn_stream_close(stream)
+
+
 def suite():
     return unittest.defaultTestLoader.loadTestsFromTestCase(
       SubversionCoreTestCase)

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/delta.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/delta.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/delta.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/delta.py Thu Dec 27 03:42:52 2018
@@ -47,14 +47,15 @@ class DeltaTestCase(unittest.TestCase):
   def testTxWindowHandler_stream_IF(self):
     """Test tx_invoke_window_handler, with svn.core.svn_stream_t object"""
     pool = svn.core.Pool()
-    in_str = "hello world"
+    in_str = b"hello world"
     src_stream = svn.core.svn_stream_from_stringbuf(in_str)
-    content_str = "bye world"
+    content_str = b"bye world"
     content_stream = svn.core.svn_stream_from_stringbuf(content_str)
     fd, fname = tempfile.mkstemp()
     os.close(fd)
     try:
-      target_stream = svn.core.svn_stream_from_aprfile2(fname, False)
+      target_stream = svn.core.svn_stream_from_aprfile2(fname.encode('UTF-8'),
+                                                        False)
       window_handler, baton = \
           svn.delta.tx_apply(src_stream, target_stream, None)
       svn.delta.tx_send_stream(content_stream, window_handler, baton, pool)
@@ -72,17 +73,18 @@ class DeltaTestCase(unittest.TestCase):
   def testTxWindowHandler_Stream_IF(self):
     """Test tx_invoke_window_handler, with svn.core.Stream object"""
     pool = svn.core.Pool()
-    in_str = "hello world"
+    in_str = b"hello world"
     src_stream = svn.core.Stream(
                     svn.core.svn_stream_from_stringbuf(in_str))
-    content_str = "bye world"
+    content_str = b"bye world"
     content_stream = svn.core.Stream(
                     svn.core.svn_stream_from_stringbuf(content_str))
     fd, fname = tempfile.mkstemp()
     os.close(fd)
     try:
       target_stream = svn.core.Stream(
-                    svn.core.svn_stream_from_aprfile2(fname, False))
+                    svn.core.svn_stream_from_aprfile2(fname.encode('UTF-8'),
+                                                      False))
       window_handler, baton = \
           svn.delta.tx_apply(src_stream, target_stream, None)
       svn.delta.tx_send_stream(content_stream, window_handler, baton, None)

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/fs.py?rev=1849784&r1=1849783&r2=1849784&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/fs.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/fs.py Thu Dec 27 03:42:52 2018
@@ -37,7 +37,7 @@ class SubversionFSTestCase(unittest.Test
 
   def log_message_func(self, items, pool):
     """ Simple log message provider for unit tests. """
-    return "Test unicode log message"
+    return b"Test unicode log message"
 
   def setUp(self):
     """Load a Subversion repository"""
@@ -68,8 +68,8 @@ class SubversionFSTestCase(unittest.Test
 
     clientctx.auth_baton = core.svn_auth_open(providers)
 
-    commitinfo = client.import2(self.tmpfile,
-                                urljoin(self.repos_uri +"/", "trunk/UniTest.txt"),
+    commitinfo = client.import2(self.tmpfile.encode('UTF-8'),
+                                urljoin(self.repos_uri + b"/", b"trunk/UniTest.txt"),
                                 True, True,
                                 clientctx)
 
@@ -87,7 +87,7 @@ class SubversionFSTestCase(unittest.Test
     """Test diffing of a repository path using the internal diff."""
 
     # Test standard internal diff
-    fdiff = fs.FileDiff(fs.revision_root(self.fs, self.commitedrev), "/trunk/UniTest.txt",
+    fdiff = fs.FileDiff(fs.revision_root(self.fs, self.commitedrev), b"/trunk/UniTest.txt",
                         None, None, diffoptions=None)
 
     diffp = fdiff.get_pipe()
@@ -108,7 +108,7 @@ class SubversionFSTestCase(unittest.Test
       else:
         raise err
 
-    fdiff = fs.FileDiff(fs.revision_root(self.fs, self.commitedrev), "/trunk/UniTest.txt",
+    fdiff = fs.FileDiff(fs.revision_root(self.fs, self.commitedrev), b"/trunk/UniTest.txt",
                         None, None, diffoptions=[])
     diffp = fdiff.get_pipe()
     diffoutput = diffp.read().decode('utf8')