From e112b0035cd98f690ea81cac84e021615beaeddf Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Wed, 4 Aug 2021 13:38:28 +0200
Subject: [PATCH 1/3] Inspect module now returns OSError for objects without
 source files

Fixes https://github.com/ipython/ipython/issues/13079
---
 IPython/core/oinspect.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py
index ab25eeeff..93e91cdfa 100644
--- a/IPython/core/oinspect.py
+++ b/IPython/core/oinspect.py
@@ -311,7 +311,7 @@ def find_file(obj) -> str:
         if hasattr(obj, '__class__'):
             try:
                 fname = inspect.getabsfile(obj.__class__)
-            except TypeError:
+            except (TypeError, OSError):
                 # Can happen for builtins
                 pass
     except:
-- 
2.31.1

From 021c89d63e9445d0f5cc0392aeeb10e02a941008 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Thu, 7 Jan 2021 14:42:34 +0100
Subject: [PATCH 2/3] Update test_magic_arguments for new argparse module

New argparse module uses "options" instead "optional arguments".

https://github.com/python/cpython/commit/41b223d29cdfeb1f222c12c3abaccc3bc128f5e7
---
 IPython/core/tests/test_magic_arguments.py | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/IPython/core/tests/test_magic_arguments.py b/IPython/core/tests/test_magic_arguments.py
index 5dea32dd8..ae3fa26a6 100644
--- a/IPython/core/tests/test_magic_arguments.py
+++ b/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,9 @@ 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 = "optional arguments:" if sys.version_info < (3, 10, 0) else "options:"
+
+    assert_equal(magic_foo1.__doc__, f'::\n\n  %foo1 [-f FOO]\n\n A docstring.\n\n{optional}\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 +89,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{optional}\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{optional}\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{optional}\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{optional}\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{optional}\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))
-- 
2.31.1

From 99ffda8be9ef1f59fc6d7c9248077f77fa8b97e9 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Thu, 7 Jan 2021 14:43:46 +0100
Subject: [PATCH 3/3] xxlimited module is xxlimited_35 in Python 3.10

---
 IPython/lib/tests/test_pretty.py | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/IPython/lib/tests/test_pretty.py b/IPython/lib/tests/test_pretty.py
index ba4c32966..79c203b5b 100644
--- a/IPython/lib/tests/test_pretty.py
+++ b/IPython/lib/tests/test_pretty.py
@@ -6,15 +6,16 @@
 
 
 from collections import Counter, defaultdict, deque, OrderedDict
+from importlib import import_module
 import os
 import types
 import string
+import sys
 import unittest
 
 import nose.tools as nt
 
 from IPython.lib import pretty
-from IPython.testing.decorators import skip_without
 
 from io import StringIO
 
@@ -118,13 +119,18 @@ def test_sets():
         yield nt.assert_equal, got_output, expected_output
 
 
-@skip_without('xxlimited')
 def test_pprint_heap_allocated_type():
     """
     Test that pprint works for heap allocated types.
     """
-    import xxlimited
-    output = pretty.pretty(xxlimited.Null)
+    module_name = "xxlimited" if sys.version_info < (3, 10, 0) else "xxlimited_35"
+    try:
+        module = import_module(module_name)
+    except ImportError:
+        pytest.skip(f"Module {module_name} is not available.")
+
+    output = pretty.pretty(getattr(module, "Null"))
+
     nt.assert_equal(output, 'xxlimited.Null')
 
 def test_pprint_nomod():
-- 
2.31.1