diff options
| author | Chris McDonough <chrism@plope.com> | 2014-01-22 03:09:29 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2014-01-22 03:09:29 -0500 |
| commit | f58977a38ac65dce742dac38fe1179f61bfc3efc (patch) | |
| tree | 81c7a359e4d8d81cec926636a3f3a8f4e1a6a546 | |
| parent | dec681201ec50c261bde022ea09d24f09e3588bd (diff) | |
| download | pyramid-f58977a38ac65dce742dac38fe1179f61bfc3efc.tar.gz pyramid-f58977a38ac65dce742dac38fe1179f61bfc3efc.tar.bz2 pyramid-f58977a38ac65dce742dac38fe1179f61bfc3efc.zip | |
- Fix a memory leak when the configurator's ``set_request_property`` method was
used or when the configurator's ``add_request_method`` method was used with
the ``property=True`` attribute. See
https://github.com/Pylons/pyramid/issues/1212 .
Closes #1212
| -rw-r--r-- | CHANGES.txt | 5 | ||||
| -rw-r--r-- | pyramid/util.py | 21 |
2 files changed, 26 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 9c38bf814..8a340f320 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,11 @@ Bug Fixes - Add a trailing semicolon to the JSONP response. This fixes JavaScript syntax errors for old IE versions. See https://github.com/Pylons/pyramid/pull/1205 +- Fix a memory leak when the configurator's ``set_request_property`` method was + used or when the configurator's ``add_request_method`` method was used with + the ``property=True`` attribute. See + https://github.com/Pylons/pyramid/issues/1212 . + 1.5a3 (2013-12-10) ================== diff --git a/pyramid/util.py b/pyramid/util.py index 73f3ebdb0..6b92f17fc 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -26,6 +26,8 @@ class DottedNameResolver(_DottedNameResolver): def __init__(self, package=None): # default to package = None for bw compat return _DottedNameResolver.__init__(self, package) +_marker = object() + class InstancePropertyMixin(object): """ Mixin that will allow an instance to add properties at run-time as if they had been defined via @property or @reify @@ -80,6 +82,25 @@ class InstancePropertyMixin(object): if attrs: parent = self.__class__ cls = type(parent.__name__, (parent, object), attrs) + # We assign __provides__, __implemented__ and __providedBy__ below + # to prevent a memory leak that results from from the usage of this + # instance's eventual use in an adapter lookup. Adapter lookup + # results in ``zope.interface.implementedBy`` being called with the + # newly-created class as an argument. Because the newly-created + # class has no interface specification data of its own, lookup + # causes new ClassProvides and Implements instances related to our + # just-generated class to be created and set into the newly-created + # class' __dict__. We don't want these instances to be created; we + # want this new class to behave exactly like it is the parent class + # instead. See https://github.com/Pylons/pyramid/issues/1212 for + # more information. + for name in ('__implemented__', '__providedBy__', '__provides__'): + # we assign these attributes conditionally to make it possible + # to test this class in isolation without having any interfaces + # attached to it + val = getattr(parent, name, _marker) + if val is not _marker: + setattr(cls, name, val) self.__class__ = cls def _set_extensions(self, extensions): |
