[MERGE] Replace Repository.__eq__/__ne__ methods with Repository.is_same_repository

Andrew Bennetts andrew at canonical.com
Tue Aug 7 02:45:17 BST 2007


Andrew Bennetts wrote:
[...]
> 
> In the meantime, I'll rework the patch to use a method other than __eq__.

Here is that patch.  It removes Repository.__eq__/__ne__, and instead adds
Repository.is_same_repository.

I've taken care to document the possibility of false negatives in the docstring.
It doesn't make any claim about lock states.

-Andrew.

-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.19)
# revision_id: andrew.bennetts at canonical.com-20070807014056-\
#   al2nq16umo9f5gc5
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: 1c74486131b29c2bf8326016e7285755d7f0e03c
# timestamp: 2007-08-07 11:41:18 +1000
# source_branch: http://people.ubuntu.com/~andrew/bzr/repository-\
#   equality
# base_revision_id: andrew.bennetts at canonical.com-20070806051155-\
#   t570bk2i3gcnebwr
# 
# Begin patch
=== modified file 'NEWS'
--- NEWS	2007-08-06 01:59:55 +0000
+++ NEWS	2007-08-07 01:40:56 +0000
@@ -195,8 +195,9 @@
     * ``bzrlib.pack.make_readv_reader`` allows readv based access to pack
       files that are stored on a transport. (Robert Collins)
 
-    * ``Repository`` objects can now be compared with ``==`` and ``!=`` to
-      determine if they are the same repository.  (Andrew Bennetts)
+    * New ``Repository.is_same_repository`` method that reports if two
+      repository objects refer to the same repository (although with some risk
+      of false negatives).  (Andrew Bennetts)
 
   TESTING:
 

=== modified file 'bzrlib/remote.py'
--- bzrlib/remote.py	2007-08-06 05:11:55 +0000
+++ bzrlib/remote.py	2007-08-07 01:40:56 +0000
@@ -249,13 +249,10 @@
         self._lock_count = 0
         self._leave_lock = False
 
-    def __eq__(self, other):
+    def is_same_repository(self, other):
         return (self.__class__ == other.__class__ and
                 self.bzrdir.transport.base == other.bzrdir.transport.base)
         
-    def __ne__(self, other):
-        return not self == other
-
     def _ensure_real(self):
         """Ensure that there is a _real_repository set.
 

=== modified file 'bzrlib/repository.py'
--- bzrlib/repository.py	2007-08-06 01:59:55 +0000
+++ bzrlib/repository.py	2007-08-07 01:40:56 +0000
@@ -235,15 +235,18 @@
         return '%s(%r)' % (self.__class__.__name__, 
                            self.bzrdir.transport.base)
 
-    def __eq__(self, other):
+    def is_same_repository(self, other):
+        """Returns a boolean indicating if this repository is at the same
+        location as another repository.
+
+        This might return False even when two repository objects are accessing
+        the same physical repository via different URLs.
+        """
         if self.__class__ is not other.__class__:
             return False
         return (self.control_files._transport.base ==
                 other.control_files._transport.base)
 
-    def __ne__(self, other):
-        return not self == other
-
     def is_locked(self):
         return self.control_files.is_locked()
 

=== modified file 'bzrlib/tests/repository_implementations/test_repository.py'
--- bzrlib/tests/repository_implementations/test_repository.py	2007-08-06 01:59:55 +0000
+++ bzrlib/tests/repository_implementations/test_repository.py	2007-08-07 01:40:56 +0000
@@ -422,64 +422,59 @@
         self.assertEqual(repo._serializer.format_num, format)
 
 
-class TestRepositoryEquality(TestCaseWithRepository):
-
-    def strictAssertEqual(self, a, b):
-        """Like assertEqual, but also checks the `!=` operator is consistent.
-
-        i.e. if `a == b` *and* `a != b`, this method will fail.
-
-        This can happen when a class defines an `__eq__` but doesn't define an
-        `__ne__`.
-        """
-        self.assertEqual(a, b)
-        self.failIf(
-            a != b,
-            "%r and %r are both equal and not equal!  Class probably defines "
-            "__eq__ without also defining __ne__." % (a, b))
-
-    def strictAssertNotEqual(self, a, b):
-        """Like assertNotEqual, but also checks the `==` operator is consistent.
-
-        i.e. if `a != b` *and* `a == b`, this method will fail.
-
-        This can happen when a class defines an `__eq__` but doesn't define an
-        `__ne__`.
-
-        :seealso: strictAssertEqual
-        """
-        self.assertNotEqual(a, b)
-        self.failIf(
-            a == b,
-            "%r and %r are both equal and not equal!  Class probably defines "
-            "__eq__ without also defining __ne__." % (a, b))
-
-    def test_same_repo_instance_is_equal(self):
-        """A repository object is always equal to itself."""
+class TestRepositoryComparison(TestCaseWithRepository):
+    """Tests for Repository.is_same_repository method."""
+
+    def assertSameRepo(self, a, b):
+        """Asserts that two objects are the same repository.
+
+        This method does the comparison both ways (`a.is_same_repository(b)` as
+        well as `b.is_same_repository(a)`) to make sure both objects'
+        `is_same_repository` methods give the same results.
+        """
+        self.assertTrue(a.is_same_repository(b),
+                        "%r is not the same repository as %r" % (a, b))
+        self.assertTrue(b.is_same_repository(a),
+                        "%r is the same as %r, but not vice versa" % (a, b))
+
+    def assertDifferentRepo(self, a, b):
+        """Asserts that two objects are the not same repository.
+
+        This method does the comparison both ways (`a.is_same_repository(b)` as
+        well as `b.is_same_repository(a)`) to make sure both objects'
+        `is_same_repository` methods give the same results.
+
+        :seealso: assertDifferentRepo
+        """
+        self.assertFalse(a.is_same_repository(b),
+                         "%r is not the same repository as %r" % (a, b))
+        self.assertFalse(b.is_same_repository(a),
+                         "%r is the same as %r, but not vice versa" % (a, b))
+
+    def test_same_repo_instance(self):
+        """A repository object is the same repository as itself."""
         repo = self.make_repository('.')
-        self.strictAssertEqual(repo, repo)
+        self.assertSameRepo(repo, repo)
 
-    def test_same_repo_location_is_equal(self):
-        """Different repository objects connected to the same location are
-        equal.
-        """
+    def test_same_repo_location(self):
+        """Different repository objects for the same location are the same."""
         repo = self.make_repository('.')
         reopened_repo = repo.bzrdir.open_repository()
         self.failIf(
             repo is reopened_repo,
             "This test depends on reopened_repo being a different instance of "
             "the same repo.")
-        self.strictAssertEqual(repo, reopened_repo)
+        self.assertSameRepo(repo, reopened_repo)
 
     def test_different_repos_not_equal(self):
-        """Repositories at different locations are not equal."""
+        """Repositories at different locations are not the same."""
         repo_one = self.make_repository('one')
         repo_two = self.make_repository('two')
-        self.strictAssertNotEqual(repo_one, repo_two)
+        self.assertDifferentRepo(repo_one, repo_two)
 
     def test_same_bzrdir_different_control_files_not_equal(self):
         """Repositories in the same bzrdir, but with different control files,
-        are not equal.
+        are not the same.
 
         This can happens e.g. when upgrading a repository.  This test mimics how
         CopyConverter creates a second repository in one bzrdir.
@@ -500,10 +495,10 @@
         backup_repo = repo._format.open(repo.bzrdir, _found=True,
                                         _override_transport=backup_transport)
 
-        self.strictAssertNotEqual(repo, backup_repo)
+        self.assertDifferentRepo(repo, backup_repo)
 
     def test_different_format_not_equal(self):
-        """Different format repositories are comparable and not equal.
+        """Different format repositories are comparable and not the same.
 
         Comparing different format repository objects should give a negative
         result, rather than trigger an exception (which could happen with a
@@ -519,10 +514,7 @@
         # Make sure the other_repo is not a RemoteRepository.
         other_bzrdir = bzrdir.BzrDir.open(self.get_vfs_only_url('other'))
         other_repo = other_bzrdir.open_repository()
-        # Compare both ways, to make sure the __eq__ on both repositories cope
-        # with comparing against a different class.
-        self.strictAssertNotEqual(repo, other_repo)
-        self.strictAssertNotEqual(other_repo, repo)
+        self.assertDifferentRepo(repo, other_repo)
 
 
 class TestRepositoryLocking(TestCaseWithRepository):

# Begin bundle
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


More information about the bazaar mailing list