first commit

This commit is contained in:
Ayxan
2022-05-23 00:16:32 +04:00
commit d660f2a4ca
24786 changed files with 4428337 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,85 @@
"""Tests for pylab tools module.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2011, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Stdlib imports
import time
# Our own imports
from IPython.lib import backgroundjobs as bg
#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
t_short = 0.0001 # very short interval to wait on jobs
#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------
def sleeper(interval=t_short, *a, **kw):
args = dict(interval=interval,
other_args=a,
kw_args=kw)
time.sleep(interval)
return args
def crasher(interval=t_short, *a, **kw):
time.sleep(interval)
raise Exception("Dead job with interval %s" % interval)
#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
def test_result():
"""Test job submission and result retrieval"""
jobs = bg.BackgroundJobManager()
j = jobs.new(sleeper)
j.join()
assert j.result["interval"] == t_short
def test_flush():
"""Test job control"""
jobs = bg.BackgroundJobManager()
j = jobs.new(sleeper)
j.join()
assert len(jobs.completed) == 1
assert len(jobs.dead) == 0
jobs.flush()
assert len(jobs.completed) == 0
def test_dead():
"""Test control of dead jobs"""
jobs = bg.BackgroundJobManager()
j = jobs.new(crasher)
j.join()
assert len(jobs.completed) == 0
assert len(jobs.dead) == 1
jobs.flush()
assert len(jobs.dead) == 0
def test_longer():
"""Test control of longer-running jobs"""
jobs = bg.BackgroundJobManager()
# Sleep for long enough for the following two checks to still report the
# job as running, but not so long that it makes the test suite noticeably
# slower.
j = jobs.new(sleeper, 0.1)
assert len(jobs.running) == 1
assert len(jobs.completed) == 0
j.join()
assert len(jobs.running) == 0
assert len(jobs.completed) == 1

View File

@ -0,0 +1,19 @@
from IPython.core.error import TryNext
from IPython.lib.clipboard import ClipboardEmpty
from IPython.testing.decorators import skip_if_no_x11
@skip_if_no_x11
def test_clipboard_get():
# Smoketest for clipboard access - we can't easily guarantee that the
# clipboard is accessible and has something on it, but this tries to
# exercise the relevant code anyway.
try:
a = get_ipython().hooks.clipboard_get()
except ClipboardEmpty:
# Nothing in clipboard to get
pass
except TryNext:
# No clipboard access API available
pass
else:
assert isinstance(a, str)

View File

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""Test suite for the deepreload module."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
import types
from pathlib import Path
import pytest
from tempfile import TemporaryDirectory
from IPython.lib.deepreload import modules_reloading
from IPython.lib.deepreload import reload as dreload
from IPython.utils.syspathcontext import prepended_to_syspath
def test_deepreload():
"Test that dreload does deep reloads and skips excluded modules."
with TemporaryDirectory() as tmpdir:
with prepended_to_syspath(tmpdir):
tmpdirpath = Path(tmpdir)
with open(tmpdirpath / "A.py", "w", encoding="utf-8") as f:
f.write("class Object:\n pass\nok = True\n")
with open(tmpdirpath / "B.py", "w", encoding="utf-8") as f:
f.write("import A\nassert A.ok, 'we are fine'\n")
import A
import B
# Test that A is not reloaded.
obj = A.Object()
dreload(B, exclude=["A"])
assert isinstance(obj, A.Object) is True
# Test that an import failure will not blow-up us.
A.ok = False
with pytest.raises(AssertionError, match="we are fine"):
dreload(B, exclude=["A"])
assert len(modules_reloading) == 0
assert not A.ok
# Test that A is reloaded.
obj = A.Object()
A.ok = False
dreload(B)
assert A.ok
assert isinstance(obj, A.Object) is False
def test_not_module():
pytest.raises(TypeError, dreload, "modulename")
def test_not_in_sys_modules():
fake_module = types.ModuleType("fake_module")
with pytest.raises(ImportError, match="not in sys.modules"):
dreload(fake_module)

View File

@ -0,0 +1,272 @@
"""Tests for IPython.lib.display.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2012, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from tempfile import NamedTemporaryFile, mkdtemp
from os.path import split, join as pjoin, dirname
import pathlib
from unittest import TestCase, mock
import struct
import wave
from io import BytesIO
# Third-party imports
import pytest
try:
import numpy
except ImportError:
pass
# Our own imports
from IPython.lib import display
from IPython.testing.decorators import skipif_not_numpy
#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
#--------------------------
# FileLink tests
#--------------------------
def test_instantiation_FileLink():
"""FileLink: Test class can be instantiated"""
fl = display.FileLink('example.txt')
# TODO: remove if when only Python >= 3.6 is supported
fl = display.FileLink(pathlib.PurePath('example.txt'))
def test_warning_on_non_existent_path_FileLink():
"""FileLink: Calling _repr_html_ on non-existent files returns a warning"""
fl = display.FileLink("example.txt")
assert fl._repr_html_().startswith("Path (<tt>example.txt</tt>)")
def test_existing_path_FileLink():
"""FileLink: Calling _repr_html_ functions as expected on existing filepath
"""
tf = NamedTemporaryFile()
fl = display.FileLink(tf.name)
actual = fl._repr_html_()
expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name, tf.name)
assert actual == expected
def test_existing_path_FileLink_repr():
"""FileLink: Calling repr() functions as expected on existing filepath
"""
tf = NamedTemporaryFile()
fl = display.FileLink(tf.name)
actual = repr(fl)
expected = tf.name
assert actual == expected
def test_error_on_directory_to_FileLink():
"""FileLink: Raises error when passed directory
"""
td = mkdtemp()
pytest.raises(ValueError, display.FileLink, td)
#--------------------------
# FileLinks tests
#--------------------------
def test_instantiation_FileLinks():
"""FileLinks: Test class can be instantiated
"""
fls = display.FileLinks('example')
def test_warning_on_non_existent_path_FileLinks():
"""FileLinks: Calling _repr_html_ on non-existent files returns a warning"""
fls = display.FileLinks("example")
assert fls._repr_html_().startswith("Path (<tt>example</tt>)")
def test_existing_path_FileLinks():
"""FileLinks: Calling _repr_html_ functions as expected on existing dir
"""
td = mkdtemp()
tf1 = NamedTemporaryFile(dir=td)
tf2 = NamedTemporaryFile(dir=td)
fl = display.FileLinks(td)
actual = fl._repr_html_()
actual = actual.split('\n')
actual.sort()
# the links should always have forward slashes, even on windows, so replace
# backslashes with forward slashes here
expected = ["%s/<br>" % td,
"&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
(tf2.name.replace("\\","/"),split(tf2.name)[1]),
"&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
(tf1.name.replace("\\","/"),split(tf1.name)[1])]
expected.sort()
# We compare the sorted list of links here as that's more reliable
assert actual == expected
def test_existing_path_FileLinks_alt_formatter():
"""FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
"""
td = mkdtemp()
tf1 = NamedTemporaryFile(dir=td)
tf2 = NamedTemporaryFile(dir=td)
def fake_formatter(dirname,fnames,included_suffixes):
return ["hello","world"]
fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
actual = fl._repr_html_()
actual = actual.split('\n')
actual.sort()
expected = ["hello","world"]
expected.sort()
# We compare the sorted list of links here as that's more reliable
assert actual == expected
def test_existing_path_FileLinks_repr():
"""FileLinks: Calling repr() functions as expected on existing directory """
td = mkdtemp()
tf1 = NamedTemporaryFile(dir=td)
tf2 = NamedTemporaryFile(dir=td)
fl = display.FileLinks(td)
actual = repr(fl)
actual = actual.split('\n')
actual.sort()
expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
expected.sort()
# We compare the sorted list of links here as that's more reliable
assert actual == expected
def test_existing_path_FileLinks_repr_alt_formatter():
"""FileLinks: Calling repr() functions as expected w/ alt formatter
"""
td = mkdtemp()
tf1 = NamedTemporaryFile(dir=td)
tf2 = NamedTemporaryFile(dir=td)
def fake_formatter(dirname,fnames,included_suffixes):
return ["hello","world"]
fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
actual = repr(fl)
actual = actual.split('\n')
actual.sort()
expected = ["hello","world"]
expected.sort()
# We compare the sorted list of links here as that's more reliable
assert actual == expected
def test_error_on_file_to_FileLinks():
"""FileLinks: Raises error when passed file
"""
td = mkdtemp()
tf1 = NamedTemporaryFile(dir=td)
pytest.raises(ValueError, display.FileLinks, tf1.name)
def test_recursive_FileLinks():
"""FileLinks: Does not recurse when recursive=False
"""
td = mkdtemp()
tf = NamedTemporaryFile(dir=td)
subtd = mkdtemp(dir=td)
subtf = NamedTemporaryFile(dir=subtd)
fl = display.FileLinks(td)
actual = str(fl)
actual = actual.split('\n')
assert len(actual) == 4, actual
fl = display.FileLinks(td, recursive=False)
actual = str(fl)
actual = actual.split('\n')
assert len(actual) == 2, actual
def test_audio_from_file():
path = pjoin(dirname(__file__), 'test.wav')
display.Audio(filename=path)
class TestAudioDataWithNumpy(TestCase):
@skipif_not_numpy
def test_audio_from_numpy_array(self):
test_tone = get_test_tone()
audio = display.Audio(test_tone, rate=44100)
assert len(read_wav(audio.data)) == len(test_tone)
@skipif_not_numpy
def test_audio_from_list(self):
test_tone = get_test_tone()
audio = display.Audio(list(test_tone), rate=44100)
assert len(read_wav(audio.data)) == len(test_tone)
@skipif_not_numpy
def test_audio_from_numpy_array_without_rate_raises(self):
self.assertRaises(ValueError, display.Audio, get_test_tone())
@skipif_not_numpy
def test_audio_data_normalization(self):
expected_max_value = numpy.iinfo(numpy.int16).max
for scale in [1, 0.5, 2]:
audio = display.Audio(get_test_tone(scale), rate=44100)
actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
assert actual_max_value == expected_max_value
@skipif_not_numpy
def test_audio_data_without_normalization(self):
max_int16 = numpy.iinfo(numpy.int16).max
for scale in [1, 0.5, 0.2]:
test_tone = get_test_tone(scale)
test_tone_max_abs = numpy.max(numpy.abs(test_tone))
expected_max_value = int(max_int16 * test_tone_max_abs)
audio = display.Audio(test_tone, rate=44100, normalize=False)
actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
assert actual_max_value == expected_max_value
def test_audio_data_without_normalization_raises_for_invalid_data(self):
self.assertRaises(
ValueError,
lambda: display.Audio([1.001], rate=44100, normalize=False))
self.assertRaises(
ValueError,
lambda: display.Audio([-1.001], rate=44100, normalize=False))
def simulate_numpy_not_installed():
try:
import numpy
return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError))
except ModuleNotFoundError:
return lambda x:x
@simulate_numpy_not_installed()
class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy):
# All tests from `TestAudioDataWithNumpy` are inherited.
@skipif_not_numpy
def test_audio_raises_for_nested_list(self):
stereo_signal = [list(get_test_tone())] * 2
self.assertRaises(TypeError, lambda: display.Audio(stereo_signal, rate=44100))
@skipif_not_numpy
def get_test_tone(scale=1):
return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale
def read_wav(data):
with wave.open(BytesIO(data)) as wave_file:
wave_data = wave_file.readframes(wave_file.getnframes())
num_samples = wave_file.getnframes() * wave_file.getnchannels()
return struct.unpack('<%sh' % num_samples, wave_data)
def test_code_from_file():
c = display.Code(filename=__file__)
assert c._repr_html_().startswith('<style>')

View File

@ -0,0 +1,32 @@
"""Test installing editor hooks"""
import sys
from unittest import mock
from IPython import get_ipython
from IPython.lib import editorhooks
def test_install_editor():
called = []
def fake_popen(*args, **kwargs):
called.append({
'args': args,
'kwargs': kwargs,
})
return mock.MagicMock(**{'wait.return_value': 0})
editorhooks.install_editor('foo -l {line} -f {filename}', wait=False)
with mock.patch('subprocess.Popen', fake_popen):
get_ipython().hooks.editor('the file', 64)
assert len(called) == 1
args = called[0]["args"]
kwargs = called[0]["kwargs"]
assert kwargs == {"shell": True}
if sys.platform.startswith("win"):
expected = ["foo", "-l", "64", "-f", "the file"]
else:
expected = "foo -l 64 -f 'the file'"
cmd = args[0]
assert cmd == expected

View File

@ -0,0 +1,11 @@
# encoding: utf-8
from IPython.testing import decorators as dec
def test_import_backgroundjobs():
from IPython.lib import backgroundjobs
def test_import_deepreload():
from IPython.lib import deepreload
def test_import_demo():
from IPython.lib import demo

View File

@ -0,0 +1,192 @@
"""Tests for IPython.utils.path.py"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from contextlib import contextmanager
from unittest.mock import patch
import pytest
from IPython.lib import latextools
from IPython.testing.decorators import (
onlyif_cmds_exist,
skipif_not_matplotlib,
)
from IPython.utils.process import FindCmdError
@pytest.mark.parametrize('command', ['latex', 'dvipng'])
def test_check_latex_to_png_dvipng_fails_when_no_cmd(command):
def mock_find_cmd(arg):
if arg == command:
raise FindCmdError
with patch.object(latextools, "find_cmd", mock_find_cmd):
assert latextools.latex_to_png_dvipng("whatever", True) is None
@contextmanager
def no_op(*args, **kwargs):
yield
@onlyif_cmds_exist("latex", "dvipng")
@pytest.mark.parametrize("s, wrap", [("$$x^2$$", False), ("x^2", True)])
def test_latex_to_png_dvipng_runs(s, wrap):
"""
Test that latex_to_png_dvipng just runs without error.
"""
def mock_kpsewhich(filename):
assert filename == "breqn.sty"
return None
latextools.latex_to_png_dvipng(s, wrap)
with patch_latextool(mock_kpsewhich):
latextools.latex_to_png_dvipng(s, wrap)
def mock_kpsewhich(filename):
assert filename == "breqn.sty"
return None
@contextmanager
def patch_latextool(mock=mock_kpsewhich):
with patch.object(latextools, "kpsewhich", mock):
yield
@pytest.mark.parametrize('context', [no_op, patch_latextool])
@pytest.mark.parametrize('s_wrap', [("$x^2$", False), ("x^2", True)])
def test_latex_to_png_mpl_runs(s_wrap, context):
"""
Test that latex_to_png_mpl just runs without error.
"""
try:
import matplotlib
except ImportError:
pytest.skip("This needs matplotlib to be available")
return
s, wrap = s_wrap
with context():
latextools.latex_to_png_mpl(s, wrap)
@skipif_not_matplotlib
def test_latex_to_html():
img = latextools.latex_to_html("$x^2$")
assert "data:image/png;base64,iVBOR" in img
def test_genelatex_no_wrap():
"""
Test genelatex with wrap=False.
"""
def mock_kpsewhich(filename):
assert False, ("kpsewhich should not be called "
"(called with {0})".format(filename))
with patch_latextool(mock_kpsewhich):
assert '\n'.join(latextools.genelatex("body text", False)) == r'''\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{bm}
\pagestyle{empty}
\begin{document}
body text
\end{document}'''
def test_genelatex_wrap_with_breqn():
"""
Test genelatex with wrap=True for the case breqn.sty is installed.
"""
def mock_kpsewhich(filename):
assert filename == "breqn.sty"
return "path/to/breqn.sty"
with patch_latextool(mock_kpsewhich):
assert '\n'.join(latextools.genelatex("x^2", True)) == r'''\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{bm}
\usepackage{breqn}
\pagestyle{empty}
\begin{document}
\begin{dmath*}
x^2
\end{dmath*}
\end{document}'''
def test_genelatex_wrap_without_breqn():
"""
Test genelatex with wrap=True for the case breqn.sty is not installed.
"""
def mock_kpsewhich(filename):
assert filename == "breqn.sty"
return None
with patch_latextool(mock_kpsewhich):
assert '\n'.join(latextools.genelatex("x^2", True)) == r'''\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{bm}
\pagestyle{empty}
\begin{document}
$$x^2$$
\end{document}'''
@skipif_not_matplotlib
@onlyif_cmds_exist('latex', 'dvipng')
def test_latex_to_png_color():
"""
Test color settings for latex_to_png.
"""
latex_string = "$x^2$"
default_value = latextools.latex_to_png(latex_string, wrap=False)
default_hexblack = latextools.latex_to_png(latex_string, wrap=False,
color='#000000')
dvipng_default = latextools.latex_to_png_dvipng(latex_string, False)
dvipng_black = latextools.latex_to_png_dvipng(latex_string, False, 'Black')
assert dvipng_default == dvipng_black
mpl_default = latextools.latex_to_png_mpl(latex_string, False)
mpl_black = latextools.latex_to_png_mpl(latex_string, False, 'Black')
assert mpl_default == mpl_black
assert default_value in [dvipng_black, mpl_black]
assert default_hexblack in [dvipng_black, mpl_black]
# Test that dvips name colors can be used without error
dvipng_maroon = latextools.latex_to_png_dvipng(latex_string, False,
'Maroon')
# And that it doesn't return the black one
assert dvipng_black != dvipng_maroon
mpl_maroon = latextools.latex_to_png_mpl(latex_string, False, 'Maroon')
assert mpl_black != mpl_maroon
mpl_white = latextools.latex_to_png_mpl(latex_string, False, 'White')
mpl_hexwhite = latextools.latex_to_png_mpl(latex_string, False, '#FFFFFF')
assert mpl_white == mpl_hexwhite
mpl_white_scale = latextools.latex_to_png_mpl(latex_string, False,
'White', 1.2)
assert mpl_white != mpl_white_scale
def test_latex_to_png_invalid_hex_colors():
"""
Test that invalid hex colors provided to dvipng gives an exception.
"""
latex_string = "$x^2$"
pytest.raises(
ValueError,
lambda: latextools.latex_to_png(
latex_string, backend="dvipng", color="#f00bar"
),
)
pytest.raises(
ValueError,
lambda: latextools.latex_to_png(latex_string, backend="dvipng", color="#f00"),
)

View File

@ -0,0 +1,176 @@
"""Test lexers module"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from unittest import TestCase
from pygments.token import Token
from pygments.lexers import BashLexer
from .. import lexers
class TestLexers(TestCase):
"""Collection of lexers tests"""
def setUp(self):
self.lexer = lexers.IPythonLexer()
self.bash_lexer = BashLexer()
def testIPythonLexer(self):
fragment = '!echo $HOME\n'
tokens = [
(Token.Operator, '!'),
]
tokens.extend(self.bash_lexer.get_tokens(fragment[1:]))
self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
fragment_2 = '!' + fragment
tokens_2 = [
(Token.Operator, '!!'),
] + tokens[1:]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = '\t %%!\n' + fragment[1:]
tokens_2 = [
(Token.Text, '\t '),
(Token.Operator, '%%!'),
(Token.Text, '\n'),
] + tokens[1:]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = 'x = ' + fragment
tokens_2 = [
(Token.Name, 'x'),
(Token.Text, ' '),
(Token.Operator, '='),
(Token.Text, ' '),
] + tokens
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = 'x, = ' + fragment
tokens_2 = [
(Token.Name, 'x'),
(Token.Punctuation, ','),
(Token.Text, ' '),
(Token.Operator, '='),
(Token.Text, ' '),
] + tokens
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = 'x, = %sx ' + fragment[1:]
tokens_2 = [
(Token.Name, 'x'),
(Token.Punctuation, ','),
(Token.Text, ' '),
(Token.Operator, '='),
(Token.Text, ' '),
(Token.Operator, '%'),
(Token.Keyword, 'sx'),
(Token.Text, ' '),
] + tokens[1:]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = 'f = %R function () {}\n'
tokens_2 = [
(Token.Name, 'f'),
(Token.Text, ' '),
(Token.Operator, '='),
(Token.Text, ' '),
(Token.Operator, '%'),
(Token.Keyword, 'R'),
(Token.Text, ' function () {}\n'),
]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = '\t%%xyz\n$foo\n'
tokens_2 = [
(Token.Text, '\t'),
(Token.Operator, '%%'),
(Token.Keyword, 'xyz'),
(Token.Text, '\n$foo\n'),
]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = '%system?\n'
tokens_2 = [
(Token.Operator, '%'),
(Token.Keyword, 'system'),
(Token.Operator, '?'),
(Token.Text, '\n'),
]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = 'x != y\n'
tokens_2 = [
(Token.Name, 'x'),
(Token.Text, ' '),
(Token.Operator, '!='),
(Token.Text, ' '),
(Token.Name, 'y'),
(Token.Text, '\n'),
]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment_2 = ' ?math.sin\n'
tokens_2 = [
(Token.Text, ' '),
(Token.Operator, '?'),
(Token.Text, 'math.sin'),
(Token.Text, '\n'),
]
self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2)))
fragment = ' *int*?\n'
tokens = [
(Token.Text, ' *int*'),
(Token.Operator, '?'),
(Token.Text, '\n'),
]
self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
fragment = '%%writefile -a foo.py\nif a == b:\n pass'
tokens = [
(Token.Operator, '%%writefile'),
(Token.Text, ' -a foo.py\n'),
(Token.Keyword, 'if'),
(Token.Text, ' '),
(Token.Name, 'a'),
(Token.Text, ' '),
(Token.Operator, '=='),
(Token.Text, ' '),
(Token.Name, 'b'),
(Token.Punctuation, ':'),
(Token.Text, '\n'),
(Token.Text, ' '),
(Token.Keyword, 'pass'),
(Token.Text, '\n'),
]
self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))
fragment = '%%timeit\nmath.sin(0)'
tokens = [
(Token.Operator, '%%timeit\n'),
(Token.Name, 'math'),
(Token.Operator, '.'),
(Token.Name, 'sin'),
(Token.Punctuation, '('),
(Token.Literal.Number.Integer, '0'),
(Token.Punctuation, ')'),
(Token.Text, '\n'),
]
fragment = '%%HTML\n<div>foo</div>'
tokens = [
(Token.Operator, '%%HTML'),
(Token.Text, '\n'),
(Token.Punctuation, '<'),
(Token.Name.Tag, 'div'),
(Token.Punctuation, '>'),
(Token.Text, 'foo'),
(Token.Punctuation, '<'),
(Token.Punctuation, '/'),
(Token.Name.Tag, 'div'),
(Token.Punctuation, '>'),
(Token.Text, '\n'),
]
self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))

View File

@ -0,0 +1,536 @@
# coding: utf-8
"""Tests for IPython.lib.pretty."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from collections import Counter, defaultdict, deque, OrderedDict, UserList
import os
import pytest
import types
import string
import sys
import unittest
import pytest
from IPython.lib import pretty
from io import StringIO
class MyList(object):
def __init__(self, content):
self.content = content
def _repr_pretty_(self, p, cycle):
if cycle:
p.text("MyList(...)")
else:
with p.group(3, "MyList(", ")"):
for (i, child) in enumerate(self.content):
if i:
p.text(",")
p.breakable()
else:
p.breakable("")
p.pretty(child)
class MyDict(dict):
def _repr_pretty_(self, p, cycle):
p.text("MyDict(...)")
class MyObj(object):
def somemethod(self):
pass
class Dummy1(object):
def _repr_pretty_(self, p, cycle):
p.text("Dummy1(...)")
class Dummy2(Dummy1):
_repr_pretty_ = None
class NoModule(object):
pass
NoModule.__module__ = None
class Breaking(object):
def _repr_pretty_(self, p, cycle):
with p.group(4,"TG: ",":"):
p.text("Breaking(")
p.break_()
p.text(")")
class BreakingRepr(object):
def __repr__(self):
return "Breaking(\n)"
class BadRepr(object):
def __repr__(self):
return 1/0
def test_indentation():
"""Test correct indentation in groups"""
count = 40
gotoutput = pretty.pretty(MyList(range(count)))
expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
assert gotoutput == expectedoutput
def test_dispatch():
"""
Test correct dispatching: The _repr_pretty_ method for MyDict
must be found before the registered printer for dict.
"""
gotoutput = pretty.pretty(MyDict())
expectedoutput = "MyDict(...)"
assert gotoutput == expectedoutput
def test_callability_checking():
"""
Test that the _repr_pretty_ method is tested for callability and skipped if
not.
"""
gotoutput = pretty.pretty(Dummy2())
expectedoutput = "Dummy1(...)"
assert gotoutput == expectedoutput
@pytest.mark.parametrize(
"obj,expected_output",
zip(
[
set(),
frozenset(),
set([1]),
frozenset([1]),
set([1, 2]),
frozenset([1, 2]),
set([-1, -2, -3]),
],
[
"set()",
"frozenset()",
"{1}",
"frozenset({1})",
"{1, 2}",
"frozenset({1, 2})",
"{-3, -2, -1}",
],
),
)
def test_sets(obj, expected_output):
"""
Test that set and frozenset use Python 3 formatting.
"""
got_output = pretty.pretty(obj)
assert got_output == expected_output
def test_pprint_heap_allocated_type():
"""
Test that pprint works for heap allocated types.
"""
module_name = "xxlimited" if sys.version_info < (3, 10) else "xxlimited_35"
xxlimited = pytest.importorskip(module_name)
output = pretty.pretty(xxlimited.Null)
assert output == "xxlimited.Null"
def test_pprint_nomod():
"""
Test that pprint works for classes with no __module__.
"""
output = pretty.pretty(NoModule)
assert output == "NoModule"
def test_pprint_break():
"""
Test that p.break_ produces expected output
"""
output = pretty.pretty(Breaking())
expected = "TG: Breaking(\n ):"
assert output == expected
def test_pprint_break_repr():
"""
Test that p.break_ is used in repr
"""
output = pretty.pretty([[BreakingRepr()]])
expected = "[[Breaking(\n )]]"
assert output == expected
output = pretty.pretty([[BreakingRepr()]*2])
expected = "[[Breaking(\n ),\n Breaking(\n )]]"
assert output == expected
def test_bad_repr():
"""Don't catch bad repr errors"""
with pytest.raises(ZeroDivisionError):
pretty.pretty(BadRepr())
class BadException(Exception):
def __str__(self):
return -1
class ReallyBadRepr(object):
__module__ = 1
@property
def __class__(self):
raise ValueError("I am horrible")
def __repr__(self):
raise BadException()
def test_really_bad_repr():
with pytest.raises(BadException):
pretty.pretty(ReallyBadRepr())
class SA(object):
pass
class SB(SA):
pass
class TestsPretty(unittest.TestCase):
def test_super_repr(self):
# "<super: module_name.SA, None>"
output = pretty.pretty(super(SA))
self.assertRegex(output, r"<super: \S+.SA, None>")
# "<super: module_name.SA, <module_name.SB at 0x...>>"
sb = SB()
output = pretty.pretty(super(SA, sb))
self.assertRegex(output, r"<super: \S+.SA,\s+<\S+.SB at 0x\S+>>")
def test_long_list(self):
lis = list(range(10000))
p = pretty.pretty(lis)
last2 = p.rsplit('\n', 2)[-2:]
self.assertEqual(last2, [' 999,', ' ...]'])
def test_long_set(self):
s = set(range(10000))
p = pretty.pretty(s)
last2 = p.rsplit('\n', 2)[-2:]
self.assertEqual(last2, [' 999,', ' ...}'])
def test_long_tuple(self):
tup = tuple(range(10000))
p = pretty.pretty(tup)
last2 = p.rsplit('\n', 2)[-2:]
self.assertEqual(last2, [' 999,', ' ...)'])
def test_long_dict(self):
d = { n:n for n in range(10000) }
p = pretty.pretty(d)
last2 = p.rsplit('\n', 2)[-2:]
self.assertEqual(last2, [' 999: 999,', ' ...}'])
def test_unbound_method(self):
output = pretty.pretty(MyObj.somemethod)
self.assertIn('MyObj.somemethod', output)
class MetaClass(type):
def __new__(cls, name):
return type.__new__(cls, name, (object,), {'name': name})
def __repr__(self):
return "[CUSTOM REPR FOR CLASS %s]" % self.name
ClassWithMeta = MetaClass('ClassWithMeta')
def test_metaclass_repr():
output = pretty.pretty(ClassWithMeta)
assert output == "[CUSTOM REPR FOR CLASS ClassWithMeta]"
def test_unicode_repr():
u = u"üniçodé"
ustr = u
class C(object):
def __repr__(self):
return ustr
c = C()
p = pretty.pretty(c)
assert p == u
p = pretty.pretty([c])
assert p == "[%s]" % u
def test_basic_class():
def type_pprint_wrapper(obj, p, cycle):
if obj is MyObj:
type_pprint_wrapper.called = True
return pretty._type_pprint(obj, p, cycle)
type_pprint_wrapper.called = False
stream = StringIO()
printer = pretty.RepresentationPrinter(stream)
printer.type_pprinters[type] = type_pprint_wrapper
printer.pretty(MyObj)
printer.flush()
output = stream.getvalue()
assert output == "%s.MyObj" % __name__
assert type_pprint_wrapper.called is True
def test_collections_userlist():
# Create userlist with cycle
a = UserList()
a.append(a)
cases = [
(UserList(), "UserList([])"),
(
UserList(i for i in range(1000, 1020)),
"UserList([1000,\n"
" 1001,\n"
" 1002,\n"
" 1003,\n"
" 1004,\n"
" 1005,\n"
" 1006,\n"
" 1007,\n"
" 1008,\n"
" 1009,\n"
" 1010,\n"
" 1011,\n"
" 1012,\n"
" 1013,\n"
" 1014,\n"
" 1015,\n"
" 1016,\n"
" 1017,\n"
" 1018,\n"
" 1019])",
),
(a, "UserList([UserList(...)])"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_collections_defaultdict():
# Create defaultdicts with cycles
a = defaultdict()
a.default_factory = a
b = defaultdict(list)
b['key'] = b
# Dictionary order cannot be relied on, test against single keys.
cases = [
(defaultdict(list), 'defaultdict(list, {})'),
(defaultdict(list, {'key': '-' * 50}),
"defaultdict(list,\n"
" {'key': '--------------------------------------------------'})"),
(a, 'defaultdict(defaultdict(...), {})'),
(b, "defaultdict(list, {'key': defaultdict(...)})"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_collections_ordereddict():
# Create OrderedDict with cycle
a = OrderedDict()
a['key'] = a
cases = [
(OrderedDict(), 'OrderedDict()'),
(OrderedDict((i, i) for i in range(1000, 1010)),
'OrderedDict([(1000, 1000),\n'
' (1001, 1001),\n'
' (1002, 1002),\n'
' (1003, 1003),\n'
' (1004, 1004),\n'
' (1005, 1005),\n'
' (1006, 1006),\n'
' (1007, 1007),\n'
' (1008, 1008),\n'
' (1009, 1009)])'),
(a, "OrderedDict([('key', OrderedDict(...))])"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_collections_deque():
# Create deque with cycle
a = deque()
a.append(a)
cases = [
(deque(), 'deque([])'),
(deque(i for i in range(1000, 1020)),
'deque([1000,\n'
' 1001,\n'
' 1002,\n'
' 1003,\n'
' 1004,\n'
' 1005,\n'
' 1006,\n'
' 1007,\n'
' 1008,\n'
' 1009,\n'
' 1010,\n'
' 1011,\n'
' 1012,\n'
' 1013,\n'
' 1014,\n'
' 1015,\n'
' 1016,\n'
' 1017,\n'
' 1018,\n'
' 1019])'),
(a, 'deque([deque(...)])'),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_collections_counter():
class MyCounter(Counter):
pass
cases = [
(Counter(), 'Counter()'),
(Counter(a=1), "Counter({'a': 1})"),
(MyCounter(a=1), "MyCounter({'a': 1})"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_mappingproxy():
MP = types.MappingProxyType
underlying_dict = {}
mp_recursive = MP(underlying_dict)
underlying_dict[2] = mp_recursive
underlying_dict[3] = underlying_dict
cases = [
(MP({}), "mappingproxy({})"),
(MP({None: MP({})}), "mappingproxy({None: mappingproxy({})})"),
(MP({k: k.upper() for k in string.ascii_lowercase}),
"mappingproxy({'a': 'A',\n"
" 'b': 'B',\n"
" 'c': 'C',\n"
" 'd': 'D',\n"
" 'e': 'E',\n"
" 'f': 'F',\n"
" 'g': 'G',\n"
" 'h': 'H',\n"
" 'i': 'I',\n"
" 'j': 'J',\n"
" 'k': 'K',\n"
" 'l': 'L',\n"
" 'm': 'M',\n"
" 'n': 'N',\n"
" 'o': 'O',\n"
" 'p': 'P',\n"
" 'q': 'Q',\n"
" 'r': 'R',\n"
" 's': 'S',\n"
" 't': 'T',\n"
" 'u': 'U',\n"
" 'v': 'V',\n"
" 'w': 'W',\n"
" 'x': 'X',\n"
" 'y': 'Y',\n"
" 'z': 'Z'})"),
(mp_recursive, "mappingproxy({2: {...}, 3: {2: {...}, 3: {...}}})"),
(underlying_dict,
"{2: mappingproxy({2: {...}, 3: {...}}), 3: {...}}"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
# TODO : pytest.mark.parametrise once nose is gone.
def test_simplenamespace():
SN = types.SimpleNamespace
sn_recursive = SN()
sn_recursive.first = sn_recursive
sn_recursive.second = sn_recursive
cases = [
(SN(), "namespace()"),
(SN(x=SN()), "namespace(x=namespace())"),
(SN(a_long_name=[SN(s=string.ascii_lowercase)]*3, a_short_name=None),
"namespace(a_long_name=[namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"
" namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"
" namespace(s='abcdefghijklmnopqrstuvwxyz')],\n"
" a_short_name=None)"),
(sn_recursive, "namespace(first=namespace(...), second=namespace(...))"),
]
for obj, expected in cases:
assert pretty.pretty(obj) == expected
def test_pretty_environ():
dict_repr = pretty.pretty(dict(os.environ))
# reindent to align with 'environ' prefix
dict_indented = dict_repr.replace('\n', '\n' + (' ' * len('environ')))
env_repr = pretty.pretty(os.environ)
assert env_repr == "environ" + dict_indented
def test_function_pretty():
"Test pretty print of function"
# posixpath is a pure python module, its interface is consistent
# across Python distributions
import posixpath
assert pretty.pretty(posixpath.join) == "<function posixpath.join(a, *p)>"
# custom function
def meaning_of_life(question=None):
if question:
return 42
return "Don't panic"
assert "meaning_of_life(question=None)" in pretty.pretty(meaning_of_life)
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
class MySet(set): # Override repr of a basic type
def __repr__(self):
return 'mine'
def test_custom_repr():
"""A custom repr should override a pretty printer for a parent type"""
oc = OrderedCounter("abracadabra")
assert "OrderedCounter(OrderedDict" in pretty.pretty(oc)
assert pretty.pretty(MySet()) == "mine"