Skip to content

Commit

Permalink
- Fix a memory leak when the configurator's set_request_property
Browse files Browse the repository at this point in the history
…method was

  used or when the configurator's ``add_request_method`` method was used with
  the ``property=True`` attribute.  See
  #1212 .

Closes #1212
  • Loading branch information
mcdonc committed Jan 22, 2014
1 parent dec6812 commit f58977a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGES.txt
Expand Up @@ -15,6 +15,11 @@ Bug Fixes
- Add a trailing semicolon to the JSONP response. This fixes JavaScript syntax - 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 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) 1.5a3 (2013-12-10)
================== ==================


Expand Down
21 changes: 21 additions & 0 deletions pyramid/util.py
Expand Up @@ -26,6 +26,8 @@ class DottedNameResolver(_DottedNameResolver):
def __init__(self, package=None): # default to package = None for bw compat def __init__(self, package=None): # default to package = None for bw compat
return _DottedNameResolver.__init__(self, package) return _DottedNameResolver.__init__(self, package)


_marker = object()

class InstancePropertyMixin(object): class InstancePropertyMixin(object):
""" Mixin that will allow an instance to add properties at """ Mixin that will allow an instance to add properties at
run-time as if they had been defined via @property or @reify run-time as if they had been defined via @property or @reify
Expand Down Expand Up @@ -80,6 +82,25 @@ def _set_properties(self, properties):
if attrs: if attrs:
parent = self.__class__ parent = self.__class__
cls = type(parent.__name__, (parent, object), attrs) 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 self.__class__ = cls


def _set_extensions(self, extensions): def _set_extensions(self, extensions):
Expand Down

0 comments on commit f58977a

Please sign in to comment.