Skip to content

Added support for Django 3, current django-debug-toolbar and Django REST framework #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ docs/_build
example/db.sqlite3
htmlcov
.tox
.idea/
*.egg-info/
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
include LICENSE
include README.rst
recursive-include debug_toolbar_line_profiler/templates *
recursive-include debug_toolbar_line_profiler/static *
33 changes: 23 additions & 10 deletions debug_toolbar_line_profiler/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
from pstats import Stats
from six import PY2

from django.urls import resolve
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
from django.utils.six.moves import cStringIO
try:
from django.utils.six.moves import cStringIO
except ImportError:
from io import StringIO as cStringIO
from debug_toolbar.panels import Panel
from django.views.generic.base import View

Expand All @@ -26,7 +30,7 @@ def get_root_func(self, view_func):
filename = view_func.__code__.co_filename
firstlineno = view_func.__code__.co_firstlineno
for func, (cc, nc, tt, ct, callers) in self.stats.items():
if (len(callers) == 0
if (len(callers) >= 0
and func[0] == filename
and func[1] == firstlineno):
self.__root = func
Expand Down Expand Up @@ -76,7 +80,9 @@ def func_std_string(self): # match what old profile produced
if idx > -1:
file_name = file_name[(idx + 14):]

file_path, file_name = file_name.rsplit(os.sep, 1)
file_items = file_name.rsplit(os.sep, 1)
file_path, file_name = file_items if len(file_items) > 1 else [
None, file_name]

return mark_safe(
'<span class="path">{0}/</span>'
Expand Down Expand Up @@ -165,8 +171,11 @@ class ProfilingPanel(Panel):
template = 'debug_toolbar_line_profiler/panels/profiling.html'

def _unwrap_closure_and_profile(self, func):
if not hasattr(func, '__code__'):
if not hasattr(func, '__code__') or func in self.added:
return

self.added.add(func)

self.line_profiler.add_function(func)
for subfunc in getattr(func, 'profile_additional', []):
self._unwrap_closure_and_profile(subfunc)
Expand All @@ -182,22 +191,26 @@ def _unwrap_closure_and_profile(self, func):
self._unwrap_closure_and_profile(cell.cell_contents)
if inspect.isclass(target) and View in inspect.getmro(target):
for name, value in inspect.getmembers(target):
if name[0] != '_' and inspect.ismethod(value):
if not name.startswith('__') and (
inspect.ismethod(value) or
inspect.isfunction(value)
):
self._unwrap_closure_and_profile(value)

def process_view(self, request, view_func, view_args, view_kwargs):
def process_request(self, request):
view_func, view_args, view_kwargs = resolve(request.path)
self.view_func = view_func
self.profiler = cProfile.Profile()
args = (request,) + view_args
self.line_profiler = LineProfiler()
self._unwrap_closure_and_profile(view_func)
self.added = set()
self._unwrap_closure_and_profile(self.view_func)
signals.profiler_setup.send(sender=self,
profiler=self.line_profiler,
view_func=view_func,
view_args=view_args,
view_kwargs=view_kwargs)
self.line_profiler.enable_by_count()
out = self.profiler.runcall(view_func, *args, **view_kwargs)
out = self.profiler.runcall(super().process_request, request)
self.line_profiler.disable_by_count()
return out

Expand Down Expand Up @@ -238,7 +251,7 @@ def add_node(self, func_list, func, max_depth, cum_time=0.1):
max_depth=max_depth,
cum_time=subfunc.cumtime()/16)

def process_response(self, request, response):
def generate_stats(self, request, response):
if not hasattr(self, 'profiler'):
return None
# Could be delayed until the panel content is requested (perf. optim.)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load i18n %}{% load static from staticfiles %}
{% load i18n %}{% load static %}
<table width="100%">
<thead>
<tr>
Expand All @@ -13,11 +13,11 @@
<tbody>
{% for call in func_list %}
<!-- style="background:{{ call.background }}" -->
<tr class="djDebugProfileRow{% for parent_id in call.parent_ids %} djToggleDetails_{{ parent_id }}{% endfor %}" depth="{{ call.depth }}">
<tr class="djDebugProfileRow{% for parent_id in call.parent_ids %} djToggleDetails_{{ parent_id }}{% endfor %}" depth="{{ call.depth }}" id="_{{ call.id }}">
<td>
<div style="padding-left: {{ call.indent }}px;">
{% if call.has_subfuncs %}
<a class="djProfileToggleDetails djToggleSwitch" data-toggle-id="{{ call.id }}" data-toggle-open="+" data-toggle-close="-" href="javascript:void(0)">-</a>
<a class="djProfileToggleDetails djToggleSwitch" data-toggle-id="{{ call.id }}" data-toggle-open="+" data-toggle-close="-" data-toggle-name="" href="javascript:void(0)">-</a>
{% else %}
<span class="djNoToggleSwitch"></span>
{% endif %}
Expand All @@ -40,5 +40,3 @@
{% endfor %}
</tbody>
</table>

<script src="{% static 'debug_toolbar_line_profiler/js/toolbar.profiling.js' %}"></script>
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='django-debug-toolbar-line-profiler',
version='0.6.1',
version='0.7.1',
description='A panel for django-debug-toolbar that integrates ' +
'information from line_profiler',
long_description=open('README.rst').read(),
Expand All @@ -13,7 +13,7 @@
license='BSD',
packages=find_packages(exclude=('tests', 'example')),
install_requires=[
'django-debug-toolbar>=1.0',
'django-debug-toolbar>=2.0',
'line_profiler>=1.0b3',
'six>=1.10',
],
Expand All @@ -31,6 +31,7 @@
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Python Modules',
],
)