Mercurial > hg
changeset 35248: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 | 9ce4e01f58ee |
children | d4ad9d695a9e |
files | mercurial/localrepo.py mercurial/repoview.py mercurial/statichttprepo.py |
diffstat | 3 files changed, 16 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Tue Dec 05 21:37:30 2017 +0900 +++ b/mercurial/localrepo.py Tue Dec 05 21:50:33 2017 +0900 @@ -502,9 +502,6 @@ # post-dirstate-status hooks self._postdsstatus = [] - # Cache of types representing filtered repos. - self._filteredrepotypes = weakref.WeakKeyDictionary() - # generic mapping between names and nodes self.names = namespaces.namespaces() @@ -680,20 +677,8 @@ def filtered(self, name): """Return a filtered version of a repository""" - # Python <3.4 easily leaks types via __mro__. See - # https://bugs.python.org/issue17950. We cache dynamically - # created types so this method doesn't leak on every - # invocation. - - key = self.unfiltered().__class__ - if key not in self._filteredrepotypes: - # Build a new type with the repoview mixin and the base - # class of this repo. - class filteredrepo(repoview.repoview, key): - pass - self._filteredrepotypes[key] = filteredrepo - - return self._filteredrepotypes[key](self, name) + cls = repoview.newtype(self.unfiltered().__class__) + return cls(self, name) @repofilecache('bookmarks', 'bookmarks.current') def _bookmarks(self):
--- 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]
--- a/mercurial/statichttprepo.py Tue Dec 05 21:37:30 2017 +0900 +++ b/mercurial/statichttprepo.py Tue Dec 05 21:50:33 2017 +0900 @@ -166,8 +166,6 @@ self.encodepats = None self.decodepats = None self._transref = None - # Cache of types representing filtered repos. - self._filteredrepotypes = {} def _restrictcapabilities(self, caps): caps = super(statichttprepository, self)._restrictcapabilities(caps)