Accepting request 947675 from devel:languages:python:jupyter
- 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 - Update requirements. - Requires the full stdlib including sqlite3 - Revert some spec-cleaner edits - 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). OBS-URL: https://build.opensuse.org/request/show/947675 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-ipython?expand=0&rev=26
This commit is contained in:
commit
19fe6222ca
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cb6aef731bf708a7727ab6cde8df87f0281b1427d41e65d62d4b68934fa54e97
|
||||
size 5154336
|
3
ipython-8.0.1.tar.gz
Normal file
3
ipython-8.0.1.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ab564d4521ea8ceaac26c3a2c6e5ddbca15c8848fd5a5cc325f960da88d42974
|
||||
size 5306811
|
@ -6,14 +6,23 @@ Subject: [PATCH 1/5] Handle changed exception type from inspect.getabsfile
|
||||
|
||||
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 @@ Index: ipython-7.30.1/IPython/core/oinspect.py
|
||||
+ 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 @@ Index: ipython-7.30.1/IPython/core/tests/test_completer.py
|
||||
# -----------------------------------------------------------------------------
|
||||
# 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,39 +66,44 @@ Index: ipython-7.30.1/IPython/core/tests/test_completer.py
|
||||
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
|
||||
def test_greedy_completions(self):
|
||||
"""
|
||||
- Test the capability of the Greedy completer.
|
||||
+ Test the capability of the Greedy completer.
|
||||
|
||||
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.
|
||||
|
||||
See the :any:`test_dict_key_completion_contexts`
|
||||
|
||||
@@ -611,7 +621,7 @@ class TestCompleter(unittest.TestCase):
|
||||
|
||||
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 @@
|
||||
|
||||
from collections import Counter, defaultdict, deque, OrderedDict, UserList
|
||||
import os
|
||||
+import pytest
|
||||
-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')
|
||||
|
||||
import sys
|
||||
|
@ -4,32 +4,13 @@ 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(-)
|
||||
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 @@ Index: ipython-7.30.1/IPython/core/oinspect.py
|
||||
+ 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,337 +32,12 @@ Index: ipython-7.30.1/IPython/core/tests/test_oinspect.py
|
||||
#-----------------------------------------------------------------------------
|
||||
# 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)
|
||||
-THIS_LINE_NUMBER = 46 # Put here the actual number of this line
|
||||
+THIS_LINE_NUMBER = 50 # Put here the actual number of this line
|
||||
|
||||
|
||||
# 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)"
|
||||
|
||||
|
||||
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():
|
||||
|
@ -1,3 +1,65 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 20 10:19:48 UTC 2022 - Ben Greiner <code@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 <code@bnavigator.de>
|
||||
|
||||
- Update requirements.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Jan 15 15:40:59 UTC 2022 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- Requires the full stdlib including sqlite3
|
||||
- Revert some spec-cleaner edits
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 14 18:19:27 UTC 2022 - Matej Cepl <mcepl@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).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Dec 20 18:35:45 UTC 2021 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
|
@ -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 @@ Source1: https://raw.githubusercontent.com/jupyter/qtconsole/4.0.0/qtcons
|
||||
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 mcepl@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 @@ Provides: python-jupyter_ipython-doc-pdf = %{version}
|
||||
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 @@ following main features:
|
||||
* 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 @@ popd
|
||||
%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 @@ $python -O -m compileall -d %{$python_sitelib} %{buildroot}%{$python_sitelib}/IP
|
||||
|
||||
%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 @@ popd
|
||||
%{_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
|
||||
|
15
skip-network-test.patch
Normal file
15
skip-network-test.patch
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
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')
|
Loading…
Reference in New Issue
Block a user