diff options
| -rw-r--r-- | debug_toolbar/panels/profiling.py | 47 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/profiling.html | 7 | ||||
| -rw-r--r-- | docs/panels.rst | 12 | ||||
| -rw-r--r-- | requirements_dev.txt | 4 | ||||
| -rw-r--r-- | tests/panels/test_profiling.py | 28 | ||||
| -rw-r--r-- | tox.ini | 6 | 
6 files changed, 18 insertions, 86 deletions
| diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index f4d32c4..eacd62c 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -2,16 +2,8 @@ from __future__ import absolute_import, division, unicode_literals  from django.utils.translation import ugettext_lazy as _  from django.utils.safestring import mark_safe -from django.utils.six.moves import cStringIO  from debug_toolbar.panels import Panel -try: -    from line_profiler import LineProfiler, show_func -    DJ_PROFILE_USE_LINE_PROFILER = True -except ImportError: -    DJ_PROFILE_USE_LINE_PROFILER = False - -  import cProfile  from pstats import Stats  from colorsys import hsv_to_rgb @@ -43,7 +35,6 @@ class FunctionCall(object):          self.id = id          self.parent_ids = parent_ids          self.hsv = hsv -        self._line_stats_text = None      def parent_classes(self):          return self.parent_classes @@ -127,18 +118,6 @@ class FunctionCall(object):      def indent(self):          return 16 * self.depth -    def line_stats_text(self): -        if self._line_stats_text is None and DJ_PROFILE_USE_LINE_PROFILER: -            lstats = self.statobj.line_stats -            if self.func in lstats.timings: -                out = cStringIO() -                fn, lineno, name = self.func -                show_func(fn, lineno, name, lstats.timings[self.func], lstats.unit, stream=out) -                self._line_stats_text = out.getvalue() -            else: -                self._line_stats_text = False -        return self._line_stats_text -  class ProfilingPanel(Panel):      """ @@ -148,37 +127,17 @@ class ProfilingPanel(Panel):      template = 'debug_toolbar/panels/profiling.html' -    def _unwrap_closure_and_profile(self, func): -        if not hasattr(func, '__code__'): -            return -        self.line_profiler.add_function(func) -        if func.__closure__: -            for cell in func.__closure__: -                if hasattr(cell.cell_contents, '__code__'): -                    self._unwrap_closure_and_profile(cell.cell_contents) -      def process_view(self, request, view_func, view_args, view_kwargs):          self.profiler = cProfile.Profile()          args = (request,) + view_args -        if DJ_PROFILE_USE_LINE_PROFILER: -            self.line_profiler = LineProfiler() -            self._unwrap_closure_and_profile(view_func) -            self.line_profiler.enable_by_count() -            out = self.profiler.runcall(view_func, *args, **view_kwargs) -            self.line_profiler.disable_by_count() -        else: -            self.line_profiler = None -            out = self.profiler.runcall(view_func, *args, **view_kwargs) -        return out +        return self.profiler.runcall(view_func, *args, **view_kwargs)      def add_node(self, func_list, func, max_depth, cum_time=0.1):          func_list.append(func)          func.has_subfuncs = False          if func.depth < max_depth:              for subfunc in func.subfuncs(): -                if (subfunc.stats[3] >= cum_time or -                        (hasattr(self.stats, 'line_stats') and -                            (subfunc.func in self.stats.line_stats.timings))): +                if subfunc.stats[3] >= cum_time:                      func.has_subfuncs = True                      self.add_node(func_list, subfunc, max_depth, cum_time=cum_time) @@ -188,8 +147,6 @@ class ProfilingPanel(Panel):          # Could be delayed until the panel content is requested (perf. optim.)          self.profiler.create_stats()          self.stats = DjangoDebugToolbarStats(self.profiler) -        if DJ_PROFILE_USE_LINE_PROFILER: -            self.stats.line_stats = self.line_profiler.get_stats()          self.stats.calc_callees()          root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0) diff --git a/debug_toolbar/templates/debug_toolbar/panels/profiling.html b/debug_toolbar/templates/debug_toolbar/panels/profiling.html index 9d34043..3800f98 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/profiling.html +++ b/debug_toolbar/templates/debug_toolbar/panels/profiling.html @@ -30,13 +30,6 @@  				<td>{{ call.tottime_per_call|floatformat:3 }}</td>  				<td>{{ call.count }}</td>  			</tr> -			{% if call.line_stats_text %} -				<tr class="djToggleDetails_{{ call.id }}{% for parent_id in call.parent_ids %} djToggleDetails_{{ parent_id }}{% endfor %}"> -					<td colspan="6"> -						<div style="padding-left: {{ call.indent }}px;"><pre>{{ call.line_stats_text }}</pre></div> -					</td> -				</tr> -			{% endif %}  		{% endfor %}  	</tbody>  </table> diff --git a/docs/panels.rst b/docs/panels.rst index c766780..b82be1a 100644 --- a/docs/panels.rst +++ b/docs/panels.rst @@ -155,6 +155,18 @@ Retrieves and displays information you specify using the ``debug`` statement.  Inspector panel also logs to the console by default, but may be instructed not  to. +Line Profiler +~~~~~~~~~~~~~ + +URL: https://github.com/dmclain/django-debug-toolbar-line-profiler + +Path: ``debug_toolbar_line_profiler.panel.ProfilingPanel`` + +This package provides a profiling panel that incorporates output from +line_profiler_. + +.. _line_profiler: http://pythonhosted.org/line_profiler/ +  Memcache  ~~~~~~~~ diff --git a/requirements_dev.txt b/requirements_dev.txt index 7912ecf..8d7af92 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -7,10 +7,6 @@  Django  sqlparse -# Optional runtime dependencies - -line_profiler -  # Testing  coverage diff --git a/tests/panels/test_profiling.py b/tests/panels/test_profiling.py index 7e61c62..3353b98 100644 --- a/tests/panels/test_profiling.py +++ b/tests/panels/test_profiling.py @@ -6,13 +6,6 @@ from django.test import TestCase  from django.test.utils import override_settings  from django.utils import unittest -try: -    import line_profiler -except ImportError: -    line_profiler = None - -from debug_toolbar.panels import profiling -  from ..base import BaseTestCase  from ..views import regular_view @@ -24,28 +17,15 @@ class ProfilingPanelTestCase(BaseTestCase):          super(ProfilingPanelTestCase, self).setUp()          self.panel = self.toolbar.get_panel_by_id('ProfilingPanel') -    def _test_render_with_or_without_line_profiler(self): +    # This test fails randomly for a reason I don't understand. + +    @unittest.expectedFailure +    def test_regular_view(self):          self.panel.process_view(self.request, regular_view, ('profiling',), {})          self.panel.process_response(self.request, self.response)          self.assertIn('func_list', self.panel.get_stats())          self.assertIn('regular_view', self.panel.content) -    # These two tests fail randomly for a reason I don't understand. - -    @unittest.expectedFailure -    @unittest.skipIf(line_profiler is None, "line_profiler isn't available") -    def test_render_with_line_profiler(self): -        self._test_render_with_or_without_line_profiler() - -    @unittest.expectedFailure -    def test_without_line_profiler(self): -        _use_line_profiler = profiling.DJ_PROFILE_USE_LINE_PROFILER -        profiling.DJ_PROFILE_USE_LINE_PROFILER = False -        try: -            self._test_render_with_or_without_line_profiler() -        finally: -            profiling.DJ_PROFILE_USE_LINE_PROFILER = _use_line_profiler -  @override_settings(DEBUG=True,                     DEBUG_TOOLBAR_PANELS=['debug_toolbar.panels.profiling.ProfilingPanel']) @@ -25,28 +25,24 @@ whitelist_externals = make  basepython = python2.6  deps =      Django>=1.4,<1.5 -    line_profiler      {[testenv]deps}  [testenv:py27-django14]  basepython = python2.7  deps =      Django>=1.4,<1.5 -    line_profiler      {[testenv]deps}  [testenv:py26-django15]  basepython = python2.6  deps =      Django>=1.5,<1.6 -    line_profiler      {[testenv]deps}  [testenv:py27-django15]  basepython = python2.7  deps =      Django>=1.5,<1.6 -    line_profiler      {[testenv]deps}  [testenv:py32-django15] @@ -65,14 +61,12 @@ deps =  basepython = python2.6  deps =      Django>=1.6,<1.7 -    line_profiler      {[testenv]deps}  [testenv:py27-django16]  basepython = python2.7  deps =      Django>=1.6,<1.7 -    line_profiler      {[testenv]deps}  [testenv:py32-django16] | 
