mercurial/profiling.py
author Augie Fackler <augie@google.com>
Sun, 06 Oct 2019 09:45:02 -0400
changeset 43076 2372284d9457
parent 42423 0ae593e791fb
child 43077 687b865b95ad
permissions -rw-r--r--
formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
# profiling.py - profiling functions
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# Copyright 2016 Gregory Szorc <gregory.szorc@gmail.com>
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
from __future__ import absolute_import, print_function
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    10
import contextlib
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
from .i18n import _
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
from . import (
30820
6a70cf94d1b5 py3: replace pycompat.getenv with encoding.environ.get
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30664
diff changeset
    14
    encoding,
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
    error,
32417
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    16
    extensions,
36683
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
    17
    pycompat,
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
    util,
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    21
32417
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    22
def _loadprofiler(ui, profiler):
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    23
    """load profiler extension. return profile method, or None on failure"""
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    24
    extname = profiler
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    25
    extensions.loadall(ui, whitelist=[extname])
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    26
    try:
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    27
        mod = extensions.find(extname)
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    28
    except KeyError:
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    29
        return None
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    30
    else:
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    31
        return getattr(mod, 'profile', None)
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 30975
diff changeset
    32
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    33
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    34
@contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    35
def lsprofile(ui, fp):
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
    36
    format = ui.config('profiling', 'format')
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
    37
    field = ui.config('profiling', 'sort')
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
    38
    limit = ui.configint('profiling', 'limit')
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
    39
    climit = ui.configint('profiling', 'nested')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
    if format not in ['text', 'kcachegrind']:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    42
        ui.warn(_("unrecognized profiling format '%s'" " - Ignored\n") % format)
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
        format = 'text'
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
    try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
        from . import lsprof
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    47
    except ImportError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    48
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    49
            _(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    50
                'lsprof not available - install from '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    51
                'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    52
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    53
        )
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
    p = lsprof.Profiler()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
    p.enable(subcalls=True)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
    try:
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    57
        yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
    finally:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
        p.disable()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
        if format == 'kcachegrind':
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
            from . import lsprofcalltree
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    63
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
            calltree = lsprofcalltree.KCacheGrind(p)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
            calltree.output(fp)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
        else:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
            # format == 'text'
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
            stats = lsprof.Stats(p.getstats())
40192
b8f6a99ad89b py3: convert sorting field to sysstr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38260
diff changeset
    69
            stats.sort(pycompat.sysstr(field))
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
            stats.pprint(limit=limit, file=fp, climit=climit)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    71
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    72
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    73
@contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    74
def flameprofile(ui, fp):
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    75
    try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    76
        from flamegraph import flamegraph
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    77
    except ImportError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    78
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    79
            _(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    80
                'flamegraph not available - install from '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    81
                'https://github.com/evanhempel/python-flamegraph'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    82
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    83
        )
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    84
    # developer config: profiling.freq
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
    85
    freq = ui.configint('profiling', 'freq')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    86
    filter_ = None
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    87
    collapse_recursion = True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    88
    thread = flamegraph.ProfileThread(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    89
        fp, 1.0 / freq, filter_, collapse_recursion
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    90
    )
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30930
diff changeset
    91
    start_time = util.timer()
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    92
    try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    93
        thread.start()
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
    94
        yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
    finally:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
        thread.stop()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
        thread.join()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    98
        print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
    99
            'Collected %d stack frames (%d unique) in %2.2f seconds.'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   100
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   101
                util.timer() - start_time,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   102
                thread.num_frames(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   103
                thread.num_frames(unique=True),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   104
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   105
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   106
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   108
@contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   109
def statprofile(ui, fp):
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   110
    from . import statprof
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   111
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
   112
    freq = ui.configint('profiling', 'freq')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   113
    if freq > 0:
29785
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
   114
        # Cannot reset when profiler is already active. So silently no-op.
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
   115
        if statprof.state.profile_level == 0:
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
   116
            statprof.reset(freq)
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   117
    else:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
        ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   119
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   120
    track = ui.config(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   121
        'profiling', 'time-track', pycompat.iswindows and 'cpu' or 'real'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   122
    )
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 36683
diff changeset
   123
    statprof.start(mechanism='thread', track=track)
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   124
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
    try:
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   126
        yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   127
    finally:
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   128
        data = statprof.stop()
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   129
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33195
diff changeset
   130
        profformat = ui.config('profiling', 'statformat')
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   131
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   132
        formats = {
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   133
            'byline': statprof.DisplayFormats.ByLine,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   134
            'bymethod': statprof.DisplayFormats.ByMethod,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   135
            'hotpath': statprof.DisplayFormats.Hotpath,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   136
            'json': statprof.DisplayFormats.Json,
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   137
            'chrome': statprof.DisplayFormats.Chrome,
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   138
        }
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   139
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   140
        if profformat in formats:
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   141
            displayformat = formats[profformat]
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   142
        else:
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   143
            ui.warn(_('unknown profiler output format: %s\n') % profformat)
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   144
            displayformat = statprof.DisplayFormats.Hotpath
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
   145
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   146
        kwargs = {}
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   147
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   148
        def fraction(s):
32978
41b081ac2145 profiling: cope with configwith default value handling changes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32851
diff changeset
   149
            if isinstance(s, (float, int)):
41b081ac2145 profiling: cope with configwith default value handling changes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32851
diff changeset
   150
                return float(s)
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   151
            if s.endswith('%'):
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   152
                v = float(s[:-1]) / 100
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   153
            else:
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   154
                v = float(s)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   155
            if 0 <= v <= 1:
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   156
                return v
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   157
            raise ValueError(s)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   158
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   159
        if profformat == 'chrome':
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   160
            showmin = ui.configwith(fraction, 'profiling', 'showmin', 0.005)
34410
fecea78ff2af configitems: register the 'profiling.showmax' config
Boris Feld <boris.feld@octobus.net>
parents: 33499
diff changeset
   161
            showmax = ui.configwith(fraction, 'profiling', 'showmax')
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   162
            kwargs.update(minthreshold=showmin, maxthreshold=showmax)
32851
cb6436e051ca profiling: allow configuring minimum display threshold for hotpath
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32810
diff changeset
   163
        elif profformat == 'hotpath':
33195
5d8942dbe49e check-config: syntax to allow inconsistent config values
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32978
diff changeset
   164
            # inconsistent config: profiling.showmin
32851
cb6436e051ca profiling: allow configuring minimum display threshold for hotpath
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32810
diff changeset
   165
            limit = ui.configwith(fraction, 'profiling', 'showmin', 0.05)
36400
7b86aa31b004 py3: fix handling of keyword arguments at more places
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34412
diff changeset
   166
            kwargs[r'limit'] = limit
42423
0ae593e791fb profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 40418
diff changeset
   167
            showtime = ui.configbool('profiling', 'showtime')
0ae593e791fb profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 40418
diff changeset
   168
            kwargs[r'showtime'] = showtime
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   169
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
   170
        statprof.display(fp, data=data, format=displayformat, **kwargs)
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   171
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   172
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   173
class profile(object):
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   174
    """Start profiling.
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   175
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   176
    Profiling is active when the context manager is active. When the context
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   177
    manager exits, profiling results will be written to the configured output.
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   178
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   179
32785
37ec8f24d912 profile: introduce a knob to control if the context is actually profiling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32784
diff changeset
   180
    def __init__(self, ui, enabled=True):
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   181
        self._ui = ui
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   182
        self._output = None
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   183
        self._fp = None
32805
2b0fc56840d0 profile: use explicit logic to control file closing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32804
diff changeset
   184
        self._fpdoclose = True
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   185
        self._profiler = None
32785
37ec8f24d912 profile: introduce a knob to control if the context is actually profiling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32784
diff changeset
   186
        self._enabled = enabled
32784
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   187
        self._entered = False
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   188
        self._started = False
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   189
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   190
    def __enter__(self):
32784
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   191
        self._entered = True
32785
37ec8f24d912 profile: introduce a knob to control if the context is actually profiling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32784
diff changeset
   192
        if self._enabled:
37ec8f24d912 profile: introduce a knob to control if the context is actually profiling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32784
diff changeset
   193
            self.start()
32786
0ead06d54ffe profile: make the contextmanager object available to the callers
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32785
diff changeset
   194
        return self
32784
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   195
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   196
    def start(self):
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   197
        """Start profiling.
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   198
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   199
        The profiling will stop at the context exit.
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   200
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   201
        If the profiler was already started, this has no effect."""
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   202
        if not self._entered:
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   203
            raise error.ProgrammingError()
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   204
        if self._started:
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   205
            return
086c1ef0f666 profile: introduce a "start" method to the profile context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32783
diff changeset
   206
        self._started = True
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   207
        profiler = encoding.environ.get('HGPROF')
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   208
        proffn = None
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   209
        if profiler is None:
34412
83dfbda40e67 configitems: register the 'profiling.type' config
Boris Feld <boris.feld@octobus.net>
parents: 34410
diff changeset
   210
            profiler = self._ui.config('profiling', 'type')
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   211
        if profiler not in ('ls', 'stat', 'flame'):
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   212
            # try load profiler from extension with the same name
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   213
            proffn = _loadprofiler(self._ui, profiler)
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   214
            if proffn is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   215
                self._ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   216
                    _("unrecognized profiler '%s' - ignored\n") % profiler
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   217
                )
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   218
                profiler = 'stat'
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   219
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   220
        self._output = self._ui.config('profiling', 'output')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   221
32808
336700745a5c profile: close 'fp' on error within '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32807
diff changeset
   222
        try:
32807
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   223
            if self._output == 'blackbox':
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   224
                self._fp = util.stringio()
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   225
            elif self._output:
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   226
                path = self._ui.expandpath(self._output)
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   227
                self._fp = open(path, 'wb')
36683
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   228
            elif pycompat.iswindows:
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   229
                # parse escape sequence by win32print()
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   230
                class uifp(object):
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   231
                    def __init__(self, ui):
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   232
                        self._ui = ui
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   233
36683
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   234
                    def write(self, data):
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   235
                        self._ui.write_err(data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   236
36683
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   237
                    def flush(self):
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   238
                        self._ui.flush()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   239
36683
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   240
                self._fpdoclose = False
e39953fdd924 profile: colorize output on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36400
diff changeset
   241
                self._fp = uifp(self._ui)
32807
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   242
            else:
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   243
                self._fpdoclose = False
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   244
                self._fp = self._ui.ferr
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   245
32807
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   246
            if proffn is not None:
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   247
                pass
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   248
            elif profiler == 'ls':
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   249
                proffn = lsprofile
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   250
            elif profiler == 'flame':
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   251
                proffn = flameprofile
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   252
            else:
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   253
                proffn = statprofile
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   254
32807
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   255
            self._profiler = proffn(self._ui, self._fp)
54b356d65079 profile: indent part of '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32806
diff changeset
   256
            self._profiler.__enter__()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   257
        except:  # re-raises
32808
336700745a5c profile: close 'fp' on error within '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32807
diff changeset
   258
            self._closefp()
336700745a5c profile: close 'fp' on error within '__enter__'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32807
diff changeset
   259
            raise
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
   260
32783
4483696dacee profile: upgrade the "profile" context manager to a full class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32417
diff changeset
   261
    def __exit__(self, exception_type, exception_value, traceback):
32810
6675d23da748 profile: properly propagate exception from the sub-context manager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32809
diff changeset
   262
        propagate = None
32809
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   263
        if self._profiler is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   264
            propagate = self._profiler.__exit__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   265
                exception_type, exception_value, traceback
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42423
diff changeset
   266
            )
32809
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   267
            if self._output == 'blackbox':
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   268
                val = 'Profile:\n%s' % self._fp.getvalue()
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   269
                # ui.log treats the input as a format string,
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   270
                # so we need to escape any % signs.
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   271
                val = val.replace('%', '%%')
062eb859d3ee profile: close 'fp' in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32808
diff changeset
   272
                self._ui.log('profile', val)
32806
3a4c677cbd6e profile: remove now useless indent
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32805
diff changeset
   273
        self._closefp()
32810
6675d23da748 profile: properly propagate exception from the sub-context manager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32809
diff changeset
   274
        return propagate
32804
c0b2c8f25ad9 profiling: move 'fp' closing logic into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32788
diff changeset
   275
c0b2c8f25ad9 profiling: move 'fp' closing logic into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32788
diff changeset
   276
    def _closefp(self):
32805
2b0fc56840d0 profile: use explicit logic to control file closing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32804
diff changeset
   277
        if self._fpdoclose and self._fp is not None:
2b0fc56840d0 profile: use explicit logic to control file closing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32804
diff changeset
   278
            self._fp.close()