Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
]

install_requires = [
'ProxyTypes>=0.9',
'wrapt>=1.10.11',
]

setup(
name='django-speedbar',
version='0.2.2',
version='0.3.0',
author='Mat Clayton',
author_email='mat@mixcloud.com',
url='http://github.com/mixcloud/django-speedbar',
Expand All @@ -36,4 +36,4 @@
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
)
)
6 changes: 3 additions & 3 deletions speedbar/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from django.conf import settings
from django.core.signals import request_started, request_finished
from django.core.urlresolvers import reverse
from django.utils.encoding import smart_unicode, smart_str
from django.utils.encoding import smart_text, smart_bytes

from speedbar.signals import setup_request_tracing, store_request_trace
from speedbar.utils import init_modules
Expand Down Expand Up @@ -87,7 +87,7 @@ def process_response(self, request, response):
# Force render of response (from lazy TemplateResponses) before speedbar is injected
if hasattr(response, 'render'):
response.render()
content = smart_unicode(response.content)
content = smart_text(response.content)

content = self.replace_templatetag_placeholders(content, metrics)

Expand All @@ -100,7 +100,7 @@ def process_response(self, request, response):
content = content.replace(panel_placeholder_url, panel_url)
request_trace.persist_details = True

response.content = smart_str(content)
response.content = smart_bytes(content)
if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
return response
Expand Down
49 changes: 16 additions & 33 deletions speedbar/modules/monkey_patching.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,35 @@
# This package has missing __init__.py files, so pylint can't see it
# pylint: disable=F0401
from peak.util.proxies import ObjectWrapper
import wrapt


# The linter is dumb
# pylint: disable=E1001,E1002
class CallableProxy(ObjectWrapper):
__slots__ = ('_eop_wrapper_')

def __init__(self, wrapped, wrapper):
super(CallableProxy, self).__init__(wrapped)
self._eop_wrapper_ = wrapper
class BoundCallableWrapper(wrapt.ObjectProxy):
def __init__(self, wrapped, instance, wrapper):
super(BoundCallableWrapper, self).__init__(wrapped)
self._self_wrapper = wrapper
self._self_instance = instance

def __call__(self, *args, **kwargs):
return self._eop_wrapper_(self.__subject__, *args, **kwargs)
return self._self_wrapper(self.__wrapped__, self._self_instance, *args, **kwargs)


class BoundMethodProxy(ObjectWrapper):
__slots__ = ('_eop_wrapper_', '_eop_instance_')

def __init__(self, wrapped, instance, wrapper):
super(BoundMethodProxy, self).__init__(wrapped)
self._eop_instance_ = instance
self._eop_wrapper_ = wrapper
class CallableWrapper(wrapt.ObjectProxy):
def __init__(self, wrapped, wrapper):
super(CallableWrapper, self).__init__(wrapped)
self._self_wrapper = wrapper

def __call__(self, *args, **kwargs):
return self._eop_wrapper_(self.__subject__, self._eop_instance_, *args, **kwargs)


class UnboundMethodProxy(CallableProxy):
__slots__ = ('_eop_wrapper_')
return self._self_wrapper(self.__wrapped__, *args, **kwargs)

def __get__(self, instance, owner):
return BoundMethodProxy(self.__subject__.__get__(instance, owner), instance or owner, self._eop_wrapper_)

def __getattribute__(self, attr, oga=object.__getattribute__):
"""We need to return our own version of __get__ or we may end up never being called if
the member we are wrapping is wrapped again by someone else"""
if attr == '__get__':
return oga(self, attr)
return super(UnboundMethodProxy, self).__getattribute__(attr)
function = self.__wrapped__.__get__(instance, owner)
return BoundCallableWrapper(function, instance or owner, self._self_wrapper)


def monkeypatch_method(cls, method_name=None):
def decorator(func):
method_to_patch = method_name or func.__name__
original = cls.__dict__[method_to_patch]
replacement = UnboundMethodProxy(original, func)
replacement = CallableWrapper(original, func)
type.__setattr__(cls, method_to_patch, replacement) # Avoid any overrides
return func
return decorator

4 changes: 2 additions & 2 deletions speedbar/modules/stacktracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from collections import defaultdict

from .base import BaseModule, RequestTrace
from .monkey_patching import monkeypatch_method, CallableProxy
from .monkey_patching import monkeypatch_method, BoundCallableWrapper

import time

Expand Down Expand Up @@ -144,7 +144,7 @@ def tracing_function(original, *args, **kwargs):
finally:
if request_trace:
request_trace.stacktracer.pop_stack()
return CallableProxy(func, tracing_function)
return BoundCallableWrapper(func, tracing_function)
except Exception:
# If we can't wrap for any reason, just return the original
return func
Expand Down
14 changes: 13 additions & 1 deletion testrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,19 @@ def runtests():
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {},
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
],
)
Expand Down
2 changes: 1 addition & 1 deletion tests/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.conf.urls import url
from django.conf.urls import url, include


def foo(request):
Expand Down