:mod:`tracemalloc` --- Trace memory allocations
===============================================

.. module:: tracemalloc
   :synopsis: Trace memory allocations.

.. versionadded:: 3.4

**Source code:** :source:`Lib/tracemalloc.py`

--------------

The tracemalloc module is a debug tool to trace memory blocks allocated by
Python. It provides the following information:

* Traceback where an object was allocated
* Statistics on allocated memory blocks per filename and per line number:
  total size, number and average size of allocated memory blocks
* Compute the differences between two snapshots to detect memory leaks

To trace most memory blocks allocated by Python, the module should be started
as early as possible by setting the :envvar:`PYTHONTRACEMALLOC` environment
variable to ``1``, or by using :option:`-X` ``tracemalloc`` command line
option. The :func:`tracemalloc.start` function can be called at runtime to
start tracing Python memory allocations.

By default, a trace of an allocated memory block only stores the most recent
frame (1 frame). To store 25 frames at startup: set the
:envvar:`PYTHONTRACEMALLOC` environment variable to ``25``, or use the
:option:`-X` ``tracemalloc=25`` command line option.


Examples
--------

Display the top 10
^^^^^^^^^^^^^^^^^^

Display the 10 files allocating the most memory::

    import tracemalloc

    tracemalloc.start()

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('lineno')

    print("[ Top 10 ]")
    for stat in top_stats[:10]:
        print(stat)


Example of output of the Python test suite::

    [ Top 10 ]
    <frozen importlib._bootstrap>:716: size=4855 KiB, count=39328, average=126 B
    <frozen importlib._bootstrap>:284: size=521 KiB, count=3199, average=167 B
    /usr/lib/python3.4/collections/__init__.py:368: size=244 KiB, count=2315, average=108 B
    /usr/lib/python3.4/unittest/case.py:381: size=185 KiB, count=779, average=243 B
    /usr/lib/python3.4/unittest/case.py:402: size=154 KiB, count=378, average=416 B
    /usr/lib/python3.4/abc.py:133: size=88.7 KiB, count=347, average=262 B
    <frozen importlib._bootstrap>:1446: size=70.4 KiB, count=911, average=79 B
    <frozen importlib._bootstrap>:1454: size=52.0 KiB, count=25, average=2131 B
    <string>:5: size=49.7 KiB, count=148, average=344 B
    /usr/lib/python3.4/sysconfig.py:411: size=48.0 KiB, count=1, average=48.0 KiB

We can see that Python loaded ``4855 KiB`` data (bytecode and constants) from
modules and that the :mod:`collections` module allocated ``244 KiB`` to build
:class:`~collections.namedtuple` types.

See :meth:`Snapshot.statistics` for more options.


Compute differences
^^^^^^^^^^^^^^^^^^^

Take two snapshots and display the differences::

    import tracemalloc
    tracemalloc.start()
    # ... start your application ...

    snapshot1 = tracemalloc.take_snapshot()
    # ... call the function leaking memory ...
    snapshot2 = tracemalloc.take_snapshot()

    top_stats = snapshot2.compare_to(snapshot1, 'lineno')

    print("[ Top 10 differences ]")
    for stat in top_stats[:10]:
        print(stat)

Example of output before/after running some tests of the Python test suite::

    [ Top 10 differences ]
    <frozen importlib._bootstrap>:716: size=8173 KiB (+4428 KiB), count=71332 (+39369), average=117 B
    /usr/lib/python3.4/linecache.py:127: size=940 KiB (+940 KiB), count=8106 (+8106), average=119 B
    /usr/lib/python3.4/unittest/case.py:571: size=298 KiB (+298 KiB), count=589 (+589), average=519 B
    <frozen importlib._bootstrap>:284: size=1005 KiB (+166 KiB), count=7423 (+1526), average=139 B
    /usr/lib/python3.4/mimetypes.py:217: size=112 KiB (+112 KiB), count=1334 (+1334), average=86 B
    /usr/lib/python3.4/http/server.py:848: size=96.0 KiB (+96.0 KiB), count=1 (+1), average=96.0 KiB
    /usr/lib/python3.4/inspect.py:1465: size=83.5 KiB (+83.5 KiB), count=109 (+109), average=784 B
    /usr/lib/python3.4/unittest/mock.py:491: size=77.7 KiB (+77.7 KiB), count=143 (+143), average=557 B
    /usr/lib/python3.4/urllib/parse.py:476: size=71.8 KiB (+71.8 KiB), count=969 (+969), average=76 B
    /usr/lib/python3.4/contextlib.py:38: size=67.2 KiB (+67.2 KiB), count=126 (+126), average=546 B

We can see that Python has loaded ``8173 KiB`` of module data (bytecode and
constants), and that this is ``4428 KiB`` more than had been loaded before the
tests, when the previous snapshot was taken. Similarly, the :mod:`linecache`
module has cached ``940 KiB`` of Python source code to format tracebacks, all
of it since the previous snapshot.

If the system has little free memory, snapshots can be written on disk using
the :meth:`Snapshot.dump` method to analyze the snapshot offline. Then use the
:meth:`Snapshot.load` method reload the snapshot.


Get the traceback of a memory block
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Code to display the traceback of the biggest memory block::

    import tracemalloc

    # Store 25 frames
    tracemalloc.start(25)

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('traceback')

    # pick the biggest memory block
    stat = top_stats[0]
    print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))
    for line in stat.traceback.format():
        print(line)

Example of output of the Python test suite (traceback limited to 25 frames)::

    903 memory blocks: 870.1 KiB
      File "<frozen importlib._bootstrap>", line 716
      File "<frozen importlib._bootstrap>", line 1036
      File "<frozen importlib._bootstrap>", line 934
      File "<frozen importlib._bootstrap>", line 1068
      File "<frozen importlib._bootstrap>", line 619
      File "<frozen importlib._bootstrap>", line 1581
      File "<frozen importlib._bootstrap>", line 1614
      File "/usr/lib/python3.4/doctest.py", line 101
        import pdb
      File "<frozen importlib._bootstrap>", line 284
      File "<frozen importlib._bootstrap>", line 938
      File "<frozen importlib._bootstrap>", line 1068
      File "<frozen importlib._bootstrap>", line 619
      File "<frozen importlib._bootstrap>", line 1581
      File "<frozen importlib._bootstrap>", line 1614
      File "/usr/lib/python3.4/test/support/__init__.py", line 1728
        import doctest
      File "/usr/lib/python3.4/test/test_pickletools.py", line 21
        support.run_doctest(pickletools)
      File "/usr/lib/python3.4/test/regrtest.py", line 1276
        test_runner()
      File "/usr/lib/python3.4/test/regrtest.py", line 976
        display_failure=not verbose)
      File "/usr/lib/python3.4/test/regrtest.py", line 761
        match_tests=ns.match_tests)
      File "/usr/lib/python3.4/test/regrtest.py", line 1563
        main()
      File "/usr/lib/python3.4/test/__main__.py", line 3
        regrtest.main_in_temp_cwd()
      File "/usr/lib/python3.4/runpy.py", line 73
        exec(code, run_globals)
      File "/usr/lib/python3.4/runpy.py", line 160
        "__main__", fname, loader, pkg_name)

We can see that the most memory was allocated in the :mod:`importlib` module to
load data (bytecode and constants) from modules: ``870.1 KiB``. The traceback is
where the :mod:`importlib` loaded data most recently: on the ``import pdb``
line of the :mod:`doctest` module. The traceback may change if a new module is
loaded.


Pretty top
^^^^^^^^^^

Code to display the 10 lines allocating the most memory with a pretty output,
ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files::

    import linecache
    import os
    import tracemalloc

    def display_top(snapshot, key_type='lineno', limit=10):
        snapshot = snapshot.filter_traces((
            tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
            tracemalloc.Filter(False, "<unknown>"),
        ))
        top_stats = snapshot.statistics(key_type)

        print("Top %s lines" % limit)
        for index, stat in enumerate(top_stats[:limit], 1):
            frame = stat.traceback[0]
            print("#%s: %s:%s: %.1f KiB"
                  % (index, frame.filename, frame.lineno, stat.size / 1024))
            line = linecache.getline(frame.filename, frame.lineno).strip()
            if line:
                print('    %s' % line)

        other = top_stats[limit:]
        if other:
            size = sum(stat.size for stat in other)
            print("%s other: %.1f KiB" % (len(other), size / 1024))
        total = sum(stat.size for stat in top_stats)
        print("Total allocated size: %.1f KiB" % (total / 1024))

    tracemalloc.start()

    # ... run your application ...

    snapshot = tracemalloc.take_snapshot()
    display_top(snapshot)

Example of output of the Python test suite::

    Top 10 lines
    #1: Lib/base64.py:414: 419.8 KiB
        _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars]
    #2: Lib/base64.py:306: 419.8 KiB
        _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars]
    #3: collections/__init__.py:368: 293.6 KiB
        exec(class_definition, namespace)
    #4: Lib/abc.py:133: 115.2 KiB
        cls = super().__new__(mcls, name, bases, namespace)
    #5: unittest/case.py:574: 103.1 KiB
        testMethod()
    #6: Lib/linecache.py:127: 95.4 KiB
        lines = fp.readlines()
    #7: urllib/parse.py:476: 71.8 KiB
        for a in _hexdig for b in _hexdig}
    #8: <string>:5: 62.0 KiB
    #9: Lib/_weakrefset.py:37: 60.0 KiB
        self.data = set()
    #10: Lib/base64.py:142: 59.8 KiB
        _b32tab2 = [a + b for a in _b32tab for b in _b32tab]
    6220 other: 3602.8 KiB
    Total allocated size: 5303.1 KiB

See :meth:`Snapshot.statistics` for more options.

Record the current and peak size of all traced memory blocks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following code computes two sums like ``0 + 1 + 2 + ...`` inefficiently, by
creating a list of those numbers. This list consumes a lot of memory
temporarily. We can use :func:`get_traced_memory` and :func:`reset_peak` to
observe the small memory usage after the sum is computed as well as the peak
memory usage during the computations::

  import tracemalloc

  tracemalloc.start()

  # Example code: compute a sum with a large temporary list
  large_sum = sum(list(range(100000)))

  first_size, first_peak = tracemalloc.get_traced_memory()

  tracemalloc.reset_peak()

  # Example code: compute a sum with a small temporary list
  small_sum = sum(list(range(1000)))

  second_size, second_peak = tracemalloc.get_traced_memory()

  print(f"{first_size=}, {first_peak=}")
  print(f"{second_size=}, {second_peak=}")

Output::

  first_size=664, first_peak=3592984
  second_size=804, second_peak=29704

Using :func:`reset_peak` ensured we could accurately record the peak during the
computation of ``small_sum``, even though it is much smaller than the overall
peak size of memory blocks since the :func:`start` call. Without the call to
:func:`reset_peak`, ``second_peak`` would still be the peak from the
computation ``large_sum`` (that is, equal to ``first_peak``). In this case,
both peaks are much higher than the final memory usage, and which suggests we
could optimise (by removing the unnecessary call to :class:`list`, and writing
``sum(range(...))``).

API
---

Functions
^^^^^^^^^

.. function:: clear_traces()

   Clear traces of memory blocks allocated by Python.

   See also :func:`stop`.


.. function:: get_object_traceback(obj)

   Get the traceback where the Python object *obj* was allocated.
   Return a :class:`Traceback` instance, or ``None`` if the :mod:`tracemalloc`
   module is not tracing memory allocations or did not trace the allocation of
   the object.

   See also :func:`gc.get_referrers` and :func:`sys.getsizeof` functions.


.. function:: get_traceback_limit()

   Get the maximum number of frames stored in the traceback of a trace.

   The :mod:`tracemalloc` module must be tracing memory allocations to
   get the limit, otherwise an exception is raised.

   The limit is set by the :func:`start` function.


.. function:: get_traced_memory()

   Get the current size and peak size of memory blocks traced by the
   :mod:`tracemalloc` module as a tuple: ``(current: int, peak: int)``.


.. function:: reset_peak()

   Set the peak size of memory blocks traced by the :mod:`tracemalloc` module
   to the current size.

   Do nothing if the :mod:`tracemalloc` module is not tracing memory
   allocations.

   This function only modifies the recorded peak size, and does not modify or
   clear any traces, unlike :func:`clear_traces`. Snapshots taken with
   :func:`take_snapshot` before a call to :func:`reset_peak` can be
   meaningfully compared to snapshots taken after the call.

   See also :func:`get_traced_memory`.

   .. versionadded:: 3.9


.. function:: get_tracemalloc_memory()

   Get the memory usage in bytes of the :mod:`tracemalloc` module used to store
   traces of memory blocks.
   Return an :class:`int`.


.. function:: is_tracing()

    ``True`` if the :mod:`tracemalloc` module is tracing Python memory
    allocations, ``False`` otherwise.

    See also :func:`start` and :func:`stop` functions.


.. function:: start(nframe: int=1)

   Start tracing Python memory allocations: install hooks on Python memory
   allocators. Collected tracebacks of traces will be limited to *nframe*
   frames. By default, a trace of a memory block only stores the most recent
   frame: the limit is ``1``. *nframe* must be greater or equal to ``1``.

   You can still read the original number of total frames that composed the
   traceback by looking at the :attr:`Traceback.total_nframe` attribute.

   Storing more than ``1`` frame is only useful to compute statistics grouped
   by ``'traceback'`` or to compute cumulative statistics: see the
   :meth:`Snapshot.compare_to` and :meth:`Snapshot.statistics` methods.

   Storing more frames increases the memory and CPU overhead of the
   :mod:`tracemalloc` module. Use the :func:`get_tracemalloc_memory` function
   to measure how much memory is used by the :mod:`tracemalloc` module.

   The :envvar:`PYTHONTRACEMALLOC` environment variable
   (``PYTHONTRACEMALLOC=NFRAME``) and the :option:`-X` ``tracemalloc=NFRAME``
   command line option can be used to start tracing at startup.

   See also :func:`stop`, :func:`is_tracing` and :func:`get_traceback_limit`
   functions.


.. function:: stop()

   Stop tracing Python memory allocations: uninstall hooks on Python memory
   allocators. Also clears all previously collected traces of memory blocks
   allocated by Python.

   Call :func:`take_snapshot` function to take a snapshot of traces before
   clearing them.

   See also :func:`start`, :func:`is_tracing` and :func:`clear_traces`
   functions.


.. function:: take_snapshot()

   Take a snapshot of traces of memory blocks allocated by Python. Return a new
   :class:`Snapshot` instance.

   The snapshot does not include memory blocks allocated before the
   :mod:`tracemalloc` module started to trace memory allocations.

   Tracebacks of traces are limited to :func:`get_traceback_limit` frames. Use
   the *nframe* parameter of the :func:`start` function to store more frames.

   The :mod:`tracemalloc` module must be tracing memory allocations to take a
   snapshot, see the :func:`start` function.

   See also the :func:`get_object_traceback` function.


DomainFilter
^^^^^^^^^^^^

.. class:: DomainFilter(inclusive: bool, domain: int)

   Filter traces of memory blocks by their address space (domain).

   .. versionadded:: 3.6

   .. attribute:: inclusive

      If *inclusive* is ``True`` (include), match memory blocks allocated
      in the address space :attr:`domain`.

      If *inclusive* is ``False`` (exclude), match memory blocks not allocated
      in the address space :attr:`domain`.

   .. attribute:: domain

      Address space of a memory block (``int``). Read-only property.


Filter
^^^^^^

.. class:: Filter(inclusive: bool, filename_pattern: str, lineno: int=None, all_frames: bool=False, domain: int=None)

   Filter on traces of memory blocks.

   See the :func:`fnmatch.fnmatch` function for the syntax of
   *filename_pattern*. The ``'.pyc'`` file extension is
   replaced with ``'.py'``.

   Examples:

   * ``Filter(True, subprocess.__file__)`` only includes traces of the
     :mod:`subprocess` module
   * ``Filter(False, tracemalloc.__file__)`` excludes traces of the
     :mod:`tracemalloc` module
   * ``Filter(False, "<unknown>")`` excludes empty tracebacks


   .. versionchanged:: 3.5
      The ``'.pyo'`` file extension is no longer replaced with ``'.py'``.

   .. versionchanged:: 3.6
      Added the :attr:`domain` attribute.


   .. attribute:: domain

      Address space of a memory block (``int`` or ``None``).

      tracemalloc uses the domain ``0`` to trace memory allocations made by
      Python. C extensions can use other domains to trace other resources.

   .. attribute:: inclusive

      If *inclusive* is ``True`` (include), only match memory blocks allocated
      in a file with a name matching :attr:`filename_pattern` at line number
      :attr:`lineno`.

      If *inclusive* is ``False`` (exclude), ignore memory blocks allocated in
      a file with a name matching :attr:`filename_pattern` at line number
      :attr:`lineno`.

   .. attribute:: lineno

      Line number (``int``) of the filter. If *lineno* is ``None``, the filter
      matches any line number.

   .. attribute:: filename_pattern

      Filename pattern of the filter (``str``). Read-only property.

   .. attribute:: all_frames

      If *all_frames* is ``True``, all frames of the traceback are checked. If
      *all_frames* is ``False``, only the most recent frame is checked.

      This attribute has no effect if the traceback limit is ``1``.  See the
      :func:`get_traceback_limit` function and :attr:`Snapshot.traceback_limit`
      attribute.


Frame
^^^^^

.. class:: Frame

   Frame of a traceback.

   The :class:`Traceback` class is a sequence of :class:`Frame` instances.

   .. attribute:: filename

      Filename (``str``).

   .. attribute:: lineno

      Line number (``int``).


Snapshot
^^^^^^^^

.. class:: Snapshot

   Snapshot of traces of memory blocks allocated by Python.

   The :func:`take_snapshot` function creates a snapshot instance.

   .. method:: compare_to(old_snapshot: Snapshot, key_type: str, cumulative: bool=False)

      Compute the differences with an old snapshot. Get statistics as a sorted
      list of :class:`StatisticDiff` instances grouped by *key_type*.

      See the :meth:`Snapshot.statistics` method for *key_type* and *cumulative*
      parameters.

      The result is sorted from the biggest to the smallest by: absolute value
      of :attr:`StatisticDiff.size_diff`, :attr:`StatisticDiff.size`, absolute
      value of :attr:`StatisticDiff.count_diff`, :attr:`Statistic.count` and
      then by :attr:`StatisticDiff.traceback`.


   .. method:: dump(filename)

      Write the snapshot into a file.

      Use :meth:`load` to reload the snapshot.


   .. method:: filter_traces(filters)

      Create a new :class:`Snapshot` instance with a filtered :attr:`traces`
      sequence, *filters* is a list of :class:`DomainFilter` and
      :class:`Filter` instances.  If *filters* is an empty list, return a new
      :class:`Snapshot` instance with a copy of the traces.

      All inclusive filters are applied at once, a trace is ignored if no
      inclusive filters match it. A trace is ignored if at least one exclusive
      filter matches it.

      .. versionchanged:: 3.6
         :class:`DomainFilter` instances are now also accepted in *filters*.


   .. classmethod:: load(filename)

      Load a snapshot from a file.

      See also :meth:`dump`.


   .. method:: statistics(key_type: str, cumulative: bool=False)

      Get statistics as a sorted list of :class:`Statistic` instances grouped
      by *key_type*:

      =====================  ========================
      key_type               description
      =====================  ========================
      ``'filename'``         filename
      ``'lineno'``           filename and line number
      ``'traceback'``        traceback
      =====================  ========================

      If *cumulative* is ``True``, cumulate size and count of memory blocks of
      all frames of the traceback of a trace, not only the most recent frame.
      The cumulative mode can only be used with *key_type* equals to
      ``'filename'`` and ``'lineno'``.

      The result is sorted from the biggest to the smallest by:
      :attr:`Statistic.size`, :attr:`Statistic.count` and then by
      :attr:`Statistic.traceback`.


   .. attribute:: traceback_limit

      Maximum number of frames stored in the traceback of :attr:`traces`:
      result of the :func:`get_traceback_limit` when the snapshot was taken.

   .. attribute:: traces

      Traces of all memory blocks allocated by Python: sequence of
      :class:`Trace` instances.

      The sequence has an undefined order. Use the :meth:`Snapshot.statistics`
      method to get a sorted list of statistics.


Statistic
^^^^^^^^^

.. class:: Statistic

   Statistic on memory allocations.

   :func:`Snapshot.statistics` returns a list of :class:`Statistic` instances.

   See also the :class:`StatisticDiff` class.

   .. attribute:: count

      Number of memory blocks (``int``).

   .. attribute:: size

      Total size of memory blocks in bytes (``int``).

   .. attribute:: traceback

      Traceback where the memory block was allocated, :class:`Traceback`
      instance.


StatisticDiff
^^^^^^^^^^^^^

.. class:: StatisticDiff

   Statistic difference on memory allocations between an old and a new
   :class:`Snapshot` instance.

   :func:`Snapshot.compare_to` returns a list of :class:`StatisticDiff`
   instances. See also the :class:`Statistic` class.

   .. attribute:: count

      Number of memory blocks in the new snapshot (``int``): ``0`` if
      the memory blocks have been released in the new snapshot.

   .. attribute:: count_diff

      Difference of number of memory blocks between the old and the new
      snapshots (``int``): ``0`` if the memory blocks have been allocated in
      the new snapshot.

   .. attribute:: size

      Total size of memory blocks in bytes in the new snapshot (``int``):
      ``0`` if the memory blocks have been released in the new snapshot.

   .. attribute:: size_diff

      Difference of total size of memory blocks in bytes between the old and
      the new snapshots (``int``): ``0`` if the memory blocks have been
      allocated in the new snapshot.

   .. attribute:: traceback

      Traceback where the memory blocks were allocated, :class:`Traceback`
      instance.


Trace
^^^^^

.. class:: Trace

   Trace of a memory block.

   The :attr:`Snapshot.traces` attribute is a sequence of :class:`Trace`
   instances.

   .. versionchanged:: 3.6
      Added the :attr:`domain` attribute.

   .. attribute:: domain

      Address space of a memory block (``int``). Read-only property.

      tracemalloc uses the domain ``0`` to trace memory allocations made by
      Python. C extensions can use other domains to trace other resources.

   .. attribute:: size

      Size of the memory block in bytes (``int``).

   .. attribute:: traceback

      Traceback where the memory block was allocated, :class:`Traceback`
      instance.


Traceback
^^^^^^^^^

.. class:: Traceback

   Sequence of :class:`Frame` instances sorted from the oldest frame to the
   most recent frame.

   A traceback contains at least ``1`` frame. If the ``tracemalloc`` module
   failed to get a frame, the filename ``"<unknown>"`` at line number ``0`` is
   used.

   When a snapshot is taken, tracebacks of traces are limited to
   :func:`get_traceback_limit` frames. See the :func:`take_snapshot` function.
   The original number of frames of the traceback is stored in the
   :attr:`Traceback.total_nframe` attribute. That allows to know if a traceback
   has been truncated by the traceback limit.

   The :attr:`Trace.traceback` attribute is an instance of :class:`Traceback`
   instance.

   .. versionchanged:: 3.7
      Frames are now sorted from the oldest to the most recent, instead of most recent to oldest.

   .. attribute:: total_nframe

      Total number of frames that composed the traceback before truncation.
      This attribute can be set to ``None`` if the information is not
      available.

   .. versionchanged:: 3.9
      The :attr:`Traceback.total_nframe` attribute was added.

   .. method:: format(limit=None, most_recent_first=False)

      Format the traceback as a list of lines. Use the :mod:`linecache` module to
      retrieve lines from the source code. If *limit* is set, format the *limit*
      most recent frames if *limit* is positive. Otherwise, format the
      ``abs(limit)`` oldest frames. If *most_recent_first* is ``True``, the order
      of the formatted frames is reversed, returning the most recent frame first
      instead of last.

      Similar to the :func:`traceback.format_tb` function, except that
      :meth:`.format` does not include newlines.

      Example::

          print("Traceback (most recent call first):")
          for line in traceback:
              print(line)

      Output::

          Traceback (most recent call first):
            File "test.py", line 9
              obj = Object()
            File "test.py", line 12
              tb = tracemalloc.get_object_traceback(f())
