line_profiler.explicit_profiler module

New in line_profiler version 4.1.0, this module defines a top-level profile decorator which will be disabled by default unless a script is being run with kernprof, if the environment variable LINE_PROFILE is set, or if --line-profile is given on the command line.

In the latter two cases, the atexit module is used to display and dump line profiling results to disk when Python exits.

If none of the enabling conditions are met, then line_profiler.profile is a noop. This means you no longer have to add and remove the implicit profile decorators required by previous version of this library.

Basic usage is to import line_profiler and decorate your function with line_profiler.profile. By default this does nothing, it’s a no-op decorator. However, if you run with the environment variable LINE_PROFILER=1 or if '--profile' in sys.argv', then it enables profiling and at the end of your script it will output the profile text.

Here is a minimal example that will write a script to disk and then run it with profiling enabled or disabled by various methods:

# Write demo python script to disk
python -c "if 1:
    import textwrap
    text = textwrap.dedent(
        '''
        from line_profiler import profile

        @profile
        def plus(a, b):
            return a + b

        @profile
        def fib(n):
            a, b = 0, 1
            while a < n:
                a, b = b, plus(a, b)

        @profile
        def main():
            import math
            import time
            start = time.time()

            print('start calculating')
            while time.time() - start < 1:
                fib(10)
                math.factorial(1000)
            print('done calculating')

        main()
        '''
    ).strip()
    with open('demo.py', 'w') as file:
        file.write(text)
"

echo "---"
echo "## Base Case: Run without any profiling"
python demo.py

echo "---"
echo "## Option 0: Original Usage"
python -m kernprof -l demo.py
python -m line_profiler -rmt demo.py.lprof

echo "---"
echo "## Option 1: Enable profiler with the command line"
python demo.py --line-profile

echo "---"
echo "## Option 1: Enable profiler with an environment variable"
LINE_PROFILE=1 python demo.py

The explicit line_profiler.profile decorator can also be enabled and configured in the Python code itself by calling line_profiler.profile.enable(). The following example demonstrates this:

# In-code enabling
python -c "if 1:
    import textwrap
    text = textwrap.dedent(
        '''
        from line_profiler import profile
        profile.enable(output_prefix='customized')

        @profile
        def fib(n):
            a, b = 0, 1
            while a < n:
                a, b = b, a + b

        fib(100)
        '''
    ).strip()
    with open('demo.py', 'w') as file:
        file.write(text)
"
echo "## Configuration handled inside the script"
python demo.py

Likewise there is a line_profiler.profile.disable() function that will prevent any subsequent functions decorated with @profile from being profiled. In the following example, profiling information will only be recorded for func2 and func4.

# In-code enabling / disable
python -c "if 1:
    import textwrap
    text = textwrap.dedent(
        '''
        from line_profiler import profile

        @profile
        def func1():
            return list(range(100))

        profile.enable(output_prefix='custom')

        @profile
        def func2():
            return tuple(range(100))

        profile.disable()

        @profile
        def func3():
            return set(range(100))

        profile.enable()

        @profile
        def func4():
            return dict(zip(range(100), range(100)))

        print(type(func1()))
        print(type(func2()))
        print(type(func3()))
        print(type(func4()))
        '''
    ).strip()
    with open('demo.py', 'w') as file:
        file.write(text)
"

echo "---"
echo "## Configuration handled inside the script"
python demo.py

# Running with --line-profile will also profile ``func1``
python demo.py --line-profile

The core functionality in this module was ported from xdev.

class line_profiler.explicit_profiler.GlobalProfiler[source]

Bases: object

Manages a profiler that will output on interpreter exit.

The line_profile.profile decorator is an instance of this object.

Variables:
  • setup_config (Dict[str, List[str]]) – Determines how the implicit setup behaves by defining which environment variables / command line flags to look for.

  • output_prefix (str) – The prefix of any output files written. Should include a part of a filename. Defaults to “profile_output”.

  • write_config (Dict[str, bool]) – Which outputs are enabled. All default to True. Options are lprof, text, timestamped_text, and stdout.

  • show_config (Dict[str, bool]) – Display configuration options. Some outputs force certain options. (e.g. text always has details and is never rich).

  • enabled (bool | None) – True if the profiler is enabled (i.e. if it will wrap a function that it decorates with a real profiler). If None, then the value defaults based on the setup_config, os.environ, and sys.argv.

Example

>>> from line_profiler.explicit_profiler import *  # NOQA
>>> self = GlobalProfiler()
>>> # Setting the _profile attribute prevents atexit from running.
>>> self._profile = LineProfiler()
>>> # User can personalize the configuration
>>> self.show_config['details'] = True
>>> self.write_config['lprof'] = False
>>> self.write_config['text'] = False
>>> self.write_config['timestamped_text'] = False
>>> # Demo data: a function to profile
>>> def collatz(n):
>>>     while n != 1:
>>>         if n % 2 == 0:
>>>             n = n // 2
>>>         else:
>>>             n = 3 * n + 1
>>>     return n
>>> # Disabled by default, implicitly checks to auto-enable on first wrap
>>> assert self.enabled is None
>>> wrapped = self(collatz)
>>> assert self.enabled is False
>>> assert wrapped is collatz
>>> # Can explicitly enable
>>> self.enable()
>>> wrapped = self(collatz)
>>> assert self.enabled is True
>>> assert wrapped is not collatz
>>> wrapped(100)
>>> # Can explicitly request output
>>> self.show()
_kernprof_overwrite(profile)[source]

Kernprof will call this when it runs, so we can use its profile object instead of our own. Note: when kernprof overwrites us we wont register an atexit hook. This is what we want because kernprof wants us to use another program to read its output file.

_implicit_setup()[source]

Called once the first time the user decorates a function with line_profiler.profile and they have not explicitly setup the global profiling options.

enable(output_prefix=None)[source]

Explicitly enables global profiler and controls its settings.

disable()[source]

Explicitly initialize and disable this global profiler.

show()[source]

Write the managed profiler stats to enabled outputs.

If the implicit setup triggered, then this will be called by atexit.

line_profiler.explicit_profiler._python_command()[source]

Return a command that corresponds to sys.executable.