mercurial/localrepo.py
changeset 39622 c5e6c1ba1c79
parent 39607 76b58f240821
child 39684 24870f1be088
--- a/mercurial/localrepo.py	Tue Sep 11 20:06:39 2018 -0700
+++ b/mercurial/localrepo.py	Wed Sep 12 19:00:46 2018 -0700
@@ -2503,3 +2503,28 @@
                      b'layout')
 
     scmutil.writerequires(hgvfs, requirements)
+
+def poisonrepository(repo):
+    """Poison a repository instance so it can no longer be used."""
+    # Perform any cleanup on the instance.
+    repo.close()
+
+    # Our strategy is to replace the type of the object with one that
+    # has all attribute lookups result in error.
+    #
+    # But we have to allow the close() method because some constructors
+    # of repos call close() on repo references.
+    class poisonedrepository(object):
+        def __getattribute__(self, item):
+            if item == r'close':
+                return object.__getattribute__(self, item)
+
+            raise error.ProgrammingError('repo instances should not be used '
+                                         'after unshare')
+
+        def close(self):
+            pass
+
+    # We may have a repoview, which intercepts __setattr__. So be sure
+    # we operate at the lowest level possible.
+    object.__setattr__(repo, r'__class__', poisonedrepository)