diff options
| author | Michael Merickel <michael@merickel.org> | 2017-03-03 19:34:05 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-03-03 19:34:05 -0600 |
| commit | 78ac16c1c683b6b4d639e25883fd35f4e9073978 (patch) | |
| tree | 1baa1d79707ca842f8f150db158f7181201505a1 | |
| parent | 7fb889349d40e361397ed31f3535689182aa5cf0 (diff) | |
| parent | 870a1d1f957d772cab0eb60bc1d1928da2ebb992 (diff) | |
| download | pyramid-78ac16c1c683b6b4d639e25883fd35f4e9073978.tar.gz pyramid-78ac16c1c683b6b4d639e25883fd35f4e9073978.tar.bz2 pyramid-78ac16c1c683b6b4d639e25883fd35f4e9073978.zip | |
Merge pull request #2967 from Cykooz/fix.memory-leaks
Fixed several reference cycles to prevent memory leaks.
| -rw-r--r-- | CONTRIBUTORS.txt | 2 | ||||
| -rw-r--r-- | pyramid/registry.py | 4 | ||||
| -rw-r--r-- | pyramid/tests/test_integration.py | 28 | ||||
| -rw-r--r-- | pyramid/util.py | 9 |
4 files changed, 39 insertions, 4 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index d5c178418..566e91195 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -292,3 +292,5 @@ Contributors - Mikko Ohtamaa, 2016/12/6 - Martin Frlin, 2016/12/7 + +- Kirill Kuzminykh, 2017/03/01 diff --git a/pyramid/registry.py b/pyramid/registry.py index 20b3643e9..7589dfcac 100644 --- a/pyramid/registry.py +++ b/pyramid/registry.py @@ -276,7 +276,9 @@ class Deferred(object): @reify def value(self): - return self.func() + result = self.func() + del self.func + return result def resolve(self): return self.value diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index 85c4466a4..f23e54609 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import datetime +import gc import locale import os import unittest @@ -8,6 +9,7 @@ import unittest from pyramid.wsgi import wsgiapp from pyramid.view import view_config from pyramid.static import static_view +from pyramid.testing import skip_on from pyramid.compat import ( text_, url_quote, @@ -741,3 +743,29 @@ def _assertBody(body, filename): data = data.replace(b'\r', b'') data = data.replace(b'\n', b'') assert(body == data) + + +class MemoryLeaksTest(unittest.TestCase): + + def tearDown(self): + import pyramid.config + pyramid.config.global_registries.empty() + + def get_gc_count(self): + last_collected = 0 + while True: + collected = gc.collect() + if collected == last_collected: + break + last_collected = collected + return len(gc.get_objects()) + + @skip_on('pypy') + def test_memory_leaks(self): + from pyramid.config import Configurator + Configurator().make_wsgi_app() # Initialize all global objects + + initial_count = self.get_gc_count() + Configurator().make_wsgi_app() + current_count = self.get_gc_count() + self.assertEqual(current_count, initial_count) diff --git a/pyramid/util.py b/pyramid/util.py index 3337d410d..2827884a3 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -231,17 +231,20 @@ class WeakOrderedSet(object): self._order.remove(oid) self._order.append(oid) return - ref = weakref.ref(item, lambda x: self.remove(item)) + ref = weakref.ref(item, lambda x: self._remove_by_id(oid)) self._items[oid] = ref self._order.append(oid) - def remove(self, item): + def _remove_by_id(self, oid): """ Remove an item from the set.""" - oid = id(item) if oid in self._items: del self._items[oid] self._order.remove(oid) + def remove(self, item): + """ Remove an item from the set.""" + self._remove_by_id(id(item)) + def empty(self): """ Clear all objects from the set.""" self._items = {} |
