Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-ipython for openSUSE:Factory 
checked in at 2022-01-22 08:17:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ipython (Old)
 and      /work/SRC/openSUSE:Factory/.python-ipython.new.1938 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ipython"

Sat Jan 22 08:17:58 2022 rev:26 rq:947675 version:8.0.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ipython/python-ipython.changes    
2021-12-25 20:16:42.825252931 +0100
+++ /work/SRC/openSUSE:Factory/.python-ipython.new.1938/python-ipython.changes  
2022-01-22 08:18:14.166882751 +0100
@@ -1,0 +2,62 @@
+Thu Jan 20 10:19:48 UTC 2022 - Ben Greiner <c...@bnavigator.de>
+
+- Update to 8.0.1
+  * Security fix CVE-2022-21699: change some default values in
+    order to prevent potential Execution with Unnecessary
+    Privileges.
+  * Almost all version of IPython looks for configuration and
+    profiles in current working directory. Since IPython was
+    developed before pip and environments existed it was used a
+    convenient way to load code/packages in a project dependant
+    way.
+  * In 2022, it is not necessary anymore, and can lead to confusing
+    behavior where for example cloning a repository and starting
+    IPython or loading a notebook from any Jupyter-Compatible
+    interface that has ipython set as a kernel can lead to code
+    execution.
+  * The current working directory is not searched anymore for
+    profiles or configurations files.
+  * Added a __patched_cves__ attribute (set of strings) to IPython
+    module that contain the list of fixed CVE. This is
+    informational only.
+- Fixes boo#1194936, CVE-2022-21699
+
+-------------------------------------------------------------------
+Sat Jan 15 22:58:17 UTC 2022 - Ben Greiner <c...@bnavigator.de>
+
+- Update requirements.
+
+-------------------------------------------------------------------
+Sat Jan 15 15:40:59 UTC 2022 - Ben Greiner <c...@bnavigator.de>
+
+- Requires the full stdlib including sqlite3
+- Revert some spec-cleaner edits
+
+-------------------------------------------------------------------
+Fri Jan 14 18:19:27 UTC 2022 - Matej Cepl <mc...@suse.com>
+
+- Update to 8.0.0:
+  - Minimum supported traitlets version if now 5+
+  - we now require stack_data
+  - Minimal Python is now 3.8
+  - pytest replaces nose.
+  - iptest/iptest3 cli entrypoints do not exists anymore.
+  - minimum officially support numpy version has been bumped, but
+    this should not have much effect on packaging.
+  - Backport some fixes for Python 3.10 (PR #13412)
+  - use full-alpha transparency on dvipng rendered LaTeX (PR #13372)
+  - Traceback improvements
+  - Autosuggestons
+  - Show pinfo information in ipdb using ??????? and ????????
+  - Autoreload 3 feature
+  - Auto formatting with black in the CLI
+  - History Range Glob feature
+  - Don???t start a multi line cell with sunken parenthesis
+  - IPython shell for ipdb interact
+  - Automatic Vi prompt stripping
+  - Empty History Ranges
+  - Windows time-implementation: Switch to process_time
+  - Re-added support for XDG config directories
+- Add skip-network-test.patch to skip (gh#ipython/ipython#13468).
+
+-------------------------------------------------------------------

Old:
----
  ipython-7.30.1.tar.gz

New:
----
  ipython-8.0.1.tar.gz
  skip-network-test.patch

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

Other differences:
------------------
++++++ python-ipython.spec ++++++
--- /var/tmp/diff_new_pack.CMSdUP/_old  2022-01-22 08:18:15.658872697 +0100
+++ /var/tmp/diff_new_pack.CMSdUP/_new  2022-01-22 08:18:15.662872670 +0100
@@ -1,7 +1,7 @@
 #
 # spec file
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -30,13 +30,11 @@
 %define psuffix %{nil}
 %bcond_with test
 %endif
+
 %{?!python_module:%define python_module() python3-%{**}}
 %define         skip_python2 1
-# Python 3.6 was officiallay supported with IPython up to 7.15
-%define         skip_python36 1
-%bcond_without  iptest
 Name:           python-ipython%{psuffix}
-Version:        7.30.1
+Version:        8.0.1
 Release:        0
 Summary:        Rich architecture for interactive computing with Python
 License:        BSD-3-Clause
@@ -48,22 +46,28 @@
 Patch0:         ipython-pr13282-py310-inspect.patch
 # PATCH-FIX-UPSTREAM ipython-pr13371-py310-oserror.patch -- 
gh#ipython/ipython#13371
 Patch1:         ipython-pr13371-py310-oserror.patch
-BuildRequires:  %{python_module backcall}
+# PATCH-FIX-OPENSUSE skip-network-test.patch gh#ipython/ipython#13468 
mc...@suse.com
+# skip doctests requiring network connection
+Patch2:         skip-network-test.patch
+BuildRequires:  %pythons
 BuildRequires:  %{python_module base >= 3.7}
 BuildRequires:  %{python_module setuptools >= 18.5}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros >= 20210929
-Requires:       python-Pygments
+# requires the full stdlib including sqlite3
+Requires:       python >= 3.7
 Requires:       python-backcall
-Requires:       python-base >= 3.7
+Requires:       python-black
 Requires:       python-decorator
 Requires:       python-jedi >= 0.16
 Requires:       python-matplotlib-inline
 Requires:       python-pexpect >= 4.3
 Requires:       python-pickleshare
-Requires:       python-prompt_toolkit < 3.1
-Requires:       python-prompt_toolkit >= 2.0
-Requires:       python-traitlets >= 4.2
+Requires:       python-pygments
+Requires:       python-setuptools >= 18.5
+Requires:       python-stack-data
+Requires:       python-traitlets >= 5
+Requires:       (python-prompt_toolkit >= 2.0 with python-prompt_toolkit < 3.1)
 Recommends:     jupyter
 Recommends:     python-ipykernel
 Recommends:     python-ipyparallel
@@ -85,17 +89,25 @@
 Obsoletes:      python-jupyter_ipython-doc-pdf < %{version}
 BuildArch:      noarch
 %if %{with test}
-# test requirements are specified in the iptest subpackage below
-BuildRequires:  %{python_module ipython-iptest = %{version}}
-BuildRequires:  %{python_module testsuite}
+BuildRequires:  %{python_module curio}
+BuildRequires:  %{python_module ipython = %{version}}
+BuildRequires:  %{python_module matplotlib}
+BuildRequires:  %{python_module nbformat}
+BuildRequires:  %{python_module numpy >= 1.19}
+BuildRequires:  %{python_module pandas}
+BuildRequires:  %{python_module pygments}
+BuildRequires:  %{python_module pytest-asyncio}
+BuildRequires:  %{python_module pytest}
+BuildRequires:  %{python_module testpath}
+BuildRequires:  %{python_module trio}
 %endif
 %if !%{with test}
 BuildRequires:  desktop-file-utils
 BuildRequires:  hicolor-icon-theme
 BuildRequires:  update-desktop-files
 %if %{with libalternatives}
-Requires:       alts
 BuildRequires:  alts
+Requires:       alts
 %else
 Requires(post): update-alternatives
 Requires(postun):update-alternatives
@@ -136,27 +148,6 @@
  * Easily embeddable in other Python programs and GUIs.
  * Integrated access to the pdb debugger and the Python profiler.
 
-%package iptest
-Summary:        Tools for testing packages that rely in %{name}
-Group:          Development/Languages/Python
-Requires:       %{name} = %{version}
-Requires:       python-Pygments
-Requires:       python-ipykernel
-Requires:       python-nbformat
-Requires:       python-nose >= 0.10.1
-Requires:       python-numpy >= 1.17
-Requires:       python-requests
-Requires:       python-testpath
-%if %{with libalternatives}
-Requires:       alts
-%endif
-Provides:       python-jupyter_ipython-iptest = %{version}
-Obsoletes:      python-jupyter_ipython-iptest < %{version}
-
-%description iptest
-This package provides the iptest command, which is used for
-testing software that uses %{name}.
-
 %prep
 %autosetup -p1 -n ipython-%{version}
 
@@ -179,13 +170,6 @@
 %python_clone -a %{buildroot}%{_bindir}/ipython
 %python_clone -a %{buildroot}%{_bindir}/ipython3
 
-%if %{with iptest}
-%python_clone -a %{buildroot}%{_bindir}/iptest
-%python_clone -a %{buildroot}%{_bindir}/iptest3
-%else
-rm %{buildroot}%{_bindir}/iptest*
-%endif
-
 # must clone after copy
 cp %{buildroot}%{_mandir}/man1/ipython{,3}.1
 %python_clone -a %{buildroot}%{_mandir}/man1/ipython.1
@@ -227,38 +211,24 @@
 
 %if %{with test}
 %check
-export LANG="en_US.UTF-8"
-mkdir tester
-pushd tester
-%python_expand iptest-%{$python_bin_suffix}
-popd
+export PYTHONPATH=$(pwd)
+%pytest
 %endif
 
 %if !%{with test}
-
 %pre
 # If libalternatives is used: Removing old update-alternatives entries.
 %python_libalternatives_reset_alternative ipython
 
-%pre iptest
-# If libalternatives is used: Removing old update-alternatives entries.
-%python_libalternatives_reset_alternative iptest
-
 %post
 %python_install_alternative ipython ipython3 ipython.1.gz ipython3.1.gz
 %desktop_database_post
 %icon_theme_cache_post
 
-%post iptest
-%python_install_alternative iptest iptest3
-
 %postun
 %python_uninstall_alternative ipython
 %desktop_database_postun
 %icon_theme_cache_postun
-
-%postun iptest
-%python_uninstall_alternative iptest
 %endif
 
 %if !%{with test}
@@ -278,11 +248,6 @@
 %{_datadir}/icons/hicolor/*x*/apps/IPythonNotebook-%{python_bin_suffix}.png
 %endif
 
-%if %{with iptest}
-%files %{python_files iptest}
-%python_alternative %{_bindir}/iptest
-%python_alternative %{_bindir}/iptest3
-%endif
 %endif
 
 %changelog


++++++ ipython-7.30.1.tar.gz -> ipython-8.0.1.tar.gz ++++++
++++ 35469 lines of diff (skipped)

++++++ ipython-pr13282-py310-inspect.patch ++++++
--- /var/tmp/diff_new_pack.CMSdUP/_old  2022-01-22 08:18:16.098869732 +0100
+++ /var/tmp/diff_new_pack.CMSdUP/_new  2022-01-22 08:18:16.102869705 +0100
@@ -6,14 +6,23 @@
 
 https://bugs.python.org/issue44648 (Python 3.10+)
 ---
- IPython/core/oinspect.py | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
+ IPython/core/oinspect.py             |    4 ++--
+ IPython/core/tests/test_completer.py |   20 +++++++++++++++-----
+ IPython/lib/tests/test_pretty.py     |    1 -
+ 3 files changed, 17 insertions(+), 8 deletions(-)
 
-Index: ipython-7.30.1/IPython/core/oinspect.py
-===================================================================
---- ipython-7.30.1.orig/IPython/core/oinspect.py
-+++ ipython-7.30.1/IPython/core/oinspect.py
-@@ -305,13 +305,13 @@ def find_file(obj) -> str:
+--- a/IPython/core/oinspect.py
++++ b/IPython/core/oinspect.py
+@@ -224,7 +224,7 @@ def format_argspec(argspec):
+ 
+     DEPRECATED (since 7.10): Do not use; will be removed in future versions.
+     """
+-    
++
+     warnings.warn('`format_argspec` function is deprecated as of IPython 7.10'
+                   'and will be removed in future versions.', 
DeprecationWarning, stacklevel=2)
+ 
+@@ -309,7 +309,7 @@ def find_file(obj) -> str:
      fname = None
      try:
          fname = inspect.getabsfile(obj)
@@ -21,93 +30,12 @@
 +    except (OSError, TypeError):
          # For an instance, the file that matters is where its class was
          # declared.
-         if hasattr(obj, '__class__'):
-             try:
-                 fname = inspect.getabsfile(obj.__class__)
--            except TypeError:
-+            except (OSError, TypeError):
-                 # Can happen for builtins
-                 pass
-     except:
-Index: ipython-7.30.1/IPython/core/tests/test_magic_arguments.py
-===================================================================
---- ipython-7.30.1.orig/IPython/core/tests/test_magic_arguments.py
-+++ ipython-7.30.1/IPython/core/tests/test_magic_arguments.py
-@@ -7,6 +7,7 @@
- #-----------------------------------------------------------------------------
- 
- import argparse
-+import sys
- from nose.tools import assert_equal
- 
- from IPython.core.magic_arguments import (argument, argument_group, kwds,
-@@ -74,7 +75,12 @@ def foo(self, args):
- 
- 
- def test_magic_arguments():
--    assert_equal(magic_foo1.__doc__, '::\n\n  %foo1 [-f FOO]\n\n A 
docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an argument\n')
-+    # ???optional arguments??? was replaced with ???options??? in argparse 
help
-+    # https://docs.python.org/3/whatsnew/3.10.html#argparse
-+    # https://bugs.python.org/issue9694
-+    options = "optional arguments" if sys.version_info < (3, 10) else 
"options"
-+
-+    assert_equal(magic_foo1.__doc__, f"::\n\n  %foo1 [-f FOO]\n\n A 
docstring.\n\n{options}:\n  -f FOO, --foo FOO  an argument\n")
-     assert_equal(getattr(magic_foo1, 'argcmd_name', None), None)
-     assert_equal(real_name(magic_foo1), 'foo1')
-     assert_equal(magic_foo1(None, ''), argparse.Namespace(foo=None))
-@@ -86,32 +92,32 @@ def test_magic_arguments():
-     assert_equal(magic_foo2(None, ''), argparse.Namespace())
-     assert hasattr(magic_foo2, 'has_arguments')
- 
--    assert_equal(magic_foo3.__doc__, '::\n\n  %foo3 [-f FOO] [-b BAR] [-z 
BAZ]\n\n A docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an 
argument\n\nGroup:\n  -b BAR, --bar BAR  a grouped argument\n\nSecond Group:\n  
-z BAZ, --baz BAZ  another grouped argument\n')
-+    assert_equal(magic_foo3.__doc__, f"::\n\n  %foo3 [-f FOO] [-b BAR] [-z 
BAZ]\n\n A docstring.\n\n{options}:\n  -f FOO, --foo FOO  an 
argument\n\nGroup:\n  -b BAR, --bar BAR  a grouped argument\n\nSecond Group:\n  
-z BAZ, --baz BAZ  another grouped argument\n")
-     assert_equal(getattr(magic_foo3, 'argcmd_name', None), None)
-     assert_equal(real_name(magic_foo3), 'foo3')
-     assert_equal(magic_foo3(None, ''),
-                        argparse.Namespace(bar=None, baz=None, foo=None))
-     assert hasattr(magic_foo3, 'has_arguments')
- 
--    assert_equal(magic_foo4.__doc__, '::\n\n  %foo4 [-f FOO]\n\n A 
docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an argument\n')
-+    assert_equal(magic_foo4.__doc__, f"::\n\n  %foo4 [-f FOO]\n\n A 
docstring.\n\n{options}:\n  -f FOO, --foo FOO  an argument\n")
-     assert_equal(getattr(magic_foo4, 'argcmd_name', None), None)
-     assert_equal(real_name(magic_foo4), 'foo4')
-     assert_equal(magic_foo4(None, ''), argparse.Namespace())
-     assert hasattr(magic_foo4, 'has_arguments')
- 
--    assert_equal(magic_foo5.__doc__, '::\n\n  %frobnicate [-f FOO]\n\n A 
docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an argument\n')
-+    assert_equal(magic_foo5.__doc__, f"::\n\n  %frobnicate [-f FOO]\n\n A 
docstring.\n\n{options}:\n  -f FOO, --foo FOO  an argument\n")
-     assert_equal(getattr(magic_foo5, 'argcmd_name', None), 'frobnicate')
-     assert_equal(real_name(magic_foo5), 'frobnicate')
-     assert_equal(magic_foo5(None, ''), argparse.Namespace(foo=None))
-     assert hasattr(magic_foo5, 'has_arguments')
- 
--    assert_equal(magic_magic_foo.__doc__, '::\n\n  %magic_foo [-f FOO]\n\n A 
docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an argument\n')
-+    assert_equal(magic_magic_foo.__doc__, f"::\n\n  %magic_foo [-f FOO]\n\n A 
docstring.\n\n{options}:\n  -f FOO, --foo FOO  an argument\n")
-     assert_equal(getattr(magic_magic_foo, 'argcmd_name', None), None)
-     assert_equal(real_name(magic_magic_foo), 'magic_foo')
-     assert_equal(magic_magic_foo(None, ''), argparse.Namespace(foo=None))
-     assert hasattr(magic_magic_foo, 'has_arguments')
- 
--    assert_equal(foo.__doc__, '::\n\n  %foo [-f FOO]\n\n A 
docstring.\n\noptional arguments:\n  -f FOO, --foo FOO  an argument\n')
-+    assert_equal(foo.__doc__, f"::\n\n  %foo [-f FOO]\n\n A 
docstring.\n\n{options}:\n  -f FOO, --foo FOO  an argument\n")
-     assert_equal(getattr(foo, 'argcmd_name', None), None)
-     assert_equal(real_name(foo), 'foo')
-     assert_equal(foo(None, ''), argparse.Namespace(foo=None))
-Index: ipython-7.30.1/IPython/core/tests/test_completer.py
-===================================================================
---- ipython-7.30.1.orig/IPython/core/tests/test_completer.py
-+++ ipython-7.30.1/IPython/core/tests/test_completer.py
-@@ -12,6 +12,7 @@ import unittest
- from contextlib import contextmanager
- 
- import nose.tools as nt
-+import pytest
- 
- from traitlets.config.loader import Config
- from IPython import get_ipython
-@@ -29,6 +30,15 @@ from IPython.core.completer import (
+         try:
+--- a/IPython/core/tests/test_completer.py
++++ b/IPython/core/tests/test_completer.py
+@@ -26,6 +26,15 @@ from IPython.core.completer import (
+     _deduplicate_completions,
  )
- from nose.tools import assert_in, assert_not_in
  
 +if sys.version_info >= (3, 10):
 +    import jedi
@@ -121,16 +49,16 @@
  # 
-----------------------------------------------------------------------------
  # Test functions
  # 
-----------------------------------------------------------------------------
-@@ -381,6 +391,8 @@ class TestCompleter(unittest.TestCase):
-                 matches = c.all_completions("TestCl")
-                 assert matches == ['TestClass'], jedi_status
-                 matches = c.all_completions("TestClass.")
-+                if jedi_status and jedi_issue:
-+                    continue
-                 assert len(matches) > 2, jedi_status
-                 matches = c.all_completions("TestClass.a")
-                 assert matches == ['TestClass.a', 'TestClass.a1'], jedi_status
-@@ -435,6 +447,7 @@ class TestCompleter(unittest.TestCase):
+@@ -94,7 +103,7 @@ def test_unicode_range():
+         """
+     assert len_exp == len_test, message
+ 
+-    # fail if new unicode symbols have been added. 
++    # fail if new unicode symbols have been added.
+     assert len_exp <= 138552, message
+ 
+ 
+@@ -475,6 +484,7 @@ class TestCompleter(unittest.TestCase):
              "encoding" in c.signature
          ), "Signature of function was not found by completer"
  
@@ -138,40 +66,45 @@
      def test_deduplicate_completions(self):
          """
          Test that completions are correctly deduplicated (even if ranges are 
not the same)
-Index: ipython-7.30.1/IPython/lib/tests/test_pretty.py
-===================================================================
---- ipython-7.30.1.orig/IPython/lib/tests/test_pretty.py
-+++ ipython-7.30.1/IPython/lib/tests/test_pretty.py
-@@ -7,14 +7,15 @@
+@@ -500,10 +510,10 @@ class TestCompleter(unittest.TestCase):
  
- from collections import Counter, defaultdict, deque, OrderedDict
- import os
-+import pytest
- import types
- import string
-+import sys
- import unittest
+     def test_greedy_completions(self):
+         """
+-        Test the capability of the Greedy completer. 
++        Test the capability of the Greedy completer.
  
- import nose.tools as nt
+         Most of the test here does not really show off the greedy completer, 
for proof
+-        each of the text below now pass with Jedi. The greedy completer is 
capable of more. 
++        each of the text below now pass with Jedi. The greedy completer is 
capable of more.
  
- from IPython.lib import pretty
--from IPython.testing.decorators import skip_without
+         See the :any:`test_dict_key_completion_contexts`
  
- from io import StringIO
+@@ -611,7 +621,7 @@ class TestCompleter(unittest.TestCase):
  
-@@ -118,12 +119,12 @@ def test_sets():
-         yield nt.assert_equal, got_output, expected_output
+     def test_limit_to__all__False_ok(self):
+         """
+-        Limit to all is deprecated, once we remove it this test can go away. 
++        Limit to all is deprecated, once we remove it this test can go away.
+         """
+         ip = get_ipython()
+         c = ip.Completer
+@@ -838,7 +848,7 @@ class TestCompleter(unittest.TestCase):
+         does return what expected, and does not crash.
+         """
+         delims = " \t\n`!@#$^&*()=+[{]}\\|;:'\",<>?"
+-        
++
+         keys = [("foo", "bar"), ("foo", "oof"), ("foo", b"bar"), ('other', 
'test')]
  
+         # Completion on first key == "foo"
+--- a/IPython/lib/tests/test_pretty.py
++++ b/IPython/lib/tests/test_pretty.py
+@@ -7,7 +7,6 @@
  
--@skip_without('xxlimited')
- def test_pprint_heap_allocated_type():
-     """
-     Test that pprint works for heap allocated types.
-     """
--    import xxlimited
-+    module_name = "xxlimited" if sys.version_info < (3, 10) else 
"xxlimited_35"
-+    xxlimited = pytest.importorskip(module_name)
-     output = pretty.pretty(xxlimited.Null)
-     nt.assert_equal(output, 'xxlimited.Null')
- 
+ from collections import Counter, defaultdict, deque, OrderedDict, UserList
+ import os
+-import pytest
+ import types
+ import string
+ import sys
 

++++++ ipython-pr13371-py310-oserror.patch ++++++
--- /var/tmp/diff_new_pack.CMSdUP/_old  2022-01-22 08:18:16.114869624 +0100
+++ /var/tmp/diff_new_pack.CMSdUP/_new  2022-01-22 08:18:16.114869624 +0100
@@ -4,32 +4,13 @@
 Subject: [PATCH 1/2] Everything is an object and has a `__class__` in Python 3
 
 ---
- IPython/core/oinspect.py | 27 +++++++++++----------------
- 1 file changed, 11 insertions(+), 16 deletions(-)
+ IPython/core/oinspect.py            |    2 +-
+ IPython/core/tests/test_oinspect.py |    6 +++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
 
-Index: ipython-7.30.1/IPython/core/oinspect.py
-===================================================================
---- ipython-7.30.1.orig/IPython/core/oinspect.py
-+++ ipython-7.30.1/IPython/core/oinspect.py
-@@ -182,11 +182,12 @@ def getsource(obj, oname='') -> Union[st
-         except TypeError:
-             # The object itself provided no meaningful source, try looking for
-             # its class definition instead.
--            if hasattr(obj, '__class__'):
--                try:
--                    src = inspect.getsource(obj.__class__)
--                except TypeError:
--                    return None
-+            try:
-+                src = inspect.getsource(obj.__class__)
-+            except (OSError, TypeError):
-+                return None
-+        except OSError:
-+            return None
- 
-         return src
- 
-@@ -305,17 +306,17 @@ def find_file(obj) -> str:
+--- a/IPython/core/oinspect.py
++++ b/IPython/core/oinspect.py
+@@ -309,7 +309,7 @@ def find_file(obj) -> str:
      fname = None
      try:
          fname = inspect.getabsfile(obj)
@@ -37,67 +18,11 @@
 +    except TypeError:
          # For an instance, the file that matters is where its class was
          # declared.
--        if hasattr(obj, '__class__'):
--            try:
--                fname = inspect.getabsfile(obj.__class__)
--            except (OSError, TypeError):
--                # Can happen for builtins
--                pass
--    except:
-+        try:
-+            fname = inspect.getabsfile(obj.__class__)
-+        except (OSError, TypeError):
-+            # Can happen for builtins
-+            pass
-+    except OSError:
-         pass
-+
-     return cast_unicode(fname)
- 
- 
-@@ -338,15 +339,14 @@ def find_source_lines(obj):
-     obj = _get_wrapped(obj)
- 
-     try:
-+        lineno = inspect.getsourcelines(obj)[1]
-+    except TypeError:
-+        # For instances, try the class object like getsource() does
          try:
--            lineno = inspect.getsourcelines(obj)[1]
--        except TypeError:
--            # For instances, try the class object like getsource() does
--            if hasattr(obj, '__class__'):
--                lineno = inspect.getsourcelines(obj.__class__)[1]
--            else:
--                lineno = None
--    except:
-+            lineno = inspect.getsourcelines(obj.__class__)[1]
-+        except (OSError, TypeError):
-+            return None
-+    except OSError:
-         return None
- 
-     return lineno
-Index: ipython-7.30.1/IPython/core/tests/test_oinspect.py
-===================================================================
---- ipython-7.30.1.orig/IPython/core/tests/test_oinspect.py
-+++ ipython-7.30.1/IPython/core/tests/test_oinspect.py
-@@ -6,10 +6,11 @@
- 
- 
- from inspect import signature, Signature, Parameter
-+import inspect
- import os
-+import pytest
- import re
--
--import nose.tools as nt
-+import sys
- 
- from .. import oinspect
- 
-@@ -30,6 +31,10 @@ def setup_module():
-     inspector = oinspect.Inspector()
+--- a/IPython/core/tests/test_oinspect.py
++++ b/IPython/core/tests/test_oinspect.py
+@@ -35,6 +35,10 @@ class SourceModuleMainTest:
+     __module__ = "__main__"
  
  
 +class SourceModuleMainTest:
@@ -107,338 +32,13 @@
  #-----------------------------------------------------------------------------
  # Local utilities
  #-----------------------------------------------------------------------------
-@@ -38,15 +43,28 @@ def setup_module():
+@@ -43,7 +47,7 @@ class SourceModuleMainTest:
  # defined, if any code is inserted above, the following line will need to be
  # updated.  Do NOT insert any whitespace between the next line and the 
function
  # definition below.
--THIS_LINE_NUMBER = 41  # Put here the actual number of this line
-+THIS_LINE_NUMBER = 46  # Put here the actual number of this line
-+
- 
--from unittest import TestCase
-+def test_find_source_lines():
-+    assert oinspect.find_source_lines(test_find_source_lines) == 
THIS_LINE_NUMBER + 3
-+    assert oinspect.find_source_lines(type) is None
-+    assert oinspect.find_source_lines(SourceModuleMainTest) is None
-+    assert oinspect.find_source_lines(SourceModuleMainTest()) is None
- 
--class Test(TestCase):
- 
--    def test_find_source_lines(self):
--        
self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
--                    THIS_LINE_NUMBER+6)
-+def test_getsource():
-+    assert oinspect.getsource(type) is None
-+    assert oinspect.getsource(SourceModuleMainTest) is None
-+    assert oinspect.getsource(SourceModuleMainTest()) is None
-+
-+
-+def test_inspect_getfile_raises_exception():
-+    """Check oinspect.find_file/getsource/find_source_lines expectations"""
-+    with pytest.raises(TypeError):
-+        inspect.getfile(type)
-+    with pytest.raises(OSError if sys.version_info >= (3, 10) else TypeError):
-+        inspect.getfile(SourceModuleMainTest)
- 
- 
- # A couple of utilities to ensure these tests work the same from a source or a
-@@ -56,11 +74,14 @@ def pyfile(fname):
- 
- 
- def match_pyfiles(f1, f2):
--    nt.assert_equal(pyfile(f1), pyfile(f2))
-+    assert pyfile(f1) == pyfile(f2)
- 
- 
- def test_find_file():
-     match_pyfiles(oinspect.find_file(test_find_file), 
os.path.abspath(__file__))
-+    assert oinspect.find_file(type) is None
-+    assert oinspect.find_file(SourceModuleMainTest) is None
-+    assert oinspect.find_file(SourceModuleMainTest()) is None
- 
- 
- def test_find_file_decorated1():
-@@ -74,9 +95,9 @@ def test_find_file_decorated1():
-     @noop1
-     def f(x):
-         "My docstring"
--    
-+
-     match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
--    nt.assert_equal(f.__doc__, "My docstring")
-+    assert f.__doc__ == "My docstring"
- 
- 
- def test_find_file_decorated2():
-@@ -90,14 +111,14 @@ def test_find_file_decorated2():
-     @noop2
-     def f(x):
-         "My docstring 2"
--    
-+
-     match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
--    nt.assert_equal(f.__doc__, "My docstring 2")
--    
-+    assert f.__doc__ == "My docstring 2"
-+
- 
- def test_find_file_magic():
-     run = ip.find_line_magic('run')
--    nt.assert_not_equal(oinspect.find_file(run), None)
-+    assert oinspect.find_file(run) is not None
- 
- 
- # A few generic objects we can then inspect in the tests below
-@@ -167,41 +188,46 @@ class SerialLiar(object):
- 
- def test_info():
-     "Check that Inspector.info fills out various fields as expected."
--    i = inspector.info(Call, oname='Call')
--    nt.assert_equal(i['type_name'], 'type')
--    expted_class = str(type(type))  # <class 'type'> (Python 3) or <type 
'type'>
--    nt.assert_equal(i['base_class'], expted_class)
--    nt.assert_regex(i['string_form'], "<class 
'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>")
-+    i = inspector.info(Call, oname="Call")
-+    assert i["type_name"] == "type"
-+    expected_class = str(type(type))  # <class 'type'> (Python 3) or <type 
'type'>
-+    assert i["base_class"] == expected_class
-+    assert re.search(
-+        "<class 'IPython.core.tests.test_oinspect.Call'( at 
0x[0-9a-f]{1,9})?>",
-+        i["string_form"],
-+    )
-     fname = __file__
-     if fname.endswith(".pyc"):
-         fname = fname[:-1]
-     # case-insensitive comparison needed on some filesystems
-     # e.g. Windows:
--    nt.assert_equal(i['file'].lower(), compress_user(fname).lower())
--    nt.assert_equal(i['definition'], None)
--    nt.assert_equal(i['docstring'], Call.__doc__)
--    nt.assert_equal(i['source'], None)
--    nt.assert_true(i['isclass'])
--    nt.assert_equal(i['init_definition'], "Call(x, y=1)")
--    nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
-+    assert i["file"].lower() == compress_user(fname).lower()
-+    assert i["definition"] == None
-+    assert i["docstring"] == Call.__doc__
-+    assert i["source"] == None
-+    assert i["isclass"] is True
-+    assert i["init_definition"] == "Call(x, y=1)"
-+    assert i["init_docstring"] == Call.__init__.__doc__
- 
-     i = inspector.info(Call, detail_level=1)
--    nt.assert_not_equal(i['source'], None)
--    nt.assert_equal(i['docstring'], None)
-+    assert i["source"] is not None
-+    assert i["docstring"] == None
- 
-     c = Call(1)
-     c.__doc__ = "Modified instance docstring"
-     i = inspector.info(c)
--    nt.assert_equal(i['type_name'], 'Call')
--    nt.assert_equal(i['docstring'], "Modified instance docstring")
--    nt.assert_equal(i['class_docstring'], Call.__doc__)
--    nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
--    nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
-+    assert i["type_name"] == "Call"
-+    assert i["docstring"] == "Modified instance docstring"
-+    assert i["class_docstring"] == Call.__doc__
-+    assert i["init_docstring"] == Call.__init__.__doc__
-+    assert i["call_docstring"] == Call.__call__.__doc__
-+
- 
- def test_class_signature():
--    info = inspector.info(HasSignature, 'HasSignature')
--    nt.assert_equal(info['init_definition'], "HasSignature(test)")
--    nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__)
-+    info = inspector.info(HasSignature, "HasSignature")
-+    assert info["init_definition"] == "HasSignature(test)"
-+    assert info["init_docstring"] == HasSignature.__init__.__doc__
-+
- 
- def test_info_awkward():
-     # Just test that this doesn't throw an error.
-@@ -216,7 +242,7 @@ def test_info_serialliar():
- 
-     # Nested attribute access should be cut off at 100 levels deep to avoid
-     # infinite loops: https://github.com/ipython/ipython/issues/9122
--    nt.assert_less(fib_tracker[0], 9000)
-+    assert fib_tracker[0] < 9000
- 
- def support_function_one(x, y=2, *a, **kw):
-     """A simple function."""
-@@ -225,14 +251,16 @@ def test_calldef_none():
-     # We should ignore __call__ for all of these.
-     for obj in [support_function_one, SimpleClass().method, any, str.upper]:
-         i = inspector.info(obj)
--        nt.assert_is(i['call_def'], None)
-+        assert i["call_def"] is None
-+
- 
- def f_kwarg(pos, *, kwonly):
-     pass
- 
- def test_definition_kwonlyargs():
--    i = inspector.info(f_kwarg, oname='f_kwarg')  # analysis:ignore
--    nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
-+    i = inspector.info(f_kwarg, oname="f_kwarg")  # analysis:ignore
-+    assert i["definition"] == "f_kwarg(pos, *, kwonly)"
-+
- 
- def test_getdoc():
-     class A(object):
-@@ -243,34 +271,33 @@ def test_getdoc():
-         """standard docstring"""
-         def getdoc(self):
-             return "custom docstring"
--    
-+
-     class C(object):
-         """standard docstring"""
-         def getdoc(self):
-             return None
--    
-+
-     a = A()
-     b = B()
-     c = C()
--    
--    nt.assert_equal(oinspect.getdoc(a), "standard docstring")
--    nt.assert_equal(oinspect.getdoc(b), "custom docstring")
--    nt.assert_equal(oinspect.getdoc(c), "standard docstring")
-+
-+    assert oinspect.getdoc(a) == "standard docstring"
-+    assert oinspect.getdoc(b) == "custom docstring"
-+    assert oinspect.getdoc(c) == "standard docstring"
- 
- 
- def test_empty_property_has_no_source():
-     i = inspector.info(property(), detail_level=1)
--    nt.assert_is(i['source'], None)
-+    assert i["source"] is None
- 
- 
- def test_property_sources():
--    import posixpath 
-     # A simple adder whose source and signature stays
-     # the same across Python distributions
-     def simple_add(a, b):
-         "Adds two numbers"
-         return a + b
--    
-+
-     class A(object):
-         @property
-         def foo(self):
-@@ -278,18 +305,18 @@ def test_property_sources():
- 
-         foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
- 
--        dname = property(posixpath.dirname)
--        adder = property(simple_add) 
-+        dname = property(oinspect.getdoc)
-+        adder = property(simple_add)
- 
-     i = inspector.info(A.foo, detail_level=1)
--    nt.assert_in('def foo(self):', i['source'])
--    nt.assert_in('lambda self, v:', i['source'])
-+    assert "def foo(self):" in i["source"]
-+    assert "lambda self, v:" in i["source"]
- 
-     i = inspector.info(A.dname, detail_level=1)
--    nt.assert_in('def dirname(p)', i['source'])
--    
-+    assert "def getdoc(obj)" in i["source"]
-+
-     i = inspector.info(A.adder, detail_level=1)
--    nt.assert_in('def simple_add(a, b)', i['source'])
-+    assert "def simple_add(a, b)" in i["source"]
- 
- 
- def test_property_docstring_is_in_info_for_detail_level_0():
-@@ -299,15 +326,17 @@ def test_property_docstring_is_in_info_f
-             """This is `foobar` property."""
-             pass
- 
--    ip.user_ns['a_obj'] = A()
--    nt.assert_equal(
--        'This is `foobar` property.',
--        ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
--
--    ip.user_ns['a_cls'] = A
--    nt.assert_equal(
--        'This is `foobar` property.',
--        ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
-+    ip.user_ns["a_obj"] = A()
-+    assert (
-+        "This is `foobar` property."
-+        == ip.object_inspect("a_obj.foobar", detail_level=0)["docstring"]
-+    )
-+
-+    ip.user_ns["a_cls"] = A
-+    assert (
-+        "This is `foobar` property."
-+        == ip.object_inspect("a_cls.foobar", detail_level=0)["docstring"]
-+    )
- 
- 
- def test_pdef():
-@@ -359,11 +388,11 @@ def test_pinfo_docstring_if_detail_and_n
-                   def bar(self):
-                       """ This is a docstring for Foo.bar """
-                       pass
--              ''' 
--    
-+              '''
-+
-     ip.run_cell(obj_def)
-     ip.run_cell('foo = Foo()')
--    
-+
-     with AssertNotPrints("Source:"):
-         with AssertPrints('Docstring:'):
-             ip._inspect('pinfo', 'foo', detail_level=0)
-@@ -388,14 +417,14 @@ def test_pinfo_magic():
- def test_init_colors():
-     # ensure colors are not present in signature info
-     info = inspector.info(HasSignature)
--    init_def = info['init_definition']
--    nt.assert_not_in('[0m', init_def)
-+    init_def = info["init_definition"]
-+    assert "[0m" not in init_def
- 
- 
- def test_builtin_init():
-     info = inspector.info(list)
-     init_def = info['init_definition']
--    nt.assert_is_not_none(init_def)
-+    assert init_def is not None
- 
- 
- def test_render_signature_short():
-@@ -404,7 +433,7 @@ def test_render_signature_short():
-         signature(short_fun),
-         short_fun.__name__,
-     )
--    nt.assert_equal(sig, 'short_fun(a=1)')
-+    assert sig == "short_fun(a=1)"
+-THIS_LINE_NUMBER = 46  # Put here the actual number of this line
++THIS_LINE_NUMBER = 50  # Put here the actual number of this line
  
  
- def test_render_signature_long():
-@@ -420,7 +449,7 @@ def test_render_signature_long():
-         signature(long_function),
-         long_function.__name__,
-     )
--    nt.assert_in(sig, [
-+    assert sig in [
-         # Python >=3.9
-         '''\
- long_function(
-@@ -444,4 +473,4 @@ long_function(
-     let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
- ) -> bool\
- ''',
--    ])
-+    ]
-\ No newline at end of file
+ def test_find_source_lines():
 

++++++ skip-network-test.patch ++++++
---
 IPython/core/display.py |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/IPython/core/display.py
+++ b/IPython/core/display.py
@@ -879,7 +879,7 @@ class Image(DisplayObject):
         a URL, or a filename from which to load image data.
         The result is always embedding image data for inline images.
 
-        >>> Image('http://www.google.fr/images/srpr/logo3w.png')
+        >>> Image('http://www.google.fr/images/srpr/logo3w.png')  # doctest: 
+SKIP
         <IPython.core.display.Image object>
 
         >>> Image('/path/to/image.jpg')

Reply via email to