diff --git a/ipython-7.29.0.tar.gz b/ipython-7.29.0.tar.gz deleted file mode 100644 index 88b73df..0000000 --- a/ipython-7.29.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f69d7423a5a1972f6347ff233e38bbf4df6a150ef20fbb00c635442ac3060aa -size 5151803 diff --git a/ipython-7.30.1.tar.gz b/ipython-7.30.1.tar.gz new file mode 100644 index 0000000..4eb4559 --- /dev/null +++ b/ipython-7.30.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb6aef731bf708a7727ab6cde8df87f0281b1427d41e65d62d4b68934fa54e97 +size 5154336 diff --git a/ipython-pr13282-py310-inspect.patch b/ipython-pr13282-py310-inspect.patch new file mode 100644 index 0000000..0eae2ba --- /dev/null +++ b/ipython-pr13282-py310-inspect.patch @@ -0,0 +1,176 @@ +From fc57ec912eec9da4c33d8db5416fdb2dada706e7 Mon Sep 17 00:00:00 2001 +From: Nikita Kniazev +Date: Mon, 1 Nov 2021 19:09:58 +0300 +Subject: [PATCH 1/5] Handle changed exception type from inspect.getabsfile + (bpo-44648) + +https://bugs.python.org/issue44648 (Python 3.10+) +--- + IPython/core/oinspect.py | 4 ++-- + 1 file changed, 2 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 +@@ -305,13 +305,13 @@ def find_file(obj) -> str: + fname = None + try: + fname = inspect.getabsfile(obj) +- except TypeError: ++ 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 ( + ) + from nose.tools import assert_in, assert_not_in + ++if sys.version_info >= (3, 10): ++ import jedi ++ from pkg_resources import parse_version ++ ++ # Requires https://github.com/davidhalter/jedi/pull/1795 ++ jedi_issue = parse_version(jedi.__version__) <= parse_version("0.18.0") ++else: ++ jedi_issue = False ++ + # ----------------------------------------------------------------------------- + # 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): + "encoding" in c.signature + ), "Signature of function was not found by completer" + ++ @pytest.mark.xfail(jedi_issue, reason="Known failure on jedi<=0.18.0") + 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 @@ + + from collections import Counter, defaultdict, deque, OrderedDict + import os ++import pytest + 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,12 +119,12 @@ 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 ++ 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') + diff --git a/ipython-pr13371-py310-oserror.patch b/ipython-pr13371-py310-oserror.patch new file mode 100644 index 0000000..30a91d3 --- /dev/null +++ b/ipython-pr13371-py310-oserror.patch @@ -0,0 +1,443 @@ +From aa169302f4acbbcae616154bf54c70167dbd1fd5 Mon Sep 17 00:00:00 2001 +From: Nikita Kniazev +Date: Sat, 4 Dec 2021 19:32:13 +0300 +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(-) + +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: + fname = None + try: + fname = inspect.getabsfile(obj) +- except (OSError, TypeError): ++ 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() + + ++class SourceModuleMainTest: ++ __module__ = "__main__" ++ ++ + #----------------------------------------------------------------------------- + # Local utilities + #----------------------------------------------------------------------------- +@@ -38,15 +43,28 @@ def setup_module(): + # 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)) # (Python 3) or +- nt.assert_equal(i['base_class'], expted_class) +- nt.assert_regex(i['string_form'], "") ++ i = inspector.info(Call, oname="Call") ++ assert i["type_name"] == "type" ++ expected_class = str(type(type)) # (Python 3) or ++ assert i["base_class"] == expected_class ++ assert re.search( ++ "", ++ 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)" + + + 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 diff --git a/python-ipython.changes b/python-ipython.changes index edbeb32..1560979 100644 --- a/python-ipython.changes +++ b/python-ipython.changes @@ -1,3 +1,38 @@ +------------------------------------------------------------------- +Mon Dec 20 18:35:45 UTC 2021 - Ben Greiner + +- Add patches for Python 3.10 + * ipython-pr13282-py310-inspect.patch -- gh#ipython/ipython#13282 + * ipython-pr13371-py310-oserror.patch -- gh#ipython/ipython#13371 + * gh#ipython/ipython#13412 + +------------------------------------------------------------------- +Sun Dec 19 19:24:08 UTC 2021 - Ben Greiner + +- Update to 7.30.1 + * IPython 7.30 fixes a couple of bugs introduce in previous + releases (in particular with respect to path handling), and + introduce a few features and improvements: + * Notably we will highlight PR #13267 “Document that %run can + execute notebooks and ipy scripts.”, which is the first commit + of Fernando Pérez since mid 2016 (IPython 5.1). If you are new + to IPython, Fernando created IPython in 2001. The other most + recent contribution of Fernando to IPython itself was May 2018, + by reviewing and merging PRs. I want to note that Fernando is + still active but mostly as a mentor and leader of the whole + Jupyter organisation, but we’re still happy to see him + contribute code ! + * PR #13290 “Use sphinxify (if available) in object_inspect_mime + path” should allow richer Repr of docstrings when using + jupyterlab inspector. + * PR #13311 make the debugger use ThreadPoolExecutor for debugger + cmdloop. This should fix some issues/infinite loop, but let us + know if you come across any regressions. In particular this + fixes issues with kmaork/madbg, a remote debugger for IPython. + * Note that this is likely the ante-penultimate release of + IPython 7.x as a stable branch, as I hope to release IPython + 8.0 as well as IPython 7.31 next month/early 2022. + ------------------------------------------------------------------- Fri Nov 12 21:30:44 UTC 2021 - Ben Greiner diff --git a/python-ipython.spec b/python-ipython.spec index e799095..43bb5f6 100644 --- a/python-ipython.spec +++ b/python-ipython.spec @@ -30,13 +30,13 @@ %define psuffix %{nil} %bcond_with test %endif -%{?!python_module:%define python_module() python-%{**} python3-%{**}} +%{?!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.29.0 +Version: 7.30.1 Release: 0 Summary: Rich architecture for interactive computing with Python License: BSD-3-Clause @@ -44,6 +44,10 @@ Group: Development/Languages/Python URL: https://github.com/ipython/ipython Source: https://files.pythonhosted.org/packages/source/i/ipython/ipython-%{version}.tar.gz Source1: https://raw.githubusercontent.com/jupyter/qtconsole/4.0.0/qtconsole/resources/icon/JupyterConsole.svg +# PATCH-FIX-UPSTREAM ipython-pr13282-py310-inspect.patch -- gh#ipython/ipython#13282, gh#ipython/ipython#13412 +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} BuildRequires: %{python_module base >= 3.7} BuildRequires: %{python_module setuptools >= 18.5} @@ -83,6 +87,7 @@ BuildArch: noarch %if %{with test} # test requirements are specified in the iptest subpackage below BuildRequires: %{python_module ipython-iptest = %{version}} +BuildRequires: %{python_module testsuite} %endif %if !%{with test} BuildRequires: desktop-file-utils @@ -142,6 +147,9 @@ 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} @@ -150,7 +158,7 @@ This package provides the iptest command, which is used for testing software that uses %{name}. %prep -%setup -q -n ipython-%{version} +%autosetup -p1 -n ipython-%{version} %build %python_build @@ -202,8 +210,8 @@ desktop-file-edit --set-comment="Enhanced interactive Python %{$python_bin_suffi %suse_update_desktop_file -i -r ipython-%{$python_bin_suffix} "System;TerminalEmulator;" } -# These can be run stand-alone, so make them executable rather than removing shebang -%{python_expand find %{buildroot}%{$python_sitelib} -type f -name "*.py" -exec sed -i "s|^#!%{_bindir}/env python$|#!%{__$python}|" {} \; +%{python_expand # These can be run stand-alone, so make them executable rather than removing shebang +find %{buildroot}%{$python_sitelib} -type f -name "*.py" -exec sed -i "s|^#!%{_bindir}/env python$|#!%{__$python}|" {} \; find %{buildroot}%{$python_sitelib} -type f -name "*.py" -exec sed -i "s|^#!%{_bindir}/python$|#!%{__$python}|" {} \; find %{buildroot}%{$python_sitelib} -type f -name "*.py" -exec grep -q "#!%{__$python}" {} \; -exec chmod a+x {} \;