Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-line_profiler for 
openSUSE:Factory checked in at 2022-09-30 17:57:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-line_profiler (Old)
 and      /work/SRC/openSUSE:Factory/.python-line_profiler.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-line_profiler"

Fri Sep 30 17:57:52 2022 rev:7 rq:1007071 version:3.5.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-line_profiler/python-line_profiler.changes    
    2022-01-08 23:24:05.898255107 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-line_profiler.new.2275/python-line_profiler.changes
      2022-09-30 17:58:10.389297184 +0200
@@ -1,0 +2,17 @@
+Thu Sep 29 14:50:17 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com>
+
+- Update to Version 3.5.2
+  * FIX: filepath test in is_ipython_kernel_cell for Windows #161
+  * ADD: setup.py now checks LINE_PROFILER_BUILD_METHOD to determine how to 
build binaries
+  * ADD: LineProfiler.add_function warns if an added function has a 
__wrapped__ attribute
+
+- Update to Version 3.5.1
+  * FIX: #19 line profiler now works on async functions again
+
+- Update to Version 3.5.0
+  * FIX: #109 kernprof fails to write to stdout if stdout was replaced
+  * FIX: Fixes max of an empty sequence error #118
+  * Make IPython optional
+  * FIX: #100 Exception raise ZeroDivisionError 
+
+-------------------------------------------------------------------

Old:
----
  line_profiler-3.4.0.tar.gz

New:
----
  line_profiler-3.5.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-line_profiler.spec ++++++
--- /var/tmp/diff_new_pack.5WmRH9/_old  2022-09-30 17:58:10.789298039 +0200
+++ /var/tmp/diff_new_pack.5WmRH9/_new  2022-09-30 17:58:10.793298048 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-line_profiler
-Version:        3.4.0
+Version:        3.5.1
 Release:        0
 Summary:        Line-by-line profiler
 License:        BSD-3-Clause

++++++ line_profiler-3.4.0.tar.gz -> line_profiler-3.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/CHANGELOG.rst 
new/line_profiler-3.5.1/CHANGELOG.rst
--- old/line_profiler-3.4.0/CHANGELOG.rst       2021-12-30 02:01:08.000000000 
+0100
+++ new/line_profiler-3.5.1/CHANGELOG.rst       2022-05-29 03:05:18.000000000 
+0200
@@ -1,10 +1,21 @@
 Changes
 =======
 
+3.5.1
+~~~~~
+* FIX: #19 line profiler now works on async functions again
+
+3.5.0
+~~~~~
+* FIX: #109 kernprof fails to write to stdout if stdout was replaced
+* FIX: Fixes max of an empty sequence error #118
+* Make IPython optional
+* FIX: #100 Exception raise ZeroDivisionError
+
 3.4.0
 ~~~~~
 * Drop support for Python <= 3.5.x
-* FIX: #104 issue with new IPython kernels 
+* FIX: #104 issue with new IPython kernels
 
 3.3.1
 ~~~~~
@@ -18,7 +29,7 @@
 3.2.6
 ~~~~~
 * FIX: Update MANIFEST.in to package pyproj.toml and missing pyx file
-* CHANGE: Removed version experimental augmentation. 
+* CHANGE: Removed version experimental augmentation.
 
 3.2.5
 ~~~~~
@@ -40,7 +51,7 @@
 
 3.2.0
 ~~~~~
-* Dropped 2.7 support, manylinux docker images no longer support 2.7 
+* Dropped 2.7 support, manylinux docker images no longer support 2.7
 * ENH: Add command line option to specify time unit and skip displaying
   functions which have not been profiled.
 * ENH: Unified versions of line_profiler and kernprof: kernprof version is now
@@ -110,4 +121,3 @@
 ~~~~~
 
 * Initial release.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/MANIFEST.in 
new/line_profiler-3.5.1/MANIFEST.in
--- old/line_profiler-3.4.0/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/MANIFEST.in 2021-05-01 00:40:57.000000000 +0200
@@ -0,0 +1,14 @@
+include *.md
+include *.rst
+include *.py
+include *.txt
+include *.toml
+include run_tests.sh
+recursive-include requirements *.txt
+recursive-include tests *.py
+recursive-include line_profiler *.txt
+recursive-include line_profiler *.pyx
+recursive-include line_profiler *.pxd
+recursive-include line_profiler *.pyd
+recursive-include line_profiler *.c
+recursive-include line_profiler *.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/PKG-INFO 
new/line_profiler-3.5.1/PKG-INFO
--- old/line_profiler-3.4.0/PKG-INFO    2021-12-30 02:01:24.562787500 +0100
+++ new/line_profiler-3.5.1/PKG-INFO    2022-05-29 03:05:39.600498000 +0200
@@ -1,19 +1,11 @@
 Metadata-Version: 2.1
 Name: line_profiler
-Version: 3.4.0
+Version: 3.5.1
 Summary: Line-by-line profiler.
 Home-page: https://github.com/pyutils/line_profiler
 Author: Robert Kern
 Author-email: robert.k...@enthought.com
 License: BSD
-Description: line_profiler will profile the time individual lines of code take 
to execute.
-        The profiler is implemented in C via Cython in order to reduce the 
overhead of
-        profiling.
-        
-        Also included is the script kernprof.py which can be used to 
conveniently
-        profile Python applications and scripts either with line_profiler or 
with the
-        function-level profiling tools in the Python standard library.
-        
 Keywords: timing,timer,profiling,profiler,line_profiler
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
@@ -31,5 +23,18 @@
 Classifier: Topic :: Software Development
 Description-Content-Type: text/x-rst
 Provides-Extra: all
+Provides-Extra: ipython
 Provides-Extra: tests
 Provides-Extra: build
+License-File: LICENSE.txt
+License-File: LICENSE_Python.txt
+
+line_profiler will profile the time individual lines of code take to execute.
+The profiler is implemented in C via Cython in order to reduce the overhead of
+profiling.
+
+Also included is the script kernprof.py which can be used to conveniently
+profile Python applications and scripts either with line_profiler or with the
+function-level profiling tools in the Python standard library.
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/README.rst 
new/line_profiler-3.5.1/README.rst
--- old/line_profiler-3.4.0/README.rst  2021-12-30 02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/README.rst  2022-05-29 02:22:11.000000000 +0200
@@ -33,6 +33,10 @@
 
     $ pip install line_profiler
 
+Installation while ensuring a compatible IPython version can also be installed 
using pip::
+
+    $ pip install line_profiler[ipython]
+
 Source releases and any binaries can be downloaded from the PyPI link.
 
     http://pypi.python.org/pypi/line_profiler
@@ -56,7 +60,7 @@
 As of 2021-06-04 Linux (x86_64 and i686), OSX (10_9_x86_64), and Win32 (win32,
 and amd64) binaries are available on pypi.
 
-Alternateively on windows you might consider using Christoph Gohlke's
+Alternatively on windows you might consider using Christoph Gohlke's
 unofficial line-profiler 
 `precompiled win32 wheels 
<https://www.lfd.uci.edu/~gohlke/pythonlibs/#line_profiler>`_.
 
@@ -251,12 +255,35 @@
 
     $ python -m pstats script_to_profile.py.prof
 
-Such files may also be viewed with graphical tools like SnakeViz_ and converted
-through pyprof2calltree_ to run on kcachegrind_ and compatible apps.
 
-.. _kcachegrind: http://kcachegrind.sourceforge.net/html/Home.html
+Such files may also be viewed with graphical tools. A list of 3rd party tools
+built on ``cProfile`` or ``line_profiler`` are as follows:
+
+* `pyprof2calltree <pyprof2calltree_>`_: converts profiling data to a format
+  that can be visualized using kcachegrind_ (linux only), wincachegrind_
+  (windows only, unmaintained), or  qcachegrind_. 
+
+* `Line Profiler GUI <qt_profiler_gui_>`_: Qt GUI for line_profiler. 
+
+* `SnakeViz <SnakeViz_>`_: A web viewer for Python profiling data.
+
+* `SnakeRunner <SnakeRunner_>`_: A fork of RunSnakeRun_, ported to Python 3.
+
+* `Pycharm plugin <pycharm_line_profiler_plugin_>`_: A PyCharm plugin for 
line_profiler.
+
+* `Spyder plugin <spyder_line_profiler_plugin_>`_: A plugin to run 
line_profiler from within the Spyder IDE.
+
+
+.. _qcachegrind: https://sourceforge.net/projects/qcachegrindwin/
+.. _kcachegrind: https://kcachegrind.github.io/html/Home.html
+.. _wincachegrind: https://github.com/ceefour/wincachegrind
 .. _pyprof2calltree: http://pypi.python.org/pypi/pyprof2calltree/
 .. _SnakeViz: https://github.com/jiffyclub/snakeviz/
+.. _SnakeRunner: https://github.com/venthur/snakerunner
+.. _RunSnakeRun: https://pypi.org/project/RunSnakeRun/
+.. _qt_profiler_gui: https://github.com/Nodd/lineprofilergui
+.. _pycharm_line_profiler_plugin: 
https://plugins.jetbrains.com/plugin/16536-line-profiler
+.. _spyder_line_profiler_plugin: 
https://github.com/spyder-ide/spyder-line-profiler
 
 Frequently Asked Questions
 ==========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/kernprof.py 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/kernprof.py
--- old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/kernprof.py 
1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/kernprof.py 
2021-12-29 23:20:40.000000000 +0100
@@ -0,0 +1,236 @@
+#!/usr/bin/env python
+""" Script to conveniently run profilers on code in a variety of circumstances.
+"""
+import builtins
+import functools
+import os
+import sys
+from argparse import ArgumentError, ArgumentParser
+
+# NOTE: This version needs to be manually maintained with the line_profiler
+# __version__ for now.
+__version__ = '3.4.0'
+
+# Guard the import of cProfile such that 3.x people
+# without lsprof can still use this script.
+try:
+    from cProfile import Profile
+except ImportError:
+    try:
+        from lsprof import Profile
+    except ImportError:
+        from profile import Profile
+
+
+def execfile(filename, globals=None, locals=None):
+    """ Python 3.x doesn't have 'execfile' builtin """
+    with open(filename, 'rb') as f:
+        exec(compile(f.read(), filename, 'exec'), globals, locals)
+# =====================================
+
+
+CO_GENERATOR = 0x0020
+
+
+def is_generator(f):
+    """ Return True if a function is a generator.
+    """
+    isgen = (f.__code__.co_flags & CO_GENERATOR) != 0
+    return isgen
+
+
+class ContextualProfile(Profile):
+    """ A subclass of Profile that adds a context manager for Python
+    2.5 with: statements and a decorator.
+    """
+
+    def __init__(self, *args, **kwds):
+        super().__init__(*args, **kwds)
+        self.enable_count = 0
+
+    def enable_by_count(self, subcalls=True, builtins=True):
+        """ Enable the profiler if it hasn't been enabled before.
+        """
+        if self.enable_count == 0:
+            self.enable(subcalls=subcalls, builtins=builtins)
+        self.enable_count += 1
+
+    def disable_by_count(self):
+        """ Disable the profiler if the number of disable requests matches the
+        number of enable requests.
+        """
+        if self.enable_count > 0:
+            self.enable_count -= 1
+            if self.enable_count == 0:
+                self.disable()
+
+    def __call__(self, func):
+        """ Decorate a function to start the profiler on function entry and 
stop
+        it on function exit.
+        """
+        # FIXME: refactor this into a utility function so that both it and
+        # line_profiler can use it.
+        if is_generator(func):
+            wrapper = self.wrap_generator(func)
+        else:
+            wrapper = self.wrap_function(func)
+        return wrapper
+
+    # FIXME: refactor this stuff so that both LineProfiler and
+    # ContextualProfile can use the same implementation.
+    def wrap_generator(self, func):
+        """ Wrap a generator to profile it.
+        """
+        @functools.wraps(func)
+        def wrapper(*args, **kwds):
+            g = func(*args, **kwds)
+            # The first iterate will not be a .send()
+            self.enable_by_count()
+            try:
+                item = next(g)
+            except StopIteration:
+                return
+            finally:
+                self.disable_by_count()
+            input = (yield item)
+            # But any following one might be.
+            while True:
+                self.enable_by_count()
+                try:
+                    item = g.send(input)
+                except StopIteration:
+                    return
+                finally:
+                    self.disable_by_count()
+                input = (yield item)
+        return wrapper
+
+    def wrap_function(self, func):
+        """ Wrap a function to profile it.
+        """
+        @functools.wraps(func)
+        def wrapper(*args, **kwds):
+            self.enable_by_count()
+            try:
+                result = func(*args, **kwds)
+            finally:
+                self.disable_by_count()
+            return result
+        return wrapper
+
+    def __enter__(self):
+        self.enable_by_count()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.disable_by_count()
+
+
+def find_script(script_name):
+    """ Find the script.
+
+    If the input is not a file, then $PATH will be searched.
+    """
+    if os.path.isfile(script_name):
+        return script_name
+    path = os.getenv('PATH', os.defpath).split(os.pathsep)
+    for dir in path:
+        if dir == '':
+            continue
+        fn = os.path.join(dir, script_name)
+        if os.path.isfile(fn):
+            return fn
+
+    sys.stderr.write('Could not find script %s\n' % script_name)
+    raise SystemExit(1)
+
+
+def main(args=None):
+    def positive_float(value):
+        val = float(value)
+        if val <= 0:
+            raise ArgumentError
+        return val
+
+    parser = ArgumentParser(description='Run and profile a python script.')
+    parser.add_argument('-V', '--version', action='version', 
version=__version__)
+    parser.add_argument('-l', '--line-by-line', action='store_true',
+                        help='Use the line-by-line profiler instead of 
cProfile. Implies --builtin.')
+    parser.add_argument('-b', '--builtin', action='store_true',
+                        help="Put 'profile' in the builtins. Use 
'profile.enable()'/'.disable()', "
+                        "'@profile' to decorate functions, or 'with profile:' 
to profile a "
+                        'section of code.')
+    parser.add_argument('-o', '--outfile',
+                        help="Save stats to <outfile> (default: 
'scriptname.lprof' with "
+                        "--line-by-line, 'scriptname.prof' without)")
+    parser.add_argument('-s', '--setup',
+                        help='Code to execute before the code to profile')
+    parser.add_argument('-v', '--view', action='store_true',
+                        help='View the results of the profile in addition to 
saving it')
+    parser.add_argument('-u', '--unit', default='1e-6', type=positive_float,
+
+                        help='Output unit (in seconds) in which the timing 
info is '
+                        'displayed (default: 1e-6)')
+    parser.add_argument('-z', '--skip-zero', action='store_true',
+                        help='Hide functions which have not been called')
+
+    parser.add_argument('script', help='The python script file to run')
+    parser.add_argument('args', nargs='...', help='Optional script arguments')
+
+    options = parser.parse_args(args)
+
+    if not options.outfile:
+        extension = 'lprof' if options.line_by_line else 'prof'
+        options.outfile = '%s.%s' % (os.path.basename(options.script), 
extension)
+
+    sys.argv = [options.script] + options.args
+    if options.setup is not None:
+        # Run some setup code outside of the profiler. This is good for large
+        # imports.
+        setup_file = find_script(options.setup)
+        __file__ = setup_file
+        __name__ = '__main__'
+        # Make sure the script's directory is on sys.path instead of just
+        # kernprof.py's.
+        sys.path.insert(0, os.path.dirname(setup_file))
+        ns = locals()
+        execfile(setup_file, ns, ns)
+
+    if options.line_by_line:
+        import line_profiler
+        prof = line_profiler.LineProfiler()
+        options.builtin = True
+    else:
+        prof = ContextualProfile()
+    if options.builtin:
+        builtins.__dict__['profile'] = prof
+
+    script_file = find_script(options.script)
+    __file__ = script_file
+    __name__ = '__main__'
+    # Make sure the script's directory is on sys.path instead of just
+    # kernprof.py's.
+    sys.path.insert(0, os.path.dirname(script_file))
+
+    try:
+        try:
+            execfile_ = execfile
+            ns = locals()
+            if options.builtin:
+                execfile(script_file, ns, ns)
+            else:
+                prof.runctx('execfile_(%r, globals())' % (script_file,), ns, 
ns)
+        except (KeyboardInterrupt, SystemExit):
+            pass
+    finally:
+        prof.dump_stats(options.outfile)
+        print('Wrote profile results to %s' % options.outfile)
+        if options.view:
+            if isinstance(prof, ContextualProfile):
+                prof.print_stats()
+            else:
+                prof.print_stats(output_unit=options.unit,
+                                 stripzeros=options.skip_zero)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__init__.py
 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__init__.py
--- 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__init__.py
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__init__.py
   2021-12-29 23:20:40.000000000 +0100
@@ -0,0 +1,22 @@
+"""
+The line_profiler modula for doing line-by-line profiling of functions
+"""
+__submodules__ = [
+    'line_profiler',
+]
+
+__autogen__ = """
+mkinit ./line_profiler/__init__.py --relative
+mkinit ./line_profiler/__init__.py --relative -w
+"""
+
+
+from .line_profiler import __version__
+
+from .line_profiler import (LineProfiler, LineProfilerMagics,
+                            load_ipython_extension, load_stats, main,
+                            show_func, show_text,)
+
+__all__ = ['LineProfiler', 'LineProfilerMagics', 'line_profiler',
+           'load_ipython_extension', 'load_stats', 'main', 'show_func',
+           'show_text', '__version__']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__main__.py
 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__main__.py
--- 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__main__.py
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__main__.py
   2021-12-29 23:20:40.000000000 +0100
@@ -0,0 +1,4 @@
+from .line_profiler import main
+
+if __name__ == '__main__':
+    main()
Binary files 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/_line_profiler.cpython-38-x86_64-linux-gnu.so
 and 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/_line_profiler.cpython-38-x86_64-linux-gnu.so
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/line_profiler.py
 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/line_profiler.py
--- 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/line_profiler.py
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/line_profiler.py
      2021-12-29 23:20:40.000000000 +0100
@@ -0,0 +1,421 @@
+#!/usr/bin/env python
+import pickle
+import functools
+import inspect
+import linecache
+import tempfile
+import os
+import sys
+from io import StringIO
+from argparse import ArgumentError, ArgumentParser
+
+from IPython.core.magic import (Magics, magics_class, line_magic)
+from IPython.core.page import page
+from IPython.utils.ipstruct import Struct
+from IPython.core.error import UsageError
+
+try:
+    from ._line_profiler import LineProfiler as CLineProfiler
+except ImportError as ex:
+    raise ImportError(
+        'The line_profiler._line_profiler c-extension is not importable. '
+        f'Has it been compiled? Underlying error is ex={ex!r}'
+    )
+
+__version__ = '3.4.0'
+
+
+def is_coroutine(f):
+    return False
+
+
+CO_GENERATOR = 0x0020
+
+
+def is_generator(f):
+    """ Return True if a function is a generator.
+    """
+    isgen = (f.__code__.co_flags & CO_GENERATOR) != 0
+    return isgen
+
+
+class LineProfiler(CLineProfiler):
+    """ A profiler that records the execution times of individual lines.
+    """
+
+    def __call__(self, func):
+        """ Decorate a function to start the profiler on function entry and 
stop
+        it on function exit.
+        """
+        self.add_function(func)
+        if is_coroutine(func):
+            wrapper = self.wrap_coroutine(func)
+        elif is_generator(func):
+            wrapper = self.wrap_generator(func)
+        else:
+            wrapper = self.wrap_function(func)
+        return wrapper
+
+    def wrap_generator(self, func):
+        """ Wrap a generator to profile it.
+        """
+        @functools.wraps(func)
+        def wrapper(*args, **kwds):
+            g = func(*args, **kwds)
+            # The first iterate will not be a .send()
+            self.enable_by_count()
+            try:
+                item = next(g)
+            except StopIteration:
+                return
+            finally:
+                self.disable_by_count()
+            input_ = (yield item)
+            # But any following one might be.
+            while True:
+                self.enable_by_count()
+                try:
+                    item = g.send(input_)
+                except StopIteration:
+                    return
+                finally:
+                    self.disable_by_count()
+                input_ = (yield item)
+        return wrapper
+
+    def wrap_function(self, func):
+        """ Wrap a function to profile it.
+        """
+        @functools.wraps(func)
+        def wrapper(*args, **kwds):
+            self.enable_by_count()
+            try:
+                result = func(*args, **kwds)
+            finally:
+                self.disable_by_count()
+            return result
+        return wrapper
+
+    def dump_stats(self, filename):
+        """ Dump a representation of the data to a file as a pickled LineStats
+        object from `get_stats()`.
+        """
+        lstats = self.get_stats()
+        with open(filename, 'wb') as f:
+            pickle.dump(lstats, f, pickle.HIGHEST_PROTOCOL)
+
+    def print_stats(self, stream=None, output_unit=None, stripzeros=False):
+        """ Show the gathered statistics.
+        """
+        lstats = self.get_stats()
+        show_text(lstats.timings, lstats.unit, output_unit=output_unit, 
stream=stream, stripzeros=stripzeros)
+
+    def run(self, cmd):
+        """ Profile a single executable statment in the main namespace.
+        """
+        import __main__
+        main_dict = __main__.__dict__
+        return self.runctx(cmd, main_dict, main_dict)
+
+    def runctx(self, cmd, globals, locals):
+        """ Profile a single executable statement in the given namespaces.
+        """
+        self.enable_by_count()
+        try:
+            exec(cmd, globals, locals)
+        finally:
+            self.disable_by_count()
+        return self
+
+    def runcall(self, func, *args, **kw):
+        """ Profile a single function call.
+        """
+        self.enable_by_count()
+        try:
+            return func(*args, **kw)
+        finally:
+            self.disable_by_count()
+
+    def add_module(self, mod):
+        """ Add all the functions in a module and its classes.
+        """
+        from inspect import isclass, isfunction
+
+        nfuncsadded = 0
+        for item in mod.__dict__.values():
+            if isclass(item):
+                for k, v in item.__dict__.items():
+                    if isfunction(v):
+                        self.add_function(v)
+                        nfuncsadded += 1
+            elif isfunction(item):
+                self.add_function(item)
+                nfuncsadded += 1
+
+        return nfuncsadded
+
+
+def is_ipython_kernel_cell(filename):
+    """ Return True if a filename corresponds to a Jupyter Notebook cell
+    """
+    return (
+        filename.startswith('<ipython-input-') or
+        filename.startswith(tempfile.gettempdir() + '/ipykernel_') or
+        filename.startswith(tempfile.gettempdir() + '/xpython_')
+    )
+
+
+def show_func(filename, start_lineno, func_name, timings, unit,
+              output_unit=None, stream=None, stripzeros=False):
+    """ Show results for a single function.
+    """
+    if stream is None:
+        stream = sys.stdout
+
+    template = '%6s %9s %12s %8s %8s  %-s'
+    d = {}
+    total_time = 0.0
+    linenos = []
+    for lineno, nhits, time in timings:
+        total_time += time
+        linenos.append(lineno)
+
+    if stripzeros and total_time == 0:
+        return
+
+    if output_unit is None:
+        output_unit = unit
+    scalar = unit / output_unit
+
+    stream.write('Total time: %g s\n' % (total_time * unit))
+    if os.path.exists(filename) or is_ipython_kernel_cell(filename):
+        stream.write(f'File: {filename}\n')
+        stream.write(f'Function: {func_name} at line {start_lineno}\n')
+        if os.path.exists(filename):
+            # Clear the cache to ensure that we get up-to-date results.
+            linecache.clearcache()
+        all_lines = linecache.getlines(filename)
+        sublines = inspect.getblock(all_lines[start_lineno - 1:])
+    else:
+        stream.write('\n')
+        stream.write(f'Could not find file {filename}\n')
+        stream.write('Are you sure you are running this program from the same 
directory\n')
+        stream.write('that you ran the profiler from?\n')
+        stream.write("Continuing without the function's contents.\n")
+        # Fake empty lines so we can see the timings, if not the code.
+        nlines = max(linenos) - min(min(linenos), start_lineno) + 1
+        sublines = [''] * nlines
+    for lineno, nhits, time in timings:
+        d[lineno] = (nhits,
+                     '%5.1f' % (time * scalar),
+                     '%5.1f' % (float(time) * scalar / nhits),
+                     '%5.1f' % (100 * time / total_time) )
+    linenos = range(start_lineno, start_lineno + len(sublines))
+    empty = ('', '', '', '')
+    header = template % ('Line #', 'Hits', 'Time', 'Per Hit', '% Time',
+                         'Line Contents')
+    stream.write('\n')
+    stream.write(header)
+    stream.write('\n')
+    stream.write('=' * len(header))
+    stream.write('\n')
+    for lineno, line in zip(linenos, sublines):
+        nhits, time, per_hit, percent = d.get(lineno, empty)
+        txt = template % (lineno, nhits, time, per_hit, percent,
+                          line.rstrip('\n').rstrip('\r'))
+        stream.write(txt)
+        stream.write('\n')
+    stream.write('\n')
+
+
+def show_text(stats, unit, output_unit=None, stream=None, stripzeros=False):
+    """ Show text for the given timings.
+    """
+    if stream is None:
+        stream = sys.stdout
+
+    if output_unit is not None:
+        stream.write('Timer unit: %g s\n\n' % output_unit)
+    else:
+        stream.write('Timer unit: %g s\n\n' % unit)
+
+    for (fn, lineno, name), timings in sorted(stats.items()):
+        show_func(fn, lineno, name, stats[fn, lineno, name], unit,
+                  output_unit=output_unit, stream=stream,
+                  stripzeros=stripzeros)
+
+
+@magics_class
+class LineProfilerMagics(Magics):
+
+    @line_magic
+    def lprun(self, parameter_s=''):
+        """ Execute a statement under the line-by-line profiler from the
+        line_profiler module.
+
+        Usage:
+          %lprun -f func1 -f func2 <statement>
+
+        The given statement (which doesn't require quote marks) is run via the
+        LineProfiler. Profiling is enabled for the functions specified by the 
-f
+        options. The statistics will be shown side-by-side with the code 
through the
+        pager once the statement has completed.
+
+        Options:
+
+        -f <function>: LineProfiler only profiles functions and methods it is 
told
+        to profile.  This option tells the profiler about these functions. 
Multiple
+        -f options may be used. The argument may be any expression that gives
+        a Python function or method object. However, one must be careful to 
avoid
+        spaces that may confuse the option parser.
+
+        -m <module>: Get all the functions/methods in a module
+
+        One or more -f or -m options are required to get any useful results.
+
+        -D <filename>: dump the raw statistics out to a pickle file on disk. 
The
+        usual extension for this is ".lprof". These statistics may be viewed 
later
+        by running line_profiler.py as a script.
+
+        -T <filename>: dump the text-formatted statistics with the code 
side-by-side
+        out to a text file.
+
+        -r: return the LineProfiler object after it has completed profiling.
+
+        -s: strip out all entries from the print-out that have zeros.
+
+        -u: specify time unit for the print-out in seconds.
+        """
+
+        # Escape quote markers.
+        opts_def = Struct(D=[''], T=[''], f=[], m=[], u=None)
+        parameter_s = parameter_s.replace('"', r'\"').replace("'", r"\'")
+        opts, arg_str = self.parse_options(parameter_s, 'rsf:m:D:T:u:', 
list_all=True)
+        opts.merge(opts_def)
+
+        global_ns = self.shell.user_global_ns
+        local_ns = self.shell.user_ns
+
+        # Get the requested functions.
+        funcs = []
+        for name in opts.f:
+            try:
+                funcs.append(eval(name, global_ns, local_ns))
+            except Exception as e:
+                raise UsageError(f'Could not find module 
{name}.\n{e.__class__.__name__}: {e}')
+
+        profile = LineProfiler(*funcs)
+
+        # Get the modules, too
+        for modname in opts.m:
+            try:
+                mod = __import__(modname, fromlist=[''])
+                profile.add_module(mod)
+            except Exception as e:
+                raise UsageError(f'Could not find module 
{modname}.\n{e.__class__.__name__}: {e}')
+
+        if opts.u is not None:
+            try:
+                output_unit = float(opts.u[0])
+            except Exception:
+                raise TypeError('Timer unit setting must be a float.')
+        else:
+            output_unit = None
+
+        # Add the profiler to the builtins for @profile.
+        import builtins
+
+        if 'profile' in builtins.__dict__:
+            had_profile = True
+            old_profile = builtins.__dict__['profile']
+        else:
+            had_profile = False
+            old_profile = None
+        builtins.__dict__['profile'] = profile
+
+        try:
+            try:
+                profile.runctx(arg_str, global_ns, local_ns)
+                message = ''
+            except SystemExit:
+                message = """*** SystemExit exception caught in code being 
profiled."""
+            except KeyboardInterrupt:
+                message = ('*** KeyboardInterrupt exception caught in code 
being '
+                           'profiled.')
+        finally:
+            if had_profile:
+                builtins.__dict__['profile'] = old_profile
+
+        # Trap text output.
+        stdout_trap = StringIO()
+        profile.print_stats(stdout_trap, output_unit=output_unit, 
stripzeros='s' in opts)
+        output = stdout_trap.getvalue()
+        output = output.rstrip()
+
+        page(output)
+        print(message, end='')
+
+        dump_file = opts.D[0]
+        if dump_file:
+            profile.dump_stats(dump_file)
+            print(f'\n*** Profile stats pickled to file {dump_file!r}. 
{message}')
+
+        text_file = opts.T[0]
+        if text_file:
+            pfile = open(text_file, 'w')
+            pfile.write(output)
+            pfile.close()
+            print(f'\n*** Profile printout saved to text file {text_file!r}. 
{message}')
+
+        return_value = None
+        if 'r' in opts:
+            return_value = profile
+
+        return return_value
+
+
+def load_ipython_extension(ip):
+    """ API for IPython to recognize this module as an IPython extension.
+    """
+    ip.register_magics(LineProfilerMagics)
+
+
+def load_stats(filename):
+    """ Utility function to load a pickled LineStats object from a given
+    filename.
+    """
+    with open(filename, 'rb') as f:
+        return pickle.load(f)
+
+
+def main():
+    def positive_float(value):
+        val = float(value)
+        if val <= 0:
+            raise ArgumentError
+        return val
+
+    parser = ArgumentParser()
+    parser.add_argument('-V', '--version', action='version', 
version=__version__)
+    parser.add_argument(
+        '-u',
+        '--unit',
+        default='1e-6',
+        type=positive_float,
+        help='Output unit (in seconds) in which the timing info is displayed 
(default: 1e-6)',
+    )
+    parser.add_argument(
+        '-z',
+        '--skip-zero',
+        action='store_true',
+        help='Hide functions which have not been called',
+    )
+    parser.add_argument('profile_output', help='*.lprof file created by 
kernprof')
+
+    args = parser.parse_args()
+    lstats = load_stats(args.profile_output)
+    show_text(lstats.timings, lstats.unit, output_unit=args.unit, 
stripzeros=args.skip_zero)
+
+
+if __name__ == '__main__':
+    main()
Binary files 
old/line_profiler-3.4.0/_skbuild/linux-x86_64-3.9/cmake-install/line_profiler/_line_profiler.cpython-39-x86_64-linux-gnu.so
 and 
new/line_profiler-3.5.1/_skbuild/linux-x86_64-3.9/cmake-install/line_profiler/_line_profiler.cpython-39-x86_64-linux-gnu.so
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/kernprof.py 
new/line_profiler-3.5.1/kernprof.py
--- old/line_profiler-3.4.0/kernprof.py 2021-12-30 02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/kernprof.py 2022-05-29 03:05:18.000000000 +0200
@@ -9,7 +9,7 @@
 
 # NOTE: This version needs to be manually maintained with the line_profiler
 # __version__ for now.
-__version__ = '3.4.0'
+__version__ = '3.5.1'
 
 # Guard the import of cProfile such that 3.x people
 # without lsprof can still use this script.
@@ -211,6 +211,7 @@
     # kernprof.py's.
     sys.path.insert(0, os.path.dirname(script_file))
 
+    original_stdout = sys.stdout
     try:
         try:
             execfile_ = execfile
@@ -226,10 +227,11 @@
         print('Wrote profile results to %s' % options.outfile)
         if options.view:
             if isinstance(prof, ContextualProfile):
-                prof.print_stats()
+                prof.print_stats(stream=original_stdout)
             else:
                 prof.print_stats(output_unit=options.unit,
-                                 stripzeros=options.skip_zero)
+                                 stripzeros=options.skip_zero,
+                                 stream=original_stdout)
 
 
 if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/line_profiler/__init__.py 
new/line_profiler-3.5.1/line_profiler/__init__.py
--- old/line_profiler-3.4.0/line_profiler/__init__.py   2021-12-30 
02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler/__init__.py   2022-04-01 
08:53:10.000000000 +0200
@@ -3,6 +3,7 @@
 """
 __submodules__ = [
     'line_profiler',
+    'ipython_extension',
 ]
 
 __autogen__ = """
@@ -13,10 +14,10 @@
 
 from .line_profiler import __version__
 
-from .line_profiler import (LineProfiler, LineProfilerMagics,
+from .line_profiler import (LineProfiler,
                             load_ipython_extension, load_stats, main,
                             show_func, show_text,)
 
-__all__ = ['LineProfiler', 'LineProfilerMagics', 'line_profiler',
+__all__ = ['LineProfiler', 'line_profiler',
            'load_ipython_extension', 'load_stats', 'main', 'show_func',
            'show_text', '__version__']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler/ipython_extension.py 
new/line_profiler-3.5.1/line_profiler/ipython_extension.py
--- old/line_profiler-3.4.0/line_profiler/ipython_extension.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler/ipython_extension.py  2022-04-01 
08:53:10.000000000 +0200
@@ -0,0 +1,143 @@
+from io import StringIO
+
+from IPython.core.magic import Magics, magics_class, line_magic
+from IPython.core.page import page
+from IPython.utils.ipstruct import Struct
+from IPython.core.error import UsageError
+
+from .line_profiler import LineProfiler
+
+
+@magics_class
+class LineProfilerMagics(Magics):
+    @line_magic
+    def lprun(self, parameter_s=""):
+        """ Execute a statement under the line-by-line profiler from the
+        line_profiler module.
+
+        Usage:
+        %lprun -f func1 -f func2 <statement>
+
+        The given statement (which doesn't require quote marks) is run via the
+        LineProfiler. Profiling is enabled for the functions specified by the 
-f
+        options. The statistics will be shown side-by-side with the code 
through the
+        pager once the statement has completed.
+
+        Options:
+
+        -f <function>: LineProfiler only profiles functions and methods it is 
told
+        to profile.  This option tells the profiler about these functions. 
Multiple
+        -f options may be used. The argument may be any expression that gives
+        a Python function or method object. However, one must be careful to 
avoid
+        spaces that may confuse the option parser.
+
+        -m <module>: Get all the functions/methods in a module
+
+        One or more -f or -m options are required to get any useful results.
+
+        -D <filename>: dump the raw statistics out to a pickle file on disk. 
The
+        usual extension for this is ".lprof". These statistics may be viewed 
later
+        by running line_profiler.py as a script.
+
+        -T <filename>: dump the text-formatted statistics with the code 
side-by-side
+        out to a text file.
+
+        -r: return the LineProfiler object after it has completed profiling.
+
+        -s: strip out all entries from the print-out that have zeros.
+
+        -u: specify time unit for the print-out in seconds.
+        """
+
+        # Escape quote markers.
+        opts_def = Struct(D=[""], T=[""], f=[], m=[], u=None)
+        parameter_s = parameter_s.replace('"', r"\"").replace("'", r"\'")
+        opts, arg_str = self.parse_options(parameter_s, "rsf:m:D:T:u:", 
list_all=True)
+        opts.merge(opts_def)
+
+        global_ns = self.shell.user_global_ns
+        local_ns = self.shell.user_ns
+
+        # Get the requested functions.
+        funcs = []
+        for name in opts.f:
+            try:
+                funcs.append(eval(name, global_ns, local_ns))
+            except Exception as e:
+                raise UsageError(
+                    f"Could not find module {name}.\n{e.__class__.__name__}: 
{e}"
+                )
+
+        profile = LineProfiler(*funcs)
+
+        # Get the modules, too
+        for modname in opts.m:
+            try:
+                mod = __import__(modname, fromlist=[""])
+                profile.add_module(mod)
+            except Exception as e:
+                raise UsageError(
+                    f"Could not find module 
{modname}.\n{e.__class__.__name__}: {e}"
+                )
+
+        if opts.u is not None:
+            try:
+                output_unit = float(opts.u[0])
+            except Exception:
+                raise TypeError("Timer unit setting must be a float.")
+        else:
+            output_unit = None
+
+        # Add the profiler to the builtins for @profile.
+        import builtins
+
+        if "profile" in builtins.__dict__:
+            had_profile = True
+            old_profile = builtins.__dict__["profile"]
+        else:
+            had_profile = False
+            old_profile = None
+        builtins.__dict__["profile"] = profile
+
+        try:
+            try:
+                profile.runctx(arg_str, global_ns, local_ns)
+                message = ""
+            except SystemExit:
+                message = """*** SystemExit exception caught in code being 
profiled."""
+            except KeyboardInterrupt:
+                message = (
+                    "*** KeyboardInterrupt exception caught in code being " 
"profiled."
+                )
+        finally:
+            if had_profile:
+                builtins.__dict__["profile"] = old_profile
+
+        # Trap text output.
+        stdout_trap = StringIO()
+        profile.print_stats(
+            stdout_trap, output_unit=output_unit, stripzeros="s" in opts
+        )
+        output = stdout_trap.getvalue()
+        output = output.rstrip()
+
+        page(output)
+        print(message, end="")
+
+        dump_file = opts.D[0]
+        if dump_file:
+            profile.dump_stats(dump_file)
+            print(f"\n*** Profile stats pickled to file {dump_file!r}. 
{message}")
+
+        text_file = opts.T[0]
+        if text_file:
+            pfile = open(text_file, "w")
+            pfile.write(output)
+            pfile.close()
+            print(f"\n*** Profile printout saved to text file {text_file!r}. 
{message}")
+
+        return_value = None
+        if "r" in opts:
+            return_value = profile
+
+        return return_value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/line_profiler/line_profiler.py 
new/line_profiler-3.5.1/line_profiler/line_profiler.py
--- old/line_profiler-3.4.0/line_profiler/line_profiler.py      2021-12-30 
02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler/line_profiler.py      2022-05-29 
03:05:18.000000000 +0200
@@ -6,14 +6,8 @@
 import tempfile
 import os
 import sys
-from io import StringIO
 from argparse import ArgumentError, ArgumentParser
 
-from IPython.core.magic import (Magics, magics_class, line_magic)
-from IPython.core.page import page
-from IPython.utils.ipstruct import Struct
-from IPython.core.error import UsageError
-
 try:
     from ._line_profiler import LineProfiler as CLineProfiler
 except ImportError as ex:
@@ -22,11 +16,18 @@
         f'Has it been compiled? Underlying error is ex={ex!r}'
     )
 
-__version__ = '3.4.0'
+__version__ = '3.5.1'
+
+
+def load_ipython_extension(ip):
+    """ API for IPython to recognize this module as an IPython extension.
+    """
+    from .ipython_extension import LineProfilerMagics
+    ip.register_magics(LineProfilerMagics)
 
 
 def is_coroutine(f):
-    return False
+    return inspect.iscoroutinefunction(f)
 
 
 CO_GENERATOR = 0x0020
@@ -56,6 +57,22 @@
             wrapper = self.wrap_function(func)
         return wrapper
 
+    def wrap_coroutine(self, func):
+        """
+        Wrap a Python 3.5 coroutine to profile it.
+        """
+
+        @functools.wraps(func)
+        async def wrapper(*args, **kwds):
+            self.enable_by_count()
+            try:
+                result = await func(*args, **kwds)
+            finally:
+                self.disable_by_count()
+            return result
+
+        return wrapper
+
     def wrap_generator(self, func):
         """ Wrap a generator to profile it.
         """
@@ -155,6 +172,8 @@
         return nfuncsadded
 
 
+# This could be in the ipython_extension submodule,
+# but it doesn't depend on the IPython module so it's easier to just let it 
stay here.
 def is_ipython_kernel_cell(filename):
     """ Return True if a filename corresponds to a Jupyter Notebook cell
     """
@@ -203,13 +222,17 @@
         stream.write('that you ran the profiler from?\n')
         stream.write("Continuing without the function's contents.\n")
         # Fake empty lines so we can see the timings, if not the code.
-        nlines = max(linenos) - min(min(linenos), start_lineno) + 1
+        nlines = 1 if not linenos else max(linenos) - min(min(linenos), 
start_lineno) + 1
         sublines = [''] * nlines
     for lineno, nhits, time in timings:
+        if total_time == 0:  # Happens rarely on empty function
+            percent = ''
+        else:
+            percent = '%5.1f' % (100 * time / total_time)
         d[lineno] = (nhits,
                      '%5.1f' % (time * scalar),
                      '%5.1f' % (float(time) * scalar / nhits),
-                     '%5.1f' % (100 * time / total_time) )
+                     percent)
     linenos = range(start_lineno, start_lineno + len(sublines))
     empty = ('', '', '', '')
     header = template % ('Line #', 'Hits', 'Time', 'Per Hit', '% Time',
@@ -244,142 +267,6 @@
                   output_unit=output_unit, stream=stream,
                   stripzeros=stripzeros)
 
-
-@magics_class
-class LineProfilerMagics(Magics):
-
-    @line_magic
-    def lprun(self, parameter_s=''):
-        """ Execute a statement under the line-by-line profiler from the
-        line_profiler module.
-
-        Usage:
-          %lprun -f func1 -f func2 <statement>
-
-        The given statement (which doesn't require quote marks) is run via the
-        LineProfiler. Profiling is enabled for the functions specified by the 
-f
-        options. The statistics will be shown side-by-side with the code 
through the
-        pager once the statement has completed.
-
-        Options:
-
-        -f <function>: LineProfiler only profiles functions and methods it is 
told
-        to profile.  This option tells the profiler about these functions. 
Multiple
-        -f options may be used. The argument may be any expression that gives
-        a Python function or method object. However, one must be careful to 
avoid
-        spaces that may confuse the option parser.
-
-        -m <module>: Get all the functions/methods in a module
-
-        One or more -f or -m options are required to get any useful results.
-
-        -D <filename>: dump the raw statistics out to a pickle file on disk. 
The
-        usual extension for this is ".lprof". These statistics may be viewed 
later
-        by running line_profiler.py as a script.
-
-        -T <filename>: dump the text-formatted statistics with the code 
side-by-side
-        out to a text file.
-
-        -r: return the LineProfiler object after it has completed profiling.
-
-        -s: strip out all entries from the print-out that have zeros.
-
-        -u: specify time unit for the print-out in seconds.
-        """
-
-        # Escape quote markers.
-        opts_def = Struct(D=[''], T=[''], f=[], m=[], u=None)
-        parameter_s = parameter_s.replace('"', r'\"').replace("'", r"\'")
-        opts, arg_str = self.parse_options(parameter_s, 'rsf:m:D:T:u:', 
list_all=True)
-        opts.merge(opts_def)
-
-        global_ns = self.shell.user_global_ns
-        local_ns = self.shell.user_ns
-
-        # Get the requested functions.
-        funcs = []
-        for name in opts.f:
-            try:
-                funcs.append(eval(name, global_ns, local_ns))
-            except Exception as e:
-                raise UsageError(f'Could not find module 
{name}.\n{e.__class__.__name__}: {e}')
-
-        profile = LineProfiler(*funcs)
-
-        # Get the modules, too
-        for modname in opts.m:
-            try:
-                mod = __import__(modname, fromlist=[''])
-                profile.add_module(mod)
-            except Exception as e:
-                raise UsageError(f'Could not find module 
{modname}.\n{e.__class__.__name__}: {e}')
-
-        if opts.u is not None:
-            try:
-                output_unit = float(opts.u[0])
-            except Exception:
-                raise TypeError('Timer unit setting must be a float.')
-        else:
-            output_unit = None
-
-        # Add the profiler to the builtins for @profile.
-        import builtins
-
-        if 'profile' in builtins.__dict__:
-            had_profile = True
-            old_profile = builtins.__dict__['profile']
-        else:
-            had_profile = False
-            old_profile = None
-        builtins.__dict__['profile'] = profile
-
-        try:
-            try:
-                profile.runctx(arg_str, global_ns, local_ns)
-                message = ''
-            except SystemExit:
-                message = """*** SystemExit exception caught in code being 
profiled."""
-            except KeyboardInterrupt:
-                message = ('*** KeyboardInterrupt exception caught in code 
being '
-                           'profiled.')
-        finally:
-            if had_profile:
-                builtins.__dict__['profile'] = old_profile
-
-        # Trap text output.
-        stdout_trap = StringIO()
-        profile.print_stats(stdout_trap, output_unit=output_unit, 
stripzeros='s' in opts)
-        output = stdout_trap.getvalue()
-        output = output.rstrip()
-
-        page(output)
-        print(message, end='')
-
-        dump_file = opts.D[0]
-        if dump_file:
-            profile.dump_stats(dump_file)
-            print(f'\n*** Profile stats pickled to file {dump_file!r}. 
{message}')
-
-        text_file = opts.T[0]
-        if text_file:
-            pfile = open(text_file, 'w')
-            pfile.write(output)
-            pfile.close()
-            print(f'\n*** Profile printout saved to text file {text_file!r}. 
{message}')
-
-        return_value = None
-        if 'r' in opts:
-            return_value = profile
-
-        return return_value
-
-
-def load_ipython_extension(ip):
-    """ API for IPython to recognize this module as an IPython extension.
-    """
-    ip.register_magics(LineProfilerMagics)
-
-
 def load_stats(filename):
     """ Utility function to load a pickled LineStats object from a given
     filename.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/line_profiler.egg-info/PKG-INFO 
new/line_profiler-3.5.1/line_profiler.egg-info/PKG-INFO
--- old/line_profiler-3.4.0/line_profiler.egg-info/PKG-INFO     1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/PKG-INFO     2022-05-29 
03:05:39.000000000 +0200
@@ -0,0 +1,40 @@
+Metadata-Version: 2.1
+Name: line-profiler
+Version: 3.5.1
+Summary: Line-by-line profiler.
+Home-page: https://github.com/pyutils/line_profiler
+Author: Robert Kern
+Author-email: robert.k...@enthought.com
+License: BSD
+Keywords: timing,timer,profiling,profiler,line_profiler
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Software Development
+Description-Content-Type: text/x-rst
+Provides-Extra: all
+Provides-Extra: ipython
+Provides-Extra: tests
+Provides-Extra: build
+License-File: LICENSE.txt
+License-File: LICENSE_Python.txt
+
+line_profiler will profile the time individual lines of code take to execute.
+The profiler is implemented in C via Cython in order to reduce the overhead of
+profiling.
+
+Also included is the script kernprof.py which can be used to conveniently
+profile Python applications and scripts either with line_profiler or with the
+function-level profiling tools in the Python standard library.
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler.egg-info/SOURCES.txt 
new/line_profiler-3.5.1/line_profiler.egg-info/SOURCES.txt
--- old/line_profiler-3.4.0/line_profiler.egg-info/SOURCES.txt  1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/SOURCES.txt  2022-05-29 
03:05:39.000000000 +0200
@@ -0,0 +1,42 @@
+CHANGELOG.rst
+CMakeLists.txt
+LICENSE.txt
+LICENSE_Python.txt
+MANIFEST.in
+README.rst
+kernprof.py
+pyproject.toml
+requirements.txt
+run_tests.py
+setup.py
+_skbuild/linux-x86_64-3.8/cmake-install/kernprof.py
+_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__init__.py
+_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/__main__.py
+_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/_line_profiler.cpython-38-x86_64-linux-gnu.so
+_skbuild/linux-x86_64-3.8/cmake-install/line_profiler/line_profiler.py
+_skbuild/linux-x86_64-3.9/cmake-install/line_profiler/_line_profiler.cpython-39-x86_64-linux-gnu.so
+line_profiler/CMakeLists.txt
+line_profiler/__init__.py
+line_profiler/__main__.py
+line_profiler/_line_profiler.pyx
+line_profiler/ipython_extension.py
+line_profiler/line_profiler.py
+line_profiler/python25.pxd
+line_profiler/timers.c
+line_profiler/timers.h
+line_profiler/unset_trace.c
+line_profiler/unset_trace.h
+line_profiler.egg-info/PKG-INFO
+line_profiler.egg-info/SOURCES.txt
+line_profiler.egg-info/dependency_links.txt
+line_profiler.egg-info/entry_points.txt
+line_profiler.egg-info/requires.txt
+line_profiler.egg-info/top_level.txt
+requirements/build.txt
+requirements/ipython.txt
+requirements/runtime.txt
+requirements/tests.txt
+tests/test_cli.py
+tests/test_ipython.py
+tests/test_kernprof.py
+tests/test_line_profiler.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler.egg-info/dependency_links.txt 
new/line_profiler-3.5.1/line_profiler.egg-info/dependency_links.txt
--- old/line_profiler-3.4.0/line_profiler.egg-info/dependency_links.txt 
1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/dependency_links.txt 
2022-05-29 03:05:39.000000000 +0200
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler.egg-info/entry_points.txt 
new/line_profiler-3.5.1/line_profiler.egg-info/entry_points.txt
--- old/line_profiler-3.4.0/line_profiler.egg-info/entry_points.txt     
1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/entry_points.txt     
2022-05-29 03:05:39.000000000 +0200
@@ -0,0 +1,3 @@
+[console_scripts]
+kernprof = kernprof:main
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler.egg-info/requires.txt 
new/line_profiler-3.5.1/line_profiler.egg-info/requires.txt
--- old/line_profiler-3.4.0/line_profiler.egg-info/requires.txt 1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/requires.txt 2022-05-29 
03:05:39.000000000 +0200
@@ -0,0 +1,44 @@
+
+[all]
+Cython
+scikit-build
+cmake
+ninja
+pytest>=4.6.11
+pytest-cov>=2.10.1
+coverage[toml]>=5.3
+ubelt>=1.0.1
+
+[all:python_version <= "3.6"]
+IPython<7.17.0,>=0.13
+IPython<7.17.0,>=0.13
+
+[all:python_version >= "3.7"]
+IPython>=0.13
+IPython>=0.13
+
+[build]
+Cython
+scikit-build
+cmake
+ninja
+
+[ipython]
+
+[ipython:python_version <= "3.6"]
+IPython<7.17.0,>=0.13
+
+[ipython:python_version >= "3.7"]
+IPython>=0.13
+
+[tests]
+pytest>=4.6.11
+pytest-cov>=2.10.1
+coverage[toml]>=5.3
+ubelt>=1.0.1
+
+[tests:python_version <= "3.6"]
+IPython<7.17.0,>=0.13
+
+[tests:python_version >= "3.7"]
+IPython>=0.13
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/line_profiler-3.4.0/line_profiler.egg-info/top_level.txt 
new/line_profiler-3.5.1/line_profiler.egg-info/top_level.txt
--- old/line_profiler-3.4.0/line_profiler.egg-info/top_level.txt        
1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/line_profiler.egg-info/top_level.txt        
2022-05-29 03:05:39.000000000 +0200
@@ -0,0 +1,2 @@
+kernprof
+line_profiler
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/requirements/ipython.txt 
new/line_profiler-3.5.1/requirements/ipython.txt
--- old/line_profiler-3.4.0/requirements/ipython.txt    1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/requirements/ipython.txt    2022-04-01 
08:53:10.000000000 +0200
@@ -0,0 +1,2 @@
+IPython >=0.13 ; python_version >= '3.7'
+IPython >=0.13, <7.17.0 ; python_version <= '3.6'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/requirements/runtime.txt 
new/line_profiler-3.5.1/requirements/runtime.txt
--- old/line_profiler-3.4.0/requirements/runtime.txt    2021-12-30 
02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/requirements/runtime.txt    2022-04-01 
08:53:10.000000000 +0200
@@ -1,2 +0,0 @@
-IPython >=0.13 ; python_version >= '3.7'
-IPython >=0.13, <7.17.0 ; python_version <= '3.6'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/requirements/tests.txt 
new/line_profiler-3.5.1/requirements/tests.txt
--- old/line_profiler-3.4.0/requirements/tests.txt      2021-12-30 
02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/requirements/tests.txt      2022-04-01 
08:54:20.000000000 +0200
@@ -1,4 +1,6 @@
 pytest >= 4.6.11
 pytest-cov >= 2.10.1
 coverage[toml] >= 5.3
-ubelt >= 0.8.7
+ubelt >= 1.0.1
+IPython >=0.13 ; python_version >= '3.7'
+IPython >=0.13, <7.17.0 ; python_version <= '3.6'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/requirements.txt 
new/line_profiler-3.5.1/requirements.txt
--- old/line_profiler-3.4.0/requirements.txt    2021-12-30 02:01:08.000000000 
+0100
+++ new/line_profiler-3.5.1/requirements.txt    2022-04-01 08:53:10.000000000 
+0200
@@ -1,3 +1,4 @@
 -r requirements/runtime.txt
+-r requirements/ipython.txt
 -r requirements/build.txt
 -r requirements/tests.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/setup.cfg 
new/line_profiler-3.5.1/setup.cfg
--- old/line_profiler-3.4.0/setup.cfg   1970-01-01 01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/setup.cfg   2022-05-29 03:05:39.600498000 +0200
@@ -0,0 +1,4 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/setup.py 
new/line_profiler-3.5.1/setup.py
--- old/line_profiler-3.4.0/setup.py    2021-12-30 02:01:08.000000000 +0100
+++ new/line_profiler-3.5.1/setup.py    2022-04-01 08:53:10.000000000 +0200
@@ -259,6 +259,7 @@
         install_requires=parse_requirements('requirements/runtime.txt'),
         extras_require={
             'all': parse_requirements('requirements.txt'),
+            'ipython': parse_requirements('requirements/ipython.txt'),
             'tests': parse_requirements('requirements/tests.txt'),
             'build': parse_requirements('requirements/build.txt'),
         },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/line_profiler-3.4.0/tests/test_ipython.py 
new/line_profiler-3.5.1/tests/test_ipython.py
--- old/line_profiler-3.4.0/tests/test_ipython.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/line_profiler-3.5.1/tests/test_ipython.py       2022-04-01 
08:53:10.000000000 +0200
@@ -0,0 +1,21 @@
+import unittest
+import io
+
+from IPython.testing.globalipapp import get_ipython
+
+class TestIPython(unittest.TestCase):
+    def test_init(self):
+        ip = get_ipython()
+        ip.run_line_magic('load_ext', 'line_profiler')
+        ip.run_cell(raw_cell='def func():\n    return 2**20')
+        lprof = ip.run_line_magic('lprun', '-r -f func func()')
+
+        timings = lprof.get_stats().timings
+        self.assertEqual(len(timings), 1)  # 1 function
+
+        func_data, lines_data = next(iter(timings.items()))
+        self.assertEqual(func_data[1], 1)  # lineno of the function
+        self.assertEqual(func_data[2], "func")  # function name
+        self.assertEqual(len(lines_data), 1)  # 1 line of code
+        self.assertEqual(lines_data[0][0], 2)  # lineno
+        self.assertEqual(lines_data[0][1], 1)  # hits

Reply via email to