Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/repository.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/repository.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/repository.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/repository.py Fri Jan 14 14:01:45 2022 @@ -20,12 +20,7 @@ # import unittest, setup_path, os, sys from sys import version_info # For Python version check -if version_info[0] >= 3: - # Python >=3.0 - from io import StringIO -else: - # Python <3.0 - from StringIO import StringIO +from io import BytesIO from svn import core, repos, fs, delta from svn.core import SubversionException import utils @@ -49,34 +44,34 @@ class DumpStreamParser(repos.ParseFns3): repos.ParseFns3.__init__(self) self.ops = [] def magic_header_record(self, version, pool=None): - self.ops.append(("magic-header", version)) + self.ops.append((b"magic-header", version)) def uuid_record(self, uuid, pool=None): - self.ops.append(("uuid", uuid)) + self.ops.append((b"uuid", uuid)) def new_revision_record(self, headers, pool=None): rev = int(headers[repos.DUMPFILE_REVISION_NUMBER]) - self.ops.append(("new-revision", rev)) + self.ops.append((b"new-revision", rev)) return rev def close_revision(self, revision_baton): - self.ops.append(("close-revision", revision_baton)) + self.ops.append((b"close-revision", revision_baton)) def new_node_record(self, headers, revision_baton, pool=None): node = headers[repos.DUMPFILE_NODE_PATH] - self.ops.append(("new-node", revision_baton, node)) + self.ops.append((b"new-node", revision_baton, node)) return (revision_baton, node) def close_node(self, node_baton): - self.ops.append(("close-node", node_baton[0], node_baton[1])) + self.ops.append((b"close-node", node_baton[0], node_baton[1])) def set_revision_property(self, revision_baton, name, value): - self.ops.append(("set-revision-prop", revision_baton, name, value)) + self.ops.append((b"set-revision-prop", revision_baton, name, value)) def set_node_property(self, node_baton, name, value): - self.ops.append(("set-node-prop", node_baton[0], node_baton[1], name, value)) + self.ops.append((b"set-node-prop", node_baton[0], node_baton[1], name, value)) def remove_node_props(self, node_baton): - self.ops.append(("remove-node-props", node_baton[0], node_baton[1])) + self.ops.append((b"remove-node-props", node_baton[0], node_baton[1])) def delete_node_property(self, node_baton, name): - self.ops.append(("delete-node-prop", node_baton[0], node_baton[1], name)) + self.ops.append((b"delete-node-prop", node_baton[0], node_baton[1], name)) def apply_textdelta(self, node_baton): - self.ops.append(("apply-textdelta", node_baton[0], node_baton[1])) + self.ops.append((b"apply-textdelta", node_baton[0], node_baton[1])) return None def set_fulltext(self, node_baton): - self.ops.append(("set-fulltext", node_baton[0], node_baton[1])) + self.ops.append((b"set-fulltext", node_baton[0], node_baton[1])) return None @@ -109,17 +104,17 @@ class SubversionRepositoryTestCase(unitt raise core.SubversionException(apr_err=core.SVN_ERR_CEASE_INVOCATION, message="Hi from history_lookup") - repos.history2(self.fs, '/trunk/README2.txt', history_lookup, None, 0, + repos.history2(self.fs, b'/trunk/README2.txt', history_lookup, None, 0, self.rev, True) self.assertEqual(len(revs), 1) def test_create(self): """Make sure that repos.create doesn't segfault when we set fs-type using a config hash""" - fs_config = { "fs-type": "fsfs" } + fs_config = { b"fs-type": b"fsfs" } for i in range(5): path = self.temper.alloc_empty_dir(suffix='-repository-create%d' % i) - repos.create(path, "", "", None, fs_config) + repos.create(path, b"", b"", None, fs_config) def test_dump_fs2(self): """Test the dump_fs2 function""" @@ -130,18 +125,18 @@ class SubversionRepositoryTestCase(unitt self.callback_calls += 1 return None - dumpstream = StringIO() - feedbackstream = StringIO() + dumpstream = BytesIO() + feedbackstream = BytesIO() repos.dump_fs2(self.repos, dumpstream, feedbackstream, 0, self.rev, 0, 0, is_cancelled) # Check that we can dump stuff dump = dumpstream.getvalue() feedback = feedbackstream.getvalue() - expected_feedback = "* Dumped revision " + str(self.rev) - self.assertEquals(dump.count("Node-path: trunk/README.txt"), 2) - self.assertEquals(feedback.count(expected_feedback), 1) - self.assertEquals(self.callback_calls, 13) + expected_feedback = b"* Dumped revision " + str(self.rev).encode('utf-8') + self.assertEqual(dump.count(b"Node-path: trunk/README.txt"), 2) + self.assertEqual(feedback.count(expected_feedback), 1) + self.assertEqual(self.callback_calls, 13) # Check that the dump can be cancelled self.assertRaises(SubversionException, repos.dump_fs2, @@ -154,22 +149,22 @@ class SubversionRepositoryTestCase(unitt self.assertRaises(ValueError, repos.dump_fs2, self.repos, dumpstream, feedbackstream, 0, self.rev, 0, 0, None) - dumpstream = StringIO() - feedbackstream = StringIO() + dumpstream = BytesIO() + feedbackstream = BytesIO() # Check that we can grab the feedback stream, but not the dumpstream repos.dump_fs2(self.repos, None, feedbackstream, 0, self.rev, 0, 0, None) feedback = feedbackstream.getvalue() - self.assertEquals(feedback.count(expected_feedback), 1) + self.assertEqual(feedback.count(expected_feedback), 1) # Check that we can grab the dumpstream, but not the feedbackstream repos.dump_fs2(self.repos, dumpstream, None, 0, self.rev, 0, 0, None) dump = dumpstream.getvalue() - self.assertEquals(dump.count("Node-path: trunk/README.txt"), 2) + self.assertEqual(dump.count(b"Node-path: trunk/README.txt"), 2) # Check that we can ignore both the dumpstream and the feedbackstream repos.dump_fs2(self.repos, dumpstream, None, 0, self.rev, 0, 0, None) - self.assertEquals(feedback.count(expected_feedback), 1) + self.assertEqual(feedback.count(expected_feedback), 1) # FIXME: The Python bindings don't check for 'NULL' values for # svn_repos_t objects, so the following call segfaults @@ -182,55 +177,70 @@ class SubversionRepositoryTestCase(unitt return None dump_path = os.path.join(os.path.dirname(sys.argv[0]), "trac/versioncontrol/tests/svnrepos.dump") - stream = open(dump_path) + stream = open(dump_path, 'rb') dsp = DumpStreamParser() ptr, baton = repos.make_parse_fns3(dsp) repos.parse_dumpstream3(stream, ptr, baton, False, is_cancelled) stream.close() self.assertEqual(self.cancel_calls, 76) expected_list = [ - ("magic-header", 2), - ('uuid', '92ea810a-adf3-0310-b540-bef912dcf5ba'), - ('new-revision', 0), - ('set-revision-prop', 0, 'svn:date', '2005-04-01T09:57:41.312767Z'), - ('close-revision', 0), - ('new-revision', 1), - ('set-revision-prop', 1, 'svn:log', 'Initial directory layout.'), - ('set-revision-prop', 1, 'svn:author', 'john'), - ('set-revision-prop', 1, 'svn:date', '2005-04-01T10:00:52.353248Z'), - ('new-node', 1, 'branches'), - ('remove-node-props', 1, 'branches'), - ('close-node', 1, 'branches'), - ('new-node', 1, 'tags'), - ('remove-node-props', 1, 'tags'), - ('close-node', 1, 'tags'), - ('new-node', 1, 'trunk'), - ('remove-node-props', 1, 'trunk'), - ('close-node', 1, 'trunk'), - ('close-revision', 1), - ('new-revision', 2), - ('set-revision-prop', 2, 'svn:log', 'Added README.'), - ('set-revision-prop', 2, 'svn:author', 'john'), - ('set-revision-prop', 2, 'svn:date', '2005-04-01T13:12:18.216267Z'), - ('new-node', 2, 'trunk/README.txt'), - ('remove-node-props', 2, 'trunk/README.txt'), - ('set-fulltext', 2, 'trunk/README.txt'), - ('close-node', 2, 'trunk/README.txt'), - ('close-revision', 2), ('new-revision', 3), - ('set-revision-prop', 3, 'svn:log', 'Fixed README.\n'), - ('set-revision-prop', 3, 'svn:author', 'kate'), - ('set-revision-prop', 3, 'svn:date', '2005-04-01T13:24:58.234643Z'), - ('new-node', 3, 'trunk/README.txt'), - ('remove-node-props', 3, 'trunk/README.txt'), - ('set-node-prop', 3, 'trunk/README.txt', 'svn:mime-type', 'text/plain'), - ('set-node-prop', 3, 'trunk/README.txt', 'svn:eol-style', 'native'), - ('set-fulltext', 3, 'trunk/README.txt'), - ('close-node', 3, 'trunk/README.txt'), ('close-revision', 3), + (b"magic-header", 2), + (b'uuid', b'92ea810a-adf3-0310-b540-bef912dcf5ba'), + (b'new-revision', 0), + (b'set-revision-prop', 0, b'svn:date', b'2005-04-01T09:57:41.312767Z'), + (b'close-revision', 0), + (b'new-revision', 1), + (b'set-revision-prop', 1, b'svn:log', b'Initial directory layout.'), + (b'set-revision-prop', 1, b'svn:author', b'john'), + (b'set-revision-prop', 1, b'svn:date', b'2005-04-01T10:00:52.353248Z'), + (b'new-node', 1, b'branches'), + (b'remove-node-props', 1, b'branches'), + (b'close-node', 1, b'branches'), + (b'new-node', 1, b'tags'), + (b'remove-node-props', 1, b'tags'), + (b'close-node', 1, b'tags'), + (b'new-node', 1, b'trunk'), + (b'remove-node-props', 1, b'trunk'), + (b'close-node', 1, b'trunk'), + (b'close-revision', 1), + (b'new-revision', 2), + (b'set-revision-prop', 2, b'svn:log', b'Added README.'), + (b'set-revision-prop', 2, b'svn:author', b'john'), + (b'set-revision-prop', 2, b'svn:date', b'2005-04-01T13:12:18.216267Z'), + (b'new-node', 2, b'trunk/README.txt'), + (b'remove-node-props', 2, b'trunk/README.txt'), + (b'set-fulltext', 2, b'trunk/README.txt'), + (b'close-node', 2, b'trunk/README.txt'), + (b'close-revision', 2), (b'new-revision', 3), + (b'set-revision-prop', 3, b'svn:log', b'Fixed README.\n'), + (b'set-revision-prop', 3, b'svn:author', b'kate'), + (b'set-revision-prop', 3, b'svn:date', b'2005-04-01T13:24:58.234643Z'), + (b'new-node', 3, b'trunk/README.txt'), + (b'remove-node-props', 3, b'trunk/README.txt'), + (b'set-node-prop', 3, b'trunk/README.txt', b'svn:mime-type', b'text/plain'), + (b'set-node-prop', 3, b'trunk/README.txt', b'svn:eol-style', b'native'), + (b'set-fulltext', 3, b'trunk/README.txt'), + (b'close-node', 3, b'trunk/README.txt'), (b'close-revision', 3), ] # Compare only the first X nodes described in the expected list - otherwise # the comparison list gets too long. self.assertEqual(dsp.ops[:len(expected_list)], expected_list) + def test_parse_fns3_invalid_set_fulltext(self): + class DumpStreamParserSubclass(DumpStreamParser): + def set_fulltext(self, node_baton): + DumpStreamParser.set_fulltext(self, node_baton) + return 42 + stream = open(os.path.join(os.path.dirname(sys.argv[0]), + "trac/versioncontrol/tests/svnrepos.dump"), "rb") + try: + dsp = DumpStreamParserSubclass() + ptr, baton = repos.make_parse_fns3(dsp) + self.assertRaises(TypeError, repos.parse_dumpstream3, + stream, ptr, baton, False, None) + finally: + stream.close() + def test_get_logs(self): """Test scope of get_logs callbacks""" logs = [] @@ -239,16 +249,16 @@ class SubversionRepositoryTestCase(unitt logs.append(paths) # Run get_logs - repos.get_logs(self.repos, ['/'], self.rev, 0, True, 0, addLog) + repos.get_logs(self.repos, [b'/'], self.rev, 0, True, 0, addLog) # Count and verify changes change_count = 0 for log in logs: - for path_changed in log.values(): + for path_changed in core._as_list(log.values()): change_count += 1 path_changed.assert_valid() - self.assertEqual(logs[2]["/tags/v1.1"].action, "A") - self.assertEqual(logs[2]["/tags/v1.1"].copyfrom_path, "/branches/v1x") + self.assertEqual(logs[2][b"/tags/v1.1"].action, b"A") + self.assertEqual(logs[2][b"/tags/v1.1"].copyfrom_path, b"/branches/v1x") self.assertEqual(len(logs), 12) self.assertEqual(change_count, 19) @@ -259,14 +269,14 @@ class SubversionRepositoryTestCase(unitt prev_root = fs.revision_root(self.fs, self.rev-1) editor = ChangeReceiver(this_root, prev_root) e_ptr, e_baton = delta.make_editor(editor) - repos.dir_delta(prev_root, '', '', this_root, '', e_ptr, e_baton, + repos.dir_delta(prev_root, b'', b'', this_root, b'', e_ptr, e_baton, _authz_callback, 1, 1, 0, 0) # Check results. # Ignore the order in which the editor delivers the two sibling files. self.assertEqual(set([editor.textdeltas[0].new_data, editor.textdeltas[1].new_data]), - set(["This is a test.\n", "A test.\n"])) + set([b"This is a test.\n", b"A test.\n"])) self.assertEqual(len(editor.textdeltas), 2) def test_unnamed_editor(self): @@ -277,29 +287,29 @@ class SubversionRepositoryTestCase(unitt this_root = fs.revision_root(self.fs, self.rev) prev_root = fs.revision_root(self.fs, self.rev-1) e_ptr, e_baton = delta.make_editor(ChangeReceiver(this_root, prev_root)) - repos.dir_delta(prev_root, '', '', this_root, '', e_ptr, e_baton, + repos.dir_delta(prev_root, b'', b'', this_root, b'', e_ptr, e_baton, _authz_callback, 1, 1, 0, 0) def test_retrieve_and_change_rev_prop(self): """Test playing with revprops""" - self.assertEqual(repos.fs_revision_prop(self.repos, self.rev, "svn:log", + self.assertEqual(repos.fs_revision_prop(self.repos, self.rev, b"svn:log", _authz_callback), - "''(a few years later)'' Argh... v1.1 was buggy, " - "after all") + b"''(a few years later)'' Argh... v1.1 was buggy, " + b"after all") # We expect this to complain because we have no pre-revprop-change # hook script for the repository. self.assertRaises(SubversionException, repos.fs_change_rev_prop3, - self.repos, self.rev, "jrandom", "svn:log", - "Youngest revision", True, True, _authz_callback) + self.repos, self.rev, b"jrandom", b"svn:log", + b"Youngest revision", True, True, _authz_callback) - repos.fs_change_rev_prop3(self.repos, self.rev, "jrandom", "svn:log", - "Youngest revision", False, False, + repos.fs_change_rev_prop3(self.repos, self.rev, b"jrandom", b"svn:log", + b"Youngest revision", False, False, _authz_callback) - self.assertEqual(repos.fs_revision_prop(self.repos, self.rev, "svn:log", + self.assertEqual(repos.fs_revision_prop(self.repos, self.rev, b"svn:log", _authz_callback), - "Youngest revision") + b"Youngest revision") def freeze_body(self, pool): self.freeze_invoked += 1 @@ -314,52 +324,52 @@ class SubversionRepositoryTestCase(unitt def test_lock_unlock(self): """Basic lock/unlock""" - access = fs.create_access('jrandom') + access = fs.create_access(b'jrandom') fs.set_access(self.fs, access) - fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, False) + fs.lock(self.fs, b'/trunk/README.txt', None, None, 0, 0, self.rev, False) try: - fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, False) + fs.lock(self.fs, b'/trunk/README.txt', None, None, 0, 0, self.rev, False) except core.SubversionException as exc: self.assertEqual(exc.apr_err, core.SVN_ERR_FS_PATH_ALREADY_LOCKED) - fs.lock(self.fs, '/trunk/README.txt', None, None, 0, 0, self.rev, True) + fs.lock(self.fs, b'/trunk/README.txt', None, None, 0, 0, self.rev, True) self.calls = 0 self.errors = 0 def unlock_callback(path, lock, err, pool): - self.assertEqual(path, '/trunk/README.txt') + self.assertEqual(path, b'/trunk/README.txt') self.assertEqual(lock, None) self.calls += 1 if err != None: self.assertEqual(err.apr_err, core.SVN_ERR_FS_NO_SUCH_LOCK) self.errors += 1 - the_lock = fs.get_lock(self.fs, '/trunk/README.txt') - fs.unlock_many(self.fs, {'/trunk/README.txt':the_lock.token}, False, + the_lock = fs.get_lock(self.fs, b'/trunk/README.txt') + fs.unlock_many(self.fs, {b'/trunk/README.txt':the_lock.token}, False, unlock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.errors, 0) self.calls = 0 - fs.unlock_many(self.fs, {'/trunk/README.txt':the_lock.token}, False, + fs.unlock_many(self.fs, {b'/trunk/README.txt':the_lock.token}, False, unlock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.errors, 1) self.locks = 0 def lock_callback(path, lock, err, pool): - self.assertEqual(path, '/trunk/README.txt') + self.assertEqual(path, b'/trunk/README.txt') if lock != None: - self.assertEqual(lock.owner, 'jrandom') + self.assertEqual(lock.owner, b'jrandom') self.locks += 1 self.calls += 1 if err != None: self.assertEqual(err.apr_err, core.SVN_ERR_FS_PATH_ALREADY_LOCKED) self.errors += 1 - + self.calls = 0 self.errors = 0 target = fs.lock_target_create(None, self.rev) - fs.lock_many(self.fs, {'trunk/README.txt':target}, + fs.lock_many(self.fs, {b'trunk/README.txt':target}, None, False, 0, False, lock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 1) @@ -367,7 +377,7 @@ class SubversionRepositoryTestCase(unitt self.calls = 0 self.locks = 0 - fs.lock_many(self.fs, {'trunk/README.txt':target}, + fs.lock_many(self.fs, {b'trunk/README.txt':target}, None, False, 0, False, lock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0) @@ -375,21 +385,21 @@ class SubversionRepositoryTestCase(unitt self.calls = 0 self.errors = 0 - the_lock = fs.get_lock(self.fs, '/trunk/README.txt') - repos.fs_unlock_many(self.repos, {'trunk/README.txt':the_lock.token}, + the_lock = fs.get_lock(self.fs, b'/trunk/README.txt') + repos.fs_unlock_many(self.repos, {b'trunk/README.txt':the_lock.token}, False, unlock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.errors, 0) self.calls = 0 - repos.fs_unlock_many(self.repos, {'trunk/README.txt':the_lock.token}, + repos.fs_unlock_many(self.repos, {b'trunk/README.txt':the_lock.token}, False, unlock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.errors, 1) self.calls = 0 self.errors = 0 - repos.fs_lock_many(self.repos, {'trunk/README.txt':target}, + repos.fs_lock_many(self.repos, {b'trunk/README.txt':target}, None, False, 0, False, lock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 1) @@ -397,7 +407,7 @@ class SubversionRepositoryTestCase(unitt self.calls = 0 self.locks = 0 - repos.fs_lock_many(self.repos, {'trunk/README.txt':target}, + repos.fs_lock_many(self.repos, {b'trunk/README.txt':target}, None, False, 0, False, lock_callback) self.assertEqual(self.calls, 1) self.assertEqual(self.locks, 0)
Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/run_all.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/run_all.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/run_all.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/run_all.py Fri Jan 14 14:01:45 2022 @@ -18,9 +18,10 @@ # under the License. # # +import sys import unittest, setup_path import mergeinfo, core, client, delta, checksum, pool, fs, ra, wc, repository, \ - auth, trac.versioncontrol.tests + auth, trac.versioncontrol.tests, typemap from svn.core import svn_cache_config_get, svn_cache_config_set # Run all tests @@ -28,7 +29,10 @@ from svn.core import svn_cache_config_ge def suite(): """Run all tests""" settings = svn_cache_config_get() - settings.cache_size = long(1024*1024*32) ### Need explicit long + if sys.hexversion < 0x3000000: + settings.cache_size = long(1024*1024*32) ### Need explicit long + else: + settings.cache_size = 1024*1024*32 svn_cache_config_set(settings) s = unittest.TestSuite() s.addTest(core.suite()) @@ -43,6 +47,7 @@ def suite(): s.addTest(repository.suite()) s.addTest(auth.suite()) s.addTest(trac.versioncontrol.tests.suite()) + s.addTest(typemap.suite()) return s if __name__ == '__main__': Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Fri Jan 14 14:01:45 2022 @@ -1 +1,2 @@ *.pyc +__pycache__ Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/ ------------------------------------------------------------------------------ --- 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/tests/trac/versioncontrol/main.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/main.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/main.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/main.py Fri Jan 14 14:01:45 2022 @@ -154,12 +154,12 @@ class Node(object): Represents a directory or file in the repository. """ - DIRECTORY = "dir" - FILE = "file" + DIRECTORY = b"dir" + FILE = b"file" def __init__(self, path, rev, kind): assert kind in (Node.DIRECTORY, Node.FILE), "Unknown node kind %s" % kind - self.path = str(path) + self.path = path self.rev = rev self.kind = kind @@ -217,7 +217,7 @@ class Node(object): content_type = property(lambda x: x.get_content_type()) def get_name(self): - return self.path.split('/')[-1] + return self.path.split(b'/')[-1] name = property(lambda x: x.get_name()) def get_last_modified(self): @@ -233,11 +233,11 @@ class Changeset(object): Represents a set of changes of a repository. """ - ADD = 'add' - COPY = 'copy' - DELETE = 'delete' - EDIT = 'edit' - MOVE = 'move' + ADD = b'add' + COPY = b'copy' + DELETE = b'delete' + EDIT = b'edit' + MOVE = b'move' def __init__(self, rev, message, author, date): self.rev = rev Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py Fri Jan 14 14:01:45 2022 @@ -63,7 +63,7 @@ _kindmap = {core.svn_node_dir: Node.DIRE def _get_history(path, authz, fs_ptr, start, end, limit=None): history = [] - if hasattr(repos, 'svn_repos_history2'): + if getattr(repos, 'svn_repos_history2', None) is not None: # For Subversion >= 1.1 def authz_cb(root, path, pool): if limit and len(history) >= limit: @@ -107,17 +107,17 @@ class SubversionRepository(Repository): raise TracError("%s does not appear to be a Subversion repository." % (path, )) if self.path != path: self.scope = path[len(self.path):] - if not self.scope[-1] == '/': - self.scope += '/' + if not self.scope[-1:] == b'/': + self.scope += b'/' else: - self.scope = '/' + self.scope = b'/' self.repos = repos.svn_repos_open(self.path) self.fs_ptr = repos.svn_repos_fs(self.repos) self.rev = fs.youngest_rev(self.fs_ptr) self.history = None - if self.scope != '/': + if self.scope != b'/': self.history = [] for path,rev in _get_history(self.scope[1:], self.authz, self.fs_ptr, 0, self.rev): @@ -132,7 +132,7 @@ class SubversionRepository(Repository): return node_type in _kindmap def normalize_path(self, path): - return path == '/' and path or path and path.strip('/') or '' + return path == b'/' and path or path and path.strip(b'/') or b'' def normalize_rev(self, rev): try: @@ -157,7 +157,7 @@ class SubversionRepository(Repository): def get_node(self, path, rev=None): self.authz.assert_permission(self.scope + path) - if path and path[-1] == '/': + if path and path[-1] == b'/': path = path[:-1] rev = self.normalize_rev(rev) @@ -166,13 +166,13 @@ class SubversionRepository(Repository): def get_oldest_rev(self): rev = 0 - if self.scope == '/': + if self.scope == b'/': return rev return self.history[-1] def get_youngest_rev(self): rev = self.rev - if self.scope == '/': + if self.scope == b'/': return rev return self.history[0] @@ -180,7 +180,7 @@ class SubversionRepository(Repository): rev = int(rev) if rev == 0: return None - if self.scope == '/': + if self.scope == b'/': return rev - 1 idx = self.history.index(rev) if idx + 1 < len(self.history): @@ -191,7 +191,7 @@ class SubversionRepository(Repository): rev = int(rev) if rev == self.rev: return None - if self.scope == '/': + if self.scope == b'/': return rev + 1 if rev == 0: return self.oldest_rev @@ -224,7 +224,7 @@ class SubversionRepository(Repository): else: # the path changed: 'newer' was a copy rev = self.previous_rev(newer[1]) # restart before the copy op yield newer[0], newer[1], Changeset.COPY - older = (older[0], older[1], 'unknown') + older = (older[0], older[1], b'unknown') break newer = older if older: # either a real ADD or the source of a COPY @@ -262,7 +262,7 @@ class SubversionRepository(Repository): def authz_cb(root, path, pool): return 1 text_deltas = 0 # as this is anyway re-done in Diff.py... entry_props = 0 # ("... typically used only for working copy updates") - repos.svn_repos_dir_delta(old_root, old_path, '', + repos.svn_repos_dir_delta(old_root, old_path, b'', new_root, new_path, e_ptr, e_baton, authz_cb, text_deltas, @@ -290,7 +290,7 @@ class SubversionNode(Node): def __init__(self, path, rev, authz, scope, fs_ptr): self.authz = authz self.scope = scope - if scope != '/': + if scope != b'/': self.scoped_path = scope + path else: self.scoped_path = path @@ -300,7 +300,8 @@ class SubversionNode(Node): self.root = fs.revision_root(fs_ptr, rev) node_type = fs.check_path(self.root, self.scoped_path) if not node_type in _kindmap: - raise TracError("No node at %s in revision %s" % (path, rev)) + raise TracError("No node at %s in revision %s" + % (path.decode('UTF-8'), rev)) self.created_rev = fs.node_created_rev(self.root, self.scoped_path) self.created_path = fs.node_created_path(self.root, self.scoped_path) # Note: 'created_path' differs from 'path' if the last change was a copy, @@ -322,8 +323,8 @@ class SubversionNode(Node): if self.isfile: return entries = fs.dir_entries(self.root, self.scoped_path) - for item in entries.keys(): - path = '/'.join((self.path, item)) + for item in entries: + path = b'/'.join((self.path, item)) if not self.authz.has_permission(path): continue yield SubversionNode(path, self._requested_rev, self.authz, @@ -349,8 +350,8 @@ class SubversionNode(Node): def get_properties(self): props = fs.node_proplist(self.root, self.scoped_path) - for name,value in props.items(): - props[name] = str(value) # Make sure the value is a proper string + for name,value in core._as_list(props.items()): + props[name] = value return props def get_content_length(self): @@ -366,7 +367,7 @@ class SubversionNode(Node): def get_last_modified(self): date = fs.revision_prop(self.fs_ptr, self.created_rev, core.SVN_PROP_REVISION_DATE) - return core.svn_time_from_cstring(date) / 1000000 + return core.svn_time_from_cstring(date) // 1000000 def _get_prop(self, name): return fs.node_prop(self.root, self.scoped_path, name) @@ -382,7 +383,7 @@ class SubversionChangeset(Changeset): message = self._get_prop(core.SVN_PROP_REVISION_LOG) author = self._get_prop(core.SVN_PROP_REVISION_AUTHOR) date = self._get_prop(core.SVN_PROP_REVISION_DATE) - date = core.svn_time_from_cstring(date) / 1000000 + date = core.svn_time_from_cstring(date) // 1000000 Changeset.__init__(self, rev, message, author, date) def get_changes(self): @@ -392,9 +393,10 @@ class SubversionChangeset(Changeset): repos.svn_repos_replay(root, e_ptr, e_baton) idx = 0 + # Variables to record copy/deletes for later move detection copies, deletions = {}, {} changes = [] - for path, change in editor.changes.items(): + for path, change in core._as_list(editor.changes.items()): if not self.authz.has_permission(path): # FIXME: what about base_path? continue @@ -409,10 +411,12 @@ class SubversionChangeset(Changeset): action = '' if change.action == repos.CHANGE_ACTION_DELETE: action = Changeset.DELETE + # Save off the index within changes of this deletion deletions[change.base_path] = idx elif change.added: if change.base_path and change.base_rev: action = Changeset.COPY + # Save off the index within changes of this copy copies[change.base_path] = idx else: action = Changeset.ADD @@ -423,18 +427,19 @@ class SubversionChangeset(Changeset): changes.append([path, kind, action, base_path, change.base_rev]) idx += 1 - moves = [] - for k,v in copies.items(): + # Detect moves by checking for copies whose source was deleted in this + # change set. + moves = set() + for k,v in core._as_list(copies.items()): if k in deletions: changes[v][2] = Changeset.MOVE - moves.append(deletions[k]) - offset = 0 - for i in moves: - del changes[i - offset] - offset += 1 + # Record the index of the now redundant delete action. + moves.add(deletions[k]) - for change in changes: - yield tuple(change) + for i, change in enumerate(changes): + # Do not return the 'delete' changes that were part of moves. + if i not in moves: + yield tuple(change) def _get_prop(self, name): return fs.revision_prop(self.fs_ptr, self.rev, name) @@ -457,7 +462,7 @@ class DiffChangeEditor(delta.Editor): # -- svn.delta.Editor callbacks def open_root(self, base_revision, dir_pool): - return ('/', Changeset.EDIT) + return (b'/', Changeset.EDIT) def add_directory(self, path, dir_baton, copyfrom_path, copyfrom_rev, dir_pool): self.deltas.append((path, Node.DIRECTORY, Changeset.ADD)) Propchange: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/ ------------------------------------------------------------------------------ --- 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/tests/trac/versioncontrol/tests/svn_fs.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py Fri Jan 14 14:01:45 2022 @@ -53,17 +53,14 @@ import shutil import sys import tempfile import unittest -from urllib import pathname2url +from io import BytesIO if sys.version_info[0] >= 3: # Python >=3.0 - from io import StringIO + from urllib.request import pathname2url else: # Python <3.0 - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO + from urllib import pathname2url from svn import core, repos @@ -72,35 +69,34 @@ from trac.versioncontrol import Changese from trac.versioncontrol.svn_fs import SubversionRepository temp_path = tempfile.mktemp("-trac-svnrepos") -REPOS_PATH = core.svn_dirent_internal_style(temp_path) -REPOS_URL = pathname2url(temp_path) +REPOS_PATH = core.svn_dirent_internal_style(temp_path.encode('UTF-8')) +REPOS_URL = pathname2url(temp_path).encode('UTF-8') del temp_path -if REPOS_URL.startswith("///"): +if REPOS_URL.startswith(b"///"): # Don't add extra slashes if they're already present. # (This is important for Windows compatibility). - REPOS_URL = "file:" + REPOS_URL + REPOS_URL = b"file:" + REPOS_URL else: # If the URL simply starts with '/', we need to add two # extra slashes to make it a valid 'file://' URL - REPOS_URL = "file://" + REPOS_URL + REPOS_URL = b"file://" + REPOS_URL REPOS_URL = core.svn_uri_canonicalize(REPOS_URL) class SubversionRepositoryTestSetup(TestSetup): def setUp(self): - dumpfile = open(os.path.join(os.path.split(__file__)[0], - 'svnrepos.dump'), 'rb') - - # Remove the trac-svnrepos directory, so that we can - # ensure a fresh start. - self.tearDown() - - r = repos.svn_repos_create(REPOS_PATH, '', '', None, None) - repos.svn_repos_load_fs2(r, dumpfile, StringIO(), - repos.svn_repos_load_uuid_ignore, '', - 0, 0, None) + dump_path = os.path.join(os.path.split(__file__)[0], 'svnrepos.dump') + with open(dump_path, 'rb') as dumpfile: + # Remove the trac-svnrepos directory, so that we can + # ensure a fresh start. + self.tearDown() + + r = repos.svn_repos_create(REPOS_PATH, b'', b'', None, None) + repos.svn_repos_load_fs2(r, dumpfile, BytesIO(), + repos.svn_repos_load_uuid_ignore, b'', + 0, 0, None) def tearDown(self): if os.path.exists(REPOS_PATH): @@ -126,110 +122,111 @@ class SubversionRepositoryTestCase(unitt self.assertEqual(None, self.repos.next_rev(12)) def test_get_node(self): - node = self.repos.get_node('/trunk') - self.assertEqual('trunk', node.name) - self.assertEqual('/trunk', node.path) + node = self.repos.get_node(b'/trunk') + self.assertEqual(b'trunk', node.name) + self.assertEqual(b'/trunk', node.path) self.assertEqual(Node.DIRECTORY, node.kind) self.assertEqual(6, node.rev) self.assertEqual(1112381806, node.last_modified) - node = self.repos.get_node('/trunk/README.txt') - self.assertEqual('README.txt', node.name) - self.assertEqual('/trunk/README.txt', node.path) + node = self.repos.get_node(b'/trunk/README.txt') + self.assertEqual(b'README.txt', node.name) + self.assertEqual(b'/trunk/README.txt', node.path) self.assertEqual(Node.FILE, node.kind) self.assertEqual(3, node.rev) self.assertEqual(1112361898, node.last_modified) def test_get_node_specific_rev(self): - node = self.repos.get_node('/trunk', 1) - self.assertEqual('trunk', node.name) - self.assertEqual('/trunk', node.path) + node = self.repos.get_node(b'/trunk', 1) + self.assertEqual(b'trunk', node.name) + self.assertEqual(b'/trunk', node.path) self.assertEqual(Node.DIRECTORY, node.kind) self.assertEqual(1, node.rev) self.assertEqual(1112349652, node.last_modified) - node = self.repos.get_node('/trunk/README.txt', 2) - self.assertEqual('README.txt', node.name) - self.assertEqual('/trunk/README.txt', node.path) + node = self.repos.get_node(b'/trunk/README.txt', 2) + self.assertEqual(b'README.txt', node.name) + self.assertEqual(b'/trunk/README.txt', node.path) self.assertEqual(Node.FILE, node.kind) self.assertEqual(2, node.rev) self.assertEqual(1112361138, node.last_modified) def test_get_dir_entries(self): - node = self.repos.get_node('/trunk') + node = self.repos.get_node(b'/trunk') entries = node.get_entries() - self.assertEqual('README2.txt', entries.next().name) - self.assertEqual('dir1', entries.next().name) - self.assertEqual('README.txt', entries.next().name) - self.assertRaises(StopIteration, entries.next) + self.assertSequenceEqual(sorted([entry.name for entry in entries]), + sorted([b'README2.txt', + b'dir1', + b'README.txt'])) def test_get_file_entries(self): - node = self.repos.get_node('/trunk/README.txt') + node = self.repos.get_node(b'/trunk/README.txt') entries = node.get_entries() - self.assertRaises(StopIteration, entries.next) + self.assertSequenceEqual([entry.name for entry in entries], + []) def test_get_dir_content(self): - node = self.repos.get_node('/trunk') + node = self.repos.get_node(b'/trunk') self.assertEqual(None, node.content_length) self.assertEqual(None, node.content_type) self.assertEqual(None, node.get_content()) def test_get_file_content(self): - node = self.repos.get_node('/trunk/README.txt') + node = self.repos.get_node(b'/trunk/README.txt') self.assertEqual(8, node.content_length) - self.assertEqual('text/plain', node.content_type) - self.assertEqual('A test.\n', node.get_content().read()) + self.assertEqual(b'text/plain', node.content_type) + self.assertEqual(b'A test.\n', node.get_content().read()) def test_get_dir_properties(self): - f = self.repos.get_node('/trunk') + f = self.repos.get_node(b'/trunk') props = f.get_properties() self.assertEqual(0, len(props)) def test_get_file_properties(self): - f = self.repos.get_node('/trunk/README.txt') + f = self.repos.get_node(b'/trunk/README.txt') props = f.get_properties() - self.assertEqual('native', props['svn:eol-style']) - self.assertEqual('text/plain', props['svn:mime-type']) + self.assertEqual(b'native', props[b'svn:eol-style']) + self.assertEqual(b'text/plain', props[b'svn:mime-type']) # Revision Log / node history def test_get_node_history(self): - node = self.repos.get_node('/trunk/README2.txt') + node = self.repos.get_node(b'/trunk/README2.txt') history = node.get_history() - self.assertEqual(('trunk/README2.txt', 6, 'copy'), history.next()) - self.assertEqual(('trunk/README.txt', 3, 'edit'), history.next()) - self.assertEqual(('trunk/README.txt', 2, 'add'), history.next()) - self.assertRaises(StopIteration, history.next) + self.assertSequenceEqual([x for x in history], + [(b'trunk/README2.txt', 6, b'copy'), + (b'trunk/README.txt', 3, b'edit'), + (b'trunk/README.txt', 2, b'add')]) def test_get_node_history_follow_copy(self): - node = self.repos.get_node('/tags/v1/README.txt') + node = self.repos.get_node(b'/tags/v1/README.txt') history = node.get_history() - self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) - self.assertEqual(('trunk/README.txt', 3, 'edit'), history.next()) - self.assertEqual(('trunk/README.txt', 2, 'add'), history.next()) - self.assertRaises(StopIteration, history.next) + self.assertSequenceEqual([x for x in history], + [(b'tags/v1/README.txt', 7, b'copy'), + (b'trunk/README.txt', 3, b'edit'), + (b'trunk/README.txt', 2, b'add')]) # Revision Log / path history def test_get_path_history(self): - history = self.repos.get_path_history('/trunk/README2.txt', None) - self.assertEqual(('trunk/README2.txt', 6, 'copy'), history.next()) - self.assertEqual(('trunk/README.txt', 3, 'unknown'), history.next()) - self.assertRaises(StopIteration, history.next) + history = self.repos.get_path_history(b'/trunk/README2.txt', None) + self.assertSequenceEqual([x for x in history], + [(b'trunk/README2.txt', 6, b'copy'), + (b'trunk/README.txt', 3, b'unknown')]) def test_get_path_history_copied_file(self): - history = self.repos.get_path_history('/tags/v1/README.txt', None) - self.assertEqual(('tags/v1/README.txt', 7, 'copy'), history.next()) - self.assertEqual(('trunk/README.txt', 3, 'unknown'), history.next()) - self.assertRaises(StopIteration, history.next) + history = self.repos.get_path_history(b'/tags/v1/README.txt', None) + self.assertSequenceEqual([x for x in history], + [(b'tags/v1/README.txt', 7, b'copy'), + (b'trunk/README.txt', 3, b'unknown')]) def test_get_path_history_copied_dir(self): - history = self.repos.get_path_history('/branches/v1x', None) - self.assertEqual(('branches/v1x', 12, 'copy'), history.next()) - self.assertEqual(('tags/v1.1', 10, 'unknown'), history.next()) - self.assertEqual(('branches/v1x', 11, 'delete'), history.next()) - self.assertEqual(('branches/v1x', 9, 'edit'), history.next()) - self.assertEqual(('branches/v1x', 8, 'copy'), history.next()) - self.assertEqual(('tags/v1', 7, 'unknown'), history.next()) - self.assertRaises(StopIteration, history.next) + history = self.repos.get_path_history(b'/branches/v1x', None) + self.assertSequenceEqual([x for x in history], + [(b'branches/v1x', 12, b'copy'), + (b'tags/v1.1', 10, b'unknown'), + (b'branches/v1x', 11, b'delete'), + (b'branches/v1x', 9, b'edit'), + (b'branches/v1x', 8, b'copy'), + (b'tags/v1', 7, b'unknown')]) # Diffs @@ -243,63 +240,63 @@ class SubversionRepositoryTestCase(unitt self.assertEqual(expected[2], (got[2], got[3])) def test_diff_file_different_revs(self): - diffs = self.repos.get_deltas('trunk/README.txt', 2, 'trunk/README.txt', 3) - self._cmp_diff((('trunk/README.txt', 2), - ('trunk/README.txt', 3), - (Node.FILE, Changeset.EDIT)), diffs.next()) - self.assertRaises(StopIteration, diffs.next) + diffs = self.repos.get_deltas(b'trunk/README.txt', 2, b'trunk/README.txt', 3) + self._cmp_diff(((b'trunk/README.txt', 2), + (b'trunk/README.txt', 3), + (Node.FILE, Changeset.EDIT)), next(diffs)) + self.assertRaises(StopIteration, lambda: next(diffs)) def test_diff_file_different_files(self): - diffs = self.repos.get_deltas('branches/v1x/README.txt', 12, - 'branches/v1x/README2.txt', 12) - self._cmp_diff((('branches/v1x/README.txt', 12), - ('branches/v1x/README2.txt', 12), - (Node.FILE, Changeset.EDIT)), diffs.next()) - self.assertRaises(StopIteration, diffs.next) + diffs = self.repos.get_deltas(b'branches/v1x/README.txt', 12, + b'branches/v1x/README2.txt', 12) + self._cmp_diff(((b'branches/v1x/README.txt', 12), + (b'branches/v1x/README2.txt', 12), + (Node.FILE, Changeset.EDIT)), next(diffs)) + self.assertRaises(StopIteration, lambda: next(diffs)) def test_diff_file_no_change(self): - diffs = self.repos.get_deltas('trunk/README.txt', 7, - 'tags/v1/README.txt', 7) - self.assertRaises(StopIteration, diffs.next) + diffs = self.repos.get_deltas(b'trunk/README.txt', 7, + b'tags/v1/README.txt', 7) + self.assertRaises(StopIteration, lambda: next(diffs)) def test_diff_dir_different_revs(self): - diffs = self.repos.get_deltas('trunk', 4, 'trunk', 8) + diffs = self.repos.get_deltas(b'trunk', 4, b'trunk', 8) expected = [ - (None, ('trunk/README2.txt', 6), + (None, (b'trunk/README2.txt', 6), (Node.FILE, Changeset.ADD)), - (None, ('trunk/dir1/dir2', 8), + (None, (b'trunk/dir1/dir2', 8), (Node.DIRECTORY, Changeset.ADD)), - (None, ('trunk/dir1/dir3', 8), + (None, (b'trunk/dir1/dir3', 8), (Node.DIRECTORY, Changeset.ADD)), - (('trunk/dir2', 4), None, + ((b'trunk/dir2', 4), None, (Node.DIRECTORY, Changeset.DELETE)), - (('trunk/dir3', 4), None, + ((b'trunk/dir3', 4), None, (Node.DIRECTORY, Changeset.DELETE)), ] - actual = [diffs.next() for i in range(5)] + actual = [next(diffs) for i in range(5)] actual = sorted(actual, key=lambda diff: ((diff[0] or diff[1]).path, (diff[0] or diff[1]).rev)) self.assertEqual(len(expected), len(actual)) for e,a in zip(expected, actual): self._cmp_diff(e,a) - self.assertRaises(StopIteration, diffs.next) + self.assertRaises(StopIteration, lambda: next(diffs)) def test_diff_dir_different_dirs(self): - diffs = self.repos.get_deltas('trunk', 1, 'branches/v1x', 12) + diffs = self.repos.get_deltas(b'trunk', 1, b'branches/v1x', 12) expected = [ - (None, ('branches/v1x/README.txt', 12), + (None, (b'branches/v1x/README.txt', 12), (Node.FILE, Changeset.ADD)), - (None, ('branches/v1x/README2.txt', 12), + (None, (b'branches/v1x/README2.txt', 12), (Node.FILE, Changeset.ADD)), - (None, ('branches/v1x/dir1', 12), + (None, (b'branches/v1x/dir1', 12), (Node.DIRECTORY, Changeset.ADD)), - (None, ('branches/v1x/dir1/dir2', 12), + (None, (b'branches/v1x/dir1/dir2', 12), (Node.DIRECTORY, Changeset.ADD)), - (None, ('branches/v1x/dir1/dir3', 12), + (None, (b'branches/v1x/dir1/dir3', 12), (Node.DIRECTORY, Changeset.ADD)), ] - actual = [diffs.next() for i in range(5)] + actual = [next(diffs) for i in range(5)] actual = sorted(actual, key=lambda diff: (diff[1].path, diff[1].rev)) # for e,a in zip(expected, actual): # t.write("%r\n" % (e,)) @@ -308,12 +305,12 @@ class SubversionRepositoryTestCase(unitt self.assertEqual(len(expected), len(actual)) for e,a in zip(expected, actual): self._cmp_diff(e,a) - self.assertRaises(StopIteration, diffs.next) + self.assertRaises(StopIteration, lambda: next(diffs)) def test_diff_dir_no_change(self): - diffs = self.repos.get_deltas('trunk', 7, - 'tags/v1', 7) - self.assertRaises(StopIteration, diffs.next) + diffs = self.repos.get_deltas(b'trunk', 7, + b'tags/v1', 7) + self.assertRaises(StopIteration, lambda: next(diffs)) # Changesets @@ -323,61 +320,57 @@ class SubversionRepositoryTestCase(unitt self.assertEqual(None, chgset.message) self.assertEqual(None, chgset.author) self.assertEqual(1112349461, chgset.date) - self.assertRaises(StopIteration, chgset.get_changes().next) + self.assertRaises(StopIteration, lambda: next(chgset.get_changes())) def test_changeset_added_dirs(self): chgset = self.repos.get_changeset(1) self.assertEqual(1, chgset.rev) - self.assertEqual('Initial directory layout.', chgset.message) - self.assertEqual('john', chgset.author) + self.assertEqual(b'Initial directory layout.', chgset.message) + self.assertEqual(b'john', chgset.author) self.assertEqual(1112349652, chgset.date) changes = chgset.get_changes() - self.assertEqual(('trunk', Node.DIRECTORY, Changeset.ADD, None, -1), - changes.next()) - self.assertEqual(('branches', Node.DIRECTORY, Changeset.ADD, None, -1), - changes.next()) - self.assertEqual(('tags', Node.DIRECTORY, Changeset.ADD, None, -1), - changes.next()) - self.assertRaises(StopIteration, changes.next) + self.assertSequenceEqual(sorted([x for x in changes]), + sorted([(b'trunk', Node.DIRECTORY, Changeset.ADD, None, -1), + (b'branches', Node.DIRECTORY, Changeset.ADD, None, -1), + (b'tags', Node.DIRECTORY, Changeset.ADD, None, -1)])) def test_changeset_file_edit(self): chgset = self.repos.get_changeset(3) self.assertEqual(3, chgset.rev) - self.assertEqual('Fixed README.\n', chgset.message) - self.assertEqual('kate', chgset.author) + self.assertEqual(b'Fixed README.\n', chgset.message) + self.assertEqual(b'kate', chgset.author) self.assertEqual(1112361898, chgset.date) changes = chgset.get_changes() - self.assertEqual(('trunk/README.txt', Node.FILE, Changeset.EDIT, - 'trunk/README.txt', 2), changes.next()) - self.assertRaises(StopIteration, changes.next) + self.assertSequenceEqual(sorted([x for x in changes]), + sorted([(b'trunk/README.txt', Node.FILE, Changeset.EDIT, + b'trunk/README.txt', 2)])) def test_changeset_dir_moves(self): chgset = self.repos.get_changeset(5) self.assertEqual(5, chgset.rev) - self.assertEqual('Moved directories.', chgset.message) - self.assertEqual('kate', chgset.author) + self.assertEqual(b'Moved directories.', chgset.message) + self.assertEqual(b'kate', chgset.author) self.assertEqual(1112372739, chgset.date) changes = chgset.get_changes() - self.assertEqual(('trunk/dir1/dir2', Node.DIRECTORY, Changeset.MOVE, - 'trunk/dir2', 4), changes.next()) - self.assertEqual(('trunk/dir1/dir3', Node.DIRECTORY, Changeset.MOVE, - 'trunk/dir3', 4), changes.next()) - self.assertRaises(StopIteration, changes.next) + self.assertSequenceEqual(sorted([x for x in changes]), + sorted([ + (b'trunk/dir1/dir2', Node.DIRECTORY, Changeset.MOVE, b'trunk/dir2', 4), + (b'trunk/dir1/dir3', Node.DIRECTORY, Changeset.MOVE, b'trunk/dir3', 4)])) def test_changeset_file_copy(self): chgset = self.repos.get_changeset(6) self.assertEqual(6, chgset.rev) - self.assertEqual('More things to read', chgset.message) - self.assertEqual('john', chgset.author) + self.assertEqual(b'More things to read', chgset.message) + self.assertEqual(b'john', chgset.author) self.assertEqual(1112381806, chgset.date) changes = chgset.get_changes() - self.assertEqual(('trunk/README2.txt', Node.FILE, Changeset.COPY, - 'trunk/README.txt', 3), changes.next()) - self.assertRaises(StopIteration, changes.next) + self.assertSequenceEqual(sorted([x for x in changes]), + sorted([(b'trunk/README2.txt', Node.FILE, Changeset.COPY, + b'trunk/README.txt', 3)])) def suite(): Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/utils.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/utils.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/utils.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/utils.py Fri Jan 14 14:01:45 2022 @@ -18,9 +18,17 @@ # under the License. # # -import os.path, sys, tempfile, urllib +import os.path, sys, tempfile, codecs from svn import core, repos -from StringIO import StringIO +from io import BytesIO +try: + # Python >=3.0 + from urllib.request import pathname2url +except ImportError: + # Python <3.0 + from urllib import pathname2url + +IS_PY3 = sys.hexversion >= 0x3000000 class Temper(object): """Class to simplify allocation and cleanup of dummy Subversion @@ -41,14 +49,19 @@ class Temper(object): def alloc_empty_dir(self, suffix = ""): """Create an empty temporary directory. Returns its full path in canonical internal form.""" - temp_dir_name = core.svn_dirent_internal_style(tempfile.mkdtemp(suffix)) + if isinstance(suffix, bytes): + suffix = suffix.decode('UTF-8') + temp_dir_name = tempfile.mkdtemp(suffix).encode('UTF-8') + temp_dir_name = core.svn_dirent_internal_style(temp_dir_name) self._cleanup_list.append((temp_dir_name, core.svn_io_remove_dir)) return temp_dir_name def alloc_empty_repo(self, suffix = ""): """Create an empty repository. Returns a tuple of its handle, path and file: URI in canonical internal form.""" - temp_path = tempfile.mkdtemp(suffix) + if isinstance(suffix, bytes): + suffix = suffix.decode('UTF-8') + temp_path = tempfile.mkdtemp(suffix).encode('UTF-8') repo_path = core.svn_dirent_internal_style(temp_path) repo_uri = core.svn_uri_canonicalize(file_uri_for_path(temp_path)) handle = repos.create(repo_path, None, None, None, None) @@ -61,15 +74,24 @@ class Temper(object): location. Returns the same as alloc_empty_repo.""" dump_path = os.path.join(os.path.dirname(sys.argv[0]), repo_id) (handle, repo_path, repo_uri) = self.alloc_empty_repo(suffix=suffix) - repos.svn_repos_load_fs2(handle, open(dump_path, 'rb'), StringIO(), - repos.load_uuid_default, None, False, False, None) + with open(dump_path, 'rb') as dump_fp: + repos.svn_repos_load_fs2(handle, dump_fp, BytesIO(), + repos.load_uuid_default, None, False, False, None) return (handle, repo_path, repo_uri) def file_uri_for_path(path): """Return the file: URI corresponding to the given path.""" - uri_path = urllib.pathname2url(path) + if not isinstance(path, str): + path = path.decode('UTF-8') + uri_path = pathname2url(path).encode('UTF-8') # pathname2url claims to return the path part of the URI, but on Windows # it returns both the authority and path parts for no reason, which # means we have to trim the leading slashes to "normalize" the result. - return 'file:///' + uri_path.lstrip('/') + return b'file:///' + uri_path.lstrip(b'/') + +def codecs_eq(a, b): + return codecs.lookup(a) == codecs.lookup(b) + +def is_defaultencoding_utf8(): + return codecs_eq(sys.getdefaultencoding(), 'utf-8') Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/wc.py URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/wc.py?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/wc.py (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/python/tests/wc.py Fri Jan 14 14:01:45 2022 @@ -19,12 +19,7 @@ # # from sys import version_info # For Python version check -if version_info[0] >= 3: - # Python >=3.0 - from io import StringIO -else: - # Python <3.0 - from cStringIO import StringIO +from io import BytesIO import unittest, os, tempfile, setup_path, binascii import svn.diff from svn import core, repos, wc, client @@ -61,10 +56,10 @@ class SubversionWorkingCopyTestCase(unit wc.entry(self.path, self.wc, True) def test_lock(self): - readme_path = '%s/trunk/README.txt' % self.path + readme_path = b'%s/trunk/README.txt' % self.path lock = core.svn_lock_create(core.Pool()) - lock.token = 'http://svnbook.org/nightly/en/svn.advanced.locking.html' + lock.token = b'http://svnbook.org/nightly/en/svn.advanced.locking.html' wc.add_lock(readme_path, lock, self.wc) self.assertEqual(True, wc.adm_locked(self.wc)) @@ -78,23 +73,23 @@ class SubversionWorkingCopyTestCase(unit self.assertEqual(self.path, wc.adm_access_path(self.wc)) def test_is_adm_dir(self): - self.assert_(wc.is_adm_dir(".svn")) - self.failIf(wc.is_adm_dir(".foosvn")) + self.assertTrue(wc.is_adm_dir(b".svn")) + self.assertFalse(wc.is_adm_dir(b".foosvn")) def test_get_adm_dir(self): - self.assert_(isinstance(wc.get_adm_dir(), basestring)) + self.assertTrue(isinstance(wc.get_adm_dir(), bytes)) def test_set_adm_dir(self): - self.assertRaises(SubversionException, wc.set_adm_dir, ".foobar") - self.assert_(wc.is_adm_dir(".svn")) - self.failIf(wc.is_adm_dir("_svn")) - self.failIf(wc.is_adm_dir(".foobar")) - wc.set_adm_dir("_svn") - self.assert_(wc.is_adm_dir("_svn")) - self.assertEqual("_svn", wc.get_adm_dir()) - wc.set_adm_dir(".svn") - self.failIf(wc.is_adm_dir("_svn")) - self.assertEqual(".svn", wc.get_adm_dir()) + self.assertRaises(SubversionException, wc.set_adm_dir, b".foobar") + self.assertTrue(wc.is_adm_dir(b".svn")) + self.assertFalse(wc.is_adm_dir(b"_svn")) + self.assertFalse(wc.is_adm_dir(b".foobar")) + wc.set_adm_dir(b"_svn") + self.assertTrue(wc.is_adm_dir(b"_svn")) + self.assertEqual(b"_svn", wc.get_adm_dir()) + wc.set_adm_dir(b".svn") + self.assertFalse(wc.is_adm_dir(b"_svn")) + self.assertEqual(b".svn", wc.get_adm_dir()) def test_init_traversal_info(self): wc.init_traversal_info() @@ -127,8 +122,8 @@ class SubversionWorkingCopyTestCase(unit pass # Remove trunk/README.txt - readme_path = '%s/trunk/README.txt' % self.path - self.assert_(os.path.exists(readme_path)) + readme_path = b'%s/trunk/README.txt' % self.path + self.assertTrue(os.path.exists(readme_path)) os.remove(readme_path) # Restore trunk/README.txt using crawl_revision2 @@ -138,8 +133,8 @@ class SubversionWorkingCopyTestCase(unit True, True, False, notify, info) # Check that the report finished - self.assert_(reporter.finished_report) - self.assertEqual([''], set_paths) + self.assertTrue(reporter.finished_report) + self.assertEqual([b''], set_paths) self.assertEqual(1, len(infos)) # Check content of infos object @@ -152,7 +147,7 @@ class SubversionWorkingCopyTestCase(unit wc.create_notify(self.path, wc.notify_add) def test_check_wc(self): - self.assert_(wc.check_wc(self.path) > 0) + self.assertTrue(wc.check_wc(self.path) > 0) def test_get_ancestry(self): self.assertEqual([self.repos_uri, 12], @@ -164,7 +159,6 @@ class SubversionWorkingCopyTestCase(unit def test_status_editor(self): paths = [] def status_func(target, status): - self.assert_(target.startswith(self.path)) paths.append(target) (anchor_access, target_access, @@ -181,54 +175,79 @@ class SubversionWorkingCopyTestCase(unit None, # traversal_info ) editor.close_edit(edit_baton) - self.assert_(len(paths) > 0) + self.assertTrue(len(paths) > 0) + for target in paths: + self.assertTrue(target.startswith(self.path)) + + def test_status_editor_callback_exception(self): + """test case for status_editor call back not to be crashed by Python exception""" + def status_func(target, status): + # Note: exception with in this call back doesn't propagate to + # the caller + raise AssertionError('intentional exception') + + (anchor_access, target_access, + target) = wc.adm_open_anchor(self.path, False, -1, None) + (editor, edit_baton, set_locks_baton, + edit_revision) = wc.get_status_editor2(anchor_access, + target, + None, # SvnConfig + True, # recursive + True, # get_all + False, # no_ignore + status_func, + None, # cancel_func + None, # traversal_info + ) + editor.close_edit(edit_baton) def test_is_normal_prop(self): - self.failIf(wc.is_normal_prop('svn:wc:foo:bar')) - self.failIf(wc.is_normal_prop('svn:entry:foo:bar')) - self.assert_(wc.is_normal_prop('svn:foo:bar')) - self.assert_(wc.is_normal_prop('foreign:foo:bar')) + self.assertFalse(wc.is_normal_prop(b'svn:wc:foo:bar')) + self.assertFalse(wc.is_normal_prop(b'svn:entry:foo:bar')) + self.assertTrue(wc.is_normal_prop(b'svn:foo:bar')) + self.assertTrue(wc.is_normal_prop(b'foreign:foo:bar')) def test_is_wc_prop(self): - self.assert_(wc.is_wc_prop('svn:wc:foo:bar')) - self.failIf(wc.is_wc_prop('svn:entry:foo:bar')) - self.failIf(wc.is_wc_prop('svn:foo:bar')) - self.failIf(wc.is_wc_prop('foreign:foo:bar')) + self.assertTrue(wc.is_wc_prop(b'svn:wc:foo:bar')) + self.assertFalse(wc.is_wc_prop(b'svn:entry:foo:bar')) + self.assertFalse(wc.is_wc_prop(b'svn:foo:bar')) + self.assertFalse(wc.is_wc_prop(b'foreign:foo:bar')) def test_is_entry_prop(self): - self.assert_(wc.is_entry_prop('svn:entry:foo:bar')) - self.failIf(wc.is_entry_prop('svn:wc:foo:bar')) - self.failIf(wc.is_entry_prop('svn:foo:bar')) - self.failIf(wc.is_entry_prop('foreign:foo:bar')) + self.assertTrue(wc.is_entry_prop(b'svn:entry:foo:bar')) + self.assertFalse(wc.is_entry_prop(b'svn:wc:foo:bar')) + self.assertFalse(wc.is_entry_prop(b'svn:foo:bar')) + self.assertFalse(wc.is_entry_prop(b'foreign:foo:bar')) def test_get_prop_diffs(self): - wc.prop_set("foreign:foo", "bla", self.path, self.wc) - self.assertEquals([{"foreign:foo": "bla"}, {}], + wc.prop_set(b"foreign:foo", b"bla", self.path, self.wc) + self.assertEqual([{b"foreign:foo": b"bla"}, {}], wc.get_prop_diffs(self.path, self.wc)) def test_get_pristine_copy_path(self): - path_to_file = '%s/trunk/README.txt' % self.path + path_to_file = b'%s/trunk/README.txt' % self.path path_to_text_base = wc.get_pristine_copy_path(path_to_file) - text_base = open(path_to_text_base).read() + with open(path_to_text_base, 'rb') as fp: + text_base = fp.read() # TODO: This test should modify the working file first, to ensure the # path isn't just the path to the working file. - self.assertEqual(text_base, 'A test.\n') + self.assertEqual(text_base, b'A test.\n') def test_entries_read(self): entries = wc.entries_read(self.wc, True) - keys = list(entries.keys()) + keys = core._as_list(entries.keys()) keys.sort() - self.assertEqual(['', 'branches', 'tags', 'trunk'], keys) + self.assertEqual([b'', b'branches', b'tags', b'trunk'], keys) def test_get_ignores(self): - self.assert_(isinstance(wc.get_ignores(None, self.wc), list)) + self.assertTrue(isinstance(wc.get_ignores(None, self.wc), list)) def test_commit(self): # Replace README.txt's contents, using binary mode so we know the # exact contents even on Windows, and therefore the MD5 checksum. - readme_path = '%s/trunk/README.txt' % self.path + readme_path = b'%s/trunk/README.txt' % self.path fp = open(readme_path, 'wb') - fp.write('hello\n') + fp.write(b'hello\n') fp.close() # Setup ra_ctx. @@ -240,7 +259,7 @@ class SubversionWorkingCopyTestCase(unit commit_info = [None] def commit_cb(_commit_info, pool): commit_info[0] = _commit_info - (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, 'log message', + (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, b'log message', commit_cb, None, False) @@ -254,7 +273,7 @@ class SubversionWorkingCopyTestCase(unit False, editor, baton, pool) return baton try: - delta.path_driver(editor, edit_baton, -1, ['trunk/README.txt'], + delta.path_driver(editor, edit_baton, -1, [b'trunk/README.txt'], driver_cb) editor.close_edit(edit_baton) except: @@ -269,9 +288,9 @@ class SubversionWorkingCopyTestCase(unit (commit_info,) = commit_info # Assert the commit. - self.assertEquals(binascii.b2a_hex(checksum), - 'b1946ac92492d2347c6235b4d2611184') - self.assertEquals(commit_info.revision, 13) + self.assertEqual(binascii.b2a_hex(checksum), + b'b1946ac92492d2347c6235b4d2611184') + self.assertEqual(commit_info.revision, 13) # Bump working copy state. wc.process_committed4(readme_path, @@ -282,10 +301,10 @@ class SubversionWorkingCopyTestCase(unit # Assert bumped state. entry = wc.entry(readme_path, self.wc, False) - self.assertEquals(entry.revision, commit_info.revision) - self.assertEquals(entry.schedule, wc.schedule_normal) - self.assertEquals(entry.cmt_rev, commit_info.revision) - self.assertEquals(entry.cmt_date, + self.assertEqual(entry.revision, commit_info.revision) + self.assertEqual(entry.schedule, wc.schedule_normal) + self.assertEqual(entry.cmt_rev, commit_info.revision) + self.assertEqual(entry.cmt_date, core.svn_time_from_cstring(commit_info.date)) def test_diff_editor4(self): @@ -294,14 +313,14 @@ class SubversionWorkingCopyTestCase(unit url = self.repos_uri # cause file_changed: Replace README.txt's contents. - readme_path = '%s/trunk/README.txt' % self.path - fp = open(readme_path, 'w') - fp.write('hello\n') + readme_path = b'%s/trunk/README.txt' % self.path + fp = open(readme_path, 'wb') + fp.write(b'hello\n') fp.close() # cause file_added: Create readme3. - readme3_path = '%s/trunk/readme3' % self.path - fp = open(readme3_path, 'w') - fp.write('hello\n') + readme3_path = b'%s/trunk/readme3' % self.path + fp = open(readme3_path, 'wb') + fp.write(b'hello\n') fp.close() wc.add2(readme3_path, wc.adm_probe_retrieve(self.wc, @@ -311,7 +330,7 @@ class SubversionWorkingCopyTestCase(unit None, # notify_func pool) # cause file_deleted: Delete README2.txt. - readme2_path = '%s/trunk/README2.txt' % self.path + readme2_path = b'%s/trunk/README2.txt' % self.path wc.delete3(readme2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(readme2_path), pool), @@ -320,8 +339,8 @@ class SubversionWorkingCopyTestCase(unit False, # keep_local pool) # cause dir_props_changed: ps testprop testval dir1/dir2 - dir2_path = '%s/trunk/dir1/dir2' % self.path - wc.prop_set2('testprop', 'testval', dir2_path, + dir2_path = b'%s/trunk/dir1/dir2' % self.path + wc.prop_set2(b'testprop', b'testval', dir2_path, wc.adm_probe_retrieve(self.wc, os.path.dirname(dir2_path), pool), False, # skip_checks @@ -331,7 +350,7 @@ class SubversionWorkingCopyTestCase(unit # Save prop changes. got_prop_changes = [] def props_changed(path, propchanges): - for (name, value) in propchanges.items(): + for (name, value) in core._as_list(propchanges.items()): (kind, _) = core.svn_property_kind(name) if kind != core.svn_prop_regular_kind: continue @@ -342,16 +361,16 @@ class SubversionWorkingCopyTestCase(unit def write_diff(path, left, right): options = svn.diff.file_options_create() diff = svn.diff.file_diff_2(left, right, options, pool) - original_header = modified_header = '' - encoding = 'utf8' + original_header = modified_header = b'' + encoding = b'utf8' relative_to_dir = None - sio = StringIO() - svn.diff.file_output_unified3(sio, diff, + bio = BytesIO() + svn.diff.file_output_unified3(bio, diff, left, right, original_header, modified_header, encoding, relative_to_dir, options.show_c_function, pool) - got_diffs[path[len(self.path) + 1:]] = sio.getvalue().splitlines() + got_diffs[path[len(self.path) + 1:]] = bio.getvalue().splitlines() # Diff callbacks that call props_changed and write_diff. contentstate = propstate = state = wc.notify_state_unknown @@ -383,7 +402,7 @@ class SubversionWorkingCopyTestCase(unit # Setup wc diff editor. (editor, edit_baton) = wc.get_diff_editor4( - self.wc, '', diff_callbacks, depth, + self.wc, b'', diff_callbacks, depth, False, # ignore_ancestry False, # use_text_base False, # reverse_order @@ -400,39 +419,39 @@ class SubversionWorkingCopyTestCase(unit (reporter, report_baton) = ra.do_diff3( ra_ctx, head, # versus_url revision - '', # diff_target + b'', # diff_target depth, False, # ignore_ancestry True, # text_deltas url, # versus_url editor, edit_baton, pool) # Report wc state (pretty plain). - reporter.set_path(report_baton, '', head, depth, + reporter.set_path(report_baton, b'', head, depth, False, # start_empty None, # lock_token pool) reporter.finish_report(report_baton, pool) # Assert we got the right diff. - expected_prop_changes = [('trunk/dir1/dir2', - 'testprop', 'testval')] + expected_prop_changes = [(b'trunk/dir1/dir2', + b'testprop', b'testval')] expected_diffs = { - 'trunk/readme3': - ['--- ', - '+++ ', - '@@ -0,0 +1 @@', - '+hello'], - 'trunk/README.txt': - ['--- ', - '+++ ', - '@@ -1 +1 @@', - '-A test.', - '+hello'], - 'trunk/README2.txt': - ['--- ', - '+++ ', - '@@ -1 +0,0 @@', - '-A test.'], + b'trunk/readme3': + [b'--- ', + b'+++ ', + b'@@ -0,0 +1 @@', + b'+hello'], + b'trunk/README.txt': + [b'--- ', + b'+++ ', + b'@@ -1 +1 @@', + b'-A test.', + b'+hello'], + b'trunk/README2.txt': + [b'--- ', + b'+++ ', + b'@@ -1 +0,0 @@', + b'-A test.'], } self.assertEqual(got_prop_changes, expected_prop_changes) self.assertEqual(got_diffs, expected_diffs) Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/client.rb URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/client.rb?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/client.rb (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/client.rb Fri Jan 14 14:01:45 2022 @@ -637,25 +637,25 @@ module Svn ignore_externals, allow_unver_obstruction, self) end - def set_log_msg_func(callback=Proc.new) + def set_log_msg_func(&callback) callback_wrapper = Proc.new do |items| items = items.collect do |item| item_wrapper = CommitItemWrapper.new(item) end callback.call(items) end - set_log_msg_func2(callback_wrapper) + set_log_msg_func2(&callback_wrapper) end - def set_log_msg_func2(callback=Proc.new) + def set_log_msg_func2(&callback) @log_msg_baton = Client.set_log_msg_func3(self, callback) end - def set_notify_func(callback=Proc.new) + def set_notify_func(&callback) @notify_baton = Client.set_notify_func2(self, callback) end - def set_cancel_func(callback=Proc.new) + def set_cancel_func(&callback) @cancel_baton = Client.set_cancel_func(self, callback) end @@ -707,9 +707,9 @@ module Svn private def init_callbacks - set_log_msg_func(nil) - set_notify_func(nil) - set_cancel_func(nil) + set_log_msg_func + set_notify_func + set_cancel_func end %w(log_msg notify cancel).each do |type| private "#{type}_func", "#{type}_baton" Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/core.rb URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/core.rb?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/core.rb (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/svn/core.rb Fri Jan 14 14:01:45 2022 @@ -249,31 +249,31 @@ module Svn end end - def add_simple_prompt_provider(retry_limit, prompt=Proc.new) + def add_simple_prompt_provider(retry_limit, &prompt) args = [retry_limit] klass = AuthCredSimple add_prompt_provider("simple", args, prompt, klass) end - def add_username_prompt_provider(retry_limit, prompt=Proc.new) + def add_username_prompt_provider(retry_limit, &prompt) args = [retry_limit] klass = AuthCredUsername add_prompt_provider("username", args, prompt, klass) end - def add_ssl_server_trust_prompt_provider(prompt=Proc.new) + def add_ssl_server_trust_prompt_provider(&prompt) args = [] klass = AuthCredSSLServerTrust add_prompt_provider("ssl_server_trust", args, prompt, klass) end - def add_ssl_client_cert_prompt_provider(retry_limit, prompt=Proc.new) + def add_ssl_client_cert_prompt_provider(retry_limit, &prompt) args = [retry_limit] klass = AuthCredSSLClientCert add_prompt_provider("ssl_client_cert", args, prompt, klass) end - def add_ssl_client_cert_pw_prompt_provider(retry_limit, prompt=Proc.new) + def add_ssl_client_cert_pw_prompt_provider(retry_limit, &prompt) args = [retry_limit] klass = AuthCredSSLClientCertPw add_prompt_provider("ssl_client_cert_pw", args, prompt, klass) Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/test/test_delta.rb URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/test/test_delta.rb?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/test/test_delta.rb (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/ruby/test/test_delta.rb Fri Jan 14 14:01:45 2022 @@ -211,29 +211,32 @@ class SvnDeltaTest < Test::Unit::TestCas assert_equal(target_text, data) end - def test_path_driver - editor = Svn::Delta::BaseEditor.new - sorted_paths = [] - callback = Proc.new do |parent_baton, path| - sorted_paths << path - end - - targets = [ - "/", - "/file1", - "/dir1", - "/dir2/file2", - "/dir2/dir3/file3", - "/dir2/dir3/file4" - ] - 10.times do - x = rand(targets.size) - y = rand(targets.size) - targets[x], targets[y] = targets[y], targets[x] - end - Svn::Delta.path_driver(editor, 0, targets, &callback) - assert_equal(targets.sort, sorted_paths) - end +# Fails since r1852536: "delta path editor binding broken for root path" +# https://issues.apache.org/jira/browse/SVN-4805 +# +# def test_path_driver +# editor = Svn::Delta::BaseEditor.new +# sorted_paths = [] +# callback = Proc.new do |parent_baton, path| +# sorted_paths << path +# end +# +# targets = [ +# "/", +# "/file1", +# "/dir1", +# "/dir2/file2", +# "/dir2/dir3/file3", +# "/dir2/dir3/file4" +# ] +# 10.times do +# x = rand(targets.size) +# y = rand(targets.size) +# targets[x], targets[y] = targets[y], targets[x] +# end +# Svn::Delta.path_driver(editor, 0, targets, &callback) +# assert_equal(targets.sort, sorted_paths) +# end def test_changed dir = "changed_dir" Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/svn_client.i URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/svn_client.i?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/svn_client.i (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/svn_client.i Fri Jan 14 14:01:45 2022 @@ -21,15 +21,16 @@ * svn_client.i: SWIG interface file for svn_client.h */ +%include svn_global.swg + #if defined(SWIGPYTHON) -%module(package="libsvn") client +%module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) client #elif defined(SWIGPERL) %module "SVN::_Client" #elif defined(SWIGRUBY) %module "svn::ext::client" #endif -%include svn_global.swg %import core.i %import svn_delta.i %import svn_wc.i @@ -119,7 +120,7 @@ ppitem = (svn_client_proplist_item_t **)(*$1)->elts; for (i = 0; i < nelts; ++i, ++ppitem) { PyObject *item = PyTuple_New(2); - PyObject *name = PyString_FromStringAndSize((*ppitem)->node_name->data, + PyObject *name = PyBytes_FromStringAndSize((*ppitem)->node_name->data, (*ppitem)->node_name->len); PyObject *hash = svn_swig_py_prophash_to_dict((*ppitem)->prop_hash); @@ -239,6 +240,33 @@ Callback: svn_client_diff_summarize_func svn_swig_rb_changelist_receiver) #endif + /* ----------------------------------------------------------------------- + Callback: svn_client_status_func_t + svn_client_status*() + svn_client__shelf_save_new_version3() + */ + +#ifdef SWIGPYTHON +%callback_typemap(svn_client_status_func_t status_func, + void *status_baton, + svn_swig_py_client_status_func, + , + ) + +%callback_typemap_maybenull(svn_client_status_func_t shelved_func, + void *shelved_baton, + svn_swig_py_client_status_func, + , + ) + +%callback_typemap_maybenull(svn_client_status_func_t not_shelved_func, + void *not_shelved_baton, + svn_swig_py_client_status_func, + , + ) +#endif + + /* ----------------------------------------------------------------------- We use 'svn_wc_status_t *' in some custom code, but it isn't in the API anywhere. Thus, SWIG doesn't generate a typemap entry for it. by Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/svn_delta.i URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/svn_delta.i?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/svn_delta.i (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/svn_delta.i Fri Jan 14 14:01:45 2022 @@ -21,15 +21,16 @@ * svn_delta.i: SWIG interface file for svn_delta.h */ +%include svn_global.swg + #if defined(SWIGPYTHON) -%module(package="libsvn") delta +%module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) delta #elif defined(SWIGPERL) %module "SVN::_Delta" #elif defined(SWIGRUBY) %module "svn::ext::delta" #endif -%include svn_global.swg %import core.i #ifdef SWIGRUBY Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/svn_diff.i URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/svn_diff.i?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/svn_diff.i (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/svn_diff.i Fri Jan 14 14:01:45 2022 @@ -21,15 +21,16 @@ * svn_diff.i: SWIG interface file for svn_diff.h */ +%include svn_global.swg + #if defined(SWIGPYTHON) -%module(package="libsvn") diff +%module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) diff #elif defined(SWIGPERL) %module "SVN::_Diff" #elif defined(SWIGRUBY) %module "svn::ext::diff" #endif -%include svn_global.swg %import core.i /* ----------------------------------------------------------------------- Modified: subversion/branches/multi-wc-format/subversion/bindings/swig/svn_fs.i URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/bindings/swig/svn_fs.i?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/bindings/swig/svn_fs.i (original) +++ subversion/branches/multi-wc-format/subversion/bindings/swig/svn_fs.i Fri Jan 14 14:01:45 2022 @@ -21,15 +21,16 @@ * svn_fs.i: SWIG interface file for svn_fs.h */ +%include svn_global.swg + #if defined(SWIGPYTHON) -%module(package="libsvn") fs +%module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) fs #elif defined(SWIGPERL) %module "SVN::_Fs" #elif defined(SWIGRUBY) %module "svn::ext::fs" #endif -%include svn_global.swg %import core.i %import svn_delta.i @@ -93,23 +94,68 @@ %apply apr_hash_t *MERGEINFO { apr_hash_t *mergeinhash }; /* ----------------------------------------------------------------------- - Fix the return value for svn_fs_commit_txn(). If the conflict result is - NULL, then %append_output() is passed Py_None, but that goofs up - because that is *also* the marker for "I haven't started assembling a - multi-valued return yet" which means the second return value (new_rev) - will not cause a 2-tuple to be manufactured. - - The answer is to explicitly create a 2-tuple return value. - - FIXME: Do the Perl and Ruby bindings need to do something similar? + Tweak a SubversionException instance when it is raised in + svn_fs_merge(), svn_fs_commit_txn() and svn_repos_fs_commit_txn(). + Those APIs return conflicts (and revision number on svn_fs_commit_txn + and svn_repos_fs_commit_txn) related to the conflict error when it + is occured. As Python wrapper functions report errors by raising + exceptions and don't return values, we use attributes of the exception + to pass these values to the caller. */ + #ifdef SWIGPYTHON -%typemap(argout) (const char **conflict_p, svn_revnum_t *new_rev) { - /* this is always Py_None */ - Py_DECREF($result); - /* build the result tuple */ - $result = Py_BuildValue("zi", *$1, (long)*$2); +%typemap(argout) (const char **conflict_p) (PyObject* conflict_ob) { + if (*$1 == NULL) + { + Py_INCREF(Py_None); + conflict_ob = Py_None; + } + else + { + /* Note: We can check if apr_err == SVN_ERR_FS_CONFLICT or not + before access to *$1 */ + conflict_ob = PyBytes_FromString((const char *)*$1); + if (conflict_ob == NULL) + { + Py_XDECREF(exc_ob); + Py_XDECREF($result); + SWIG_fail; + } + } + if (exc_ob != NULL) + { + PyObject_SetAttrString(exc_ob, "$1_name", conflict_ob); + Py_DECREF(conflict_ob); + } + else + { + %append_output(conflict_ob); + } +} + +%typemap(argout) svn_revnum_t *new_rev (PyObject *rev_ob) { + rev_ob = PyInt_FromLong((long)*$1); + if (rev_ob == NULL) + { + Py_XDECREF(exc_ob); + Py_XDECREF($result); + SWIG_fail; + } + if (exc_ob != NULL) + { + PyObject_SetAttrString(exc_ob, "$1_name", rev_ob); + Py_DECREF(rev_ob); + } + else + { + %append_output(rev_ob); + } } + +%apply svn_error_t *SVN_ERR_WITH_ATTRS { + svn_error_t * svn_fs_commit_txn, + svn_error_t * svn_fs_merge +}; #endif /* Ruby fixups for functions not following the pool convention. */
