Chris McDonough
2014-01-22 f58977a38ac65dce742dac38fe1179f61bfc3efc
- 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
2 files modified
26 ■■■■■ changed files
CHANGES.txt 5 ●●●●● patch | view | raw | blame | history
pyramid/util.py 21 ●●●●● patch | view | raw | blame | history
CHANGES.txt
@@ -15,6 +15,11 @@
- 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)
==================
pyramid/util.py
@@ -26,6 +26,8 @@
    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 @@
        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):