diff mercurial/repoview.py @ 35257:c752fbe228fb

repoview: extract a factory function of proxy class This makes sure that dynamically-created class objects are isolated from local binding of repo instances. The type cache is moved to module level as it isn't tied to each instance.
author Yuya Nishihara <yuya@tcha.org>
date Tue, 05 Dec 2017 21:50:33 +0900
parents 586645e0589c
children d4ad9d695a9e
line wrap: on
line diff
--- a/mercurial/repoview.py	Tue Dec 05 21:37:30 2017 +0900
+++ b/mercurial/repoview.py	Tue Dec 05 21:50:33 2017 +0900
@@ -9,6 +9,7 @@
 from __future__ import absolute_import
 
 import copy
+import weakref
 
 from .node import nullrev
 from . import (
@@ -240,3 +241,16 @@
 
     def __delattr__(self, attr):
         return delattr(self._unfilteredrepo, attr)
+
+# Python <3.4 easily leaks types via __mro__. See
+# https://bugs.python.org/issue17950. We cache dynamically created types
+# so they won't be leaked on every invocation of repo.filtered().
+_filteredrepotypes = weakref.WeakKeyDictionary()
+
+def newtype(base):
+    """Create a new type with the repoview mixin and the given base class"""
+    if base not in _filteredrepotypes:
+        class filteredrepo(repoview, base):
+            pass
+        _filteredrepotypes[base] = filteredrepo
+    return _filteredrepotypes[base]