Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
BIN
venv/Lib/site-packages/IPython/core/tests/2x2.jpg
Normal file
BIN
venv/Lib/site-packages/IPython/core/tests/2x2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 331 B |
BIN
venv/Lib/site-packages/IPython/core/tests/2x2.png
Normal file
BIN
venv/Lib/site-packages/IPython/core/tests/2x2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 B |
0
venv/Lib/site-packages/IPython/core/tests/__init__.py
Normal file
0
venv/Lib/site-packages/IPython/core/tests/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
14
venv/Lib/site-packages/IPython/core/tests/bad_all.py
Normal file
14
venv/Lib/site-packages/IPython/core/tests/bad_all.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""Module with bad __all__
|
||||
|
||||
To test https://github.com/ipython/ipython/issues/9678
|
||||
"""
|
||||
|
||||
def evil():
|
||||
pass
|
||||
|
||||
def puppies():
|
||||
pass
|
||||
|
||||
__all__ = [evil, # Bad
|
||||
'puppies', # Good
|
||||
]
|
||||
Binary file not shown.
|
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Useless IPython extension to test installing and loading extensions.
|
||||
"""
|
||||
some_vars = {'arq': 185}
|
||||
|
||||
def load_ipython_extension(ip):
|
||||
# set up simplified quantity input
|
||||
ip.push(some_vars)
|
||||
|
||||
def unload_ipython_extension(ip):
|
||||
ip.drop_by_id(some_vars)
|
||||
4
venv/Lib/site-packages/IPython/core/tests/nonascii.py
Normal file
4
venv/Lib/site-packages/IPython/core/tests/nonascii.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# coding: iso-8859-5
|
||||
# (Unlikely to be the default encoding for most testers.)
|
||||
# ±¶ÿàáâãäåæçèéêëìíîï <- Cyrillic characters
|
||||
u = '®âðÄ'
|
||||
4
venv/Lib/site-packages/IPython/core/tests/nonascii2.py
Normal file
4
venv/Lib/site-packages/IPython/core/tests/nonascii2.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# coding: iso-8859-5
|
||||
# (Unlikely to be the default encoding for most testers.)
|
||||
# БЖџрстуфхцчшщъыьэюя <- Cyrillic characters
|
||||
'Ўт№Ф'
|
||||
2
venv/Lib/site-packages/IPython/core/tests/print_argv.py
Normal file
2
venv/Lib/site-packages/IPython/core/tests/print_argv.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import sys
|
||||
print(sys.argv[1:])
|
||||
46
venv/Lib/site-packages/IPython/core/tests/refbug.py
Normal file
46
venv/Lib/site-packages/IPython/core/tests/refbug.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"""Minimal script to reproduce our nasty reference counting bug.
|
||||
|
||||
The problem is related to https://github.com/ipython/ipython/issues/141
|
||||
|
||||
The original fix for that appeared to work, but John D. Hunter found a
|
||||
matplotlib example which, when run twice in a row, would break. The problem
|
||||
were references held by open figures to internals of Tkinter.
|
||||
|
||||
This code reproduces the problem that John saw, without matplotlib.
|
||||
|
||||
This script is meant to be called by other parts of the test suite that call it
|
||||
via %run as if it were executed interactively by the user. As of 2011-05-29,
|
||||
test_run.py calls it.
|
||||
"""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Module imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
from IPython import get_ipython
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Globals
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# This needs to be here because nose and other test runners will import
|
||||
# this module. Importing this module has potential side effects that we
|
||||
# want to prevent.
|
||||
if __name__ == '__main__':
|
||||
|
||||
ip = get_ipython()
|
||||
|
||||
if not '_refbug_cache' in ip.user_ns:
|
||||
ip.user_ns['_refbug_cache'] = []
|
||||
|
||||
|
||||
aglobal = 'Hello'
|
||||
def f():
|
||||
return aglobal
|
||||
|
||||
cache = ip.user_ns['_refbug_cache']
|
||||
cache.append(f)
|
||||
|
||||
def call_f():
|
||||
for func in cache:
|
||||
print('lowercased:',func().lower())
|
||||
32
venv/Lib/site-packages/IPython/core/tests/simpleerr.py
Normal file
32
venv/Lib/site-packages/IPython/core/tests/simpleerr.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
"""Error script. DO NOT EDIT FURTHER! It will break exception doctests!!!"""
|
||||
import sys
|
||||
|
||||
def div0():
|
||||
"foo"
|
||||
x = 1
|
||||
y = 0
|
||||
x/y
|
||||
|
||||
def sysexit(stat, mode):
|
||||
raise SystemExit(stat, 'Mode = %s' % mode)
|
||||
|
||||
def bar(mode):
|
||||
"bar"
|
||||
if mode=='div':
|
||||
div0()
|
||||
elif mode=='exit':
|
||||
try:
|
||||
stat = int(sys.argv[2])
|
||||
except:
|
||||
stat = 1
|
||||
sysexit(stat, mode)
|
||||
else:
|
||||
raise ValueError('Unknown mode')
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
mode = sys.argv[1]
|
||||
except IndexError:
|
||||
mode = 'div'
|
||||
|
||||
bar(mode)
|
||||
34
venv/Lib/site-packages/IPython/core/tests/tclass.py
Normal file
34
venv/Lib/site-packages/IPython/core/tests/tclass.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
"""Simple script to be run *twice*, to check reference counting bugs.
|
||||
|
||||
See test_run for details."""
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
# We want to ensure that while objects remain available for immediate access,
|
||||
# objects from *previous* runs of the same script get collected, to avoid
|
||||
# accumulating massive amounts of old references.
|
||||
class C(object):
|
||||
def __init__(self,name):
|
||||
self.name = name
|
||||
self.p = print
|
||||
self.flush_stdout = sys.stdout.flush
|
||||
|
||||
def __del__(self):
|
||||
self.p('tclass.py: deleting object:',self.name)
|
||||
self.flush_stdout()
|
||||
|
||||
try:
|
||||
name = sys.argv[1]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
if name.startswith('C'):
|
||||
c = C(name)
|
||||
|
||||
#print >> sys.stderr, "ARGV:", sys.argv # dbg
|
||||
|
||||
# This next print statement is NOT debugging, we're making the check on a
|
||||
# completely separate process so we verify by capturing stdout:
|
||||
print('ARGV 1-:', sys.argv[1:])
|
||||
sys.stdout.flush()
|
||||
65
venv/Lib/site-packages/IPython/core/tests/test_alias.py
Normal file
65
venv/Lib/site-packages/IPython/core/tests/test_alias.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
from IPython.utils.capture import capture_output
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
def test_alias_lifecycle():
|
||||
name = 'test_alias1'
|
||||
cmd = 'echo "Hello"'
|
||||
am = _ip.alias_manager
|
||||
am.clear_aliases()
|
||||
am.define_alias(name, cmd)
|
||||
assert am.is_alias(name)
|
||||
nt.assert_equal(am.retrieve_alias(name), cmd)
|
||||
nt.assert_in((name, cmd), am.aliases)
|
||||
|
||||
# Test running the alias
|
||||
orig_system = _ip.system
|
||||
result = []
|
||||
_ip.system = result.append
|
||||
try:
|
||||
_ip.run_cell('%{}'.format(name))
|
||||
result = [c.strip() for c in result]
|
||||
nt.assert_equal(result, [cmd])
|
||||
finally:
|
||||
_ip.system = orig_system
|
||||
|
||||
# Test removing the alias
|
||||
am.undefine_alias(name)
|
||||
assert not am.is_alias(name)
|
||||
with nt.assert_raises(ValueError):
|
||||
am.retrieve_alias(name)
|
||||
nt.assert_not_in((name, cmd), am.aliases)
|
||||
|
||||
|
||||
def test_alias_args_error():
|
||||
"""Error expanding with wrong number of arguments"""
|
||||
_ip.alias_manager.define_alias('parts', 'echo first %s second %s')
|
||||
# capture stderr:
|
||||
with capture_output() as cap:
|
||||
_ip.run_cell('parts 1')
|
||||
|
||||
nt.assert_equal(cap.stderr.split(':')[0], 'UsageError')
|
||||
|
||||
def test_alias_args_commented():
|
||||
"""Check that alias correctly ignores 'commented out' args"""
|
||||
_ip.magic('alias commetarg echo this is %%s a commented out arg')
|
||||
|
||||
with capture_output() as cap:
|
||||
_ip.run_cell('commetarg')
|
||||
|
||||
# strip() is for pytest compat; testing via iptest patch IPython shell
|
||||
# in testin.globalipapp and replace the system call which messed up the
|
||||
# \r\n
|
||||
assert cap.stdout.strip() == 'this is %s a commented out arg'
|
||||
|
||||
def test_alias_args_commented_nargs():
|
||||
"""Check that alias correctly counts args, excluding those commented out"""
|
||||
am = _ip.alias_manager
|
||||
alias_name = 'comargcount'
|
||||
cmd = 'echo this is %%s a commented out arg and this is not %s'
|
||||
|
||||
am.define_alias(alias_name, cmd)
|
||||
assert am.is_alias(alias_name)
|
||||
|
||||
thealias = am.get_alias(alias_name)
|
||||
nt.assert_equal(thealias.nargs, 1)
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# coding: utf-8
|
||||
"""Tests for IPython.core.application"""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from traitlets import Unicode
|
||||
|
||||
from IPython.core.application import BaseIPythonApplication
|
||||
from IPython.testing import decorators as dec
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
|
||||
@dec.onlyif_unicode_paths
|
||||
def test_unicode_cwd():
|
||||
"""Check that IPython starts with non-ascii characters in the path."""
|
||||
wd = tempfile.mkdtemp(suffix=u"€")
|
||||
|
||||
old_wd = os.getcwd()
|
||||
os.chdir(wd)
|
||||
#raise Exception(repr(os.getcwd()))
|
||||
try:
|
||||
app = BaseIPythonApplication()
|
||||
# The lines below are copied from Application.initialize()
|
||||
app.init_profile_dir()
|
||||
app.init_config_files()
|
||||
app.load_config_file(suppress_errors=False)
|
||||
finally:
|
||||
os.chdir(old_wd)
|
||||
|
||||
@dec.onlyif_unicode_paths
|
||||
def test_unicode_ipdir():
|
||||
"""Check that IPython starts with non-ascii characters in the IP dir."""
|
||||
ipdir = tempfile.mkdtemp(suffix=u"€")
|
||||
|
||||
# Create the config file, so it tries to load it.
|
||||
with open(os.path.join(ipdir, 'ipython_config.py'), "w") as f:
|
||||
pass
|
||||
|
||||
old_ipdir1 = os.environ.pop("IPYTHONDIR", None)
|
||||
old_ipdir2 = os.environ.pop("IPYTHON_DIR", None)
|
||||
os.environ["IPYTHONDIR"] = ipdir
|
||||
try:
|
||||
app = BaseIPythonApplication()
|
||||
# The lines below are copied from Application.initialize()
|
||||
app.init_profile_dir()
|
||||
app.init_config_files()
|
||||
app.load_config_file(suppress_errors=False)
|
||||
finally:
|
||||
if old_ipdir1:
|
||||
os.environ["IPYTHONDIR"] = old_ipdir1
|
||||
if old_ipdir2:
|
||||
os.environ["IPYTHONDIR"] = old_ipdir2
|
||||
|
||||
def test_cli_priority():
|
||||
with TemporaryDirectory() as td:
|
||||
|
||||
class TestApp(BaseIPythonApplication):
|
||||
test = Unicode().tag(config=True)
|
||||
|
||||
# Create the config file, so it tries to load it.
|
||||
with open(os.path.join(td, 'ipython_config.py'), "w") as f:
|
||||
f.write("c.TestApp.test = 'config file'")
|
||||
|
||||
app = TestApp()
|
||||
app.initialize(['--profile-dir', td])
|
||||
nt.assert_equal(app.test, 'config file')
|
||||
app = TestApp()
|
||||
app.initialize(['--profile-dir', td, '--TestApp.test=cli'])
|
||||
nt.assert_equal(app.test, 'cli')
|
||||
|
||||
316
venv/Lib/site-packages/IPython/core/tests/test_async_helpers.py
Normal file
316
venv/Lib/site-packages/IPython/core/tests/test_async_helpers.py
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
"""
|
||||
Test for async helpers.
|
||||
|
||||
Should only trigger on python 3.5+ or will have syntax errors.
|
||||
"""
|
||||
from itertools import chain, repeat
|
||||
import nose.tools as nt
|
||||
from textwrap import dedent, indent
|
||||
from unittest import TestCase
|
||||
from IPython.testing.decorators import skip_without
|
||||
import sys
|
||||
|
||||
iprc = lambda x: ip.run_cell(dedent(x)).raise_error()
|
||||
iprc_nr = lambda x: ip.run_cell(dedent(x))
|
||||
|
||||
from IPython.core.async_helpers import _should_be_async
|
||||
|
||||
class AsyncTest(TestCase):
|
||||
def test_should_be_async(self):
|
||||
nt.assert_false(_should_be_async("False"))
|
||||
nt.assert_true(_should_be_async("await bar()"))
|
||||
nt.assert_true(_should_be_async("x = await bar()"))
|
||||
nt.assert_false(
|
||||
_should_be_async(
|
||||
dedent(
|
||||
"""
|
||||
async def awaitable():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def _get_top_level_cases(self):
|
||||
# These are test cases that should be valid in a function
|
||||
# but invalid outside of a function.
|
||||
test_cases = []
|
||||
test_cases.append(('basic', "{val}"))
|
||||
|
||||
# Note, in all conditional cases, I use True instead of
|
||||
# False so that the peephole optimizer won't optimize away
|
||||
# the return, so CPython will see this as a syntax error:
|
||||
#
|
||||
# while True:
|
||||
# break
|
||||
# return
|
||||
#
|
||||
# But not this:
|
||||
#
|
||||
# while False:
|
||||
# return
|
||||
#
|
||||
# See https://bugs.python.org/issue1875
|
||||
|
||||
test_cases.append(('if', dedent("""
|
||||
if True:
|
||||
{val}
|
||||
""")))
|
||||
|
||||
test_cases.append(('while', dedent("""
|
||||
while True:
|
||||
{val}
|
||||
break
|
||||
""")))
|
||||
|
||||
test_cases.append(('try', dedent("""
|
||||
try:
|
||||
{val}
|
||||
except:
|
||||
pass
|
||||
""")))
|
||||
|
||||
test_cases.append(('except', dedent("""
|
||||
try:
|
||||
pass
|
||||
except:
|
||||
{val}
|
||||
""")))
|
||||
|
||||
test_cases.append(('finally', dedent("""
|
||||
try:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
{val}
|
||||
""")))
|
||||
|
||||
test_cases.append(('for', dedent("""
|
||||
for _ in range(4):
|
||||
{val}
|
||||
""")))
|
||||
|
||||
|
||||
test_cases.append(('nested', dedent("""
|
||||
if True:
|
||||
while True:
|
||||
{val}
|
||||
break
|
||||
""")))
|
||||
|
||||
test_cases.append(('deep-nested', dedent("""
|
||||
if True:
|
||||
while True:
|
||||
break
|
||||
for x in range(3):
|
||||
if True:
|
||||
while True:
|
||||
for x in range(3):
|
||||
{val}
|
||||
""")))
|
||||
|
||||
return test_cases
|
||||
|
||||
def _get_ry_syntax_errors(self):
|
||||
# This is a mix of tests that should be a syntax error if
|
||||
# return or yield whether or not they are in a function
|
||||
|
||||
test_cases = []
|
||||
|
||||
test_cases.append(('class', dedent("""
|
||||
class V:
|
||||
{val}
|
||||
""")))
|
||||
|
||||
test_cases.append(('nested-class', dedent("""
|
||||
class V:
|
||||
class C:
|
||||
{val}
|
||||
""")))
|
||||
|
||||
return test_cases
|
||||
|
||||
|
||||
def test_top_level_return_error(self):
|
||||
tl_err_test_cases = self._get_top_level_cases()
|
||||
tl_err_test_cases.extend(self._get_ry_syntax_errors())
|
||||
|
||||
vals = ('return', 'yield', 'yield from (_ for _ in range(3))',
|
||||
dedent('''
|
||||
def f():
|
||||
pass
|
||||
return
|
||||
'''),
|
||||
)
|
||||
|
||||
for test_name, test_case in tl_err_test_cases:
|
||||
# This example should work if 'pass' is used as the value
|
||||
with self.subTest((test_name, 'pass')):
|
||||
iprc(test_case.format(val='pass'))
|
||||
|
||||
# It should fail with all the values
|
||||
for val in vals:
|
||||
with self.subTest((test_name, val)):
|
||||
msg = "Syntax error not raised for %s, %s" % (test_name, val)
|
||||
with self.assertRaises(SyntaxError, msg=msg):
|
||||
iprc(test_case.format(val=val))
|
||||
|
||||
def test_in_func_no_error(self):
|
||||
# Test that the implementation of top-level return/yield
|
||||
# detection isn't *too* aggressive, and works inside a function
|
||||
func_contexts = []
|
||||
|
||||
func_contexts.append(('func', False, dedent("""
|
||||
def f():""")))
|
||||
|
||||
func_contexts.append(('method', False, dedent("""
|
||||
class MyClass:
|
||||
def __init__(self):
|
||||
""")))
|
||||
|
||||
func_contexts.append(('async-func', True, dedent("""
|
||||
async def f():""")))
|
||||
|
||||
func_contexts.append(('async-method', True, dedent("""
|
||||
class MyClass:
|
||||
async def f(self):""")))
|
||||
|
||||
func_contexts.append(('closure', False, dedent("""
|
||||
def f():
|
||||
def g():
|
||||
""")))
|
||||
|
||||
def nest_case(context, case):
|
||||
# Detect indentation
|
||||
lines = context.strip().splitlines()
|
||||
prefix_len = 0
|
||||
for c in lines[-1]:
|
||||
if c != ' ':
|
||||
break
|
||||
prefix_len += 1
|
||||
|
||||
indented_case = indent(case, ' ' * (prefix_len + 4))
|
||||
return context + '\n' + indented_case
|
||||
|
||||
# Gather and run the tests
|
||||
|
||||
# yield is allowed in async functions, starting in Python 3.6,
|
||||
# and yield from is not allowed in any version
|
||||
vals = ('return', 'yield', 'yield from (_ for _ in range(3))')
|
||||
async_safe = (True,
|
||||
True,
|
||||
False)
|
||||
vals = tuple(zip(vals, async_safe))
|
||||
|
||||
success_tests = zip(self._get_top_level_cases(), repeat(False))
|
||||
failure_tests = zip(self._get_ry_syntax_errors(), repeat(True))
|
||||
|
||||
tests = chain(success_tests, failure_tests)
|
||||
|
||||
for context_name, async_func, context in func_contexts:
|
||||
for (test_name, test_case), should_fail in tests:
|
||||
nested_case = nest_case(context, test_case)
|
||||
|
||||
for val, async_safe in vals:
|
||||
val_should_fail = (should_fail or
|
||||
(async_func and not async_safe))
|
||||
|
||||
test_id = (context_name, test_name, val)
|
||||
cell = nested_case.format(val=val)
|
||||
|
||||
with self.subTest(test_id):
|
||||
if val_should_fail:
|
||||
msg = ("SyntaxError not raised for %s" %
|
||||
str(test_id))
|
||||
with self.assertRaises(SyntaxError, msg=msg):
|
||||
iprc(cell)
|
||||
|
||||
print(cell)
|
||||
else:
|
||||
iprc(cell)
|
||||
|
||||
def test_nonlocal(self):
|
||||
# fails if outer scope is not a function scope or if var not defined
|
||||
with self.assertRaises(SyntaxError):
|
||||
iprc("nonlocal x")
|
||||
iprc("""
|
||||
x = 1
|
||||
def f():
|
||||
nonlocal x
|
||||
x = 10000
|
||||
yield x
|
||||
""")
|
||||
iprc("""
|
||||
def f():
|
||||
def g():
|
||||
nonlocal x
|
||||
x = 10000
|
||||
yield x
|
||||
""")
|
||||
|
||||
# works if outer scope is a function scope and var exists
|
||||
iprc("""
|
||||
def f():
|
||||
x = 20
|
||||
def g():
|
||||
nonlocal x
|
||||
x = 10000
|
||||
yield x
|
||||
""")
|
||||
|
||||
|
||||
def test_execute(self):
|
||||
iprc("""
|
||||
import asyncio
|
||||
await asyncio.sleep(0.001)
|
||||
"""
|
||||
)
|
||||
|
||||
def test_autoawait(self):
|
||||
iprc("%autoawait False")
|
||||
iprc("%autoawait True")
|
||||
iprc("""
|
||||
from asyncio import sleep
|
||||
await sleep(0.1)
|
||||
"""
|
||||
)
|
||||
|
||||
if sys.version_info < (3,9):
|
||||
# new pgen parser in 3.9 does not raise MemoryError on too many nested
|
||||
# parens anymore
|
||||
def test_memory_error(self):
|
||||
with self.assertRaises(MemoryError):
|
||||
iprc("(" * 200 + ")" * 200)
|
||||
|
||||
@skip_without('curio')
|
||||
def test_autoawait_curio(self):
|
||||
iprc("%autoawait curio")
|
||||
|
||||
@skip_without('trio')
|
||||
def test_autoawait_trio(self):
|
||||
iprc("%autoawait trio")
|
||||
|
||||
@skip_without('trio')
|
||||
def test_autoawait_trio_wrong_sleep(self):
|
||||
iprc("%autoawait trio")
|
||||
res = iprc_nr("""
|
||||
import asyncio
|
||||
await asyncio.sleep(0)
|
||||
""")
|
||||
with nt.assert_raises(TypeError):
|
||||
res.raise_error()
|
||||
|
||||
@skip_without('trio')
|
||||
def test_autoawait_asyncio_wrong_sleep(self):
|
||||
iprc("%autoawait asyncio")
|
||||
res = iprc_nr("""
|
||||
import trio
|
||||
await trio.sleep(0)
|
||||
""")
|
||||
with nt.assert_raises(RuntimeError):
|
||||
res.raise_error()
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
ip.loop_runner = "asyncio"
|
||||
66
venv/Lib/site-packages/IPython/core/tests/test_autocall.py
Normal file
66
venv/Lib/site-packages/IPython/core/tests/test_autocall.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"""These kinds of tests are less than ideal, but at least they run.
|
||||
|
||||
This was an old test that was being run interactively in the top-level tests/
|
||||
directory, which we are removing. For now putting this here ensures at least
|
||||
we do run the test, though ultimately this functionality should all be tested
|
||||
with better-isolated tests that don't rely on the global instance in iptest.
|
||||
"""
|
||||
from IPython.core.splitinput import LineInfo
|
||||
from IPython.core.prefilter import AutocallChecker
|
||||
|
||||
def doctest_autocall():
|
||||
"""
|
||||
In [1]: def f1(a,b,c):
|
||||
...: return a+b+c
|
||||
...:
|
||||
|
||||
In [2]: def f2(a):
|
||||
...: return a + a
|
||||
...:
|
||||
|
||||
In [3]: def r(x):
|
||||
...: return True
|
||||
...:
|
||||
|
||||
In [4]: ;f2 a b c
|
||||
Out[4]: 'a b ca b c'
|
||||
|
||||
In [5]: assert _ == "a b ca b c"
|
||||
|
||||
In [6]: ,f1 a b c
|
||||
Out[6]: 'abc'
|
||||
|
||||
In [7]: assert _ == 'abc'
|
||||
|
||||
In [8]: print(_)
|
||||
abc
|
||||
|
||||
In [9]: /f1 1,2,3
|
||||
Out[9]: 6
|
||||
|
||||
In [10]: assert _ == 6
|
||||
|
||||
In [11]: /f2 4
|
||||
Out[11]: 8
|
||||
|
||||
In [12]: assert _ == 8
|
||||
|
||||
In [12]: del f1, f2
|
||||
|
||||
In [13]: ,r a
|
||||
Out[13]: True
|
||||
|
||||
In [14]: assert _ == True
|
||||
|
||||
In [15]: r'a'
|
||||
Out[15]: 'a'
|
||||
|
||||
In [16]: assert _ == 'a'
|
||||
"""
|
||||
|
||||
|
||||
def test_autocall_should_ignore_raw_strings():
|
||||
line_info = LineInfo("r'a'")
|
||||
pm = ip.prefilter_manager
|
||||
ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm, config=pm.config)
|
||||
assert ac.check(line_info) is None
|
||||
73
venv/Lib/site-packages/IPython/core/tests/test_compilerop.py
Normal file
73
venv/Lib/site-packages/IPython/core/tests/test_compilerop.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# coding: utf-8
|
||||
"""Tests for the compilerop module.
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2010-2011 The IPython Development Team.
|
||||
#
|
||||
# Distributed under the terms of the BSD License.
|
||||
#
|
||||
# The full license is in the file COPYING.txt, distributed with this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Stdlib imports
|
||||
import linecache
|
||||
import sys
|
||||
|
||||
# Third-party imports
|
||||
import nose.tools as nt
|
||||
|
||||
# Our own imports
|
||||
from IPython.core import compilerop
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def test_code_name():
|
||||
code = 'x=1'
|
||||
name = compilerop.code_name(code)
|
||||
nt.assert_true(name.startswith('<ipython-input-0'))
|
||||
|
||||
|
||||
def test_code_name2():
|
||||
code = 'x=1'
|
||||
name = compilerop.code_name(code, 9)
|
||||
nt.assert_true(name.startswith('<ipython-input-9'))
|
||||
|
||||
|
||||
def test_cache():
|
||||
"""Test the compiler correctly compiles and caches inputs
|
||||
"""
|
||||
cp = compilerop.CachingCompiler()
|
||||
ncache = len(linecache.cache)
|
||||
cp.cache('x=1')
|
||||
nt.assert_true(len(linecache.cache) > ncache)
|
||||
|
||||
def test_proper_default_encoding():
|
||||
# Check we're in a proper Python 2 environment (some imports, such
|
||||
# as GTK, can change the default encoding, which can hide bugs.)
|
||||
nt.assert_equal(sys.getdefaultencoding(), "utf-8")
|
||||
|
||||
def test_cache_unicode():
|
||||
cp = compilerop.CachingCompiler()
|
||||
ncache = len(linecache.cache)
|
||||
cp.cache(u"t = 'žćčšđ'")
|
||||
nt.assert_true(len(linecache.cache) > ncache)
|
||||
|
||||
def test_compiler_check_cache():
|
||||
"""Test the compiler properly manages the cache.
|
||||
"""
|
||||
# Rather simple-minded tests that just exercise the API
|
||||
cp = compilerop.CachingCompiler()
|
||||
cp.cache('x=1', 99)
|
||||
# Ensure now that after clearing the cache, our entries survive
|
||||
linecache.checkcache()
|
||||
for k in linecache.cache:
|
||||
if k.startswith('<ipython-input-99'):
|
||||
break
|
||||
else:
|
||||
raise AssertionError('Entry for input-99 missing from linecache')
|
||||
1111
venv/Lib/site-packages/IPython/core/tests/test_completer.py
Normal file
1111
venv/Lib/site-packages/IPython/core/tests/test_completer.py
Normal file
File diff suppressed because it is too large
Load diff
178
venv/Lib/site-packages/IPython/core/tests/test_completerlib.py
Normal file
178
venv/Lib/site-packages/IPython/core/tests/test_completerlib.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Tests for completerlib.
|
||||
|
||||
"""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from os.path import join
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core.completerlib import magic_run_completer, module_completion, try_import
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
from IPython.testing.decorators import onlyif_unicode_paths
|
||||
|
||||
|
||||
class MockEvent(object):
|
||||
def __init__(self, line):
|
||||
self.line = line
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions begin
|
||||
#-----------------------------------------------------------------------------
|
||||
class Test_magic_run_completer(unittest.TestCase):
|
||||
files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
|
||||
dirs = [u"adir/", "bdir/"]
|
||||
|
||||
def setUp(self):
|
||||
self.BASETESTDIR = tempfile.mkdtemp()
|
||||
for fil in self.files:
|
||||
with open(join(self.BASETESTDIR, fil), "w") as sfile:
|
||||
sfile.write("pass\n")
|
||||
for d in self.dirs:
|
||||
os.mkdir(join(self.BASETESTDIR, d))
|
||||
|
||||
self.oldpath = os.getcwd()
|
||||
os.chdir(self.BASETESTDIR)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.oldpath)
|
||||
shutil.rmtree(self.BASETESTDIR)
|
||||
|
||||
def test_1(self):
|
||||
"""Test magic_run_completer, should match two alternatives
|
||||
"""
|
||||
event = MockEvent(u"%run a")
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
|
||||
|
||||
def test_2(self):
|
||||
"""Test magic_run_completer, should match one alternative
|
||||
"""
|
||||
event = MockEvent(u"%run aa")
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"aao.py"})
|
||||
|
||||
def test_3(self):
|
||||
"""Test magic_run_completer with unterminated " """
|
||||
event = MockEvent(u'%run "a')
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
|
||||
|
||||
def test_completion_more_args(self):
|
||||
event = MockEvent(u'%run a.py ')
|
||||
match = set(magic_run_completer(None, event))
|
||||
self.assertEqual(match, set(self.files + self.dirs))
|
||||
|
||||
def test_completion_in_dir(self):
|
||||
# Github issue #3459
|
||||
event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
|
||||
print(repr(event.line))
|
||||
match = set(magic_run_completer(None, event))
|
||||
# We specifically use replace here rather than normpath, because
|
||||
# at one point there were duplicates 'adir' and 'adir/', and normpath
|
||||
# would hide the failure for that.
|
||||
self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
|
||||
for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
|
||||
|
||||
class Test_magic_run_completer_nonascii(unittest.TestCase):
|
||||
@onlyif_unicode_paths
|
||||
def setUp(self):
|
||||
self.BASETESTDIR = tempfile.mkdtemp()
|
||||
for fil in [u"aaø.py", u"a.py", u"b.py"]:
|
||||
with open(join(self.BASETESTDIR, fil), "w") as sfile:
|
||||
sfile.write("pass\n")
|
||||
self.oldpath = os.getcwd()
|
||||
os.chdir(self.BASETESTDIR)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.oldpath)
|
||||
shutil.rmtree(self.BASETESTDIR)
|
||||
|
||||
@onlyif_unicode_paths
|
||||
def test_1(self):
|
||||
"""Test magic_run_completer, should match two alternatives
|
||||
"""
|
||||
event = MockEvent(u"%run a")
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"a.py", u"aaø.py"})
|
||||
|
||||
@onlyif_unicode_paths
|
||||
def test_2(self):
|
||||
"""Test magic_run_completer, should match one alternative
|
||||
"""
|
||||
event = MockEvent(u"%run aa")
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"aaø.py"})
|
||||
|
||||
@onlyif_unicode_paths
|
||||
def test_3(self):
|
||||
"""Test magic_run_completer with unterminated " """
|
||||
event = MockEvent(u'%run "a')
|
||||
mockself = None
|
||||
match = set(magic_run_completer(mockself, event))
|
||||
self.assertEqual(match, {u"a.py", u"aaø.py"})
|
||||
|
||||
# module_completer:
|
||||
|
||||
def test_import_invalid_module():
|
||||
"""Testing of issue https://github.com/ipython/ipython/issues/1107"""
|
||||
invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
|
||||
valid_module_names = {'foobar'}
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
sys.path.insert( 0, tmpdir )
|
||||
for name in invalid_module_names | valid_module_names:
|
||||
filename = os.path.join(tmpdir, name + '.py')
|
||||
open(filename, 'w').close()
|
||||
|
||||
s = set( module_completion('import foo') )
|
||||
intersection = s.intersection(invalid_module_names)
|
||||
nt.assert_equal(intersection, set())
|
||||
|
||||
assert valid_module_names.issubset(s), valid_module_names.intersection(s)
|
||||
|
||||
|
||||
def test_bad_module_all():
|
||||
"""Test module with invalid __all__
|
||||
|
||||
https://github.com/ipython/ipython/issues/9678
|
||||
"""
|
||||
testsdir = os.path.dirname(__file__)
|
||||
sys.path.insert(0, testsdir)
|
||||
try:
|
||||
results = module_completion('from bad_all import ')
|
||||
nt.assert_in('puppies', results)
|
||||
for r in results:
|
||||
nt.assert_is_instance(r, str)
|
||||
finally:
|
||||
sys.path.remove(testsdir)
|
||||
|
||||
|
||||
def test_module_without_init():
|
||||
"""
|
||||
Test module without __init__.py.
|
||||
|
||||
https://github.com/ipython/ipython/issues/11226
|
||||
"""
|
||||
fake_module_name = "foo"
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
sys.path.insert(0, tmpdir)
|
||||
try:
|
||||
os.makedirs(os.path.join(tmpdir, fake_module_name))
|
||||
s = try_import(mod=fake_module_name)
|
||||
assert s == []
|
||||
finally:
|
||||
sys.path.remove(tmpdir)
|
||||
326
venv/Lib/site-packages/IPython/core/tests/test_debugger.py
Normal file
326
venv/Lib/site-packages/IPython/core/tests/test_debugger.py
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
"""Tests for debugging machinery.
|
||||
"""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import bdb
|
||||
import builtins
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import warnings
|
||||
from subprocess import PIPE, CalledProcessError, check_output
|
||||
from tempfile import NamedTemporaryFile
|
||||
from textwrap import dedent
|
||||
from unittest.mock import patch
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core import debugger
|
||||
from IPython.testing import IPYTHON_TESTING_TIMEOUT_SCALE
|
||||
from IPython.testing.decorators import skip_win32
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Helper classes, from CPython's Pdb test suite
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class _FakeInput(object):
|
||||
"""
|
||||
A fake input stream for pdb's interactive debugger. Whenever a
|
||||
line is read, print it (to simulate the user typing it), and then
|
||||
return it. The set of lines to return is specified in the
|
||||
constructor; they should not have trailing newlines.
|
||||
"""
|
||||
def __init__(self, lines):
|
||||
self.lines = iter(lines)
|
||||
|
||||
def readline(self):
|
||||
line = next(self.lines)
|
||||
print(line)
|
||||
return line+'\n'
|
||||
|
||||
class PdbTestInput(object):
|
||||
"""Context manager that makes testing Pdb in doctests easier."""
|
||||
|
||||
def __init__(self, input):
|
||||
self.input = input
|
||||
|
||||
def __enter__(self):
|
||||
self.real_stdin = sys.stdin
|
||||
sys.stdin = _FakeInput(self.input)
|
||||
|
||||
def __exit__(self, *exc):
|
||||
sys.stdin = self.real_stdin
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Tests
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def test_longer_repr():
|
||||
try:
|
||||
from reprlib import repr as trepr # Py 3
|
||||
except ImportError:
|
||||
from repr import repr as trepr # Py 2
|
||||
|
||||
a = '1234567890'* 7
|
||||
ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
|
||||
a_trunc = "'123456789012...8901234567890'"
|
||||
nt.assert_equal(trepr(a), a_trunc)
|
||||
# The creation of our tracer modifies the repr module's repr function
|
||||
# in-place, since that global is used directly by the stdlib's pdb module.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
debugger.Tracer()
|
||||
nt.assert_equal(trepr(a), ar)
|
||||
|
||||
def test_ipdb_magics():
|
||||
'''Test calling some IPython magics from ipdb.
|
||||
|
||||
First, set up some test functions and classes which we can inspect.
|
||||
|
||||
>>> class ExampleClass(object):
|
||||
... """Docstring for ExampleClass."""
|
||||
... def __init__(self):
|
||||
... """Docstring for ExampleClass.__init__"""
|
||||
... pass
|
||||
... def __str__(self):
|
||||
... return "ExampleClass()"
|
||||
|
||||
>>> def example_function(x, y, z="hello"):
|
||||
... """Docstring for example_function."""
|
||||
... pass
|
||||
|
||||
>>> old_trace = sys.gettrace()
|
||||
|
||||
Create a function which triggers ipdb.
|
||||
|
||||
>>> def trigger_ipdb():
|
||||
... a = ExampleClass()
|
||||
... debugger.Pdb().set_trace()
|
||||
|
||||
>>> with PdbTestInput([
|
||||
... 'pdef example_function',
|
||||
... 'pdoc ExampleClass',
|
||||
... 'up',
|
||||
... 'down',
|
||||
... 'list',
|
||||
... 'pinfo a',
|
||||
... 'll',
|
||||
... 'continue',
|
||||
... ]):
|
||||
... trigger_ipdb()
|
||||
--Return--
|
||||
None
|
||||
> <doctest ...>(3)trigger_ipdb()
|
||||
1 def trigger_ipdb():
|
||||
2 a = ExampleClass()
|
||||
----> 3 debugger.Pdb().set_trace()
|
||||
<BLANKLINE>
|
||||
ipdb> pdef example_function
|
||||
example_function(x, y, z='hello')
|
||||
ipdb> pdoc ExampleClass
|
||||
Class docstring:
|
||||
Docstring for ExampleClass.
|
||||
Init docstring:
|
||||
Docstring for ExampleClass.__init__
|
||||
ipdb> up
|
||||
> <doctest ...>(11)<module>()
|
||||
7 'pinfo a',
|
||||
8 'll',
|
||||
9 'continue',
|
||||
10 ]):
|
||||
---> 11 trigger_ipdb()
|
||||
<BLANKLINE>
|
||||
ipdb> down
|
||||
None
|
||||
> <doctest ...>(3)trigger_ipdb()
|
||||
1 def trigger_ipdb():
|
||||
2 a = ExampleClass()
|
||||
----> 3 debugger.Pdb().set_trace()
|
||||
<BLANKLINE>
|
||||
ipdb> list
|
||||
1 def trigger_ipdb():
|
||||
2 a = ExampleClass()
|
||||
----> 3 debugger.Pdb().set_trace()
|
||||
<BLANKLINE>
|
||||
ipdb> pinfo a
|
||||
Type: ExampleClass
|
||||
String form: ExampleClass()
|
||||
Namespace: Local...
|
||||
Docstring: Docstring for ExampleClass.
|
||||
Init docstring: Docstring for ExampleClass.__init__
|
||||
ipdb> ll
|
||||
1 def trigger_ipdb():
|
||||
2 a = ExampleClass()
|
||||
----> 3 debugger.Pdb().set_trace()
|
||||
<BLANKLINE>
|
||||
ipdb> continue
|
||||
|
||||
Restore previous trace function, e.g. for coverage.py
|
||||
|
||||
>>> sys.settrace(old_trace)
|
||||
'''
|
||||
|
||||
def test_ipdb_magics2():
|
||||
'''Test ipdb with a very short function.
|
||||
|
||||
>>> old_trace = sys.gettrace()
|
||||
|
||||
>>> def bar():
|
||||
... pass
|
||||
|
||||
Run ipdb.
|
||||
|
||||
>>> with PdbTestInput([
|
||||
... 'continue',
|
||||
... ]):
|
||||
... debugger.Pdb().runcall(bar)
|
||||
> <doctest ...>(2)bar()
|
||||
1 def bar():
|
||||
----> 2 pass
|
||||
<BLANKLINE>
|
||||
ipdb> continue
|
||||
|
||||
Restore previous trace function, e.g. for coverage.py
|
||||
|
||||
>>> sys.settrace(old_trace)
|
||||
'''
|
||||
|
||||
def can_quit():
|
||||
'''Test that quit work in ipydb
|
||||
|
||||
>>> old_trace = sys.gettrace()
|
||||
|
||||
>>> def bar():
|
||||
... pass
|
||||
|
||||
>>> with PdbTestInput([
|
||||
... 'quit',
|
||||
... ]):
|
||||
... debugger.Pdb().runcall(bar)
|
||||
> <doctest ...>(2)bar()
|
||||
1 def bar():
|
||||
----> 2 pass
|
||||
<BLANKLINE>
|
||||
ipdb> quit
|
||||
|
||||
Restore previous trace function, e.g. for coverage.py
|
||||
|
||||
>>> sys.settrace(old_trace)
|
||||
'''
|
||||
|
||||
|
||||
def can_exit():
|
||||
'''Test that quit work in ipydb
|
||||
|
||||
>>> old_trace = sys.gettrace()
|
||||
|
||||
>>> def bar():
|
||||
... pass
|
||||
|
||||
>>> with PdbTestInput([
|
||||
... 'exit',
|
||||
... ]):
|
||||
... debugger.Pdb().runcall(bar)
|
||||
> <doctest ...>(2)bar()
|
||||
1 def bar():
|
||||
----> 2 pass
|
||||
<BLANKLINE>
|
||||
ipdb> exit
|
||||
|
||||
Restore previous trace function, e.g. for coverage.py
|
||||
|
||||
>>> sys.settrace(old_trace)
|
||||
'''
|
||||
|
||||
|
||||
def test_interruptible_core_debugger():
|
||||
"""The debugger can be interrupted.
|
||||
|
||||
The presumption is there is some mechanism that causes a KeyboardInterrupt
|
||||
(this is implemented in ipykernel). We want to ensure the
|
||||
KeyboardInterrupt cause debugging to cease.
|
||||
"""
|
||||
def raising_input(msg="", called=[0]):
|
||||
called[0] += 1
|
||||
if called[0] == 1:
|
||||
raise KeyboardInterrupt()
|
||||
else:
|
||||
raise AssertionError("input() should only be called once!")
|
||||
|
||||
with patch.object(builtins, "input", raising_input):
|
||||
debugger.InterruptiblePdb().set_trace()
|
||||
# The way this test will fail is by set_trace() never exiting,
|
||||
# resulting in a timeout by the test runner. The alternative
|
||||
# implementation would involve a subprocess, but that adds issues with
|
||||
# interrupting subprocesses that are rather complex, so it's simpler
|
||||
# just to do it this way.
|
||||
|
||||
@skip_win32
|
||||
def test_xmode_skip():
|
||||
"""that xmode skip frames
|
||||
|
||||
Not as a doctest as pytest does not run doctests.
|
||||
"""
|
||||
import pexpect
|
||||
env = os.environ.copy()
|
||||
env["IPY_TEST_SIMPLE_PROMPT"] = "1"
|
||||
|
||||
child = pexpect.spawn(
|
||||
sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
|
||||
)
|
||||
child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
|
||||
|
||||
child.expect("IPython")
|
||||
child.expect("\n")
|
||||
child.expect_exact("In [1]")
|
||||
|
||||
block = dedent(
|
||||
"""
|
||||
def f():
|
||||
__tracebackhide__ = True
|
||||
g()
|
||||
|
||||
def g():
|
||||
raise ValueError
|
||||
|
||||
f()
|
||||
"""
|
||||
)
|
||||
|
||||
for line in block.splitlines():
|
||||
child.sendline(line)
|
||||
child.expect_exact(line)
|
||||
child.expect_exact("skipping")
|
||||
|
||||
block = dedent(
|
||||
"""
|
||||
def f():
|
||||
__tracebackhide__ = True
|
||||
g()
|
||||
|
||||
def g():
|
||||
from IPython.core.debugger import set_trace
|
||||
set_trace()
|
||||
|
||||
f()
|
||||
"""
|
||||
)
|
||||
|
||||
for line in block.splitlines():
|
||||
child.sendline(line)
|
||||
child.expect_exact(line)
|
||||
|
||||
child.expect("ipdb>")
|
||||
child.sendline("w")
|
||||
child.expect("hidden")
|
||||
child.expect("ipdb>")
|
||||
child.sendline("skip_hidden false")
|
||||
child.sendline("w")
|
||||
child.expect("__traceba")
|
||||
child.expect("ipdb>")
|
||||
|
||||
child.close()
|
||||
455
venv/Lib/site-packages/IPython/core/tests/test_display.py
Normal file
455
venv/Lib/site-packages/IPython/core/tests/test_display.py
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from unittest import mock
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core import display
|
||||
from IPython.core.getipython import get_ipython
|
||||
from IPython.utils.io import capture_output
|
||||
from IPython.utils.tempdir import NamedFileInTemporaryDirectory
|
||||
from IPython import paths as ipath
|
||||
from IPython.testing.tools import AssertNotPrints
|
||||
|
||||
import IPython.testing.decorators as dec
|
||||
|
||||
def test_image_size():
|
||||
"""Simple test for display.Image(args, width=x,height=y)"""
|
||||
thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
|
||||
img = display.Image(url=thisurl, width=200, height=200)
|
||||
nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
|
||||
img = display.Image(url=thisurl, metadata={'width':200, 'height':200})
|
||||
nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
|
||||
img = display.Image(url=thisurl, width=200)
|
||||
nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
|
||||
img = display.Image(url=thisurl)
|
||||
nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
|
||||
img = display.Image(url=thisurl, unconfined=True)
|
||||
nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_())
|
||||
|
||||
|
||||
def test_image_mimes():
|
||||
fmt = get_ipython().display_formatter.format
|
||||
for format in display.Image._ACCEPTABLE_EMBEDDINGS:
|
||||
mime = display.Image._MIMETYPES[format]
|
||||
img = display.Image(b'garbage', format=format)
|
||||
data, metadata = fmt(img)
|
||||
nt.assert_equal(sorted(data), sorted([mime, 'text/plain']))
|
||||
|
||||
|
||||
def test_geojson():
|
||||
|
||||
gj = display.GeoJSON(data={
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [-81.327, 296.038]
|
||||
},
|
||||
"properties": {
|
||||
"name": "Inca City"
|
||||
}
|
||||
},
|
||||
url_template="http://s3-eu-west-1.amazonaws.com/whereonmars.cartodb.net/{basemap_id}/{z}/{x}/{y}.png",
|
||||
layer_options={
|
||||
"basemap_id": "celestia_mars-shaded-16k_global",
|
||||
"attribution": "Celestia/praesepe",
|
||||
"minZoom": 0,
|
||||
"maxZoom": 18,
|
||||
})
|
||||
nt.assert_equal(u'<IPython.core.display.GeoJSON object>', str(gj))
|
||||
|
||||
def test_retina_png():
|
||||
here = os.path.dirname(__file__)
|
||||
img = display.Image(os.path.join(here, "2x2.png"), retina=True)
|
||||
nt.assert_equal(img.height, 1)
|
||||
nt.assert_equal(img.width, 1)
|
||||
data, md = img._repr_png_()
|
||||
nt.assert_equal(md['width'], 1)
|
||||
nt.assert_equal(md['height'], 1)
|
||||
|
||||
def test_embed_svg_url():
|
||||
import gzip
|
||||
from io import BytesIO
|
||||
svg_data = b'<svg><circle x="0" y="0" r="1"/></svg>'
|
||||
url = 'http://test.com/circle.svg'
|
||||
|
||||
gzip_svg = BytesIO()
|
||||
with gzip.open(gzip_svg, 'wb') as fp:
|
||||
fp.write(svg_data)
|
||||
gzip_svg = gzip_svg.getvalue()
|
||||
|
||||
def mocked_urlopen(*args, **kwargs):
|
||||
class MockResponse:
|
||||
def __init__(self, svg):
|
||||
self._svg_data = svg
|
||||
self.headers = {'content-type': 'image/svg+xml'}
|
||||
|
||||
def read(self):
|
||||
return self._svg_data
|
||||
|
||||
if args[0] == url:
|
||||
return MockResponse(svg_data)
|
||||
elif args[0] == url + 'z':
|
||||
ret= MockResponse(gzip_svg)
|
||||
ret.headers['content-encoding']= 'gzip'
|
||||
return ret
|
||||
return MockResponse(None)
|
||||
|
||||
with mock.patch('urllib.request.urlopen', side_effect=mocked_urlopen):
|
||||
svg = display.SVG(url=url)
|
||||
nt.assert_true(svg._repr_svg_().startswith('<svg'))
|
||||
svg = display.SVG(url=url + 'z')
|
||||
nt.assert_true(svg._repr_svg_().startswith('<svg'))
|
||||
|
||||
def test_retina_jpeg():
|
||||
here = os.path.dirname(__file__)
|
||||
img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
|
||||
nt.assert_equal(img.height, 1)
|
||||
nt.assert_equal(img.width, 1)
|
||||
data, md = img._repr_jpeg_()
|
||||
nt.assert_equal(md['width'], 1)
|
||||
nt.assert_equal(md['height'], 1)
|
||||
|
||||
def test_base64image():
|
||||
display.Image("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AAAAACAAHiIbwzAAAAAElFTkSuQmCC")
|
||||
|
||||
def test_image_filename_defaults():
|
||||
'''test format constraint, and validity of jpeg and png'''
|
||||
tpath = ipath.get_ipython_package_dir()
|
||||
nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.zip'),
|
||||
embed=True)
|
||||
nt.assert_raises(ValueError, display.Image)
|
||||
nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
|
||||
# check boths paths to allow packages to test at build and install time
|
||||
imgfile = os.path.join(tpath, 'core/tests/2x2.png')
|
||||
img = display.Image(filename=imgfile)
|
||||
nt.assert_equal('png', img.format)
|
||||
nt.assert_is_not_none(img._repr_png_())
|
||||
img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
|
||||
nt.assert_equal('jpeg', img.format)
|
||||
nt.assert_is_none(img._repr_jpeg_())
|
||||
|
||||
def _get_inline_config():
|
||||
from ipykernel.pylab.config import InlineBackend
|
||||
return InlineBackend.instance()
|
||||
|
||||
@dec.skip_without('matplotlib')
|
||||
def test_set_matplotlib_close():
|
||||
cfg = _get_inline_config()
|
||||
cfg.close_figures = False
|
||||
display.set_matplotlib_close()
|
||||
assert cfg.close_figures
|
||||
display.set_matplotlib_close(False)
|
||||
assert not cfg.close_figures
|
||||
|
||||
_fmt_mime_map = {
|
||||
'png': 'image/png',
|
||||
'jpeg': 'image/jpeg',
|
||||
'pdf': 'application/pdf',
|
||||
'retina': 'image/png',
|
||||
'svg': 'image/svg+xml',
|
||||
}
|
||||
|
||||
@dec.skip_without('matplotlib')
|
||||
def test_set_matplotlib_formats():
|
||||
from matplotlib.figure import Figure
|
||||
formatters = get_ipython().display_formatter.formatters
|
||||
for formats in [
|
||||
('png',),
|
||||
('pdf', 'svg'),
|
||||
('jpeg', 'retina', 'png'),
|
||||
(),
|
||||
]:
|
||||
active_mimes = {_fmt_mime_map[fmt] for fmt in formats}
|
||||
display.set_matplotlib_formats(*formats)
|
||||
for mime, f in formatters.items():
|
||||
if mime in active_mimes:
|
||||
nt.assert_in(Figure, f)
|
||||
else:
|
||||
nt.assert_not_in(Figure, f)
|
||||
|
||||
@dec.skip_without('matplotlib')
|
||||
def test_set_matplotlib_formats_kwargs():
|
||||
from matplotlib.figure import Figure
|
||||
ip = get_ipython()
|
||||
cfg = _get_inline_config()
|
||||
cfg.print_figure_kwargs.update(dict(foo='bar'))
|
||||
kwargs = dict(quality=10)
|
||||
display.set_matplotlib_formats('png', **kwargs)
|
||||
formatter = ip.display_formatter.formatters['image/png']
|
||||
f = formatter.lookup_by_type(Figure)
|
||||
cell = f.__closure__[0].cell_contents
|
||||
expected = kwargs
|
||||
expected.update(cfg.print_figure_kwargs)
|
||||
nt.assert_equal(cell, expected)
|
||||
|
||||
def test_display_available():
|
||||
"""
|
||||
Test that display is available without import
|
||||
|
||||
We don't really care if it's in builtin or anything else, but it should
|
||||
always be available.
|
||||
"""
|
||||
ip = get_ipython()
|
||||
with AssertNotPrints('NameError'):
|
||||
ip.run_cell('display')
|
||||
try:
|
||||
ip.run_cell('del display')
|
||||
except NameError:
|
||||
pass # it's ok, it might be in builtins
|
||||
# even if deleted it should be back
|
||||
with AssertNotPrints('NameError'):
|
||||
ip.run_cell('display')
|
||||
|
||||
def test_textdisplayobj_pretty_repr():
|
||||
p = display.Pretty("This is a simple test")
|
||||
nt.assert_equal(repr(p), '<IPython.core.display.Pretty object>')
|
||||
nt.assert_equal(p.data, 'This is a simple test')
|
||||
|
||||
p._show_mem_addr = True
|
||||
nt.assert_equal(repr(p), object.__repr__(p))
|
||||
|
||||
def test_displayobject_repr():
|
||||
h = display.HTML('<br />')
|
||||
nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
|
||||
h._show_mem_addr = True
|
||||
nt.assert_equal(repr(h), object.__repr__(h))
|
||||
h._show_mem_addr = False
|
||||
nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
|
||||
|
||||
j = display.Javascript('')
|
||||
nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
|
||||
j._show_mem_addr = True
|
||||
nt.assert_equal(repr(j), object.__repr__(j))
|
||||
j._show_mem_addr = False
|
||||
nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
|
||||
|
||||
@mock.patch('warnings.warn')
|
||||
def test_encourage_iframe_over_html(m_warn):
|
||||
display.HTML()
|
||||
m_warn.assert_not_called()
|
||||
|
||||
display.HTML('<br />')
|
||||
m_warn.assert_not_called()
|
||||
|
||||
display.HTML('<html><p>Lots of content here</p><iframe src="http://a.com"></iframe>')
|
||||
m_warn.assert_not_called()
|
||||
|
||||
display.HTML('<iframe src="http://a.com"></iframe>')
|
||||
m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
|
||||
|
||||
m_warn.reset_mock()
|
||||
display.HTML('<IFRAME SRC="http://a.com"></IFRAME>')
|
||||
m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
|
||||
|
||||
def test_progress():
|
||||
p = display.ProgressBar(10)
|
||||
nt.assert_in('0/10',repr(p))
|
||||
p.html_width = '100%'
|
||||
p.progress = 5
|
||||
nt.assert_equal(p._repr_html_(), "<progress style='width:100%' max='10' value='5'></progress>")
|
||||
|
||||
def test_progress_iter():
|
||||
with capture_output(display=False) as captured:
|
||||
for i in display.ProgressBar(5):
|
||||
out = captured.stdout
|
||||
nt.assert_in('{0}/5'.format(i), out)
|
||||
out = captured.stdout
|
||||
nt.assert_in('5/5', out)
|
||||
|
||||
def test_json():
|
||||
d = {'a': 5}
|
||||
lis = [d]
|
||||
metadata = [
|
||||
{'expanded': False, 'root': 'root'},
|
||||
{'expanded': True, 'root': 'root'},
|
||||
{'expanded': False, 'root': 'custom'},
|
||||
{'expanded': True, 'root': 'custom'},
|
||||
]
|
||||
json_objs = [
|
||||
display.JSON(d),
|
||||
display.JSON(d, expanded=True),
|
||||
display.JSON(d, root='custom'),
|
||||
display.JSON(d, expanded=True, root='custom'),
|
||||
]
|
||||
for j, md in zip(json_objs, metadata):
|
||||
nt.assert_equal(j._repr_json_(), (d, md))
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
j = display.JSON(json.dumps(d))
|
||||
nt.assert_equal(len(w), 1)
|
||||
nt.assert_equal(j._repr_json_(), (d, metadata[0]))
|
||||
|
||||
json_objs = [
|
||||
display.JSON(lis),
|
||||
display.JSON(lis, expanded=True),
|
||||
display.JSON(lis, root='custom'),
|
||||
display.JSON(lis, expanded=True, root='custom'),
|
||||
]
|
||||
for j, md in zip(json_objs, metadata):
|
||||
nt.assert_equal(j._repr_json_(), (lis, md))
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
j = display.JSON(json.dumps(lis))
|
||||
nt.assert_equal(len(w), 1)
|
||||
nt.assert_equal(j._repr_json_(), (lis, metadata[0]))
|
||||
|
||||
def test_video_embedding():
|
||||
"""use a tempfile, with dummy-data, to ensure that video embedding doesn't crash"""
|
||||
v = display.Video("http://ignored")
|
||||
assert not v.embed
|
||||
html = v._repr_html_()
|
||||
nt.assert_not_in('src="data:', html)
|
||||
nt.assert_in('src="http://ignored"', html)
|
||||
|
||||
with nt.assert_raises(ValueError):
|
||||
v = display.Video(b'abc')
|
||||
|
||||
with NamedFileInTemporaryDirectory('test.mp4') as f:
|
||||
f.write(b'abc')
|
||||
f.close()
|
||||
|
||||
v = display.Video(f.name)
|
||||
assert not v.embed
|
||||
html = v._repr_html_()
|
||||
nt.assert_not_in('src="data:', html)
|
||||
|
||||
v = display.Video(f.name, embed=True)
|
||||
html = v._repr_html_()
|
||||
nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
|
||||
|
||||
v = display.Video(f.name, embed=True, mimetype='video/other')
|
||||
html = v._repr_html_()
|
||||
nt.assert_in('src="data:video/other;base64,YWJj"',html)
|
||||
|
||||
v = display.Video(b'abc', embed=True, mimetype='video/mp4')
|
||||
html = v._repr_html_()
|
||||
nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
|
||||
|
||||
v = display.Video(u'YWJj', embed=True, mimetype='video/xyz')
|
||||
html = v._repr_html_()
|
||||
nt.assert_in('src="data:video/xyz;base64,YWJj"',html)
|
||||
|
||||
def test_html_metadata():
|
||||
s = "<h1>Test</h1>"
|
||||
h = display.HTML(s, metadata={"isolated": True})
|
||||
nt.assert_equal(h._repr_html_(), (s, {"isolated": True}))
|
||||
|
||||
def test_display_id():
|
||||
ip = get_ipython()
|
||||
with mock.patch.object(ip.display_pub, 'publish') as pub:
|
||||
handle = display.display('x')
|
||||
nt.assert_is(handle, None)
|
||||
handle = display.display('y', display_id='secret')
|
||||
nt.assert_is_instance(handle, display.DisplayHandle)
|
||||
handle2 = display.display('z', display_id=True)
|
||||
nt.assert_is_instance(handle2, display.DisplayHandle)
|
||||
nt.assert_not_equal(handle.display_id, handle2.display_id)
|
||||
|
||||
nt.assert_equal(pub.call_count, 3)
|
||||
args, kwargs = pub.call_args_list[0]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('x')
|
||||
},
|
||||
'metadata': {},
|
||||
})
|
||||
args, kwargs = pub.call_args_list[1]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('y')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': handle.display_id,
|
||||
},
|
||||
})
|
||||
args, kwargs = pub.call_args_list[2]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('z')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': handle2.display_id,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
def test_update_display():
|
||||
ip = get_ipython()
|
||||
with mock.patch.object(ip.display_pub, 'publish') as pub:
|
||||
with nt.assert_raises(TypeError):
|
||||
display.update_display('x')
|
||||
display.update_display('x', display_id='1')
|
||||
display.update_display('y', display_id='2')
|
||||
args, kwargs = pub.call_args_list[0]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('x')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': '1',
|
||||
},
|
||||
'update': True,
|
||||
})
|
||||
args, kwargs = pub.call_args_list[1]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('y')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': '2',
|
||||
},
|
||||
'update': True,
|
||||
})
|
||||
|
||||
|
||||
def test_display_handle():
|
||||
ip = get_ipython()
|
||||
handle = display.DisplayHandle()
|
||||
nt.assert_is_instance(handle.display_id, str)
|
||||
handle = display.DisplayHandle('my-id')
|
||||
nt.assert_equal(handle.display_id, 'my-id')
|
||||
with mock.patch.object(ip.display_pub, 'publish') as pub:
|
||||
handle.display('x')
|
||||
handle.update('y')
|
||||
|
||||
args, kwargs = pub.call_args_list[0]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('x')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': handle.display_id,
|
||||
}
|
||||
})
|
||||
args, kwargs = pub.call_args_list[1]
|
||||
nt.assert_equal(args, ())
|
||||
nt.assert_equal(kwargs, {
|
||||
'data': {
|
||||
'text/plain': repr('y')
|
||||
},
|
||||
'metadata': {},
|
||||
'transient': {
|
||||
'display_id': handle.display_id,
|
||||
},
|
||||
'update': True,
|
||||
})
|
||||
|
||||
112
venv/Lib/site-packages/IPython/core/tests/test_displayhook.py
Normal file
112
venv/Lib/site-packages/IPython/core/tests/test_displayhook.py
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import sys
|
||||
from IPython.testing.tools import AssertPrints, AssertNotPrints
|
||||
from IPython.core.displayhook import CapturingDisplayHook
|
||||
from IPython.utils.capture import CapturedIO
|
||||
|
||||
def test_output_displayed():
|
||||
"""Checking to make sure that output is displayed"""
|
||||
|
||||
with AssertPrints('2'):
|
||||
ip.run_cell('1+1', store_history=True)
|
||||
|
||||
with AssertPrints('2'):
|
||||
ip.run_cell('1+1 # comment with a semicolon;', store_history=True)
|
||||
|
||||
with AssertPrints('2'):
|
||||
ip.run_cell('1+1\n#commented_out_function();', store_history=True)
|
||||
|
||||
|
||||
def test_output_quiet():
|
||||
"""Checking to make sure that output is quiet"""
|
||||
|
||||
with AssertNotPrints('2'):
|
||||
ip.run_cell('1+1;', store_history=True)
|
||||
|
||||
with AssertNotPrints('2'):
|
||||
ip.run_cell('1+1; # comment with a semicolon', store_history=True)
|
||||
|
||||
with AssertNotPrints('2'):
|
||||
ip.run_cell('1+1;\n#commented_out_function()', store_history=True)
|
||||
|
||||
def test_underscore_no_overrite_user():
|
||||
ip.run_cell('_ = 42', store_history=True)
|
||||
ip.run_cell('1+1', store_history=True)
|
||||
|
||||
with AssertPrints('42'):
|
||||
ip.run_cell('print(_)', store_history=True)
|
||||
|
||||
ip.run_cell('del _', store_history=True)
|
||||
ip.run_cell('6+6', store_history=True)
|
||||
with AssertPrints('12'):
|
||||
ip.run_cell('_', store_history=True)
|
||||
|
||||
|
||||
def test_underscore_no_overrite_builtins():
|
||||
ip.run_cell("import gettext ; gettext.install('foo')", store_history=True)
|
||||
ip.run_cell('3+3', store_history=True)
|
||||
|
||||
with AssertPrints('gettext'):
|
||||
ip.run_cell('print(_)', store_history=True)
|
||||
|
||||
ip.run_cell('_ = "userset"', store_history=True)
|
||||
|
||||
with AssertPrints('userset'):
|
||||
ip.run_cell('print(_)', store_history=True)
|
||||
ip.run_cell('import builtins; del builtins._')
|
||||
|
||||
|
||||
def test_interactivehooks_ast_modes():
|
||||
"""
|
||||
Test that ast nodes can be triggered with different modes
|
||||
"""
|
||||
saved_mode = ip.ast_node_interactivity
|
||||
ip.ast_node_interactivity = 'last_expr_or_assign'
|
||||
|
||||
try:
|
||||
with AssertPrints('2'):
|
||||
ip.run_cell('a = 1+1', store_history=True)
|
||||
|
||||
with AssertPrints('9'):
|
||||
ip.run_cell('b = 1+8 # comment with a semicolon;', store_history=False)
|
||||
|
||||
with AssertPrints('7'):
|
||||
ip.run_cell('c = 1+6\n#commented_out_function();', store_history=True)
|
||||
|
||||
ip.run_cell('d = 11', store_history=True)
|
||||
with AssertPrints('12'):
|
||||
ip.run_cell('d += 1', store_history=True)
|
||||
|
||||
with AssertNotPrints('42'):
|
||||
ip.run_cell('(u,v) = (41+1, 43-1)')
|
||||
|
||||
finally:
|
||||
ip.ast_node_interactivity = saved_mode
|
||||
|
||||
def test_interactivehooks_ast_modes_semi_suppress():
|
||||
"""
|
||||
Test that ast nodes can be triggered with different modes and suppressed
|
||||
by semicolon
|
||||
"""
|
||||
saved_mode = ip.ast_node_interactivity
|
||||
ip.ast_node_interactivity = 'last_expr_or_assign'
|
||||
|
||||
try:
|
||||
with AssertNotPrints('2'):
|
||||
ip.run_cell('x = 1+1;', store_history=True)
|
||||
|
||||
with AssertNotPrints('7'):
|
||||
ip.run_cell('y = 1+6; # comment with a semicolon', store_history=True)
|
||||
|
||||
with AssertNotPrints('9'):
|
||||
ip.run_cell('z = 1+8;\n#commented_out_function()', store_history=True)
|
||||
|
||||
finally:
|
||||
ip.ast_node_interactivity = saved_mode
|
||||
|
||||
def test_capture_display_hook_format():
|
||||
"""Tests that the capture display hook conforms to the CapturedIO output format"""
|
||||
hook = CapturingDisplayHook(ip)
|
||||
hook({"foo": "bar"})
|
||||
captured = CapturedIO(sys.stdout, sys.stderr, hook.outputs)
|
||||
# Should not raise with RichOutput transformation error
|
||||
captured.outputs
|
||||
92
venv/Lib/site-packages/IPython/core/tests/test_events.py
Normal file
92
venv/Lib/site-packages/IPython/core/tests/test_events.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import unittest
|
||||
from unittest.mock import Mock
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core import events
|
||||
import IPython.testing.tools as tt
|
||||
|
||||
|
||||
@events._define_event
|
||||
def ping_received():
|
||||
pass
|
||||
|
||||
|
||||
@events._define_event
|
||||
def event_with_argument(argument):
|
||||
pass
|
||||
|
||||
|
||||
class CallbackTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.em = events.EventManager(get_ipython(),
|
||||
{'ping_received': ping_received,
|
||||
'event_with_argument': event_with_argument})
|
||||
|
||||
def test_register_unregister(self):
|
||||
cb = Mock()
|
||||
|
||||
self.em.register('ping_received', cb)
|
||||
self.em.trigger('ping_received')
|
||||
self.assertEqual(cb.call_count, 1)
|
||||
|
||||
self.em.unregister('ping_received', cb)
|
||||
self.em.trigger('ping_received')
|
||||
self.assertEqual(cb.call_count, 1)
|
||||
|
||||
def test_bare_function_missed_unregister(self):
|
||||
def cb1():
|
||||
...
|
||||
|
||||
def cb2():
|
||||
...
|
||||
|
||||
self.em.register('ping_received', cb1)
|
||||
nt.assert_raises(ValueError, self.em.unregister, 'ping_received', cb2)
|
||||
self.em.unregister('ping_received', cb1)
|
||||
|
||||
def test_cb_error(self):
|
||||
cb = Mock(side_effect=ValueError)
|
||||
self.em.register('ping_received', cb)
|
||||
with tt.AssertPrints("Error in callback"):
|
||||
self.em.trigger('ping_received')
|
||||
|
||||
def test_cb_keyboard_interrupt(self):
|
||||
cb = Mock(side_effect=KeyboardInterrupt)
|
||||
self.em.register('ping_received', cb)
|
||||
with tt.AssertPrints("Error in callback"):
|
||||
self.em.trigger('ping_received')
|
||||
|
||||
def test_unregister_during_callback(self):
|
||||
invoked = [False] * 3
|
||||
|
||||
def func1(*_):
|
||||
invoked[0] = True
|
||||
self.em.unregister('ping_received', func1)
|
||||
self.em.register('ping_received', func3)
|
||||
|
||||
def func2(*_):
|
||||
invoked[1] = True
|
||||
self.em.unregister('ping_received', func2)
|
||||
|
||||
def func3(*_):
|
||||
invoked[2] = True
|
||||
|
||||
self.em.register('ping_received', func1)
|
||||
self.em.register('ping_received', func2)
|
||||
|
||||
self.em.trigger('ping_received')
|
||||
self.assertEqual([True, True, False], invoked)
|
||||
self.assertEqual([func3], self.em.callbacks['ping_received'])
|
||||
|
||||
def test_ignore_event_arguments_if_no_argument_required(self):
|
||||
call_count = [0]
|
||||
def event_with_no_argument():
|
||||
call_count[0] += 1
|
||||
|
||||
self.em.register('event_with_argument', event_with_no_argument)
|
||||
self.em.trigger('event_with_argument', 'the argument')
|
||||
self.assertEqual(call_count[0], 1)
|
||||
|
||||
self.em.unregister('event_with_argument', event_with_no_argument)
|
||||
self.em.trigger('ping_received')
|
||||
self.assertEqual(call_count[0], 1)
|
||||
96
venv/Lib/site-packages/IPython/core/tests/test_extension.py
Normal file
96
venv/Lib/site-packages/IPython/core/tests/test_extension.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import os.path
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
import IPython.testing.tools as tt
|
||||
from IPython.utils.syspathcontext import prepended_to_syspath
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
ext1_content = """
|
||||
def load_ipython_extension(ip):
|
||||
print("Running ext1 load")
|
||||
|
||||
def unload_ipython_extension(ip):
|
||||
print("Running ext1 unload")
|
||||
"""
|
||||
|
||||
ext2_content = """
|
||||
def load_ipython_extension(ip):
|
||||
print("Running ext2 load")
|
||||
"""
|
||||
|
||||
ext3_content = """
|
||||
def load_ipython_extension(ip):
|
||||
ip2 = get_ipython()
|
||||
print(ip is ip2)
|
||||
"""
|
||||
|
||||
def test_extension_loading():
|
||||
em = get_ipython().extension_manager
|
||||
with TemporaryDirectory() as td:
|
||||
ext1 = os.path.join(td, 'ext1.py')
|
||||
with open(ext1, 'w') as f:
|
||||
f.write(ext1_content)
|
||||
|
||||
ext2 = os.path.join(td, 'ext2.py')
|
||||
with open(ext2, 'w') as f:
|
||||
f.write(ext2_content)
|
||||
|
||||
with prepended_to_syspath(td):
|
||||
assert 'ext1' not in em.loaded
|
||||
assert 'ext2' not in em.loaded
|
||||
|
||||
# Load extension
|
||||
with tt.AssertPrints("Running ext1 load"):
|
||||
assert em.load_extension('ext1') is None
|
||||
assert 'ext1' in em.loaded
|
||||
|
||||
# Should refuse to load it again
|
||||
with tt.AssertNotPrints("Running ext1 load"):
|
||||
assert em.load_extension('ext1') == 'already loaded'
|
||||
|
||||
# Reload
|
||||
with tt.AssertPrints("Running ext1 unload"):
|
||||
with tt.AssertPrints("Running ext1 load", suppress=False):
|
||||
em.reload_extension('ext1')
|
||||
|
||||
# Unload
|
||||
with tt.AssertPrints("Running ext1 unload"):
|
||||
assert em.unload_extension('ext1') is None
|
||||
|
||||
# Can't unload again
|
||||
with tt.AssertNotPrints("Running ext1 unload"):
|
||||
assert em.unload_extension('ext1') == 'not loaded'
|
||||
assert em.unload_extension('ext2') == 'not loaded'
|
||||
|
||||
# Load extension 2
|
||||
with tt.AssertPrints("Running ext2 load"):
|
||||
assert em.load_extension('ext2') is None
|
||||
|
||||
# Can't unload this
|
||||
assert em.unload_extension('ext2') == 'no unload function'
|
||||
|
||||
# But can reload it
|
||||
with tt.AssertPrints("Running ext2 load"):
|
||||
em.reload_extension('ext2')
|
||||
|
||||
|
||||
def test_extension_builtins():
|
||||
em = get_ipython().extension_manager
|
||||
with TemporaryDirectory() as td:
|
||||
ext3 = os.path.join(td, 'ext3.py')
|
||||
with open(ext3, 'w') as f:
|
||||
f.write(ext3_content)
|
||||
|
||||
assert 'ext3' not in em.loaded
|
||||
|
||||
with prepended_to_syspath(td):
|
||||
# Load extension
|
||||
with tt.AssertPrints("True"):
|
||||
assert em.load_extension('ext3') is None
|
||||
assert 'ext3' in em.loaded
|
||||
|
||||
|
||||
def test_non_extension():
|
||||
em = get_ipython().extension_manager
|
||||
nt.assert_equal(em.load_extension('sys'), "no load function")
|
||||
533
venv/Lib/site-packages/IPython/core/tests/test_formatters.py
Normal file
533
venv/Lib/site-packages/IPython/core/tests/test_formatters.py
Normal file
|
|
@ -0,0 +1,533 @@
|
|||
"""Tests for the Formatters."""
|
||||
|
||||
import warnings
|
||||
from math import pi
|
||||
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
numpy = None
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython import get_ipython
|
||||
from traitlets.config import Config
|
||||
from IPython.core.formatters import (
|
||||
PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key,
|
||||
DisplayFormatter, JSONFormatter,
|
||||
)
|
||||
from IPython.utils.io import capture_output
|
||||
|
||||
class A(object):
|
||||
def __repr__(self):
|
||||
return 'A()'
|
||||
|
||||
class B(A):
|
||||
def __repr__(self):
|
||||
return 'B()'
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
class BadRepr(object):
|
||||
def __repr__(self):
|
||||
raise ValueError("bad repr")
|
||||
|
||||
class BadPretty(object):
|
||||
_repr_pretty_ = None
|
||||
|
||||
class GoodPretty(object):
|
||||
def _repr_pretty_(self, pp, cycle):
|
||||
pp.text('foo')
|
||||
|
||||
def __repr__(self):
|
||||
return 'GoodPretty()'
|
||||
|
||||
def foo_printer(obj, pp, cycle):
|
||||
pp.text('foo')
|
||||
|
||||
def test_pretty():
|
||||
f = PlainTextFormatter()
|
||||
f.for_type(A, foo_printer)
|
||||
nt.assert_equal(f(A()), 'foo')
|
||||
nt.assert_equal(f(B()), 'B()')
|
||||
nt.assert_equal(f(GoodPretty()), 'foo')
|
||||
# Just don't raise an exception for the following:
|
||||
f(BadPretty())
|
||||
|
||||
f.pprint = False
|
||||
nt.assert_equal(f(A()), 'A()')
|
||||
nt.assert_equal(f(B()), 'B()')
|
||||
nt.assert_equal(f(GoodPretty()), 'GoodPretty()')
|
||||
|
||||
|
||||
def test_deferred():
|
||||
f = PlainTextFormatter()
|
||||
|
||||
def test_precision():
|
||||
"""test various values for float_precision."""
|
||||
f = PlainTextFormatter()
|
||||
nt.assert_equal(f(pi), repr(pi))
|
||||
f.float_precision = 0
|
||||
if numpy:
|
||||
po = numpy.get_printoptions()
|
||||
nt.assert_equal(po['precision'], 0)
|
||||
nt.assert_equal(f(pi), '3')
|
||||
f.float_precision = 2
|
||||
if numpy:
|
||||
po = numpy.get_printoptions()
|
||||
nt.assert_equal(po['precision'], 2)
|
||||
nt.assert_equal(f(pi), '3.14')
|
||||
f.float_precision = '%g'
|
||||
if numpy:
|
||||
po = numpy.get_printoptions()
|
||||
nt.assert_equal(po['precision'], 2)
|
||||
nt.assert_equal(f(pi), '3.14159')
|
||||
f.float_precision = '%e'
|
||||
nt.assert_equal(f(pi), '3.141593e+00')
|
||||
f.float_precision = ''
|
||||
if numpy:
|
||||
po = numpy.get_printoptions()
|
||||
nt.assert_equal(po['precision'], 8)
|
||||
nt.assert_equal(f(pi), repr(pi))
|
||||
|
||||
def test_bad_precision():
|
||||
"""test various invalid values for float_precision."""
|
||||
f = PlainTextFormatter()
|
||||
def set_fp(p):
|
||||
f.float_precision=p
|
||||
nt.assert_raises(ValueError, set_fp, '%')
|
||||
nt.assert_raises(ValueError, set_fp, '%.3f%i')
|
||||
nt.assert_raises(ValueError, set_fp, 'foo')
|
||||
nt.assert_raises(ValueError, set_fp, -1)
|
||||
|
||||
def test_for_type():
|
||||
f = PlainTextFormatter()
|
||||
|
||||
# initial return, None
|
||||
nt.assert_is(f.for_type(C, foo_printer), None)
|
||||
# no func queries
|
||||
nt.assert_is(f.for_type(C), foo_printer)
|
||||
# shouldn't change anything
|
||||
nt.assert_is(f.for_type(C), foo_printer)
|
||||
# None should do the same
|
||||
nt.assert_is(f.for_type(C, None), foo_printer)
|
||||
nt.assert_is(f.for_type(C, None), foo_printer)
|
||||
|
||||
def test_for_type_string():
|
||||
f = PlainTextFormatter()
|
||||
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
|
||||
# initial return, None
|
||||
nt.assert_is(f.for_type(type_str, foo_printer), None)
|
||||
# no func queries
|
||||
nt.assert_is(f.for_type(type_str), foo_printer)
|
||||
nt.assert_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_is(f.for_type(C), foo_printer)
|
||||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_in(C, f.type_printers)
|
||||
|
||||
def test_for_type_by_name():
|
||||
f = PlainTextFormatter()
|
||||
|
||||
mod = C.__module__
|
||||
|
||||
# initial return, None
|
||||
nt.assert_is(f.for_type_by_name(mod, 'C', foo_printer), None)
|
||||
# no func queries
|
||||
nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
|
||||
# shouldn't change anything
|
||||
nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
|
||||
# None should do the same
|
||||
nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
|
||||
nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
|
||||
|
||||
def test_lookup():
|
||||
f = PlainTextFormatter()
|
||||
|
||||
f.for_type(C, foo_printer)
|
||||
nt.assert_is(f.lookup(C()), foo_printer)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.lookup(A())
|
||||
|
||||
def test_lookup_string():
|
||||
f = PlainTextFormatter()
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
|
||||
f.for_type(type_str, foo_printer)
|
||||
nt.assert_is(f.lookup(C()), foo_printer)
|
||||
# should move from deferred to imported dict
|
||||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_in(C, f.type_printers)
|
||||
|
||||
def test_lookup_by_type():
|
||||
f = PlainTextFormatter()
|
||||
f.for_type(C, foo_printer)
|
||||
nt.assert_is(f.lookup_by_type(C), foo_printer)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.lookup_by_type(A)
|
||||
|
||||
def test_lookup_by_type_string():
|
||||
f = PlainTextFormatter()
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
f.for_type(type_str, foo_printer)
|
||||
|
||||
# verify insertion
|
||||
nt.assert_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_not_in(C, f.type_printers)
|
||||
|
||||
nt.assert_is(f.lookup_by_type(type_str), foo_printer)
|
||||
# lookup by string doesn't cause import
|
||||
nt.assert_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_not_in(C, f.type_printers)
|
||||
|
||||
nt.assert_is(f.lookup_by_type(C), foo_printer)
|
||||
# should move from deferred to imported dict
|
||||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
|
||||
nt.assert_in(C, f.type_printers)
|
||||
|
||||
def test_in_formatter():
|
||||
f = PlainTextFormatter()
|
||||
f.for_type(C, foo_printer)
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
nt.assert_in(C, f)
|
||||
nt.assert_in(type_str, f)
|
||||
|
||||
def test_string_in_formatter():
|
||||
f = PlainTextFormatter()
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
f.for_type(type_str, foo_printer)
|
||||
nt.assert_in(type_str, f)
|
||||
nt.assert_in(C, f)
|
||||
|
||||
def test_pop():
|
||||
f = PlainTextFormatter()
|
||||
f.for_type(C, foo_printer)
|
||||
nt.assert_is(f.lookup_by_type(C), foo_printer)
|
||||
nt.assert_is(f.pop(C, None), foo_printer)
|
||||
f.for_type(C, foo_printer)
|
||||
nt.assert_is(f.pop(C), foo_printer)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.lookup_by_type(C)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.pop(C)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.pop(A)
|
||||
nt.assert_is(f.pop(A, None), None)
|
||||
|
||||
def test_pop_string():
|
||||
f = PlainTextFormatter()
|
||||
type_str = '%s.%s' % (C.__module__, 'C')
|
||||
|
||||
with nt.assert_raises(KeyError):
|
||||
f.pop(type_str)
|
||||
|
||||
f.for_type(type_str, foo_printer)
|
||||
f.pop(type_str)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.lookup_by_type(C)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.pop(type_str)
|
||||
|
||||
f.for_type(C, foo_printer)
|
||||
nt.assert_is(f.pop(type_str, None), foo_printer)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.lookup_by_type(C)
|
||||
with nt.assert_raises(KeyError):
|
||||
f.pop(type_str)
|
||||
nt.assert_is(f.pop(type_str, None), None)
|
||||
|
||||
|
||||
def test_error_method():
|
||||
f = HTMLFormatter()
|
||||
class BadHTML(object):
|
||||
def _repr_html_(self):
|
||||
raise ValueError("Bad HTML")
|
||||
bad = BadHTML()
|
||||
with capture_output() as captured:
|
||||
result = f(bad)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_in("Traceback", captured.stdout)
|
||||
nt.assert_in("Bad HTML", captured.stdout)
|
||||
nt.assert_in("_repr_html_", captured.stdout)
|
||||
|
||||
def test_nowarn_notimplemented():
|
||||
f = HTMLFormatter()
|
||||
class HTMLNotImplemented(object):
|
||||
def _repr_html_(self):
|
||||
raise NotImplementedError
|
||||
h = HTMLNotImplemented()
|
||||
with capture_output() as captured:
|
||||
result = f(h)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_equal("", captured.stderr)
|
||||
nt.assert_equal("", captured.stdout)
|
||||
|
||||
def test_warn_error_for_type():
|
||||
f = HTMLFormatter()
|
||||
f.for_type(int, lambda i: name_error)
|
||||
with capture_output() as captured:
|
||||
result = f(5)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_in("Traceback", captured.stdout)
|
||||
nt.assert_in("NameError", captured.stdout)
|
||||
nt.assert_in("name_error", captured.stdout)
|
||||
|
||||
def test_error_pretty_method():
|
||||
f = PlainTextFormatter()
|
||||
class BadPretty(object):
|
||||
def _repr_pretty_(self):
|
||||
return "hello"
|
||||
bad = BadPretty()
|
||||
with capture_output() as captured:
|
||||
result = f(bad)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_in("Traceback", captured.stdout)
|
||||
nt.assert_in("_repr_pretty_", captured.stdout)
|
||||
nt.assert_in("given", captured.stdout)
|
||||
nt.assert_in("argument", captured.stdout)
|
||||
|
||||
|
||||
def test_bad_repr_traceback():
|
||||
f = PlainTextFormatter()
|
||||
bad = BadRepr()
|
||||
with capture_output() as captured:
|
||||
result = f(bad)
|
||||
# catches error, returns None
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_in("Traceback", captured.stdout)
|
||||
nt.assert_in("__repr__", captured.stdout)
|
||||
nt.assert_in("ValueError", captured.stdout)
|
||||
|
||||
|
||||
class MakePDF(object):
|
||||
def _repr_pdf_(self):
|
||||
return 'PDF'
|
||||
|
||||
def test_pdf_formatter():
|
||||
pdf = MakePDF()
|
||||
f = PDFFormatter()
|
||||
nt.assert_equal(f(pdf), 'PDF')
|
||||
|
||||
def test_print_method_bound():
|
||||
f = HTMLFormatter()
|
||||
class MyHTML(object):
|
||||
def _repr_html_(self):
|
||||
return "hello"
|
||||
with capture_output() as captured:
|
||||
result = f(MyHTML)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_not_in("FormatterWarning", captured.stderr)
|
||||
|
||||
with capture_output() as captured:
|
||||
result = f(MyHTML())
|
||||
nt.assert_equal(result, "hello")
|
||||
nt.assert_equal(captured.stderr, "")
|
||||
|
||||
def test_print_method_weird():
|
||||
|
||||
class TextMagicHat(object):
|
||||
def __getattr__(self, key):
|
||||
return key
|
||||
|
||||
f = HTMLFormatter()
|
||||
|
||||
text_hat = TextMagicHat()
|
||||
nt.assert_equal(text_hat._repr_html_, '_repr_html_')
|
||||
with capture_output() as captured:
|
||||
result = f(text_hat)
|
||||
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_not_in("FormatterWarning", captured.stderr)
|
||||
|
||||
class CallableMagicHat(object):
|
||||
def __getattr__(self, key):
|
||||
return lambda : key
|
||||
|
||||
call_hat = CallableMagicHat()
|
||||
with capture_output() as captured:
|
||||
result = f(call_hat)
|
||||
|
||||
nt.assert_equal(result, None)
|
||||
|
||||
class BadReprArgs(object):
|
||||
def _repr_html_(self, extra, args):
|
||||
return "html"
|
||||
|
||||
bad = BadReprArgs()
|
||||
with capture_output() as captured:
|
||||
result = f(bad)
|
||||
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_not_in("FormatterWarning", captured.stderr)
|
||||
|
||||
|
||||
def test_format_config():
|
||||
"""config objects don't pretend to support fancy reprs with lazy attrs"""
|
||||
f = HTMLFormatter()
|
||||
cfg = Config()
|
||||
with capture_output() as captured:
|
||||
result = f(cfg)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_equal(captured.stderr, "")
|
||||
|
||||
with capture_output() as captured:
|
||||
result = f(Config)
|
||||
nt.assert_is(result, None)
|
||||
nt.assert_equal(captured.stderr, "")
|
||||
|
||||
def test_pretty_max_seq_length():
|
||||
f = PlainTextFormatter(max_seq_length=1)
|
||||
lis = list(range(3))
|
||||
text = f(lis)
|
||||
nt.assert_equal(text, '[0, ...]')
|
||||
f.max_seq_length = 0
|
||||
text = f(lis)
|
||||
nt.assert_equal(text, '[0, 1, 2]')
|
||||
text = f(list(range(1024)))
|
||||
lines = text.splitlines()
|
||||
nt.assert_equal(len(lines), 1024)
|
||||
|
||||
|
||||
def test_ipython_display_formatter():
|
||||
"""Objects with _ipython_display_ defined bypass other formatters"""
|
||||
f = get_ipython().display_formatter
|
||||
catcher = []
|
||||
class SelfDisplaying(object):
|
||||
def _ipython_display_(self):
|
||||
catcher.append(self)
|
||||
|
||||
class NotSelfDisplaying(object):
|
||||
def __repr__(self):
|
||||
return "NotSelfDisplaying"
|
||||
|
||||
def _ipython_display_(self):
|
||||
raise NotImplementedError
|
||||
|
||||
save_enabled = f.ipython_display_formatter.enabled
|
||||
f.ipython_display_formatter.enabled = True
|
||||
|
||||
yes = SelfDisplaying()
|
||||
no = NotSelfDisplaying()
|
||||
|
||||
d, md = f.format(no)
|
||||
nt.assert_equal(d, {'text/plain': repr(no)})
|
||||
nt.assert_equal(md, {})
|
||||
nt.assert_equal(catcher, [])
|
||||
|
||||
d, md = f.format(yes)
|
||||
nt.assert_equal(d, {})
|
||||
nt.assert_equal(md, {})
|
||||
nt.assert_equal(catcher, [yes])
|
||||
|
||||
f.ipython_display_formatter.enabled = save_enabled
|
||||
|
||||
|
||||
def test_json_as_string_deprecated():
|
||||
class JSONString(object):
|
||||
def _repr_json_(self):
|
||||
return '{}'
|
||||
|
||||
f = JSONFormatter()
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
d = f(JSONString())
|
||||
nt.assert_equal(d, {})
|
||||
nt.assert_equal(len(w), 1)
|
||||
|
||||
|
||||
def test_repr_mime():
|
||||
class HasReprMime(object):
|
||||
def _repr_mimebundle_(self, include=None, exclude=None):
|
||||
return {
|
||||
'application/json+test.v2': {
|
||||
'x': 'y'
|
||||
},
|
||||
'plain/text' : '<HasReprMime>',
|
||||
'image/png' : 'i-overwrite'
|
||||
}
|
||||
|
||||
def _repr_png_(self):
|
||||
return 'should-be-overwritten'
|
||||
def _repr_html_(self):
|
||||
return '<b>hi!</b>'
|
||||
|
||||
f = get_ipython().display_formatter
|
||||
html_f = f.formatters['text/html']
|
||||
save_enabled = html_f.enabled
|
||||
html_f.enabled = True
|
||||
obj = HasReprMime()
|
||||
d, md = f.format(obj)
|
||||
html_f.enabled = save_enabled
|
||||
|
||||
nt.assert_equal(sorted(d), ['application/json+test.v2',
|
||||
'image/png',
|
||||
'plain/text',
|
||||
'text/html',
|
||||
'text/plain'])
|
||||
nt.assert_equal(md, {})
|
||||
|
||||
d, md = f.format(obj, include={'image/png'})
|
||||
nt.assert_equal(list(d.keys()), ['image/png'],
|
||||
'Include should filter out even things from repr_mimebundle')
|
||||
nt.assert_equal(d['image/png'], 'i-overwrite', '_repr_mimebundle_ take precedence')
|
||||
|
||||
|
||||
|
||||
def test_pass_correct_include_exclude():
|
||||
class Tester(object):
|
||||
|
||||
def __init__(self, include=None, exclude=None):
|
||||
self.include = include
|
||||
self.exclude = exclude
|
||||
|
||||
def _repr_mimebundle_(self, include, exclude, **kwargs):
|
||||
if include and (include != self.include):
|
||||
raise ValueError('include got modified: display() may be broken.')
|
||||
if exclude and (exclude != self.exclude):
|
||||
raise ValueError('exclude got modified: display() may be broken.')
|
||||
|
||||
return None
|
||||
|
||||
include = {'a', 'b', 'c'}
|
||||
exclude = {'c', 'e' , 'f'}
|
||||
|
||||
f = get_ipython().display_formatter
|
||||
f.format(Tester(include=include, exclude=exclude), include=include, exclude=exclude)
|
||||
f.format(Tester(exclude=exclude), exclude=exclude)
|
||||
f.format(Tester(include=include), include=include)
|
||||
|
||||
|
||||
def test_repr_mime_meta():
|
||||
class HasReprMimeMeta(object):
|
||||
def _repr_mimebundle_(self, include=None, exclude=None):
|
||||
data = {
|
||||
'image/png': 'base64-image-data',
|
||||
}
|
||||
metadata = {
|
||||
'image/png': {
|
||||
'width': 5,
|
||||
'height': 10,
|
||||
}
|
||||
}
|
||||
return (data, metadata)
|
||||
|
||||
f = get_ipython().display_formatter
|
||||
obj = HasReprMimeMeta()
|
||||
d, md = f.format(obj)
|
||||
nt.assert_equal(sorted(d), ['image/png', 'text/plain'])
|
||||
nt.assert_equal(md, {
|
||||
'image/png': {
|
||||
'width': 5,
|
||||
'height': 10,
|
||||
}
|
||||
})
|
||||
|
||||
def test_repr_mime_failure():
|
||||
class BadReprMime(object):
|
||||
def _repr_mimebundle_(self, include=None, exclude=None):
|
||||
raise RuntimeError
|
||||
|
||||
f = get_ipython().display_formatter
|
||||
obj = BadReprMime()
|
||||
d, md = f.format(obj)
|
||||
nt.assert_in('text/plain', d)
|
||||
94
venv/Lib/site-packages/IPython/core/tests/test_handlers.py
Normal file
94
venv/Lib/site-packages/IPython/core/tests/test_handlers.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
"""Tests for input handlers.
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Module imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# third party
|
||||
import nose.tools as nt
|
||||
|
||||
# our own packages
|
||||
from IPython.core import autocall
|
||||
from IPython.testing import tools as tt
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Globals
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Get the public instance of IPython
|
||||
|
||||
failures = []
|
||||
num_tests = 0
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class CallableIndexable(object):
|
||||
def __getitem__(self, idx): return True
|
||||
def __call__(self, *args, **kws): return True
|
||||
|
||||
|
||||
class Autocallable(autocall.IPyAutocall):
|
||||
def __call__(self):
|
||||
return "called"
|
||||
|
||||
|
||||
def run(tests):
|
||||
"""Loop through a list of (pre, post) inputs, where pre is the string
|
||||
handed to ipython, and post is how that string looks after it's been
|
||||
transformed (i.e. ipython's notion of _i)"""
|
||||
tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
|
||||
|
||||
|
||||
def test_handlers():
|
||||
call_idx = CallableIndexable()
|
||||
ip.user_ns['call_idx'] = call_idx
|
||||
|
||||
# For many of the below, we're also checking that leading whitespace
|
||||
# turns off the esc char, which it should unless there is a continuation
|
||||
# line.
|
||||
run(
|
||||
[('"no change"', '"no change"'), # normal
|
||||
(u"lsmagic", "get_ipython().run_line_magic('lsmagic', '')"), # magic
|
||||
#("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
|
||||
])
|
||||
|
||||
# Objects which are instances of IPyAutocall are *always* autocalled
|
||||
autocallable = Autocallable()
|
||||
ip.user_ns['autocallable'] = autocallable
|
||||
|
||||
# auto
|
||||
ip.magic('autocall 0')
|
||||
# Only explicit escapes or instances of IPyAutocallable should get
|
||||
# expanded
|
||||
run([
|
||||
('len "abc"', 'len "abc"'),
|
||||
('autocallable', 'autocallable()'),
|
||||
# Don't add extra brackets (gh-1117)
|
||||
('autocallable()', 'autocallable()'),
|
||||
])
|
||||
ip.magic('autocall 1')
|
||||
run([
|
||||
('len "abc"', 'len("abc")'),
|
||||
('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
|
||||
# Autocall is turned off if first arg is [] and the object
|
||||
# is both callable and indexable. Like so:
|
||||
('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
|
||||
('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
|
||||
('call_idx 1', 'call_idx(1)'),
|
||||
('len', 'len'), # only at 2 does it auto-call on single args
|
||||
])
|
||||
ip.magic('autocall 2')
|
||||
run([
|
||||
('len "abc"', 'len("abc")'),
|
||||
('len "abc";', 'len("abc");'),
|
||||
('len [1,2]', 'len([1,2])'),
|
||||
('call_idx [1]', 'call_idx [1]'),
|
||||
('call_idx 1', 'call_idx(1)'),
|
||||
# This is what's different:
|
||||
('len', 'len()'), # only at 2 does it auto-call on single args
|
||||
])
|
||||
ip.magic('autocall 1')
|
||||
|
||||
nt.assert_equal(failures, [])
|
||||
214
venv/Lib/site-packages/IPython/core/tests/test_history.py
Normal file
214
venv/Lib/site-packages/IPython/core/tests/test_history.py
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
# coding: utf-8
|
||||
"""Tests for the IPython tab-completion machinery.
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Module imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# stdlib
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
import sqlite3
|
||||
|
||||
# third party
|
||||
import nose.tools as nt
|
||||
|
||||
# our own packages
|
||||
from traitlets.config.loader import Config
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
from IPython.core.history import HistoryManager, extract_hist_ranges
|
||||
from IPython.testing.decorators import skipif
|
||||
|
||||
def test_proper_default_encoding():
|
||||
nt.assert_equal(sys.getdefaultencoding(), "utf-8")
|
||||
|
||||
@skipif(sqlite3.sqlite_version_info > (3,24,0))
|
||||
def test_history():
|
||||
ip = get_ipython()
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
hist_manager_ori = ip.history_manager
|
||||
hist_file = os.path.join(tmpdir, 'history.sqlite')
|
||||
try:
|
||||
ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
|
||||
hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
|
||||
for i, h in enumerate(hist, start=1):
|
||||
ip.history_manager.store_inputs(i, h)
|
||||
|
||||
ip.history_manager.db_log_output = True
|
||||
# Doesn't match the input, but we'll just check it's stored.
|
||||
ip.history_manager.output_hist_reprs[3] = "spam"
|
||||
ip.history_manager.store_output(3)
|
||||
|
||||
nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
|
||||
|
||||
# Detailed tests for _get_range_session
|
||||
grs = ip.history_manager._get_range_session
|
||||
nt.assert_equal(list(grs(start=2,stop=-1)), list(zip([0], [2], hist[1:-1])))
|
||||
nt.assert_equal(list(grs(start=-2)), list(zip([0,0], [2,3], hist[-2:])))
|
||||
nt.assert_equal(list(grs(output=True)), list(zip([0,0,0], [1,2,3], zip(hist, [None,None,'spam']))))
|
||||
|
||||
# Check whether specifying a range beyond the end of the current
|
||||
# session results in an error (gh-804)
|
||||
ip.magic('%hist 2-500')
|
||||
|
||||
# Check that we can write non-ascii characters to a file
|
||||
ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
|
||||
ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
|
||||
ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
|
||||
ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
|
||||
|
||||
# New session
|
||||
ip.history_manager.reset()
|
||||
newcmds = [u"z=5",
|
||||
u"class X(object):\n pass",
|
||||
u"k='p'",
|
||||
u"z=5"]
|
||||
for i, cmd in enumerate(newcmds, start=1):
|
||||
ip.history_manager.store_inputs(i, cmd)
|
||||
gothist = ip.history_manager.get_range(start=1, stop=4)
|
||||
nt.assert_equal(list(gothist), list(zip([0,0,0],[1,2,3], newcmds)))
|
||||
# Previous session:
|
||||
gothist = ip.history_manager.get_range(-1, 1, 4)
|
||||
nt.assert_equal(list(gothist), list(zip([1,1,1],[1,2,3], hist)))
|
||||
|
||||
newhist = [(2, i, c) for (i, c) in enumerate(newcmds, 1)]
|
||||
|
||||
# Check get_hist_tail
|
||||
gothist = ip.history_manager.get_tail(5, output=True,
|
||||
include_latest=True)
|
||||
expected = [(1, 3, (hist[-1], "spam"))] \
|
||||
+ [(s, n, (c, None)) for (s, n, c) in newhist]
|
||||
nt.assert_equal(list(gothist), expected)
|
||||
|
||||
gothist = ip.history_manager.get_tail(2)
|
||||
expected = newhist[-3:-1]
|
||||
nt.assert_equal(list(gothist), expected)
|
||||
|
||||
# Check get_hist_search
|
||||
|
||||
gothist = ip.history_manager.search("*test*")
|
||||
nt.assert_equal(list(gothist), [(1,2,hist[1])] )
|
||||
|
||||
gothist = ip.history_manager.search("*=*")
|
||||
nt.assert_equal(list(gothist),
|
||||
[(1, 1, hist[0]),
|
||||
(1, 2, hist[1]),
|
||||
(1, 3, hist[2]),
|
||||
newhist[0],
|
||||
newhist[2],
|
||||
newhist[3]])
|
||||
|
||||
gothist = ip.history_manager.search("*=*", n=4)
|
||||
nt.assert_equal(list(gothist),
|
||||
[(1, 3, hist[2]),
|
||||
newhist[0],
|
||||
newhist[2],
|
||||
newhist[3]])
|
||||
|
||||
gothist = ip.history_manager.search("*=*", unique=True)
|
||||
nt.assert_equal(list(gothist),
|
||||
[(1, 1, hist[0]),
|
||||
(1, 2, hist[1]),
|
||||
(1, 3, hist[2]),
|
||||
newhist[2],
|
||||
newhist[3]])
|
||||
|
||||
gothist = ip.history_manager.search("*=*", unique=True, n=3)
|
||||
nt.assert_equal(list(gothist),
|
||||
[(1, 3, hist[2]),
|
||||
newhist[2],
|
||||
newhist[3]])
|
||||
|
||||
gothist = ip.history_manager.search("b*", output=True)
|
||||
nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
|
||||
|
||||
# Cross testing: check that magic %save can get previous session.
|
||||
testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
|
||||
ip.magic("save " + testfilename + " ~1/1-3")
|
||||
with io.open(testfilename, encoding='utf-8') as testfile:
|
||||
nt.assert_equal(testfile.read(),
|
||||
u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
|
||||
|
||||
# Duplicate line numbers - check that it doesn't crash, and
|
||||
# gets a new session
|
||||
ip.history_manager.store_inputs(1, "rogue")
|
||||
ip.history_manager.writeout_cache()
|
||||
nt.assert_equal(ip.history_manager.session_number, 3)
|
||||
finally:
|
||||
# Ensure saving thread is shut down before we try to clean up the files
|
||||
ip.history_manager.save_thread.stop()
|
||||
# Forcibly close database rather than relying on garbage collection
|
||||
ip.history_manager.db.close()
|
||||
# Restore history manager
|
||||
ip.history_manager = hist_manager_ori
|
||||
|
||||
|
||||
def test_extract_hist_ranges():
|
||||
instr = "1 2/3 ~4/5-6 ~4/7-~4/9 ~9/2-~7/5 ~10/"
|
||||
expected = [(0, 1, 2), # 0 == current session
|
||||
(2, 3, 4),
|
||||
(-4, 5, 7),
|
||||
(-4, 7, 10),
|
||||
(-9, 2, None), # None == to end
|
||||
(-8, 1, None),
|
||||
(-7, 1, 6),
|
||||
(-10, 1, None)]
|
||||
actual = list(extract_hist_ranges(instr))
|
||||
nt.assert_equal(actual, expected)
|
||||
|
||||
def test_magic_rerun():
|
||||
"""Simple test for %rerun (no args -> rerun last line)"""
|
||||
ip = get_ipython()
|
||||
ip.run_cell("a = 10", store_history=True)
|
||||
ip.run_cell("a += 1", store_history=True)
|
||||
nt.assert_equal(ip.user_ns["a"], 11)
|
||||
ip.run_cell("%rerun", store_history=True)
|
||||
nt.assert_equal(ip.user_ns["a"], 12)
|
||||
|
||||
def test_timestamp_type():
|
||||
ip = get_ipython()
|
||||
info = ip.history_manager.get_session_info()
|
||||
nt.assert_true(isinstance(info[1], datetime))
|
||||
|
||||
def test_hist_file_config():
|
||||
cfg = Config()
|
||||
tfile = tempfile.NamedTemporaryFile(delete=False)
|
||||
cfg.HistoryManager.hist_file = tfile.name
|
||||
try:
|
||||
hm = HistoryManager(shell=get_ipython(), config=cfg)
|
||||
nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file)
|
||||
finally:
|
||||
try:
|
||||
os.remove(tfile.name)
|
||||
except OSError:
|
||||
# same catch as in testing.tools.TempFileMixin
|
||||
# On Windows, even though we close the file, we still can't
|
||||
# delete it. I have no clue why
|
||||
pass
|
||||
|
||||
def test_histmanager_disabled():
|
||||
"""Ensure that disabling the history manager doesn't create a database."""
|
||||
cfg = Config()
|
||||
cfg.HistoryAccessor.enabled = False
|
||||
|
||||
ip = get_ipython()
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
hist_manager_ori = ip.history_manager
|
||||
hist_file = os.path.join(tmpdir, 'history.sqlite')
|
||||
cfg.HistoryManager.hist_file = hist_file
|
||||
try:
|
||||
ip.history_manager = HistoryManager(shell=ip, config=cfg)
|
||||
hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
|
||||
for i, h in enumerate(hist, start=1):
|
||||
ip.history_manager.store_inputs(i, h)
|
||||
nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
|
||||
ip.history_manager.reset()
|
||||
ip.history_manager.end_session()
|
||||
finally:
|
||||
ip.history_manager = hist_manager_ori
|
||||
|
||||
# hist_file should not be created
|
||||
nt.assert_false(os.path.exists(hist_file))
|
||||
80
venv/Lib/site-packages/IPython/core/tests/test_hooks.py
Normal file
80
venv/Lib/site-packages/IPython/core/tests/test_hooks.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Tests for CommandChainDispatcher."""
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import nose.tools as nt
|
||||
from IPython.core.error import TryNext
|
||||
from IPython.core.hooks import CommandChainDispatcher
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Local utilities
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Define two classes, one which succeeds and one which raises TryNext. Each
|
||||
# sets the attribute `called` to True when it is called.
|
||||
class Okay(object):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
self.called = False
|
||||
def __call__(self):
|
||||
self.called = True
|
||||
return self.message
|
||||
|
||||
class Fail(object):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
self.called = False
|
||||
def __call__(self):
|
||||
self.called = True
|
||||
raise TryNext(self.message)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def test_command_chain_dispatcher_ff():
|
||||
"""Test two failing hooks"""
|
||||
fail1 = Fail(u'fail1')
|
||||
fail2 = Fail(u'fail2')
|
||||
dp = CommandChainDispatcher([(0, fail1),
|
||||
(10, fail2)])
|
||||
|
||||
try:
|
||||
dp()
|
||||
except TryNext as e:
|
||||
nt.assert_equal(str(e), u'fail2')
|
||||
else:
|
||||
assert False, "Expected exception was not raised."
|
||||
|
||||
nt.assert_true(fail1.called)
|
||||
nt.assert_true(fail2.called)
|
||||
|
||||
def test_command_chain_dispatcher_fofo():
|
||||
"""Test a mixture of failing and succeeding hooks."""
|
||||
fail1 = Fail(u'fail1')
|
||||
fail2 = Fail(u'fail2')
|
||||
okay1 = Okay(u'okay1')
|
||||
okay2 = Okay(u'okay2')
|
||||
|
||||
dp = CommandChainDispatcher([(0, fail1),
|
||||
# (5, okay1), # add this later
|
||||
(10, fail2),
|
||||
(15, okay2)])
|
||||
dp.add(okay1, 5)
|
||||
|
||||
nt.assert_equal(dp(), u'okay1')
|
||||
|
||||
nt.assert_true(fail1.called)
|
||||
nt.assert_true(okay1.called)
|
||||
nt.assert_false(fail2.called)
|
||||
nt.assert_false(okay2.called)
|
||||
|
||||
def test_command_chain_dispatcher_eq_priority():
|
||||
okay1 = Okay(u'okay1')
|
||||
okay2 = Okay(u'okay2')
|
||||
dp = CommandChainDispatcher([(1, okay1)])
|
||||
dp.add(okay2, 1)
|
||||
52
venv/Lib/site-packages/IPython/core/tests/test_imports.py
Normal file
52
venv/Lib/site-packages/IPython/core/tests/test_imports.py
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# encoding: utf-8
|
||||
|
||||
def test_import_completer():
|
||||
from IPython.core import completer
|
||||
|
||||
def test_import_crashhandler():
|
||||
from IPython.core import crashhandler
|
||||
|
||||
def test_import_debugger():
|
||||
from IPython.core import debugger
|
||||
|
||||
def test_import_excolors():
|
||||
from IPython.core import excolors
|
||||
|
||||
def test_import_history():
|
||||
from IPython.core import history
|
||||
|
||||
def test_import_hooks():
|
||||
from IPython.core import hooks
|
||||
|
||||
def test_import_getipython():
|
||||
from IPython.core import getipython
|
||||
|
||||
def test_import_interactiveshell():
|
||||
from IPython.core import interactiveshell
|
||||
|
||||
def test_import_logger():
|
||||
from IPython.core import logger
|
||||
|
||||
def test_import_macro():
|
||||
from IPython.core import macro
|
||||
|
||||
def test_import_magic():
|
||||
from IPython.core import magic
|
||||
|
||||
def test_import_oinspect():
|
||||
from IPython.core import oinspect
|
||||
|
||||
def test_import_prefilter():
|
||||
from IPython.core import prefilter
|
||||
|
||||
def test_import_prompts():
|
||||
from IPython.core import prompts
|
||||
|
||||
def test_import_release():
|
||||
from IPython.core import release
|
||||
|
||||
def test_import_ultratb():
|
||||
from IPython.core import ultratb
|
||||
|
||||
def test_import_usage():
|
||||
from IPython.core import usage
|
||||
639
venv/Lib/site-packages/IPython/core/tests/test_inputsplitter.py
Normal file
639
venv/Lib/site-packages/IPython/core/tests/test_inputsplitter.py
Normal file
|
|
@ -0,0 +1,639 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Tests for the inputsplitter module."""
|
||||
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core import inputsplitter as isp
|
||||
from IPython.core.inputtransformer import InputTransformer
|
||||
from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
|
||||
from IPython.testing import tools as tt
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Semi-complete examples (also used as tests)
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Note: at the bottom, there's a slightly more complete version of this that
|
||||
# can be useful during development of code here.
|
||||
|
||||
def mini_interactive_loop(input_func):
|
||||
"""Minimal example of the logic of an interactive interpreter loop.
|
||||
|
||||
This serves as an example, and it is used by the test system with a fake
|
||||
raw_input that simulates interactive input."""
|
||||
|
||||
from IPython.core.inputsplitter import InputSplitter
|
||||
|
||||
isp = InputSplitter()
|
||||
# In practice, this input loop would be wrapped in an outside loop to read
|
||||
# input indefinitely, until some exit/quit command was issued. Here we
|
||||
# only illustrate the basic inner loop.
|
||||
while isp.push_accepts_more():
|
||||
indent = ' '*isp.get_indent_spaces()
|
||||
prompt = '>>> ' + indent
|
||||
line = indent + input_func(prompt)
|
||||
isp.push(line)
|
||||
|
||||
# Here we just return input so we can use it in a test suite, but a real
|
||||
# interpreter would instead send it for execution somewhere.
|
||||
src = isp.source_reset()
|
||||
#print 'Input source was:\n', src # dbg
|
||||
return src
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test utilities, just for local use
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def assemble(block):
|
||||
"""Assemble a block into multi-line sub-blocks."""
|
||||
return ['\n'.join(sub_block)+'\n' for sub_block in block]
|
||||
|
||||
|
||||
def pseudo_input(lines):
|
||||
"""Return a function that acts like raw_input but feeds the input list."""
|
||||
ilines = iter(lines)
|
||||
def raw_in(prompt):
|
||||
try:
|
||||
return next(ilines)
|
||||
except StopIteration:
|
||||
return ''
|
||||
return raw_in
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Tests
|
||||
#-----------------------------------------------------------------------------
|
||||
def test_spaces():
|
||||
tests = [('', 0),
|
||||
(' ', 1),
|
||||
('\n', 0),
|
||||
(' \n', 1),
|
||||
('x', 0),
|
||||
(' x', 1),
|
||||
(' x',2),
|
||||
(' x',4),
|
||||
# Note: tabs are counted as a single whitespace!
|
||||
('\tx', 1),
|
||||
('\t x', 2),
|
||||
]
|
||||
tt.check_pairs(isp.num_ini_spaces, tests)
|
||||
|
||||
|
||||
def test_remove_comments():
|
||||
tests = [('text', 'text'),
|
||||
('text # comment', 'text '),
|
||||
('text # comment\n', 'text \n'),
|
||||
('text # comment \n', 'text \n'),
|
||||
('line # c \nline\n','line \nline\n'),
|
||||
('line # c \nline#c2 \nline\nline #c\n\n',
|
||||
'line \nline\nline\nline \n\n'),
|
||||
]
|
||||
tt.check_pairs(isp.remove_comments, tests)
|
||||
|
||||
|
||||
def test_get_input_encoding():
|
||||
encoding = isp.get_input_encoding()
|
||||
nt.assert_true(isinstance(encoding, str))
|
||||
# simple-minded check that at least encoding a simple string works with the
|
||||
# encoding we got.
|
||||
nt.assert_equal(u'test'.encode(encoding), b'test')
|
||||
|
||||
|
||||
class NoInputEncodingTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.old_stdin = sys.stdin
|
||||
class X: pass
|
||||
fake_stdin = X()
|
||||
sys.stdin = fake_stdin
|
||||
|
||||
def test(self):
|
||||
# Verify that if sys.stdin has no 'encoding' attribute we do the right
|
||||
# thing
|
||||
enc = isp.get_input_encoding()
|
||||
self.assertEqual(enc, 'ascii')
|
||||
|
||||
def tearDown(self):
|
||||
sys.stdin = self.old_stdin
|
||||
|
||||
|
||||
class InputSplitterTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.isp = isp.InputSplitter()
|
||||
|
||||
def test_reset(self):
|
||||
isp = self.isp
|
||||
isp.push('x=1')
|
||||
isp.reset()
|
||||
self.assertEqual(isp._buffer, [])
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
self.assertEqual(isp.source, '')
|
||||
self.assertEqual(isp.code, None)
|
||||
self.assertEqual(isp._is_complete, False)
|
||||
|
||||
def test_source(self):
|
||||
self.isp._store('1')
|
||||
self.isp._store('2')
|
||||
self.assertEqual(self.isp.source, '1\n2\n')
|
||||
self.assertEqual(len(self.isp._buffer)>0, True)
|
||||
self.assertEqual(self.isp.source_reset(), '1\n2\n')
|
||||
self.assertEqual(self.isp._buffer, [])
|
||||
self.assertEqual(self.isp.source, '')
|
||||
|
||||
def test_indent(self):
|
||||
isp = self.isp # shorthand
|
||||
isp.push('x=1')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n x=1')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('y=2\n')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_indent2(self):
|
||||
isp = self.isp
|
||||
isp.push('if 1:')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push(' x=1')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
# Blank lines shouldn't change the indent level
|
||||
isp.push(' '*2)
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
|
||||
def test_indent3(self):
|
||||
isp = self.isp
|
||||
# When a multiline statement contains parens or multiline strings, we
|
||||
# shouldn't get confused.
|
||||
isp.push("if 1:")
|
||||
isp.push(" x = (1+\n 2)")
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
|
||||
def test_indent4(self):
|
||||
isp = self.isp
|
||||
# whitespace after ':' should not screw up indent level
|
||||
isp.push('if 1: \n x=1')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('y=2\n')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\t\n x=1')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('y=2\n')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_dedent_pass(self):
|
||||
isp = self.isp # shorthand
|
||||
# should NOT cause dedent
|
||||
isp.push('if 1:\n passes = 5')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('if 1:\n pass')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n pass ')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_dedent_break(self):
|
||||
isp = self.isp # shorthand
|
||||
# should NOT cause dedent
|
||||
isp.push('while 1:\n breaks = 5')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('while 1:\n break')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('while 1:\n break ')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_dedent_continue(self):
|
||||
isp = self.isp # shorthand
|
||||
# should NOT cause dedent
|
||||
isp.push('while 1:\n continues = 5')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('while 1:\n continue')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('while 1:\n continue ')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_dedent_raise(self):
|
||||
isp = self.isp # shorthand
|
||||
# should NOT cause dedent
|
||||
isp.push('if 1:\n raised = 4')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('if 1:\n raise TypeError()')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n raise')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n raise ')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_dedent_return(self):
|
||||
isp = self.isp # shorthand
|
||||
# should NOT cause dedent
|
||||
isp.push('if 1:\n returning = 4')
|
||||
self.assertEqual(isp.get_indent_spaces(), 4)
|
||||
isp.push('if 1:\n return 5 + 493')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n return')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n return ')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
isp.push('if 1:\n return(0)')
|
||||
self.assertEqual(isp.get_indent_spaces(), 0)
|
||||
|
||||
def test_push(self):
|
||||
isp = self.isp
|
||||
self.assertEqual(isp.push('x=1'), True)
|
||||
|
||||
def test_push2(self):
|
||||
isp = self.isp
|
||||
self.assertEqual(isp.push('if 1:'), False)
|
||||
for line in [' x=1', '# a comment', ' y=2']:
|
||||
print(line)
|
||||
self.assertEqual(isp.push(line), True)
|
||||
|
||||
def test_push3(self):
|
||||
isp = self.isp
|
||||
isp.push('if True:')
|
||||
isp.push(' a = 1')
|
||||
self.assertEqual(isp.push('b = [1,'), False)
|
||||
|
||||
def test_push_accepts_more(self):
|
||||
isp = self.isp
|
||||
isp.push('x=1')
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_push_accepts_more2(self):
|
||||
isp = self.isp
|
||||
isp.push('if 1:')
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
isp.push(' x=1')
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
isp.push('')
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_push_accepts_more3(self):
|
||||
isp = self.isp
|
||||
isp.push("x = (2+\n3)")
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_push_accepts_more4(self):
|
||||
isp = self.isp
|
||||
# When a multiline statement contains parens or multiline strings, we
|
||||
# shouldn't get confused.
|
||||
# FIXME: we should be able to better handle de-dents in statements like
|
||||
# multiline strings and multiline expressions (continued with \ or
|
||||
# parens). Right now we aren't handling the indentation tracking quite
|
||||
# correctly with this, though in practice it may not be too much of a
|
||||
# problem. We'll need to see.
|
||||
isp.push("if 1:")
|
||||
isp.push(" x = (2+")
|
||||
isp.push(" 3)")
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
isp.push(" y = 3")
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
isp.push('')
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_push_accepts_more5(self):
|
||||
isp = self.isp
|
||||
isp.push('try:')
|
||||
isp.push(' a = 5')
|
||||
isp.push('except:')
|
||||
isp.push(' raise')
|
||||
# We want to be able to add an else: block at this point, so it should
|
||||
# wait for a blank line.
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
|
||||
def test_continuation(self):
|
||||
isp = self.isp
|
||||
isp.push("import os, \\")
|
||||
self.assertEqual(isp.push_accepts_more(), True)
|
||||
isp.push("sys")
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_syntax_error(self):
|
||||
isp = self.isp
|
||||
# Syntax errors immediately produce a 'ready' block, so the invalid
|
||||
# Python can be sent to the kernel for evaluation with possible ipython
|
||||
# special-syntax conversion.
|
||||
isp.push('run foo')
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_unicode(self):
|
||||
self.isp.push(u"Pérez")
|
||||
self.isp.push(u'\xc3\xa9')
|
||||
self.isp.push(u"u'\xc3\xa9'")
|
||||
|
||||
def test_line_continuation(self):
|
||||
""" Test issue #2108."""
|
||||
isp = self.isp
|
||||
# A blank line after a line continuation should not accept more
|
||||
isp.push("1 \\\n\n")
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
# Whitespace after a \ is a SyntaxError. The only way to test that
|
||||
# here is to test that push doesn't accept more (as with
|
||||
# test_syntax_error() above).
|
||||
isp.push(r"1 \ ")
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
# Even if the line is continuable (c.f. the regular Python
|
||||
# interpreter)
|
||||
isp.push(r"(1 \ ")
|
||||
self.assertEqual(isp.push_accepts_more(), False)
|
||||
|
||||
def test_check_complete(self):
|
||||
isp = self.isp
|
||||
self.assertEqual(isp.check_complete("a = 1"), ('complete', None))
|
||||
self.assertEqual(isp.check_complete("for a in range(5):"), ('incomplete', 4))
|
||||
self.assertEqual(isp.check_complete("raise = 2"), ('invalid', None))
|
||||
self.assertEqual(isp.check_complete("a = [1,\n2,"), ('incomplete', 0))
|
||||
self.assertEqual(isp.check_complete("def a():\n x=1\n global x"), ('invalid', None))
|
||||
|
||||
class InteractiveLoopTestCase(unittest.TestCase):
|
||||
"""Tests for an interactive loop like a python shell.
|
||||
"""
|
||||
def check_ns(self, lines, ns):
|
||||
"""Validate that the given input lines produce the resulting namespace.
|
||||
|
||||
Note: the input lines are given exactly as they would be typed in an
|
||||
auto-indenting environment, as mini_interactive_loop above already does
|
||||
auto-indenting and prepends spaces to the input.
|
||||
"""
|
||||
src = mini_interactive_loop(pseudo_input(lines))
|
||||
test_ns = {}
|
||||
exec(src, test_ns)
|
||||
# We can't check that the provided ns is identical to the test_ns,
|
||||
# because Python fills test_ns with extra keys (copyright, etc). But
|
||||
# we can check that the given dict is *contained* in test_ns
|
||||
for k,v in ns.items():
|
||||
self.assertEqual(test_ns[k], v)
|
||||
|
||||
def test_simple(self):
|
||||
self.check_ns(['x=1'], dict(x=1))
|
||||
|
||||
def test_simple2(self):
|
||||
self.check_ns(['if 1:', 'x=2'], dict(x=2))
|
||||
|
||||
def test_xy(self):
|
||||
self.check_ns(['x=1; y=2'], dict(x=1, y=2))
|
||||
|
||||
def test_abc(self):
|
||||
self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
|
||||
|
||||
def test_multi(self):
|
||||
self.check_ns(['x =(1+','1+','2)'], dict(x=4))
|
||||
|
||||
|
||||
class IPythonInputTestCase(InputSplitterTestCase):
|
||||
"""By just creating a new class whose .isp is a different instance, we
|
||||
re-run the same test battery on the new input splitter.
|
||||
|
||||
In addition, this runs the tests over the syntax and syntax_ml dicts that
|
||||
were tested by individual functions, as part of the OO interface.
|
||||
|
||||
It also makes some checks on the raw buffer storage.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.isp = isp.IPythonInputSplitter()
|
||||
|
||||
def test_syntax(self):
|
||||
"""Call all single-line syntax tests from the main object"""
|
||||
isp = self.isp
|
||||
for example in syntax.values():
|
||||
for raw, out_t in example:
|
||||
if raw.startswith(' '):
|
||||
continue
|
||||
|
||||
isp.push(raw+'\n')
|
||||
out_raw = isp.source_raw
|
||||
out = isp.source_reset()
|
||||
self.assertEqual(out.rstrip(), out_t,
|
||||
tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
|
||||
self.assertEqual(out_raw.rstrip(), raw.rstrip())
|
||||
|
||||
def test_syntax_multiline(self):
|
||||
isp = self.isp
|
||||
for example in syntax_ml.values():
|
||||
for line_pairs in example:
|
||||
out_t_parts = []
|
||||
raw_parts = []
|
||||
for lraw, out_t_part in line_pairs:
|
||||
if out_t_part is not None:
|
||||
out_t_parts.append(out_t_part)
|
||||
|
||||
if lraw is not None:
|
||||
isp.push(lraw)
|
||||
raw_parts.append(lraw)
|
||||
|
||||
out_raw = isp.source_raw
|
||||
out = isp.source_reset()
|
||||
out_t = '\n'.join(out_t_parts).rstrip()
|
||||
raw = '\n'.join(raw_parts).rstrip()
|
||||
self.assertEqual(out.rstrip(), out_t)
|
||||
self.assertEqual(out_raw.rstrip(), raw)
|
||||
|
||||
def test_syntax_multiline_cell(self):
|
||||
isp = self.isp
|
||||
for example in syntax_ml.values():
|
||||
|
||||
out_t_parts = []
|
||||
for line_pairs in example:
|
||||
raw = '\n'.join(r for r, _ in line_pairs if r is not None)
|
||||
out_t = '\n'.join(t for _,t in line_pairs if t is not None)
|
||||
out = isp.transform_cell(raw)
|
||||
# Match ignoring trailing whitespace
|
||||
self.assertEqual(out.rstrip(), out_t.rstrip())
|
||||
|
||||
def test_cellmagic_preempt(self):
|
||||
isp = self.isp
|
||||
for raw, name, line, cell in [
|
||||
("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
|
||||
("%%cellm \nline\n>>> hi", u'cellm', u'', u'line\n>>> hi'),
|
||||
(">>> %%cellm \nline\n>>> hi", u'cellm', u'', u'line\nhi'),
|
||||
("%%cellm \n>>> hi", u'cellm', u'', u'>>> hi'),
|
||||
("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
|
||||
("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
|
||||
]:
|
||||
expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
|
||||
name, line, cell
|
||||
)
|
||||
out = isp.transform_cell(raw)
|
||||
self.assertEqual(out.rstrip(), expected.rstrip())
|
||||
|
||||
def test_multiline_passthrough(self):
|
||||
isp = self.isp
|
||||
class CommentTransformer(InputTransformer):
|
||||
def __init__(self):
|
||||
self._lines = []
|
||||
|
||||
def push(self, line):
|
||||
self._lines.append(line + '#')
|
||||
|
||||
def reset(self):
|
||||
text = '\n'.join(self._lines)
|
||||
self._lines = []
|
||||
return text
|
||||
|
||||
isp.physical_line_transforms.insert(0, CommentTransformer())
|
||||
|
||||
for raw, expected in [
|
||||
("a=5", "a=5#"),
|
||||
("%ls foo", "get_ipython().run_line_magic(%r, %r)" % (u'ls', u'foo#')),
|
||||
("!ls foo\n%ls bar", "get_ipython().system(%r)\nget_ipython().run_line_magic(%r, %r)" % (
|
||||
u'ls foo#', u'ls', u'bar#'
|
||||
)),
|
||||
("1\n2\n3\n%ls foo\n4\n5", "1#\n2#\n3#\nget_ipython().run_line_magic(%r, %r)\n4#\n5#" % (u'ls', u'foo#')),
|
||||
]:
|
||||
out = isp.transform_cell(raw)
|
||||
self.assertEqual(out.rstrip(), expected.rstrip())
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main - use as a script, mostly for developer experiments
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
# A simple demo for interactive experimentation. This code will not get
|
||||
# picked up by any test suite.
|
||||
from IPython.core.inputsplitter import IPythonInputSplitter
|
||||
|
||||
# configure here the syntax to use, prompt and whether to autoindent
|
||||
#isp, start_prompt = InputSplitter(), '>>> '
|
||||
isp, start_prompt = IPythonInputSplitter(), 'In> '
|
||||
|
||||
autoindent = True
|
||||
#autoindent = False
|
||||
|
||||
try:
|
||||
while True:
|
||||
prompt = start_prompt
|
||||
while isp.push_accepts_more():
|
||||
indent = ' '*isp.get_indent_spaces()
|
||||
if autoindent:
|
||||
line = indent + input(prompt+indent)
|
||||
else:
|
||||
line = input(prompt)
|
||||
isp.push(line)
|
||||
prompt = '... '
|
||||
|
||||
# Here we just return input so we can use it in a test suite, but a
|
||||
# real interpreter would instead send it for execution somewhere.
|
||||
#src = isp.source; raise EOFError # dbg
|
||||
raw = isp.source_raw
|
||||
src = isp.source_reset()
|
||||
print('Input source was:\n', src)
|
||||
print('Raw source was:\n', raw)
|
||||
except EOFError:
|
||||
print('Bye')
|
||||
|
||||
# Tests for cell magics support
|
||||
|
||||
def test_last_blank():
|
||||
nt.assert_false(isp.last_blank(''))
|
||||
nt.assert_false(isp.last_blank('abc'))
|
||||
nt.assert_false(isp.last_blank('abc\n'))
|
||||
nt.assert_false(isp.last_blank('abc\na'))
|
||||
|
||||
nt.assert_true(isp.last_blank('\n'))
|
||||
nt.assert_true(isp.last_blank('\n '))
|
||||
nt.assert_true(isp.last_blank('abc\n '))
|
||||
nt.assert_true(isp.last_blank('abc\n\n'))
|
||||
nt.assert_true(isp.last_blank('abc\nd\n\n'))
|
||||
nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
|
||||
nt.assert_true(isp.last_blank('abc \n \n \n\n'))
|
||||
|
||||
|
||||
def test_last_two_blanks():
|
||||
nt.assert_false(isp.last_two_blanks(''))
|
||||
nt.assert_false(isp.last_two_blanks('abc'))
|
||||
nt.assert_false(isp.last_two_blanks('abc\n'))
|
||||
nt.assert_false(isp.last_two_blanks('abc\n\na'))
|
||||
nt.assert_false(isp.last_two_blanks('abc\n \n'))
|
||||
nt.assert_false(isp.last_two_blanks('abc\n\n'))
|
||||
|
||||
nt.assert_true(isp.last_two_blanks('\n\n'))
|
||||
nt.assert_true(isp.last_two_blanks('\n\n '))
|
||||
nt.assert_true(isp.last_two_blanks('\n \n'))
|
||||
nt.assert_true(isp.last_two_blanks('abc\n\n '))
|
||||
nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
|
||||
nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
|
||||
nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
|
||||
nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
|
||||
nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
|
||||
nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
|
||||
|
||||
|
||||
class CellMagicsCommon(object):
|
||||
|
||||
def test_whole_cell(self):
|
||||
src = "%%cellm line\nbody\n"
|
||||
out = self.sp.transform_cell(src)
|
||||
ref = "get_ipython().run_cell_magic('cellm', 'line', 'body')\n"
|
||||
nt.assert_equal(out, ref)
|
||||
|
||||
def test_cellmagic_help(self):
|
||||
self.sp.push('%%cellm?')
|
||||
nt.assert_false(self.sp.push_accepts_more())
|
||||
|
||||
def tearDown(self):
|
||||
self.sp.reset()
|
||||
|
||||
|
||||
class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
|
||||
sp = isp.IPythonInputSplitter(line_input_checker=False)
|
||||
|
||||
def test_incremental(self):
|
||||
sp = self.sp
|
||||
sp.push('%%cellm firstline\n')
|
||||
nt.assert_true(sp.push_accepts_more()) #1
|
||||
sp.push('line2\n')
|
||||
nt.assert_true(sp.push_accepts_more()) #2
|
||||
sp.push('\n')
|
||||
# This should accept a blank line and carry on until the cell is reset
|
||||
nt.assert_true(sp.push_accepts_more()) #3
|
||||
|
||||
def test_no_strip_coding(self):
|
||||
src = '\n'.join([
|
||||
'%%writefile foo.py',
|
||||
'# coding: utf-8',
|
||||
'print(u"üñîçø∂é")',
|
||||
])
|
||||
out = self.sp.transform_cell(src)
|
||||
nt.assert_in('# coding: utf-8', out)
|
||||
|
||||
|
||||
class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
|
||||
sp = isp.IPythonInputSplitter(line_input_checker=True)
|
||||
|
||||
def test_incremental(self):
|
||||
sp = self.sp
|
||||
sp.push('%%cellm line2\n')
|
||||
nt.assert_true(sp.push_accepts_more()) #1
|
||||
sp.push('\n')
|
||||
# In this case, a blank line should end the cell magic
|
||||
nt.assert_false(sp.push_accepts_more()) #2
|
||||
|
||||
indentation_samples = [
|
||||
('a = 1', 0),
|
||||
('for a in b:', 4),
|
||||
('def f():', 4),
|
||||
('def f(): #comment', 4),
|
||||
('a = ":#not a comment"', 0),
|
||||
('def f():\n a = 1', 4),
|
||||
('def f():\n return 1', 0),
|
||||
('for a in b:\n'
|
||||
' if a < 0:'
|
||||
' continue', 3),
|
||||
('a = {', 4),
|
||||
('a = {\n'
|
||||
' 1,', 5),
|
||||
('b = """123', 0),
|
||||
('', 0),
|
||||
('def f():\n pass', 0),
|
||||
('class Bar:\n def f():\n pass', 4),
|
||||
('class Bar:\n def f():\n raise', 4),
|
||||
]
|
||||
|
||||
def test_find_next_indent():
|
||||
for code, exp in indentation_samples:
|
||||
res = isp.find_next_indent(code)
|
||||
msg = "{!r} != {!r} (expected)\n Code: {!r}".format(res, exp, code)
|
||||
assert res == exp, msg
|
||||
|
|
@ -0,0 +1,495 @@
|
|||
import tokenize
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.testing import tools as tt
|
||||
from IPython.utils import py3compat
|
||||
u_fmt = py3compat.u_format
|
||||
|
||||
from IPython.core import inputtransformer as ipt
|
||||
|
||||
def transform_and_reset(transformer):
|
||||
transformer = transformer()
|
||||
def transform(inp):
|
||||
try:
|
||||
return transformer.push(inp)
|
||||
finally:
|
||||
transformer.reset()
|
||||
|
||||
return transform
|
||||
|
||||
# Transformer tests
|
||||
def transform_checker(tests, transformer, **kwargs):
|
||||
"""Utility to loop over test inputs"""
|
||||
transformer = transformer(**kwargs)
|
||||
try:
|
||||
for inp, tr in tests:
|
||||
if inp is None:
|
||||
out = transformer.reset()
|
||||
else:
|
||||
out = transformer.push(inp)
|
||||
nt.assert_equal(out, tr)
|
||||
finally:
|
||||
transformer.reset()
|
||||
|
||||
# Data for all the syntax tests in the form of lists of pairs of
|
||||
# raw/transformed input. We store it here as a global dict so that we can use
|
||||
# it both within single-function tests and also to validate the behavior of the
|
||||
# larger objects
|
||||
|
||||
syntax = \
|
||||
dict(assign_system =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[(u'a =! ls', "a = get_ipython().getoutput('ls')"),
|
||||
(u'b = !ls', "b = get_ipython().getoutput('ls')"),
|
||||
(u'c= !ls', "c = get_ipython().getoutput('ls')"),
|
||||
(u'd == !ls', u'd == !ls'), # Invalid syntax, but we leave == alone.
|
||||
('x=1', 'x=1'), # normal input is unmodified
|
||||
(' ',' '), # blank lines are kept intact
|
||||
# Tuple unpacking
|
||||
(u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput(\"echo 'a\\\\nb'\")"),
|
||||
(u"a,= !echo 'a'", u"a, = get_ipython().getoutput(\"echo 'a'\")"),
|
||||
(u"a, *bc = !echo 'a\\nb\\nc'", u"a, *bc = get_ipython().getoutput(\"echo 'a\\\\nb\\\\nc'\")"),
|
||||
# Tuple unpacking with regular Python expressions, not our syntax.
|
||||
(u"a, b = range(2)", u"a, b = range(2)"),
|
||||
(u"a, = range(1)", u"a, = range(1)"),
|
||||
(u"a, *bc = range(3)", u"a, *bc = range(3)"),
|
||||
]],
|
||||
|
||||
assign_magic =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[(u'a =% who', "a = get_ipython().run_line_magic('who', '')"),
|
||||
(u'b = %who', "b = get_ipython().run_line_magic('who', '')"),
|
||||
(u'c= %ls', "c = get_ipython().run_line_magic('ls', '')"),
|
||||
(u'd == %ls', u'd == %ls'), # Invalid syntax, but we leave == alone.
|
||||
('x=1', 'x=1'), # normal input is unmodified
|
||||
(' ',' '), # blank lines are kept intact
|
||||
(u"a, b = %foo", u"a, b = get_ipython().run_line_magic('foo', '')"),
|
||||
]],
|
||||
|
||||
classic_prompt =
|
||||
[('>>> x=1', 'x=1'),
|
||||
('x=1', 'x=1'), # normal input is unmodified
|
||||
(' ', ' '), # blank lines are kept intact
|
||||
],
|
||||
|
||||
ipy_prompt =
|
||||
[('In [1]: x=1', 'x=1'),
|
||||
('x=1', 'x=1'), # normal input is unmodified
|
||||
(' ',' '), # blank lines are kept intact
|
||||
],
|
||||
|
||||
# Tests for the escape transformer to leave normal code alone
|
||||
escaped_noesc =
|
||||
[ (' ', ' '),
|
||||
('x=1', 'x=1'),
|
||||
],
|
||||
|
||||
# System calls
|
||||
escaped_shell =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[ (u'!ls', "get_ipython().system('ls')"),
|
||||
# Double-escape shell, this means to capture the output of the
|
||||
# subprocess and return it
|
||||
(u'!!ls', "get_ipython().getoutput('ls')"),
|
||||
]],
|
||||
|
||||
# Help/object info
|
||||
escaped_help =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[ (u'?', 'get_ipython().show_usage()'),
|
||||
(u'?x1', "get_ipython().run_line_magic('pinfo', 'x1')"),
|
||||
(u'??x2', "get_ipython().run_line_magic('pinfo2', 'x2')"),
|
||||
(u'?a.*s', "get_ipython().run_line_magic('psearch', 'a.*s')"),
|
||||
(u'?%hist1', "get_ipython().run_line_magic('pinfo', '%hist1')"),
|
||||
(u'?%%hist2', "get_ipython().run_line_magic('pinfo', '%%hist2')"),
|
||||
(u'?abc = qwe', "get_ipython().run_line_magic('pinfo', 'abc')"),
|
||||
]],
|
||||
|
||||
end_help =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[ (u'x3?', "get_ipython().run_line_magic('pinfo', 'x3')"),
|
||||
(u'x4??', "get_ipython().run_line_magic('pinfo2', 'x4')"),
|
||||
(u'%hist1?', "get_ipython().run_line_magic('pinfo', '%hist1')"),
|
||||
(u'%hist2??', "get_ipython().run_line_magic('pinfo2', '%hist2')"),
|
||||
(u'%%hist3?', "get_ipython().run_line_magic('pinfo', '%%hist3')"),
|
||||
(u'%%hist4??', "get_ipython().run_line_magic('pinfo2', '%%hist4')"),
|
||||
(u'π.foo?', "get_ipython().run_line_magic('pinfo', 'π.foo')"),
|
||||
(u'f*?', "get_ipython().run_line_magic('psearch', 'f*')"),
|
||||
(u'ax.*aspe*?', "get_ipython().run_line_magic('psearch', 'ax.*aspe*')"),
|
||||
(u'a = abc?', "get_ipython().set_next_input('a = abc');"
|
||||
"get_ipython().run_line_magic('pinfo', 'abc')"),
|
||||
(u'a = abc.qe??', "get_ipython().set_next_input('a = abc.qe');"
|
||||
"get_ipython().run_line_magic('pinfo2', 'abc.qe')"),
|
||||
(u'a = *.items?', "get_ipython().set_next_input('a = *.items');"
|
||||
"get_ipython().run_line_magic('psearch', '*.items')"),
|
||||
(u'plot(a?', "get_ipython().set_next_input('plot(a');"
|
||||
"get_ipython().run_line_magic('pinfo', 'a')"),
|
||||
(u'a*2 #comment?', 'a*2 #comment?'),
|
||||
]],
|
||||
|
||||
# Explicit magic calls
|
||||
escaped_magic =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[ (u'%cd', "get_ipython().run_line_magic('cd', '')"),
|
||||
(u'%cd /home', "get_ipython().run_line_magic('cd', '/home')"),
|
||||
# Backslashes need to be escaped.
|
||||
(u'%cd C:\\User', "get_ipython().run_line_magic('cd', 'C:\\\\User')"),
|
||||
(u' %magic', " get_ipython().run_line_magic('magic', '')"),
|
||||
]],
|
||||
|
||||
# Quoting with separate arguments
|
||||
escaped_quote =
|
||||
[ (',f', 'f("")'),
|
||||
(',f x', 'f("x")'),
|
||||
(' ,f y', ' f("y")'),
|
||||
(',f a b', 'f("a", "b")'),
|
||||
],
|
||||
|
||||
# Quoting with single argument
|
||||
escaped_quote2 =
|
||||
[ (';f', 'f("")'),
|
||||
(';f x', 'f("x")'),
|
||||
(' ;f y', ' f("y")'),
|
||||
(';f a b', 'f("a b")'),
|
||||
],
|
||||
|
||||
# Simply apply parens
|
||||
escaped_paren =
|
||||
[ ('/f', 'f()'),
|
||||
('/f x', 'f(x)'),
|
||||
(' /f y', ' f(y)'),
|
||||
('/f a b', 'f(a, b)'),
|
||||
],
|
||||
|
||||
# Check that we transform prompts before other transforms
|
||||
mixed =
|
||||
[(i,py3compat.u_format(o)) for i,o in \
|
||||
[ (u'In [1]: %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"),
|
||||
(u'>>> %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"),
|
||||
(u'In [2]: !ls', "get_ipython().system('ls')"),
|
||||
(u'In [3]: abs?', "get_ipython().run_line_magic('pinfo', 'abs')"),
|
||||
(u'In [4]: b = %who', "b = get_ipython().run_line_magic('who', '')"),
|
||||
]],
|
||||
)
|
||||
|
||||
# multiline syntax examples. Each of these should be a list of lists, with
|
||||
# each entry itself having pairs of raw/transformed input. The union (with
|
||||
# '\n'.join() of the transformed inputs is what the splitter should produce
|
||||
# when fed the raw lines one at a time via push.
|
||||
syntax_ml = \
|
||||
dict(classic_prompt =
|
||||
[ [('>>> for i in range(10):','for i in range(10):'),
|
||||
('... print i',' print i'),
|
||||
('... ', ''),
|
||||
],
|
||||
[('>>> a="""','a="""'),
|
||||
('... 123"""','123"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
('... 123','123'),
|
||||
('... 456"""','456"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
('>>> 123','123'),
|
||||
('... 456"""','456"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
('123','123'),
|
||||
('... 456"""','... 456"""'),
|
||||
],
|
||||
[('....__class__','....__class__'),
|
||||
],
|
||||
[('a=5', 'a=5'),
|
||||
('...', ''),
|
||||
],
|
||||
[('>>> def f(x):', 'def f(x):'),
|
||||
('...', ''),
|
||||
('... return x', ' return x'),
|
||||
],
|
||||
[('board = """....', 'board = """....'),
|
||||
('....', '....'),
|
||||
('...."""', '...."""'),
|
||||
],
|
||||
],
|
||||
|
||||
ipy_prompt =
|
||||
[ [('In [24]: for i in range(10):','for i in range(10):'),
|
||||
(' ....: print i',' print i'),
|
||||
(' ....: ', ''),
|
||||
],
|
||||
[('In [24]: for i in range(10):','for i in range(10):'),
|
||||
# Qt console prompts expand with spaces, not dots
|
||||
(' ...: print i',' print i'),
|
||||
(' ...: ', ''),
|
||||
],
|
||||
[('In [24]: for i in range(10):','for i in range(10):'),
|
||||
# Sometimes whitespace preceding '...' has been removed
|
||||
('...: print i',' print i'),
|
||||
('...: ', ''),
|
||||
],
|
||||
[('In [24]: for i in range(10):','for i in range(10):'),
|
||||
# Space after last continuation prompt has been removed (issue #6674)
|
||||
('...: print i',' print i'),
|
||||
('...:', ''),
|
||||
],
|
||||
[('In [2]: a="""','a="""'),
|
||||
(' ...: 123"""','123"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
(' ...: 123','123'),
|
||||
(' ...: 456"""','456"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
('In [1]: 123','123'),
|
||||
(' ...: 456"""','456"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
('123','123'),
|
||||
(' ...: 456"""',' ...: 456"""'),
|
||||
],
|
||||
],
|
||||
|
||||
multiline_datastructure_prompt =
|
||||
[ [('>>> a = [1,','a = [1,'),
|
||||
('... 2]','2]'),
|
||||
],
|
||||
],
|
||||
|
||||
multiline_datastructure =
|
||||
[ [('b = ("%s"', None),
|
||||
('# comment', None),
|
||||
('%foo )', 'b = ("%s"\n# comment\n%foo )'),
|
||||
],
|
||||
],
|
||||
|
||||
multiline_string =
|
||||
[ [("'''foo?", None),
|
||||
("bar'''", "'''foo?\nbar'''"),
|
||||
],
|
||||
],
|
||||
|
||||
leading_indent =
|
||||
[ [(' print "hi"','print "hi"'),
|
||||
],
|
||||
[(' for a in range(5):','for a in range(5):'),
|
||||
(' a*2',' a*2'),
|
||||
],
|
||||
[(' a="""','a="""'),
|
||||
(' 123"""','123"""'),
|
||||
],
|
||||
[('a="""','a="""'),
|
||||
(' 123"""',' 123"""'),
|
||||
],
|
||||
],
|
||||
|
||||
cellmagic =
|
||||
[ [(u'%%foo a', None),
|
||||
(None, u_fmt("get_ipython().run_cell_magic('foo', 'a', '')")),
|
||||
],
|
||||
[(u'%%bar 123', None),
|
||||
(u'hello', None),
|
||||
(None , u_fmt("get_ipython().run_cell_magic('bar', '123', 'hello')")),
|
||||
],
|
||||
[(u'a=5', 'a=5'),
|
||||
(u'%%cellmagic', '%%cellmagic'),
|
||||
],
|
||||
],
|
||||
|
||||
escaped =
|
||||
[ [('%abc def \\', None),
|
||||
('ghi', u_fmt("get_ipython().run_line_magic('abc', 'def ghi')")),
|
||||
],
|
||||
[('%abc def \\', None),
|
||||
('ghi\\', None),
|
||||
(None, u_fmt("get_ipython().run_line_magic('abc', 'def ghi')")),
|
||||
],
|
||||
],
|
||||
|
||||
assign_magic =
|
||||
[ [(u'a = %bc de \\', None),
|
||||
(u'fg', u_fmt("a = get_ipython().run_line_magic('bc', 'de fg')")),
|
||||
],
|
||||
[(u'a = %bc de \\', None),
|
||||
(u'fg\\', None),
|
||||
(None, u_fmt("a = get_ipython().run_line_magic('bc', 'de fg')")),
|
||||
],
|
||||
],
|
||||
|
||||
assign_system =
|
||||
[ [(u'a = !bc de \\', None),
|
||||
(u'fg', u_fmt("a = get_ipython().getoutput('bc de fg')")),
|
||||
],
|
||||
[(u'a = !bc de \\', None),
|
||||
(u'fg\\', None),
|
||||
(None, u_fmt("a = get_ipython().getoutput('bc de fg')")),
|
||||
],
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_assign_system():
|
||||
tt.check_pairs(transform_and_reset(ipt.assign_from_system), syntax['assign_system'])
|
||||
|
||||
def test_assign_magic():
|
||||
tt.check_pairs(transform_and_reset(ipt.assign_from_magic), syntax['assign_magic'])
|
||||
|
||||
def test_classic_prompt():
|
||||
tt.check_pairs(transform_and_reset(ipt.classic_prompt), syntax['classic_prompt'])
|
||||
for example in syntax_ml['classic_prompt']:
|
||||
transform_checker(example, ipt.classic_prompt)
|
||||
for example in syntax_ml['multiline_datastructure_prompt']:
|
||||
transform_checker(example, ipt.classic_prompt)
|
||||
|
||||
# Check that we don't transform the second line if the first is obviously
|
||||
# IPython syntax
|
||||
transform_checker([
|
||||
(u'%foo', '%foo'),
|
||||
(u'>>> bar', '>>> bar'),
|
||||
], ipt.classic_prompt)
|
||||
|
||||
|
||||
def test_ipy_prompt():
|
||||
tt.check_pairs(transform_and_reset(ipt.ipy_prompt), syntax['ipy_prompt'])
|
||||
for example in syntax_ml['ipy_prompt']:
|
||||
transform_checker(example, ipt.ipy_prompt)
|
||||
|
||||
# Check that we don't transform the second line if we're inside a cell magic
|
||||
transform_checker([
|
||||
(u'%%foo', '%%foo'),
|
||||
(u'In [1]: bar', 'In [1]: bar'),
|
||||
], ipt.ipy_prompt)
|
||||
|
||||
def test_assemble_logical_lines():
|
||||
tests = \
|
||||
[ [(u"a = \\", None),
|
||||
(u"123", u"a = 123"),
|
||||
],
|
||||
[(u"a = \\", None), # Test resetting when within a multi-line string
|
||||
(u"12 *\\", None),
|
||||
(None, u"a = 12 *"),
|
||||
],
|
||||
[(u"# foo\\", u"# foo\\"), # Comments can't be continued like this
|
||||
],
|
||||
]
|
||||
for example in tests:
|
||||
transform_checker(example, ipt.assemble_logical_lines)
|
||||
|
||||
def test_assemble_python_lines():
|
||||
tests = \
|
||||
[ [(u"a = '''", None),
|
||||
(u"abc'''", u"a = '''\nabc'''"),
|
||||
],
|
||||
[(u"a = '''", None), # Test resetting when within a multi-line string
|
||||
(u"def", None),
|
||||
(None, u"a = '''\ndef"),
|
||||
],
|
||||
[(u"a = [1,", None),
|
||||
(u"2]", u"a = [1,\n2]"),
|
||||
],
|
||||
[(u"a = [1,", None), # Test resetting when within a multi-line string
|
||||
(u"2,", None),
|
||||
(None, u"a = [1,\n2,"),
|
||||
],
|
||||
[(u"a = '''", None), # Test line continuation within a multi-line string
|
||||
(u"abc\\", None),
|
||||
(u"def", None),
|
||||
(u"'''", u"a = '''\nabc\\\ndef\n'''"),
|
||||
],
|
||||
] + syntax_ml['multiline_datastructure']
|
||||
for example in tests:
|
||||
transform_checker(example, ipt.assemble_python_lines)
|
||||
|
||||
|
||||
def test_help_end():
|
||||
tt.check_pairs(transform_and_reset(ipt.help_end), syntax['end_help'])
|
||||
|
||||
def test_escaped_noesc():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_noesc'])
|
||||
|
||||
|
||||
def test_escaped_shell():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_shell'])
|
||||
|
||||
|
||||
def test_escaped_help():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_help'])
|
||||
|
||||
|
||||
def test_escaped_magic():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_magic'])
|
||||
|
||||
|
||||
def test_escaped_quote():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote'])
|
||||
|
||||
|
||||
def test_escaped_quote2():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote2'])
|
||||
|
||||
|
||||
def test_escaped_paren():
|
||||
tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_paren'])
|
||||
|
||||
|
||||
def test_cellmagic():
|
||||
for example in syntax_ml['cellmagic']:
|
||||
transform_checker(example, ipt.cellmagic)
|
||||
|
||||
line_example = [(u'%%bar 123', None),
|
||||
(u'hello', None),
|
||||
(u'' , u_fmt("get_ipython().run_cell_magic('bar', '123', 'hello')")),
|
||||
]
|
||||
transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True)
|
||||
|
||||
def test_has_comment():
|
||||
tests = [('text', False),
|
||||
('text #comment', True),
|
||||
('text #comment\n', True),
|
||||
('#comment', True),
|
||||
('#comment\n', True),
|
||||
('a = "#string"', False),
|
||||
('a = "#string" # comment', True),
|
||||
('a #comment not "string"', True),
|
||||
]
|
||||
tt.check_pairs(ipt.has_comment, tests)
|
||||
|
||||
@ipt.TokenInputTransformer.wrap
|
||||
def decistmt(tokens):
|
||||
"""Substitute Decimals for floats in a string of statements.
|
||||
|
||||
Based on an example from the tokenize module docs.
|
||||
"""
|
||||
result = []
|
||||
for toknum, tokval, _, _, _ in tokens:
|
||||
if toknum == tokenize.NUMBER and '.' in tokval: # replace NUMBER tokens
|
||||
for newtok in [
|
||||
(tokenize.NAME, 'Decimal'),
|
||||
(tokenize.OP, '('),
|
||||
(tokenize.STRING, repr(tokval)),
|
||||
(tokenize.OP, ')')
|
||||
]:
|
||||
yield newtok
|
||||
else:
|
||||
yield (toknum, tokval)
|
||||
|
||||
|
||||
|
||||
def test_token_input_transformer():
|
||||
tests = [(u'1.2', u_fmt(u"Decimal ('1.2')")),
|
||||
(u'"1.2"', u'"1.2"'),
|
||||
]
|
||||
tt.check_pairs(transform_and_reset(decistmt), tests)
|
||||
ml_tests = \
|
||||
[ [(u"a = 1.2; b = '''x", None),
|
||||
(u"y'''", u_fmt(u"a =Decimal ('1.2');b ='''x\ny'''")),
|
||||
],
|
||||
[(u"a = [1.2,", None),
|
||||
(u"3]", u_fmt(u"a =[Decimal ('1.2'),\n3 ]")),
|
||||
],
|
||||
[(u"a = '''foo", None), # Test resetting when within a multi-line string
|
||||
(u"bar", None),
|
||||
(None, u"a = '''foo\nbar"),
|
||||
],
|
||||
]
|
||||
for example in ml_tests:
|
||||
transform_checker(example, decistmt)
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
"""Tests for the token-based transformers in IPython.core.inputtransformer2
|
||||
|
||||
Line-based transformers are the simpler ones; token-based transformers are
|
||||
more complex. See test_inputtransformer2_line for tests for line-based
|
||||
transformations.
|
||||
"""
|
||||
import nose.tools as nt
|
||||
import string
|
||||
|
||||
from IPython.core import inputtransformer2 as ipt2
|
||||
from IPython.core.inputtransformer2 import make_tokens_by_line, _find_assign_op
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
MULTILINE_MAGIC = ("""\
|
||||
a = f()
|
||||
%foo \\
|
||||
bar
|
||||
g()
|
||||
""".splitlines(keepends=True), (2, 0), """\
|
||||
a = f()
|
||||
get_ipython().run_line_magic('foo', ' bar')
|
||||
g()
|
||||
""".splitlines(keepends=True))
|
||||
|
||||
INDENTED_MAGIC = ("""\
|
||||
for a in range(5):
|
||||
%ls
|
||||
""".splitlines(keepends=True), (2, 4), """\
|
||||
for a in range(5):
|
||||
get_ipython().run_line_magic('ls', '')
|
||||
""".splitlines(keepends=True))
|
||||
|
||||
MULTILINE_MAGIC_ASSIGN = ("""\
|
||||
a = f()
|
||||
b = %foo \\
|
||||
bar
|
||||
g()
|
||||
""".splitlines(keepends=True), (2, 4), """\
|
||||
a = f()
|
||||
b = get_ipython().run_line_magic('foo', ' bar')
|
||||
g()
|
||||
""".splitlines(keepends=True))
|
||||
|
||||
MULTILINE_SYSTEM_ASSIGN = ("""\
|
||||
a = f()
|
||||
b = !foo \\
|
||||
bar
|
||||
g()
|
||||
""".splitlines(keepends=True), (2, 4), """\
|
||||
a = f()
|
||||
b = get_ipython().getoutput('foo bar')
|
||||
g()
|
||||
""".splitlines(keepends=True))
|
||||
|
||||
#####
|
||||
|
||||
MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT = ("""\
|
||||
def test():
|
||||
for i in range(1):
|
||||
print(i)
|
||||
res =! ls
|
||||
""".splitlines(keepends=True), (4, 7), '''\
|
||||
def test():
|
||||
for i in range(1):
|
||||
print(i)
|
||||
res =get_ipython().getoutput(\' ls\')
|
||||
'''.splitlines(keepends=True))
|
||||
|
||||
######
|
||||
|
||||
AUTOCALL_QUOTE = (
|
||||
[",f 1 2 3\n"], (1, 0),
|
||||
['f("1", "2", "3")\n']
|
||||
)
|
||||
|
||||
AUTOCALL_QUOTE2 = (
|
||||
[";f 1 2 3\n"], (1, 0),
|
||||
['f("1 2 3")\n']
|
||||
)
|
||||
|
||||
AUTOCALL_PAREN = (
|
||||
["/f 1 2 3\n"], (1, 0),
|
||||
['f(1, 2, 3)\n']
|
||||
)
|
||||
|
||||
SIMPLE_HELP = (
|
||||
["foo?\n"], (1, 0),
|
||||
["get_ipython().run_line_magic('pinfo', 'foo')\n"]
|
||||
)
|
||||
|
||||
DETAILED_HELP = (
|
||||
["foo??\n"], (1, 0),
|
||||
["get_ipython().run_line_magic('pinfo2', 'foo')\n"]
|
||||
)
|
||||
|
||||
MAGIC_HELP = (
|
||||
["%foo?\n"], (1, 0),
|
||||
["get_ipython().run_line_magic('pinfo', '%foo')\n"]
|
||||
)
|
||||
|
||||
HELP_IN_EXPR = (
|
||||
["a = b + c?\n"], (1, 0),
|
||||
["get_ipython().set_next_input('a = b + c');"
|
||||
"get_ipython().run_line_magic('pinfo', 'c')\n"]
|
||||
)
|
||||
|
||||
HELP_CONTINUED_LINE = ("""\
|
||||
a = \\
|
||||
zip?
|
||||
""".splitlines(keepends=True), (1, 0),
|
||||
[r"get_ipython().set_next_input('a = \\\nzip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"]
|
||||
)
|
||||
|
||||
HELP_MULTILINE = ("""\
|
||||
(a,
|
||||
b) = zip?
|
||||
""".splitlines(keepends=True), (1, 0),
|
||||
[r"get_ipython().set_next_input('(a,\nb) = zip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"]
|
||||
)
|
||||
|
||||
HELP_UNICODE = (
|
||||
["π.foo?\n"], (1, 0),
|
||||
["get_ipython().run_line_magic('pinfo', 'π.foo')\n"]
|
||||
)
|
||||
|
||||
|
||||
def null_cleanup_transformer(lines):
|
||||
"""
|
||||
A cleanup transform that returns an empty list.
|
||||
"""
|
||||
return []
|
||||
|
||||
def check_make_token_by_line_never_ends_empty():
|
||||
"""
|
||||
Check that not sequence of single or double characters ends up leading to en empty list of tokens
|
||||
"""
|
||||
from string import printable
|
||||
for c in printable:
|
||||
nt.assert_not_equal(make_tokens_by_line(c)[-1], [])
|
||||
for k in printable:
|
||||
nt.assert_not_equal(make_tokens_by_line(c+k)[-1], [])
|
||||
|
||||
def check_find(transformer, case, match=True):
|
||||
sample, expected_start, _ = case
|
||||
tbl = make_tokens_by_line(sample)
|
||||
res = transformer.find(tbl)
|
||||
if match:
|
||||
# start_line is stored 0-indexed, expected values are 1-indexed
|
||||
nt.assert_equal((res.start_line+1, res.start_col), expected_start)
|
||||
return res
|
||||
else:
|
||||
nt.assert_is(res, None)
|
||||
|
||||
def check_transform(transformer_cls, case):
|
||||
lines, start, expected = case
|
||||
transformer = transformer_cls(start)
|
||||
nt.assert_equal(transformer.transform(lines), expected)
|
||||
|
||||
def test_continued_line():
|
||||
lines = MULTILINE_MAGIC_ASSIGN[0]
|
||||
nt.assert_equal(ipt2.find_end_of_continued_line(lines, 1), 2)
|
||||
|
||||
nt.assert_equal(ipt2.assemble_continued_line(lines, (1, 5), 2), "foo bar")
|
||||
|
||||
def test_find_assign_magic():
|
||||
check_find(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN)
|
||||
check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN, match=False)
|
||||
check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT, match=False)
|
||||
|
||||
def test_transform_assign_magic():
|
||||
check_transform(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN)
|
||||
|
||||
def test_find_assign_system():
|
||||
check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN)
|
||||
check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT)
|
||||
check_find(ipt2.SystemAssign, (["a = !ls\n"], (1, 5), None))
|
||||
check_find(ipt2.SystemAssign, (["a=!ls\n"], (1, 2), None))
|
||||
check_find(ipt2.SystemAssign, MULTILINE_MAGIC_ASSIGN, match=False)
|
||||
|
||||
def test_transform_assign_system():
|
||||
check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN)
|
||||
check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT)
|
||||
|
||||
def test_find_magic_escape():
|
||||
check_find(ipt2.EscapedCommand, MULTILINE_MAGIC)
|
||||
check_find(ipt2.EscapedCommand, INDENTED_MAGIC)
|
||||
check_find(ipt2.EscapedCommand, MULTILINE_MAGIC_ASSIGN, match=False)
|
||||
|
||||
def test_transform_magic_escape():
|
||||
check_transform(ipt2.EscapedCommand, MULTILINE_MAGIC)
|
||||
check_transform(ipt2.EscapedCommand, INDENTED_MAGIC)
|
||||
|
||||
def test_find_autocalls():
|
||||
for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]:
|
||||
print("Testing %r" % case[0])
|
||||
check_find(ipt2.EscapedCommand, case)
|
||||
|
||||
def test_transform_autocall():
|
||||
for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]:
|
||||
print("Testing %r" % case[0])
|
||||
check_transform(ipt2.EscapedCommand, case)
|
||||
|
||||
def test_find_help():
|
||||
for case in [SIMPLE_HELP, DETAILED_HELP, MAGIC_HELP, HELP_IN_EXPR]:
|
||||
check_find(ipt2.HelpEnd, case)
|
||||
|
||||
tf = check_find(ipt2.HelpEnd, HELP_CONTINUED_LINE)
|
||||
nt.assert_equal(tf.q_line, 1)
|
||||
nt.assert_equal(tf.q_col, 3)
|
||||
|
||||
tf = check_find(ipt2.HelpEnd, HELP_MULTILINE)
|
||||
nt.assert_equal(tf.q_line, 1)
|
||||
nt.assert_equal(tf.q_col, 8)
|
||||
|
||||
# ? in a comment does not trigger help
|
||||
check_find(ipt2.HelpEnd, (["foo # bar?\n"], None, None), match=False)
|
||||
# Nor in a string
|
||||
check_find(ipt2.HelpEnd, (["foo = '''bar?\n"], None, None), match=False)
|
||||
|
||||
def test_transform_help():
|
||||
tf = ipt2.HelpEnd((1, 0), (1, 9))
|
||||
nt.assert_equal(tf.transform(HELP_IN_EXPR[0]), HELP_IN_EXPR[2])
|
||||
|
||||
tf = ipt2.HelpEnd((1, 0), (2, 3))
|
||||
nt.assert_equal(tf.transform(HELP_CONTINUED_LINE[0]), HELP_CONTINUED_LINE[2])
|
||||
|
||||
tf = ipt2.HelpEnd((1, 0), (2, 8))
|
||||
nt.assert_equal(tf.transform(HELP_MULTILINE[0]), HELP_MULTILINE[2])
|
||||
|
||||
tf = ipt2.HelpEnd((1, 0), (1, 0))
|
||||
nt.assert_equal(tf.transform(HELP_UNICODE[0]), HELP_UNICODE[2])
|
||||
|
||||
def test_find_assign_op_dedent():
|
||||
"""
|
||||
be careful that empty token like dedent are not counted as parens
|
||||
"""
|
||||
class Tk:
|
||||
def __init__(self, s):
|
||||
self.string = s
|
||||
|
||||
nt.assert_equal(_find_assign_op([Tk(s) for s in ('','a','=','b')]), 2)
|
||||
nt.assert_equal(_find_assign_op([Tk(s) for s in ('','(', 'a','=','b', ')', '=' ,'5')]), 6)
|
||||
|
||||
def test_check_complete():
|
||||
cc = ipt2.TransformerManager().check_complete
|
||||
nt.assert_equal(cc("a = 1"), ('complete', None))
|
||||
nt.assert_equal(cc("for a in range(5):"), ('incomplete', 4))
|
||||
nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ('incomplete', 8))
|
||||
nt.assert_equal(cc("raise = 2"), ('invalid', None))
|
||||
nt.assert_equal(cc("a = [1,\n2,"), ('incomplete', 0))
|
||||
nt.assert_equal(cc(")"), ('incomplete', 0))
|
||||
nt.assert_equal(cc("\\\r\n"), ('incomplete', 0))
|
||||
nt.assert_equal(cc("a = '''\n hi"), ('incomplete', 3))
|
||||
nt.assert_equal(cc("def a():\n x=1\n global x"), ('invalid', None))
|
||||
nt.assert_equal(cc("a \\ "), ('invalid', None)) # Nothing allowed after backslash
|
||||
nt.assert_equal(cc("1\\\n+2"), ('complete', None))
|
||||
nt.assert_equal(cc("exit"), ('complete', None))
|
||||
|
||||
example = dedent("""
|
||||
if True:
|
||||
a=1""" )
|
||||
|
||||
nt.assert_equal(cc(example), ('incomplete', 4))
|
||||
nt.assert_equal(cc(example+'\n'), ('complete', None))
|
||||
nt.assert_equal(cc(example+'\n '), ('complete', None))
|
||||
|
||||
# no need to loop on all the letters/numbers.
|
||||
short = '12abAB'+string.printable[62:]
|
||||
for c in short:
|
||||
# test does not raise:
|
||||
cc(c)
|
||||
for k in short:
|
||||
cc(c+k)
|
||||
|
||||
nt.assert_equal(cc("def f():\n x=0\n \\\n "), ('incomplete', 2))
|
||||
|
||||
def test_check_complete_II():
|
||||
"""
|
||||
Test that multiple line strings are properly handled.
|
||||
|
||||
Separate test function for convenience
|
||||
|
||||
"""
|
||||
cc = ipt2.TransformerManager().check_complete
|
||||
nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4))
|
||||
|
||||
|
||||
def test_null_cleanup_transformer():
|
||||
manager = ipt2.TransformerManager()
|
||||
manager.cleanup_transforms.insert(0, null_cleanup_transformer)
|
||||
nt.assert_is(manager.transform_cell(""), "")
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
"""Tests for the line-based transformers in IPython.core.inputtransformer2
|
||||
|
||||
Line-based transformers are the simpler ones; token-based transformers are
|
||||
more complex. See test_inputtransformer2 for tests for token-based transformers.
|
||||
"""
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core import inputtransformer2 as ipt2
|
||||
|
||||
CELL_MAGIC = ("""\
|
||||
%%foo arg
|
||||
body 1
|
||||
body 2
|
||||
""", """\
|
||||
get_ipython().run_cell_magic('foo', 'arg', 'body 1\\nbody 2\\n')
|
||||
""")
|
||||
|
||||
def test_cell_magic():
|
||||
for sample, expected in [CELL_MAGIC]:
|
||||
nt.assert_equal(ipt2.cell_magic(sample.splitlines(keepends=True)),
|
||||
expected.splitlines(keepends=True))
|
||||
|
||||
CLASSIC_PROMPT = ("""\
|
||||
>>> for a in range(5):
|
||||
... print(a)
|
||||
""", """\
|
||||
for a in range(5):
|
||||
print(a)
|
||||
""")
|
||||
|
||||
CLASSIC_PROMPT_L2 = ("""\
|
||||
for a in range(5):
|
||||
... print(a)
|
||||
... print(a ** 2)
|
||||
""", """\
|
||||
for a in range(5):
|
||||
print(a)
|
||||
print(a ** 2)
|
||||
""")
|
||||
|
||||
def test_classic_prompt():
|
||||
for sample, expected in [CLASSIC_PROMPT, CLASSIC_PROMPT_L2]:
|
||||
nt.assert_equal(ipt2.classic_prompt(sample.splitlines(keepends=True)),
|
||||
expected.splitlines(keepends=True))
|
||||
|
||||
IPYTHON_PROMPT = ("""\
|
||||
In [1]: for a in range(5):
|
||||
...: print(a)
|
||||
""", """\
|
||||
for a in range(5):
|
||||
print(a)
|
||||
""")
|
||||
|
||||
IPYTHON_PROMPT_L2 = ("""\
|
||||
for a in range(5):
|
||||
...: print(a)
|
||||
...: print(a ** 2)
|
||||
""", """\
|
||||
for a in range(5):
|
||||
print(a)
|
||||
print(a ** 2)
|
||||
""")
|
||||
|
||||
def test_ipython_prompt():
|
||||
for sample, expected in [IPYTHON_PROMPT, IPYTHON_PROMPT_L2]:
|
||||
nt.assert_equal(ipt2.ipython_prompt(sample.splitlines(keepends=True)),
|
||||
expected.splitlines(keepends=True))
|
||||
|
||||
INDENT_SPACES = ("""\
|
||||
if True:
|
||||
a = 3
|
||||
""", """\
|
||||
if True:
|
||||
a = 3
|
||||
""")
|
||||
|
||||
INDENT_TABS = ("""\
|
||||
\tif True:
|
||||
\t\tb = 4
|
||||
""", """\
|
||||
if True:
|
||||
\tb = 4
|
||||
""")
|
||||
|
||||
def test_leading_indent():
|
||||
for sample, expected in [INDENT_SPACES, INDENT_TABS]:
|
||||
nt.assert_equal(ipt2.leading_indent(sample.splitlines(keepends=True)),
|
||||
expected.splitlines(keepends=True))
|
||||
|
||||
LEADING_EMPTY_LINES = ("""\
|
||||
\t
|
||||
|
||||
if True:
|
||||
a = 3
|
||||
|
||||
b = 4
|
||||
""", """\
|
||||
if True:
|
||||
a = 3
|
||||
|
||||
b = 4
|
||||
""")
|
||||
|
||||
ONLY_EMPTY_LINES = ("""\
|
||||
\t
|
||||
|
||||
""", """\
|
||||
\t
|
||||
|
||||
""")
|
||||
|
||||
def test_leading_empty_lines():
|
||||
for sample, expected in [LEADING_EMPTY_LINES, ONLY_EMPTY_LINES]:
|
||||
nt.assert_equal(
|
||||
ipt2.leading_empty_lines(sample.splitlines(keepends=True)),
|
||||
expected.splitlines(keepends=True))
|
||||
1018
venv/Lib/site-packages/IPython/core/tests/test_interactiveshell.py
Normal file
1018
venv/Lib/site-packages/IPython/core/tests/test_interactiveshell.py
Normal file
File diff suppressed because it is too large
Load diff
246
venv/Lib/site-packages/IPython/core/tests/test_iplib.py
Normal file
246
venv/Lib/site-packages/IPython/core/tests/test_iplib.py
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
"""Tests for the key interactiveshell module, where the main ipython class is defined.
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Module imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# third party
|
||||
import nose.tools as nt
|
||||
|
||||
# our own packages
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def test_reset():
|
||||
"""reset must clear most namespaces."""
|
||||
|
||||
# Check that reset runs without error
|
||||
ip.reset()
|
||||
|
||||
# Once we've reset it (to clear of any junk that might have been there from
|
||||
# other tests, we can count how many variables are in the user's namespace
|
||||
nvars_user_ns = len(ip.user_ns)
|
||||
nvars_hidden = len(ip.user_ns_hidden)
|
||||
|
||||
# Now add a few variables to user_ns, and check that reset clears them
|
||||
ip.user_ns['x'] = 1
|
||||
ip.user_ns['y'] = 1
|
||||
ip.reset()
|
||||
|
||||
# Finally, check that all namespaces have only as many variables as we
|
||||
# expect to find in them:
|
||||
nt.assert_equal(len(ip.user_ns), nvars_user_ns)
|
||||
nt.assert_equal(len(ip.user_ns_hidden), nvars_hidden)
|
||||
|
||||
|
||||
# Tests for reporting of exceptions in various modes, handling of SystemExit,
|
||||
# and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
|
||||
|
||||
def doctest_tb_plain():
|
||||
"""
|
||||
In [18]: xmode plain
|
||||
Exception reporting mode: Plain
|
||||
|
||||
In [19]: run simpleerr.py
|
||||
Traceback (most recent call last):
|
||||
...line 32, in <module>
|
||||
bar(mode)
|
||||
...line 16, in bar
|
||||
div0()
|
||||
...line 8, in div0
|
||||
x/y
|
||||
ZeroDivisionError: ...
|
||||
"""
|
||||
|
||||
|
||||
def doctest_tb_context():
|
||||
"""
|
||||
In [3]: xmode context
|
||||
Exception reporting mode: Context
|
||||
|
||||
In [4]: run simpleerr.py
|
||||
---------------------------------------------------------------------------
|
||||
ZeroDivisionError Traceback (most recent call last)
|
||||
<BLANKLINE>
|
||||
... in <module>
|
||||
30 mode = 'div'
|
||||
31
|
||||
---> 32 bar(mode)
|
||||
<BLANKLINE>
|
||||
... in bar(mode)
|
||||
14 "bar"
|
||||
15 if mode=='div':
|
||||
---> 16 div0()
|
||||
17 elif mode=='exit':
|
||||
18 try:
|
||||
<BLANKLINE>
|
||||
... in div0()
|
||||
6 x = 1
|
||||
7 y = 0
|
||||
----> 8 x/y
|
||||
9
|
||||
10 def sysexit(stat, mode):
|
||||
<BLANKLINE>
|
||||
ZeroDivisionError: ...
|
||||
"""
|
||||
|
||||
|
||||
def doctest_tb_verbose():
|
||||
"""
|
||||
In [5]: xmode verbose
|
||||
Exception reporting mode: Verbose
|
||||
|
||||
In [6]: run simpleerr.py
|
||||
---------------------------------------------------------------------------
|
||||
ZeroDivisionError Traceback (most recent call last)
|
||||
<BLANKLINE>
|
||||
... in <module>
|
||||
30 mode = 'div'
|
||||
31
|
||||
---> 32 bar(mode)
|
||||
global bar = <function bar at ...>
|
||||
global mode = 'div'
|
||||
<BLANKLINE>
|
||||
... in bar(mode='div')
|
||||
14 "bar"
|
||||
15 if mode=='div':
|
||||
---> 16 div0()
|
||||
global div0 = <function div0 at ...>
|
||||
17 elif mode=='exit':
|
||||
18 try:
|
||||
<BLANKLINE>
|
||||
... in div0()
|
||||
6 x = 1
|
||||
7 y = 0
|
||||
----> 8 x/y
|
||||
x = 1
|
||||
y = 0
|
||||
9
|
||||
10 def sysexit(stat, mode):
|
||||
<BLANKLINE>
|
||||
ZeroDivisionError: ...
|
||||
"""
|
||||
|
||||
def doctest_tb_sysexit():
|
||||
"""
|
||||
In [17]: %xmode plain
|
||||
Exception reporting mode: Plain
|
||||
|
||||
In [18]: %run simpleerr.py exit
|
||||
An exception has occurred, use %tb to see the full traceback.
|
||||
SystemExit: (1, 'Mode = exit')
|
||||
|
||||
In [19]: %run simpleerr.py exit 2
|
||||
An exception has occurred, use %tb to see the full traceback.
|
||||
SystemExit: (2, 'Mode = exit')
|
||||
|
||||
In [20]: %tb
|
||||
Traceback (most recent call last):
|
||||
File ... in <module>
|
||||
bar(mode)
|
||||
File ... line 22, in bar
|
||||
sysexit(stat, mode)
|
||||
File ... line 11, in sysexit
|
||||
raise SystemExit(stat, 'Mode = %s' % mode)
|
||||
SystemExit: (2, 'Mode = exit')
|
||||
|
||||
In [21]: %xmode context
|
||||
Exception reporting mode: Context
|
||||
|
||||
In [22]: %tb
|
||||
---------------------------------------------------------------------------
|
||||
SystemExit Traceback (most recent call last)
|
||||
<BLANKLINE>
|
||||
...<module>
|
||||
30 mode = 'div'
|
||||
31
|
||||
---> 32 bar(mode)
|
||||
<BLANKLINE>
|
||||
...bar(mode)
|
||||
20 except:
|
||||
21 stat = 1
|
||||
---> 22 sysexit(stat, mode)
|
||||
23 else:
|
||||
24 raise ValueError('Unknown mode')
|
||||
<BLANKLINE>
|
||||
...sysexit(stat, mode)
|
||||
9
|
||||
10 def sysexit(stat, mode):
|
||||
---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
|
||||
12
|
||||
13 def bar(mode):
|
||||
<BLANKLINE>
|
||||
SystemExit: (2, 'Mode = exit')
|
||||
|
||||
In [23]: %xmode verbose
|
||||
Exception reporting mode: Verbose
|
||||
|
||||
In [24]: %tb
|
||||
---------------------------------------------------------------------------
|
||||
SystemExit Traceback (most recent call last)
|
||||
<BLANKLINE>
|
||||
... in <module>
|
||||
30 mode = 'div'
|
||||
31
|
||||
---> 32 bar(mode)
|
||||
global bar = <function bar at ...>
|
||||
global mode = 'exit'
|
||||
<BLANKLINE>
|
||||
... in bar(mode='exit')
|
||||
20 except:
|
||||
21 stat = 1
|
||||
---> 22 sysexit(stat, mode)
|
||||
global sysexit = <function sysexit at ...>
|
||||
stat = 2
|
||||
mode = 'exit'
|
||||
23 else:
|
||||
24 raise ValueError('Unknown mode')
|
||||
<BLANKLINE>
|
||||
... in sysexit(stat=2, mode='exit')
|
||||
9
|
||||
10 def sysexit(stat, mode):
|
||||
---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
|
||||
global SystemExit = undefined
|
||||
stat = 2
|
||||
mode = 'exit'
|
||||
12
|
||||
13 def bar(mode):
|
||||
<BLANKLINE>
|
||||
SystemExit: (2, 'Mode = exit')
|
||||
"""
|
||||
|
||||
|
||||
def test_run_cell():
|
||||
import textwrap
|
||||
ip.run_cell('a = 10\na+=1')
|
||||
ip.run_cell('assert a == 11\nassert 1')
|
||||
|
||||
nt.assert_equal(ip.user_ns['a'], 11)
|
||||
complex = textwrap.dedent("""
|
||||
if 1:
|
||||
print "hello"
|
||||
if 1:
|
||||
print "world"
|
||||
|
||||
if 2:
|
||||
print "foo"
|
||||
|
||||
if 3:
|
||||
print "bar"
|
||||
|
||||
if 4:
|
||||
print "bar"
|
||||
|
||||
""")
|
||||
# Simply verifies that this kind of input is run
|
||||
ip.run_cell(complex)
|
||||
|
||||
|
||||
def test_db():
|
||||
"""Test the internal database used for variable persistence."""
|
||||
ip.db['__unittest_'] = 12
|
||||
nt.assert_equal(ip.db['__unittest_'], 12)
|
||||
del ip.db['__unittest_']
|
||||
assert '__unittest_' not in ip.db
|
||||
30
venv/Lib/site-packages/IPython/core/tests/test_logger.py
Normal file
30
venv/Lib/site-packages/IPython/core/tests/test_logger.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Test IPython.core.logger"""
|
||||
|
||||
import os.path
|
||||
|
||||
import nose.tools as nt
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
def test_logstart_inaccessible_file():
|
||||
try:
|
||||
_ip.logger.logstart(logfname="/") # Opening that filename will fail.
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
nt.assert_true(False) # The try block should never pass.
|
||||
|
||||
try:
|
||||
_ip.run_cell("a=1") # Check it doesn't try to log this
|
||||
finally:
|
||||
_ip.logger.log_active = False # If this fails, don't let later tests fail
|
||||
|
||||
def test_logstart_unicode():
|
||||
with TemporaryDirectory() as tdir:
|
||||
logfname = os.path.join(tdir, "test_unicode.log")
|
||||
_ip.run_cell("'abc€'")
|
||||
try:
|
||||
_ip.magic("logstart -to %s" % logfname)
|
||||
_ip.run_cell("'abc€'")
|
||||
finally:
|
||||
_ip.logger.logstop()
|
||||
1225
venv/Lib/site-packages/IPython/core/tests/test_magic.py
Normal file
1225
venv/Lib/site-packages/IPython/core/tests/test_magic.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,118 @@
|
|||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2010-2011, 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.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import argparse
|
||||
from nose.tools import assert_equal
|
||||
|
||||
from IPython.core.magic_arguments import (argument, argument_group, kwds,
|
||||
magic_arguments, parse_argstring, real_name)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
def magic_foo1(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_foo1, args)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
def magic_foo2(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_foo2, args)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
@argument_group('Group')
|
||||
@argument('-b', '--bar', help="a grouped argument")
|
||||
@argument_group('Second Group')
|
||||
@argument('-z', '--baz', help="another grouped argument")
|
||||
def magic_foo3(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_foo3, args)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
@kwds(argument_default=argparse.SUPPRESS)
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
def magic_foo4(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_foo4, args)
|
||||
|
||||
|
||||
@magic_arguments('frobnicate')
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
def magic_foo5(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_foo5, args)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
def magic_magic_foo(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(magic_magic_foo, args)
|
||||
|
||||
|
||||
@magic_arguments()
|
||||
@argument('-f', '--foo', help="an argument")
|
||||
def foo(self, args):
|
||||
""" A docstring.
|
||||
"""
|
||||
return parse_argstring(foo, 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')
|
||||
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))
|
||||
assert hasattr(magic_foo1, 'has_arguments')
|
||||
|
||||
assert_equal(magic_foo2.__doc__, '::\n\n %foo2\n\n A docstring.\n')
|
||||
assert_equal(getattr(magic_foo2, 'argcmd_name', None), None)
|
||||
assert_equal(real_name(magic_foo2), 'foo2')
|
||||
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(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(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(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(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(getattr(foo, 'argcmd_name', None), None)
|
||||
assert_equal(real_name(foo), 'foo')
|
||||
assert_equal(foo(None, ''), argparse.Namespace(foo=None))
|
||||
assert hasattr(foo, 'has_arguments')
|
||||
192
venv/Lib/site-packages/IPython/core/tests/test_magic_terminal.py
Normal file
192
venv/Lib/site-packages/IPython/core/tests/test_magic_terminal.py
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
"""Tests for various magic functions specific to the terminal frontend.
|
||||
|
||||
Needs to be run by nose (to make ipython session available).
|
||||
"""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
from io import StringIO
|
||||
from unittest import TestCase
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.testing import tools as tt
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions begin
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def check_cpaste(code, should_fail=False):
|
||||
"""Execute code via 'cpaste' and ensure it was executed, unless
|
||||
should_fail is set.
|
||||
"""
|
||||
ip.user_ns['code_ran'] = False
|
||||
|
||||
src = StringIO()
|
||||
if not hasattr(src, 'encoding'):
|
||||
# IPython expects stdin to have an encoding attribute
|
||||
src.encoding = None
|
||||
src.write(code)
|
||||
src.write('\n--\n')
|
||||
src.seek(0)
|
||||
|
||||
stdin_save = sys.stdin
|
||||
sys.stdin = src
|
||||
|
||||
try:
|
||||
context = tt.AssertPrints if should_fail else tt.AssertNotPrints
|
||||
with context("Traceback (most recent call last)"):
|
||||
ip.magic('cpaste')
|
||||
|
||||
if not should_fail:
|
||||
assert ip.user_ns['code_ran'], "%r failed" % code
|
||||
finally:
|
||||
sys.stdin = stdin_save
|
||||
|
||||
def test_cpaste():
|
||||
"""Test cpaste magic"""
|
||||
|
||||
def runf():
|
||||
"""Marker function: sets a flag when executed.
|
||||
"""
|
||||
ip.user_ns['code_ran'] = True
|
||||
return 'runf' # return string so '+ runf()' doesn't result in success
|
||||
|
||||
tests = {'pass': ["runf()",
|
||||
"In [1]: runf()",
|
||||
"In [1]: if 1:\n ...: runf()",
|
||||
"> > > runf()",
|
||||
">>> runf()",
|
||||
" >>> runf()",
|
||||
],
|
||||
|
||||
'fail': ["1 + runf()",
|
||||
"++ runf()",
|
||||
]}
|
||||
|
||||
ip.user_ns['runf'] = runf
|
||||
|
||||
for code in tests['pass']:
|
||||
check_cpaste(code)
|
||||
|
||||
for code in tests['fail']:
|
||||
check_cpaste(code, should_fail=True)
|
||||
|
||||
|
||||
class PasteTestCase(TestCase):
|
||||
"""Multiple tests for clipboard pasting"""
|
||||
|
||||
def paste(self, txt, flags='-q'):
|
||||
"""Paste input text, by default in quiet mode"""
|
||||
ip.hooks.clipboard_get = lambda : txt
|
||||
ip.magic('paste '+flags)
|
||||
|
||||
def setUp(self):
|
||||
# Inject fake clipboard hook but save original so we can restore it later
|
||||
self.original_clip = ip.hooks.clipboard_get
|
||||
|
||||
def tearDown(self):
|
||||
# Restore original hook
|
||||
ip.hooks.clipboard_get = self.original_clip
|
||||
|
||||
def test_paste(self):
|
||||
ip.user_ns.pop('x', None)
|
||||
self.paste('x = 1')
|
||||
nt.assert_equal(ip.user_ns['x'], 1)
|
||||
ip.user_ns.pop('x')
|
||||
|
||||
def test_paste_pyprompt(self):
|
||||
ip.user_ns.pop('x', None)
|
||||
self.paste('>>> x=2')
|
||||
nt.assert_equal(ip.user_ns['x'], 2)
|
||||
ip.user_ns.pop('x')
|
||||
|
||||
def test_paste_py_multi(self):
|
||||
self.paste("""
|
||||
>>> x = [1,2,3]
|
||||
>>> y = []
|
||||
>>> for i in x:
|
||||
... y.append(i**2)
|
||||
...
|
||||
""")
|
||||
nt.assert_equal(ip.user_ns['x'], [1,2,3])
|
||||
nt.assert_equal(ip.user_ns['y'], [1,4,9])
|
||||
|
||||
def test_paste_py_multi_r(self):
|
||||
"Now, test that self.paste -r works"
|
||||
self.test_paste_py_multi()
|
||||
nt.assert_equal(ip.user_ns.pop('x'), [1,2,3])
|
||||
nt.assert_equal(ip.user_ns.pop('y'), [1,4,9])
|
||||
nt.assert_false('x' in ip.user_ns)
|
||||
ip.magic('paste -r')
|
||||
nt.assert_equal(ip.user_ns['x'], [1,2,3])
|
||||
nt.assert_equal(ip.user_ns['y'], [1,4,9])
|
||||
|
||||
def test_paste_email(self):
|
||||
"Test pasting of email-quoted contents"
|
||||
self.paste("""\
|
||||
>> def foo(x):
|
||||
>> return x + 1
|
||||
>> xx = foo(1.1)""")
|
||||
nt.assert_equal(ip.user_ns['xx'], 2.1)
|
||||
|
||||
def test_paste_email2(self):
|
||||
"Email again; some programs add a space also at each quoting level"
|
||||
self.paste("""\
|
||||
> > def foo(x):
|
||||
> > return x + 1
|
||||
> > yy = foo(2.1) """)
|
||||
nt.assert_equal(ip.user_ns['yy'], 3.1)
|
||||
|
||||
def test_paste_email_py(self):
|
||||
"Email quoting of interactive input"
|
||||
self.paste("""\
|
||||
>> >>> def f(x):
|
||||
>> ... return x+1
|
||||
>> ...
|
||||
>> >>> zz = f(2.5) """)
|
||||
nt.assert_equal(ip.user_ns['zz'], 3.5)
|
||||
|
||||
def test_paste_echo(self):
|
||||
"Also test self.paste echoing, by temporarily faking the writer"
|
||||
w = StringIO()
|
||||
writer = ip.write
|
||||
ip.write = w.write
|
||||
code = """
|
||||
a = 100
|
||||
b = 200"""
|
||||
try:
|
||||
self.paste(code,'')
|
||||
out = w.getvalue()
|
||||
finally:
|
||||
ip.write = writer
|
||||
nt.assert_equal(ip.user_ns['a'], 100)
|
||||
nt.assert_equal(ip.user_ns['b'], 200)
|
||||
assert out == code+"\n## -- End pasted text --\n"
|
||||
|
||||
def test_paste_leading_commas(self):
|
||||
"Test multiline strings with leading commas"
|
||||
tm = ip.magics_manager.registry['TerminalMagics']
|
||||
s = '''\
|
||||
a = """
|
||||
,1,2,3
|
||||
"""'''
|
||||
ip.user_ns.pop('foo', None)
|
||||
tm.store_or_execute(s, 'foo')
|
||||
nt.assert_in('foo', ip.user_ns)
|
||||
|
||||
|
||||
def test_paste_trailing_question(self):
|
||||
"Test pasting sources with trailing question marks"
|
||||
tm = ip.magics_manager.registry['TerminalMagics']
|
||||
s = '''\
|
||||
def funcfoo():
|
||||
if True: #am i true?
|
||||
return 'fooresult'
|
||||
'''
|
||||
ip.user_ns.pop('funcfoo', None)
|
||||
self.paste(s)
|
||||
nt.assert_equal(ip.user_ns['funcfoo'](), 'fooresult')
|
||||
447
venv/Lib/site-packages/IPython/core/tests/test_oinspect.py
Normal file
447
venv/Lib/site-packages/IPython/core/tests/test_oinspect.py
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
"""Tests for the object inspection functionality.
|
||||
"""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
from inspect import signature, Signature, Parameter
|
||||
import os
|
||||
import re
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from .. import oinspect
|
||||
|
||||
from decorator import decorator
|
||||
|
||||
from IPython.testing.tools import AssertPrints, AssertNotPrints
|
||||
from IPython.utils.path import compress_user
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Globals and constants
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
inspector = None
|
||||
|
||||
def setup_module():
|
||||
global inspector
|
||||
inspector = oinspect.Inspector()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Local utilities
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# WARNING: since this test checks the line number where a function is
|
||||
# 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
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
class Test(TestCase):
|
||||
|
||||
def test_find_source_lines(self):
|
||||
self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
|
||||
THIS_LINE_NUMBER+6)
|
||||
|
||||
|
||||
# A couple of utilities to ensure these tests work the same from a source or a
|
||||
# binary install
|
||||
def pyfile(fname):
|
||||
return os.path.normcase(re.sub('.py[co]$', '.py', fname))
|
||||
|
||||
|
||||
def match_pyfiles(f1, f2):
|
||||
nt.assert_equal(pyfile(f1), pyfile(f2))
|
||||
|
||||
|
||||
def test_find_file():
|
||||
match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_find_file_decorated1():
|
||||
|
||||
@decorator
|
||||
def noop1(f):
|
||||
def wrapper(*a, **kw):
|
||||
return f(*a, **kw)
|
||||
return wrapper
|
||||
|
||||
@noop1
|
||||
def f(x):
|
||||
"My docstring"
|
||||
|
||||
match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
|
||||
nt.assert_equal(f.__doc__, "My docstring")
|
||||
|
||||
|
||||
def test_find_file_decorated2():
|
||||
|
||||
@decorator
|
||||
def noop2(f, *a, **kw):
|
||||
return f(*a, **kw)
|
||||
|
||||
@noop2
|
||||
@noop2
|
||||
@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")
|
||||
|
||||
|
||||
def test_find_file_magic():
|
||||
run = ip.find_line_magic('run')
|
||||
nt.assert_not_equal(oinspect.find_file(run), None)
|
||||
|
||||
|
||||
# A few generic objects we can then inspect in the tests below
|
||||
|
||||
class Call(object):
|
||||
"""This is the class docstring."""
|
||||
|
||||
def __init__(self, x, y=1):
|
||||
"""This is the constructor docstring."""
|
||||
|
||||
def __call__(self, *a, **kw):
|
||||
"""This is the call docstring."""
|
||||
|
||||
def method(self, x, z=2):
|
||||
"""Some method's docstring"""
|
||||
|
||||
class HasSignature(object):
|
||||
"""This is the class docstring."""
|
||||
__signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
|
||||
|
||||
def __init__(self, *args):
|
||||
"""This is the init docstring"""
|
||||
|
||||
|
||||
class SimpleClass(object):
|
||||
def method(self, x, z=2):
|
||||
"""Some method's docstring"""
|
||||
|
||||
|
||||
class Awkward(object):
|
||||
def __getattr__(self, name):
|
||||
raise Exception(name)
|
||||
|
||||
class NoBoolCall:
|
||||
"""
|
||||
callable with `__bool__` raising should still be inspect-able.
|
||||
"""
|
||||
|
||||
def __call__(self):
|
||||
"""does nothing"""
|
||||
pass
|
||||
|
||||
def __bool__(self):
|
||||
"""just raise NotImplemented"""
|
||||
raise NotImplementedError('Must be implemented')
|
||||
|
||||
|
||||
class SerialLiar(object):
|
||||
"""Attribute accesses always get another copy of the same class.
|
||||
|
||||
unittest.mock.call does something similar, but it's not ideal for testing
|
||||
as the failure mode is to eat all your RAM. This gives up after 10k levels.
|
||||
"""
|
||||
def __init__(self, max_fibbing_twig, lies_told=0):
|
||||
if lies_told > 10000:
|
||||
raise RuntimeError('Nose too long, honesty is the best policy')
|
||||
self.max_fibbing_twig = max_fibbing_twig
|
||||
self.lies_told = lies_told
|
||||
max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
|
||||
|
||||
def __getattr__(self, item):
|
||||
return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Tests
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
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})?>")
|
||||
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__)
|
||||
|
||||
i = inspector.info(Call, detail_level=1)
|
||||
nt.assert_not_equal(i['source'], None)
|
||||
nt.assert_equal(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__)
|
||||
|
||||
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__)
|
||||
|
||||
def test_info_awkward():
|
||||
# Just test that this doesn't throw an error.
|
||||
inspector.info(Awkward())
|
||||
|
||||
def test_bool_raise():
|
||||
inspector.info(NoBoolCall())
|
||||
|
||||
def test_info_serialliar():
|
||||
fib_tracker = [0]
|
||||
inspector.info(SerialLiar(fib_tracker))
|
||||
|
||||
# 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)
|
||||
|
||||
def support_function_one(x, y=2, *a, **kw):
|
||||
"""A simple function."""
|
||||
|
||||
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)
|
||||
|
||||
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)")
|
||||
|
||||
def test_getdoc():
|
||||
class A(object):
|
||||
"""standard docstring"""
|
||||
pass
|
||||
|
||||
class B(object):
|
||||
"""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")
|
||||
|
||||
|
||||
def test_empty_property_has_no_source():
|
||||
i = inspector.info(property(), detail_level=1)
|
||||
nt.assert_is(i['source'], 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):
|
||||
return 'bar'
|
||||
|
||||
foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
|
||||
|
||||
dname = property(posixpath.dirname)
|
||||
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'])
|
||||
|
||||
i = inspector.info(A.dname, detail_level=1)
|
||||
nt.assert_in('def dirname(p)', i['source'])
|
||||
|
||||
i = inspector.info(A.adder, detail_level=1)
|
||||
nt.assert_in('def simple_add(a, b)', i['source'])
|
||||
|
||||
|
||||
def test_property_docstring_is_in_info_for_detail_level_0():
|
||||
class A(object):
|
||||
@property
|
||||
def foobar(self):
|
||||
"""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'])
|
||||
|
||||
|
||||
def test_pdef():
|
||||
# See gh-1914
|
||||
def foo(): pass
|
||||
inspector.pdef(foo, 'foo')
|
||||
|
||||
|
||||
def test_pinfo_nonascii():
|
||||
# See gh-1177
|
||||
from . import nonascii2
|
||||
ip.user_ns['nonascii2'] = nonascii2
|
||||
ip._inspect('pinfo', 'nonascii2', detail_level=1)
|
||||
|
||||
def test_pinfo_type():
|
||||
"""
|
||||
type can fail in various edge case, for example `type.__subclass__()`
|
||||
"""
|
||||
ip._inspect('pinfo', 'type')
|
||||
|
||||
|
||||
def test_pinfo_docstring_no_source():
|
||||
"""Docstring should be included with detail_level=1 if there is no source"""
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'str.format', detail_level=0)
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'str.format', detail_level=1)
|
||||
|
||||
|
||||
def test_pinfo_no_docstring_if_source():
|
||||
"""Docstring should not be included with detail_level=1 if source is found"""
|
||||
def foo():
|
||||
"""foo has a docstring"""
|
||||
|
||||
ip.user_ns['foo'] = foo
|
||||
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'foo', detail_level=0)
|
||||
with AssertPrints('Source:'):
|
||||
ip._inspect('pinfo', 'foo', detail_level=1)
|
||||
with AssertNotPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'foo', detail_level=1)
|
||||
|
||||
|
||||
def test_pinfo_docstring_if_detail_and_no_source():
|
||||
""" Docstring should be displayed if source info not available """
|
||||
obj_def = '''class Foo(object):
|
||||
""" This is a docstring for Foo """
|
||||
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)
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'foo', detail_level=1)
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'foo.bar', detail_level=0)
|
||||
|
||||
with AssertNotPrints('Docstring:'):
|
||||
with AssertPrints('Source:'):
|
||||
ip._inspect('pinfo', 'foo.bar', detail_level=1)
|
||||
|
||||
|
||||
def test_pinfo_magic():
|
||||
with AssertPrints('Docstring:'):
|
||||
ip._inspect('pinfo', 'lsmagic', detail_level=0)
|
||||
|
||||
with AssertPrints('Source:'):
|
||||
ip._inspect('pinfo', 'lsmagic', detail_level=1)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def test_builtin_init():
|
||||
info = inspector.info(list)
|
||||
init_def = info['init_definition']
|
||||
nt.assert_is_not_none(init_def)
|
||||
|
||||
|
||||
def test_render_signature_short():
|
||||
def short_fun(a=1): pass
|
||||
sig = oinspect._render_signature(
|
||||
signature(short_fun),
|
||||
short_fun.__name__,
|
||||
)
|
||||
nt.assert_equal(sig, 'short_fun(a=1)')
|
||||
|
||||
|
||||
def test_render_signature_long():
|
||||
from typing import Optional
|
||||
|
||||
def long_function(
|
||||
a_really_long_parameter: int,
|
||||
and_another_long_one: bool = False,
|
||||
let_us_make_sure_this_is_looong: Optional[str] = None,
|
||||
) -> bool: pass
|
||||
|
||||
sig = oinspect._render_signature(
|
||||
signature(long_function),
|
||||
long_function.__name__,
|
||||
)
|
||||
nt.assert_in(sig, [
|
||||
# Python >=3.9
|
||||
'''\
|
||||
long_function(
|
||||
a_really_long_parameter: int,
|
||||
and_another_long_one: bool = False,
|
||||
let_us_make_sure_this_is_looong: Optional[str] = None,
|
||||
) -> bool\
|
||||
''',
|
||||
# Python >=3.7
|
||||
'''\
|
||||
long_function(
|
||||
a_really_long_parameter: int,
|
||||
and_another_long_one: bool = False,
|
||||
let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
|
||||
) -> bool\
|
||||
''', # Python <=3.6
|
||||
'''\
|
||||
long_function(
|
||||
a_really_long_parameter:int,
|
||||
and_another_long_one:bool=False,
|
||||
let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
|
||||
) -> bool\
|
||||
''',
|
||||
])
|
||||
20
venv/Lib/site-packages/IPython/core/tests/test_page.py
Normal file
20
venv/Lib/site-packages/IPython/core/tests/test_page.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2010-2011 The IPython Development Team.
|
||||
#
|
||||
# Distributed under the terms of the BSD License.
|
||||
#
|
||||
# The full license is in the file COPYING.txt, distributed with this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
import io
|
||||
|
||||
# N.B. For the test suite, page.page is overridden (see IPython.testing.globalipapp)
|
||||
from IPython.core import page
|
||||
|
||||
def test_detect_screen_size():
|
||||
"""Simple smoketest for page._detect_screen_size."""
|
||||
try:
|
||||
page._detect_screen_size(True, 25)
|
||||
except (TypeError, io.UnsupportedOperation):
|
||||
# This can happen in the test suite, because stdout may not have a
|
||||
# fileno.
|
||||
pass
|
||||
200
venv/Lib/site-packages/IPython/core/tests/test_paths.py
Normal file
200
venv/Lib/site-packages/IPython/core/tests/test_paths.py
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
import errno
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import warnings
|
||||
from unittest.mock import patch
|
||||
|
||||
import nose.tools as nt
|
||||
from testpath import modified_env, assert_isdir, assert_isfile
|
||||
|
||||
from IPython import paths
|
||||
from IPython.testing.decorators import skip_win32
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp())
|
||||
HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
|
||||
XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir")
|
||||
XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir")
|
||||
IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
|
||||
|
||||
def setup_module():
|
||||
"""Setup testenvironment for the module:
|
||||
|
||||
- Adds dummy home dir tree
|
||||
"""
|
||||
# Do not mask exceptions here. In particular, catching WindowsError is a
|
||||
# problem because that exception is only defined on Windows...
|
||||
os.makedirs(IP_TEST_DIR)
|
||||
os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
|
||||
os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython'))
|
||||
|
||||
|
||||
def teardown_module():
|
||||
"""Teardown testenvironment for the module:
|
||||
|
||||
- Remove dummy home dir tree
|
||||
"""
|
||||
# Note: we remove the parent test dir, which is the root of all test
|
||||
# subdirs we may have created. Use shutil instead of os.removedirs, so
|
||||
# that non-empty directories are all recursively removed.
|
||||
shutil.rmtree(TMP_TEST_DIR)
|
||||
|
||||
def patch_get_home_dir(dirpath):
|
||||
return patch.object(paths, 'get_home_dir', return_value=dirpath)
|
||||
|
||||
|
||||
def test_get_ipython_dir_1():
|
||||
"""test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
|
||||
env_ipdir = os.path.join("someplace", ".ipython")
|
||||
with patch.object(paths, '_writable_dir', return_value=True), \
|
||||
modified_env({'IPYTHONDIR': env_ipdir}):
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, env_ipdir)
|
||||
|
||||
def test_get_ipython_dir_2():
|
||||
"""test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
|
||||
with patch_get_home_dir('someplace'), \
|
||||
patch.object(paths, 'get_xdg_dir', return_value=None), \
|
||||
patch.object(paths, '_writable_dir', return_value=True), \
|
||||
patch('os.name', "posix"), \
|
||||
modified_env({'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'XDG_CONFIG_HOME': None
|
||||
}):
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
|
||||
|
||||
def test_get_ipython_dir_3():
|
||||
"""test_get_ipython_dir_3, move XDG if defined, and .ipython doesn't exist."""
|
||||
tmphome = TemporaryDirectory()
|
||||
try:
|
||||
with patch_get_home_dir(tmphome.name), \
|
||||
patch('os.name', 'posix'), \
|
||||
modified_env({
|
||||
'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'XDG_CONFIG_HOME': XDG_TEST_DIR,
|
||||
}), warnings.catch_warnings(record=True) as w:
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, os.path.join(tmphome.name, ".ipython"))
|
||||
if sys.platform != 'darwin':
|
||||
nt.assert_equal(len(w), 1)
|
||||
nt.assert_in('Moving', str(w[0]))
|
||||
finally:
|
||||
tmphome.cleanup()
|
||||
|
||||
def test_get_ipython_dir_4():
|
||||
"""test_get_ipython_dir_4, warn if XDG and home both exist."""
|
||||
with patch_get_home_dir(HOME_TEST_DIR), \
|
||||
patch('os.name', 'posix'):
|
||||
try:
|
||||
os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython'))
|
||||
except OSError as e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
|
||||
with modified_env({
|
||||
'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'XDG_CONFIG_HOME': XDG_TEST_DIR,
|
||||
}), warnings.catch_warnings(record=True) as w:
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, ".ipython"))
|
||||
if sys.platform != 'darwin':
|
||||
nt.assert_equal(len(w), 1)
|
||||
nt.assert_in('Ignoring', str(w[0]))
|
||||
|
||||
def test_get_ipython_dir_5():
|
||||
"""test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
|
||||
with patch_get_home_dir(HOME_TEST_DIR), \
|
||||
patch('os.name', 'posix'):
|
||||
try:
|
||||
os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
with modified_env({
|
||||
'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'XDG_CONFIG_HOME': XDG_TEST_DIR,
|
||||
}):
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, IP_TEST_DIR)
|
||||
|
||||
def test_get_ipython_dir_6():
|
||||
"""test_get_ipython_dir_6, use home over XDG if defined and neither exist."""
|
||||
xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
|
||||
os.mkdir(xdg)
|
||||
shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
|
||||
print(paths._writable_dir)
|
||||
with patch_get_home_dir(HOME_TEST_DIR), \
|
||||
patch.object(paths, 'get_xdg_dir', return_value=xdg), \
|
||||
patch('os.name', 'posix'), \
|
||||
modified_env({
|
||||
'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'XDG_CONFIG_HOME': None,
|
||||
}), warnings.catch_warnings(record=True) as w:
|
||||
ipdir = paths.get_ipython_dir()
|
||||
|
||||
nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, '.ipython'))
|
||||
nt.assert_equal(len(w), 0)
|
||||
|
||||
def test_get_ipython_dir_7():
|
||||
"""test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
|
||||
home_dir = os.path.normpath(os.path.expanduser('~'))
|
||||
with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \
|
||||
patch.object(paths, '_writable_dir', return_value=True):
|
||||
ipdir = paths.get_ipython_dir()
|
||||
nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
|
||||
|
||||
@skip_win32
|
||||
def test_get_ipython_dir_8():
|
||||
"""test_get_ipython_dir_8, test / home directory"""
|
||||
with patch.object(paths, '_writable_dir', lambda path: bool(path)), \
|
||||
patch.object(paths, 'get_xdg_dir', return_value=None), \
|
||||
modified_env({
|
||||
'IPYTHON_DIR': None,
|
||||
'IPYTHONDIR': None,
|
||||
'HOME': '/',
|
||||
}):
|
||||
nt.assert_equal(paths.get_ipython_dir(), '/.ipython')
|
||||
|
||||
|
||||
def test_get_ipython_cache_dir():
|
||||
with modified_env({'HOME': HOME_TEST_DIR}):
|
||||
if os.name == 'posix' and sys.platform != 'darwin':
|
||||
# test default
|
||||
os.makedirs(os.path.join(HOME_TEST_DIR, ".cache"))
|
||||
with modified_env({'XDG_CACHE_HOME': None}):
|
||||
ipdir = paths.get_ipython_cache_dir()
|
||||
nt.assert_equal(os.path.join(HOME_TEST_DIR, ".cache", "ipython"),
|
||||
ipdir)
|
||||
assert_isdir(ipdir)
|
||||
|
||||
# test env override
|
||||
with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}):
|
||||
ipdir = paths.get_ipython_cache_dir()
|
||||
assert_isdir(ipdir)
|
||||
nt.assert_equal(ipdir, os.path.join(XDG_CACHE_DIR, "ipython"))
|
||||
else:
|
||||
nt.assert_equal(paths.get_ipython_cache_dir(),
|
||||
paths.get_ipython_dir())
|
||||
|
||||
def test_get_ipython_package_dir():
|
||||
ipdir = paths.get_ipython_package_dir()
|
||||
assert_isdir(ipdir)
|
||||
|
||||
|
||||
def test_get_ipython_module_path():
|
||||
ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp')
|
||||
assert_isfile(ipapp_path)
|
||||
127
venv/Lib/site-packages/IPython/core/tests/test_prefilter.py
Normal file
127
venv/Lib/site-packages/IPython/core/tests/test_prefilter.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
"""Tests for input manipulation machinery."""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core.prefilter import AutocallChecker
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Tests
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def test_prefilter():
|
||||
"""Test user input conversions"""
|
||||
|
||||
# pairs of (raw, expected correct) input
|
||||
pairs = [ ('2+2','2+2'),
|
||||
]
|
||||
|
||||
for raw, correct in pairs:
|
||||
nt.assert_equal(ip.prefilter(raw), correct)
|
||||
|
||||
def test_prefilter_shadowed():
|
||||
def dummy_magic(line): pass
|
||||
|
||||
prev_automagic_state = ip.automagic
|
||||
ip.automagic = True
|
||||
ip.autocall = 0
|
||||
|
||||
try:
|
||||
# These should not be transformed - they are shadowed by other names
|
||||
for name in ['if', 'zip', 'get_ipython']: # keyword, builtin, global
|
||||
ip.register_magic_function(dummy_magic, magic_name=name)
|
||||
res = ip.prefilter(name+' foo')
|
||||
nt.assert_equal(res, name+' foo')
|
||||
del ip.magics_manager.magics['line'][name]
|
||||
|
||||
# These should be transformed
|
||||
for name in ['fi', 'piz', 'nohtypi_teg']:
|
||||
ip.register_magic_function(dummy_magic, magic_name=name)
|
||||
res = ip.prefilter(name+' foo')
|
||||
nt.assert_not_equal(res, name+' foo')
|
||||
del ip.magics_manager.magics['line'][name]
|
||||
|
||||
finally:
|
||||
ip.automagic = prev_automagic_state
|
||||
|
||||
def test_autocall_binops():
|
||||
"""See https://github.com/ipython/ipython/issues/81"""
|
||||
ip.magic('autocall 2')
|
||||
f = lambda x: x
|
||||
ip.user_ns['f'] = f
|
||||
try:
|
||||
nt.assert_equal(ip.prefilter('f 1'),'f(1)')
|
||||
for t in ['f +1', 'f -1']:
|
||||
nt.assert_equal(ip.prefilter(t), t)
|
||||
|
||||
# Run tests again with a more permissive exclude_regexp, which will
|
||||
# allow transformation of binary operations ('f -1' -> 'f(-1)').
|
||||
pm = ip.prefilter_manager
|
||||
ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm,
|
||||
config=pm.config)
|
||||
try:
|
||||
ac.priority = 1
|
||||
ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or '
|
||||
pm.sort_checkers()
|
||||
|
||||
nt.assert_equal(ip.prefilter('f -1'), 'f(-1)')
|
||||
nt.assert_equal(ip.prefilter('f +1'), 'f(+1)')
|
||||
finally:
|
||||
pm.unregister_checker(ac)
|
||||
finally:
|
||||
ip.magic('autocall 0')
|
||||
del ip.user_ns['f']
|
||||
|
||||
|
||||
def test_issue_114():
|
||||
"""Check that multiline string literals don't expand as magic
|
||||
see http://github.com/ipython/ipython/issues/114"""
|
||||
|
||||
template = '"""\n%s\n"""'
|
||||
# Store the current value of multi_line_specials and turn it off before
|
||||
# running test, since it could be true (case in which the test doesn't make
|
||||
# sense, as multiline string literals *will* expand as magic in that case).
|
||||
msp = ip.prefilter_manager.multi_line_specials
|
||||
ip.prefilter_manager.multi_line_specials = False
|
||||
try:
|
||||
for mgk in ip.magics_manager.lsmagic()['line']:
|
||||
raw = template % mgk
|
||||
nt.assert_equal(ip.prefilter(raw), raw)
|
||||
finally:
|
||||
ip.prefilter_manager.multi_line_specials = msp
|
||||
|
||||
|
||||
def test_prefilter_attribute_errors():
|
||||
"""Capture exceptions thrown by user objects on attribute access.
|
||||
|
||||
See http://github.com/ipython/ipython/issues/988."""
|
||||
|
||||
class X(object):
|
||||
def __getattr__(self, k):
|
||||
raise ValueError('broken object')
|
||||
def __call__(self, x):
|
||||
return x
|
||||
|
||||
# Create a callable broken object
|
||||
ip.user_ns['x'] = X()
|
||||
ip.magic('autocall 2')
|
||||
try:
|
||||
# Even if x throws an attribute error when looking at its rewrite
|
||||
# attribute, we should not crash. So the test here is simply making
|
||||
# the prefilter call and not having an exception.
|
||||
ip.prefilter('x 1')
|
||||
finally:
|
||||
del ip.user_ns['x']
|
||||
ip.magic('autocall 0')
|
||||
|
||||
|
||||
def test_autocall_should_support_unicode():
|
||||
ip.magic('autocall 2')
|
||||
ip.user_ns['π'] = lambda x: x
|
||||
try:
|
||||
nt.assert_equal(ip.prefilter('π 3'),'π(3)')
|
||||
finally:
|
||||
ip.magic('autocall 0')
|
||||
del ip.user_ns['π']
|
||||
161
venv/Lib/site-packages/IPython/core/tests/test_profile.py
Normal file
161
venv/Lib/site-packages/IPython/core/tests/test_profile.py
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# coding: utf-8
|
||||
"""Tests for profile-related functions.
|
||||
|
||||
Currently only the startup-dir functionality is tested, but more tests should
|
||||
be added for:
|
||||
|
||||
* ipython profile create
|
||||
* ipython profile list
|
||||
* ipython profile create --parallel
|
||||
* security dir permissions
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
* MinRK
|
||||
|
||||
"""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
|
||||
from IPython.core.profiledir import ProfileDir
|
||||
|
||||
from IPython.testing import decorators as dec
|
||||
from IPython.testing import tools as tt
|
||||
from IPython.utils.process import getoutput
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Globals
|
||||
#-----------------------------------------------------------------------------
|
||||
TMP_TEST_DIR = tempfile.mkdtemp()
|
||||
HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
|
||||
IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
|
||||
|
||||
#
|
||||
# Setup/teardown functions/decorators
|
||||
#
|
||||
|
||||
def setup_module():
|
||||
"""Setup test environment for the module:
|
||||
|
||||
- Adds dummy home dir tree
|
||||
"""
|
||||
# Do not mask exceptions here. In particular, catching WindowsError is a
|
||||
# problem because that exception is only defined on Windows...
|
||||
os.makedirs(IP_TEST_DIR)
|
||||
|
||||
|
||||
def teardown_module():
|
||||
"""Teardown test environment for the module:
|
||||
|
||||
- Remove dummy home dir tree
|
||||
"""
|
||||
# Note: we remove the parent test dir, which is the root of all test
|
||||
# subdirs we may have created. Use shutil instead of os.removedirs, so
|
||||
# that non-empty directories are all recursively removed.
|
||||
shutil.rmtree(TMP_TEST_DIR)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test functions
|
||||
#-----------------------------------------------------------------------------
|
||||
def win32_without_pywin32():
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
import pywin32
|
||||
except ImportError:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ProfileStartupTest(TestCase):
|
||||
def setUp(self):
|
||||
# create profile dir
|
||||
self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
|
||||
self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
|
||||
self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
|
||||
|
||||
def tearDown(self):
|
||||
# We must remove this profile right away so its presence doesn't
|
||||
# confuse other tests.
|
||||
shutil.rmtree(self.pd.location)
|
||||
|
||||
def init(self, startup_file, startup, test):
|
||||
# write startup python file
|
||||
with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
|
||||
f.write(startup)
|
||||
# write simple test file, to check that the startup file was run
|
||||
with open(self.fname, 'w') as f:
|
||||
f.write(test)
|
||||
|
||||
def validate(self, output):
|
||||
tt.ipexec_validate(self.fname, output, '', options=self.options)
|
||||
|
||||
@dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
|
||||
def test_startup_py(self):
|
||||
self.init('00-start.py', 'zzz=123\n', 'print(zzz)\n')
|
||||
self.validate('123')
|
||||
|
||||
@dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
|
||||
def test_startup_ipy(self):
|
||||
self.init('00-start.ipy', '%xmode plain\n', '')
|
||||
self.validate('Exception reporting mode: Plain')
|
||||
|
||||
|
||||
def test_list_profiles_in():
|
||||
# No need to remove these directories and files, as they will get nuked in
|
||||
# the module-level teardown.
|
||||
td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
|
||||
for name in ('profile_foo', 'profile_hello', 'not_a_profile'):
|
||||
os.mkdir(os.path.join(td, name))
|
||||
if dec.unicode_paths:
|
||||
os.mkdir(os.path.join(td, u'profile_ünicode'))
|
||||
|
||||
with open(os.path.join(td, 'profile_file'), 'w') as f:
|
||||
f.write("I am not a profile directory")
|
||||
profiles = list_profiles_in(td)
|
||||
|
||||
# unicode normalization can turn u'ünicode' into u'u\0308nicode',
|
||||
# so only check for *nicode, and that creating a ProfileDir from the
|
||||
# name remains valid
|
||||
found_unicode = False
|
||||
for p in list(profiles):
|
||||
if p.endswith('nicode'):
|
||||
pd = ProfileDir.find_profile_dir_by_name(td, p)
|
||||
profiles.remove(p)
|
||||
found_unicode = True
|
||||
break
|
||||
if dec.unicode_paths:
|
||||
nt.assert_true(found_unicode)
|
||||
nt.assert_equal(set(profiles), {'foo', 'hello'})
|
||||
|
||||
|
||||
def test_list_bundled_profiles():
|
||||
# This variable will need to be updated when a new profile gets bundled
|
||||
bundled = sorted(list_bundled_profiles())
|
||||
nt.assert_equal(bundled, [])
|
||||
|
||||
|
||||
def test_profile_create_ipython_dir():
|
||||
"""ipython profile create respects --ipython-dir"""
|
||||
with TemporaryDirectory() as td:
|
||||
getoutput([sys.executable, '-m', 'IPython', 'profile', 'create',
|
||||
'foo', '--ipython-dir=%s' % td])
|
||||
profile_dir = os.path.join(td, 'profile_foo')
|
||||
assert os.path.exists(profile_dir)
|
||||
ipython_config = os.path.join(profile_dir, 'ipython_config.py')
|
||||
assert os.path.exists(ipython_config)
|
||||
|
||||
30
venv/Lib/site-packages/IPython/core/tests/test_prompts.py
Normal file
30
venv/Lib/site-packages/IPython/core/tests/test_prompts.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8
|
||||
"""Tests for prompt generation."""
|
||||
|
||||
import unittest
|
||||
|
||||
from IPython.core.prompts import LazyEvaluate
|
||||
|
||||
class PromptTests(unittest.TestCase):
|
||||
def test_lazy_eval_unicode(self):
|
||||
u = u'ünicødé'
|
||||
lz = LazyEvaluate(lambda : u)
|
||||
self.assertEqual(str(lz), u)
|
||||
self.assertEqual(format(lz), u)
|
||||
|
||||
def test_lazy_eval_nonascii_bytes(self):
|
||||
u = u'ünicødé'
|
||||
b = u.encode('utf8')
|
||||
lz = LazyEvaluate(lambda : b)
|
||||
# unicode(lz) would fail
|
||||
self.assertEqual(str(lz), str(b))
|
||||
self.assertEqual(format(lz), str(b))
|
||||
|
||||
def test_lazy_eval_float(self):
|
||||
f = 0.503
|
||||
lz = LazyEvaluate(lambda : f)
|
||||
|
||||
self.assertEqual(str(lz), str(f))
|
||||
self.assertEqual(format(lz), str(f))
|
||||
self.assertEqual(format(lz, '.1'), '0.5')
|
||||
|
||||
256
venv/Lib/site-packages/IPython/core/tests/test_pylabtools.py
Normal file
256
venv/Lib/site-packages/IPython/core/tests/test_pylabtools.py
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
"""Tests for pylab tools module.
|
||||
"""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
from io import UnsupportedOperation, BytesIO
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
from nose import SkipTest
|
||||
import nose.tools as nt
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
from IPython.core.getipython import get_ipython
|
||||
from IPython.core.interactiveshell import InteractiveShell
|
||||
from IPython.core.display import _PNG, _JPEG
|
||||
from .. import pylabtools as pt
|
||||
|
||||
from IPython.testing import decorators as dec
|
||||
|
||||
|
||||
def test_figure_to_svg():
|
||||
# simple empty-figure test
|
||||
fig = plt.figure()
|
||||
nt.assert_equal(pt.print_figure(fig, 'svg'), None)
|
||||
|
||||
plt.close('all')
|
||||
|
||||
# simple check for at least svg-looking output
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1,1,1)
|
||||
ax.plot([1,2,3])
|
||||
plt.draw()
|
||||
svg = pt.print_figure(fig, 'svg')[:100].lower()
|
||||
nt.assert_in(u'doctype svg', svg)
|
||||
|
||||
def _check_pil_jpeg_bytes():
|
||||
"""Skip if PIL can't write JPEGs to BytesIO objects"""
|
||||
# PIL's JPEG plugin can't write to BytesIO objects
|
||||
# Pillow fixes this
|
||||
from PIL import Image
|
||||
buf = BytesIO()
|
||||
img = Image.new("RGB", (4,4))
|
||||
try:
|
||||
img.save(buf, 'jpeg')
|
||||
except Exception as e:
|
||||
ename = e.__class__.__name__
|
||||
raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e))
|
||||
|
||||
@dec.skip_without("PIL.Image")
|
||||
def test_figure_to_jpeg():
|
||||
_check_pil_jpeg_bytes()
|
||||
# simple check for at least jpeg-looking output
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1,1,1)
|
||||
ax.plot([1,2,3])
|
||||
plt.draw()
|
||||
jpeg = pt.print_figure(fig, 'jpeg', pil_kwargs={'optimize': 50})[:100].lower()
|
||||
assert jpeg.startswith(_JPEG)
|
||||
|
||||
def test_retina_figure():
|
||||
# simple empty-figure test
|
||||
fig = plt.figure()
|
||||
nt.assert_equal(pt.retina_figure(fig), None)
|
||||
plt.close('all')
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1,1,1)
|
||||
ax.plot([1,2,3])
|
||||
plt.draw()
|
||||
png, md = pt.retina_figure(fig)
|
||||
assert png.startswith(_PNG)
|
||||
nt.assert_in('width', md)
|
||||
nt.assert_in('height', md)
|
||||
|
||||
_fmt_mime_map = {
|
||||
'png': 'image/png',
|
||||
'jpeg': 'image/jpeg',
|
||||
'pdf': 'application/pdf',
|
||||
'retina': 'image/png',
|
||||
'svg': 'image/svg+xml',
|
||||
}
|
||||
|
||||
def test_select_figure_formats_str():
|
||||
ip = get_ipython()
|
||||
for fmt, active_mime in _fmt_mime_map.items():
|
||||
pt.select_figure_formats(ip, fmt)
|
||||
for mime, f in ip.display_formatter.formatters.items():
|
||||
if mime == active_mime:
|
||||
nt.assert_in(Figure, f)
|
||||
else:
|
||||
nt.assert_not_in(Figure, f)
|
||||
|
||||
def test_select_figure_formats_kwargs():
|
||||
ip = get_ipython()
|
||||
kwargs = dict(quality=10, bbox_inches='tight')
|
||||
pt.select_figure_formats(ip, 'png', **kwargs)
|
||||
formatter = ip.display_formatter.formatters['image/png']
|
||||
f = formatter.lookup_by_type(Figure)
|
||||
cell = f.__closure__[0].cell_contents
|
||||
nt.assert_equal(cell, kwargs)
|
||||
|
||||
# check that the formatter doesn't raise
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1,1,1)
|
||||
ax.plot([1,2,3])
|
||||
plt.draw()
|
||||
formatter.enabled = True
|
||||
png = formatter(fig)
|
||||
assert png.startswith(_PNG)
|
||||
|
||||
def test_select_figure_formats_set():
|
||||
ip = get_ipython()
|
||||
for fmts in [
|
||||
{'png', 'svg'},
|
||||
['png'],
|
||||
('jpeg', 'pdf', 'retina'),
|
||||
{'svg'},
|
||||
]:
|
||||
active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
|
||||
pt.select_figure_formats(ip, fmts)
|
||||
for mime, f in ip.display_formatter.formatters.items():
|
||||
if mime in active_mimes:
|
||||
nt.assert_in(Figure, f)
|
||||
else:
|
||||
nt.assert_not_in(Figure, f)
|
||||
|
||||
def test_select_figure_formats_bad():
|
||||
ip = get_ipython()
|
||||
with nt.assert_raises(ValueError):
|
||||
pt.select_figure_formats(ip, 'foo')
|
||||
with nt.assert_raises(ValueError):
|
||||
pt.select_figure_formats(ip, {'png', 'foo'})
|
||||
with nt.assert_raises(ValueError):
|
||||
pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad'])
|
||||
|
||||
def test_import_pylab():
|
||||
ns = {}
|
||||
pt.import_pylab(ns, import_all=False)
|
||||
nt.assert_true('plt' in ns)
|
||||
nt.assert_equal(ns['np'], np)
|
||||
|
||||
class TestPylabSwitch(object):
|
||||
class Shell(InteractiveShell):
|
||||
def enable_gui(self, gui):
|
||||
pass
|
||||
|
||||
def setup(self):
|
||||
import matplotlib
|
||||
def act_mpl(backend):
|
||||
matplotlib.rcParams['backend'] = backend
|
||||
|
||||
# Save rcParams since they get modified
|
||||
self._saved_rcParams = matplotlib.rcParams
|
||||
self._saved_rcParamsOrig = matplotlib.rcParamsOrig
|
||||
matplotlib.rcParams = dict(backend='Qt4Agg')
|
||||
matplotlib.rcParamsOrig = dict(backend='Qt4Agg')
|
||||
|
||||
# Mock out functions
|
||||
self._save_am = pt.activate_matplotlib
|
||||
pt.activate_matplotlib = act_mpl
|
||||
self._save_ip = pt.import_pylab
|
||||
pt.import_pylab = lambda *a,**kw:None
|
||||
self._save_cis = pt.configure_inline_support
|
||||
pt.configure_inline_support = lambda *a,**kw:None
|
||||
|
||||
def teardown(self):
|
||||
pt.activate_matplotlib = self._save_am
|
||||
pt.import_pylab = self._save_ip
|
||||
pt.configure_inline_support = self._save_cis
|
||||
import matplotlib
|
||||
matplotlib.rcParams = self._saved_rcParams
|
||||
matplotlib.rcParamsOrig = self._saved_rcParamsOrig
|
||||
|
||||
def test_qt(self):
|
||||
s = self.Shell()
|
||||
gui, backend = s.enable_matplotlib(None)
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
gui, backend = s.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
gui, backend = s.enable_matplotlib('qt')
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
gui, backend = s.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
gui, backend = s.enable_matplotlib()
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
def test_inline(self):
|
||||
s = self.Shell()
|
||||
gui, backend = s.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
nt.assert_equal(s.pylab_gui_select, None)
|
||||
|
||||
gui, backend = s.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
nt.assert_equal(s.pylab_gui_select, None)
|
||||
|
||||
gui, backend = s.enable_matplotlib('qt')
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
def test_inline_twice(self):
|
||||
"Using '%matplotlib inline' twice should not reset formatters"
|
||||
|
||||
ip = self.Shell()
|
||||
gui, backend = ip.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
|
||||
fmts = {'png'}
|
||||
active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
|
||||
pt.select_figure_formats(ip, fmts)
|
||||
|
||||
gui, backend = ip.enable_matplotlib('inline')
|
||||
nt.assert_equal(gui, 'inline')
|
||||
|
||||
for mime, f in ip.display_formatter.formatters.items():
|
||||
if mime in active_mimes:
|
||||
nt.assert_in(Figure, f)
|
||||
else:
|
||||
nt.assert_not_in(Figure, f)
|
||||
|
||||
def test_qt_gtk(self):
|
||||
s = self.Shell()
|
||||
gui, backend = s.enable_matplotlib('qt')
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
gui, backend = s.enable_matplotlib('gtk')
|
||||
nt.assert_equal(gui, 'qt')
|
||||
nt.assert_equal(s.pylab_gui_select, 'qt')
|
||||
|
||||
|
||||
def test_no_gui_backends():
|
||||
for k in ['agg', 'svg', 'pdf', 'ps']:
|
||||
assert k not in pt.backend2gui
|
||||
|
||||
|
||||
def test_figure_no_canvas():
|
||||
fig = Figure()
|
||||
fig.canvas = None
|
||||
pt.print_figure(fig)
|
||||
607
venv/Lib/site-packages/IPython/core/tests/test_run.py
Normal file
607
venv/Lib/site-packages/IPython/core/tests/test_run.py
Normal file
|
|
@ -0,0 +1,607 @@
|
|||
# encoding: utf-8
|
||||
"""Tests for code execution (%run and related), which is particularly tricky.
|
||||
|
||||
Because of how %run manages namespaces, and the fact that we are trying here to
|
||||
verify subtle object deletion and reference counting issues, the %run tests
|
||||
will be kept in this separate file. This makes it easier to aggregate in one
|
||||
place the tricks needed to handle it; most other magics are much easier to test
|
||||
and we do so in a common test_magic file.
|
||||
|
||||
Note that any test using `run -i` should make sure to do a `reset` afterwards,
|
||||
as otherwise it may influence later tests.
|
||||
"""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
|
||||
import functools
|
||||
import os
|
||||
from os.path import join as pjoin
|
||||
import random
|
||||
import string
|
||||
import sys
|
||||
import textwrap
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import nose.tools as nt
|
||||
from nose import SkipTest
|
||||
|
||||
from IPython.testing import decorators as dec
|
||||
from IPython.testing import tools as tt
|
||||
from IPython.utils.io import capture_output
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
from IPython.core import debugger
|
||||
|
||||
def doctest_refbug():
|
||||
"""Very nasty problem with references held by multiple runs of a script.
|
||||
See: https://github.com/ipython/ipython/issues/141
|
||||
|
||||
In [1]: _ip.clear_main_mod_cache()
|
||||
# random
|
||||
|
||||
In [2]: %run refbug
|
||||
|
||||
In [3]: call_f()
|
||||
lowercased: hello
|
||||
|
||||
In [4]: %run refbug
|
||||
|
||||
In [5]: call_f()
|
||||
lowercased: hello
|
||||
lowercased: hello
|
||||
"""
|
||||
|
||||
|
||||
def doctest_run_builtins():
|
||||
r"""Check that %run doesn't damage __builtins__.
|
||||
|
||||
In [1]: import tempfile
|
||||
|
||||
In [2]: bid1 = id(__builtins__)
|
||||
|
||||
In [3]: fname = tempfile.mkstemp('.py')[1]
|
||||
|
||||
In [3]: f = open(fname,'w')
|
||||
|
||||
In [4]: dummy= f.write('pass\n')
|
||||
|
||||
In [5]: f.flush()
|
||||
|
||||
In [6]: t1 = type(__builtins__)
|
||||
|
||||
In [7]: %run $fname
|
||||
|
||||
In [7]: f.close()
|
||||
|
||||
In [8]: bid2 = id(__builtins__)
|
||||
|
||||
In [9]: t2 = type(__builtins__)
|
||||
|
||||
In [10]: t1 == t2
|
||||
Out[10]: True
|
||||
|
||||
In [10]: bid1 == bid2
|
||||
Out[10]: True
|
||||
|
||||
In [12]: try:
|
||||
....: os.unlink(fname)
|
||||
....: except:
|
||||
....: pass
|
||||
....:
|
||||
"""
|
||||
|
||||
|
||||
def doctest_run_option_parser():
|
||||
r"""Test option parser in %run.
|
||||
|
||||
In [1]: %run print_argv.py
|
||||
[]
|
||||
|
||||
In [2]: %run print_argv.py print*.py
|
||||
['print_argv.py']
|
||||
|
||||
In [3]: %run -G print_argv.py print*.py
|
||||
['print*.py']
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@dec.skip_win32
|
||||
def doctest_run_option_parser_for_posix():
|
||||
r"""Test option parser in %run (Linux/OSX specific).
|
||||
|
||||
You need double quote to escape glob in POSIX systems:
|
||||
|
||||
In [1]: %run print_argv.py print\\*.py
|
||||
['print*.py']
|
||||
|
||||
You can't use quote to escape glob in POSIX systems:
|
||||
|
||||
In [2]: %run print_argv.py 'print*.py'
|
||||
['print_argv.py']
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@dec.skip_if_not_win32
|
||||
def doctest_run_option_parser_for_windows():
|
||||
r"""Test option parser in %run (Windows specific).
|
||||
|
||||
In Windows, you can't escape ``*` `by backslash:
|
||||
|
||||
In [1]: %run print_argv.py print\\*.py
|
||||
['print\\*.py']
|
||||
|
||||
You can use quote to escape glob:
|
||||
|
||||
In [2]: %run print_argv.py 'print*.py'
|
||||
['print*.py']
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def doctest_reset_del():
|
||||
"""Test that resetting doesn't cause errors in __del__ methods.
|
||||
|
||||
In [2]: class A(object):
|
||||
...: def __del__(self):
|
||||
...: print(str("Hi"))
|
||||
...:
|
||||
|
||||
In [3]: a = A()
|
||||
|
||||
In [4]: get_ipython().reset()
|
||||
Hi
|
||||
|
||||
In [5]: 1+1
|
||||
Out[5]: 2
|
||||
"""
|
||||
|
||||
# For some tests, it will be handy to organize them in a class with a common
|
||||
# setup that makes a temp file
|
||||
|
||||
class TestMagicRunPass(tt.TempFileMixin):
|
||||
|
||||
def setUp(self):
|
||||
content = "a = [1,2,3]\nb = 1"
|
||||
self.mktmp(content)
|
||||
|
||||
def run_tmpfile(self):
|
||||
_ip = get_ipython()
|
||||
# This fails on Windows if self.tmpfile.name has spaces or "~" in it.
|
||||
# See below and ticket https://bugs.launchpad.net/bugs/366353
|
||||
_ip.magic('run %s' % self.fname)
|
||||
|
||||
def run_tmpfile_p(self):
|
||||
_ip = get_ipython()
|
||||
# This fails on Windows if self.tmpfile.name has spaces or "~" in it.
|
||||
# See below and ticket https://bugs.launchpad.net/bugs/366353
|
||||
_ip.magic('run -p %s' % self.fname)
|
||||
|
||||
def test_builtins_id(self):
|
||||
"""Check that %run doesn't damage __builtins__ """
|
||||
_ip = get_ipython()
|
||||
# Test that the id of __builtins__ is not modified by %run
|
||||
bid1 = id(_ip.user_ns['__builtins__'])
|
||||
self.run_tmpfile()
|
||||
bid2 = id(_ip.user_ns['__builtins__'])
|
||||
nt.assert_equal(bid1, bid2)
|
||||
|
||||
def test_builtins_type(self):
|
||||
"""Check that the type of __builtins__ doesn't change with %run.
|
||||
|
||||
However, the above could pass if __builtins__ was already modified to
|
||||
be a dict (it should be a module) by a previous use of %run. So we
|
||||
also check explicitly that it really is a module:
|
||||
"""
|
||||
_ip = get_ipython()
|
||||
self.run_tmpfile()
|
||||
nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
|
||||
|
||||
def test_run_profile( self ):
|
||||
"""Test that the option -p, which invokes the profiler, do not
|
||||
crash by invoking execfile"""
|
||||
self.run_tmpfile_p()
|
||||
|
||||
def test_run_debug_twice(self):
|
||||
# https://github.com/ipython/ipython/issues/10028
|
||||
_ip = get_ipython()
|
||||
with tt.fake_input(['c']):
|
||||
_ip.magic('run -d %s' % self.fname)
|
||||
with tt.fake_input(['c']):
|
||||
_ip.magic('run -d %s' % self.fname)
|
||||
|
||||
def test_run_debug_twice_with_breakpoint(self):
|
||||
"""Make a valid python temp file."""
|
||||
_ip = get_ipython()
|
||||
with tt.fake_input(['b 2', 'c', 'c']):
|
||||
_ip.magic('run -d %s' % self.fname)
|
||||
|
||||
with tt.fake_input(['c']):
|
||||
with tt.AssertNotPrints('KeyError'):
|
||||
_ip.magic('run -d %s' % self.fname)
|
||||
|
||||
|
||||
class TestMagicRunSimple(tt.TempFileMixin):
|
||||
|
||||
def test_simpledef(self):
|
||||
"""Test that simple class definitions work."""
|
||||
src = ("class foo: pass\n"
|
||||
"def f(): return foo()")
|
||||
self.mktmp(src)
|
||||
_ip.magic('run %s' % self.fname)
|
||||
_ip.run_cell('t = isinstance(f(), foo)')
|
||||
nt.assert_true(_ip.user_ns['t'])
|
||||
|
||||
def test_obj_del(self):
|
||||
"""Test that object's __del__ methods are called on exit."""
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
import win32api
|
||||
except ImportError:
|
||||
raise SkipTest("Test requires pywin32")
|
||||
src = ("class A(object):\n"
|
||||
" def __del__(self):\n"
|
||||
" print('object A deleted')\n"
|
||||
"a = A()\n")
|
||||
self.mktmp(src)
|
||||
if dec.module_not_available('sqlite3'):
|
||||
err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
|
||||
else:
|
||||
err = None
|
||||
tt.ipexec_validate(self.fname, 'object A deleted', err)
|
||||
|
||||
def test_aggressive_namespace_cleanup(self):
|
||||
"""Test that namespace cleanup is not too aggressive GH-238
|
||||
|
||||
Returning from another run magic deletes the namespace"""
|
||||
# see ticket https://github.com/ipython/ipython/issues/238
|
||||
|
||||
with tt.TempFileMixin() as empty:
|
||||
empty.mktmp('')
|
||||
# On Windows, the filename will have \users in it, so we need to use the
|
||||
# repr so that the \u becomes \\u.
|
||||
src = ("ip = get_ipython()\n"
|
||||
"for i in range(5):\n"
|
||||
" try:\n"
|
||||
" ip.magic(%r)\n"
|
||||
" except NameError as e:\n"
|
||||
" print(i)\n"
|
||||
" break\n" % ('run ' + empty.fname))
|
||||
self.mktmp(src)
|
||||
_ip.magic('run %s' % self.fname)
|
||||
_ip.run_cell('ip == get_ipython()')
|
||||
nt.assert_equal(_ip.user_ns['i'], 4)
|
||||
|
||||
def test_run_second(self):
|
||||
"""Test that running a second file doesn't clobber the first, gh-3547
|
||||
"""
|
||||
self.mktmp("avar = 1\n"
|
||||
"def afunc():\n"
|
||||
" return avar\n")
|
||||
|
||||
with tt.TempFileMixin() as empty:
|
||||
empty.mktmp("")
|
||||
|
||||
_ip.magic('run %s' % self.fname)
|
||||
_ip.magic('run %s' % empty.fname)
|
||||
nt.assert_equal(_ip.user_ns['afunc'](), 1)
|
||||
|
||||
@dec.skip_win32
|
||||
def test_tclass(self):
|
||||
mydir = os.path.dirname(__file__)
|
||||
tc = os.path.join(mydir, 'tclass')
|
||||
src = ("%%run '%s' C-first\n"
|
||||
"%%run '%s' C-second\n"
|
||||
"%%run '%s' C-third\n") % (tc, tc, tc)
|
||||
self.mktmp(src, '.ipy')
|
||||
out = """\
|
||||
ARGV 1-: ['C-first']
|
||||
ARGV 1-: ['C-second']
|
||||
tclass.py: deleting object: C-first
|
||||
ARGV 1-: ['C-third']
|
||||
tclass.py: deleting object: C-second
|
||||
tclass.py: deleting object: C-third
|
||||
"""
|
||||
if dec.module_not_available('sqlite3'):
|
||||
err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
|
||||
else:
|
||||
err = None
|
||||
tt.ipexec_validate(self.fname, out, err)
|
||||
|
||||
def test_run_i_after_reset(self):
|
||||
"""Check that %run -i still works after %reset (gh-693)"""
|
||||
src = "yy = zz\n"
|
||||
self.mktmp(src)
|
||||
_ip.run_cell("zz = 23")
|
||||
try:
|
||||
_ip.magic('run -i %s' % self.fname)
|
||||
nt.assert_equal(_ip.user_ns['yy'], 23)
|
||||
finally:
|
||||
_ip.magic('reset -f')
|
||||
|
||||
_ip.run_cell("zz = 23")
|
||||
try:
|
||||
_ip.magic('run -i %s' % self.fname)
|
||||
nt.assert_equal(_ip.user_ns['yy'], 23)
|
||||
finally:
|
||||
_ip.magic('reset -f')
|
||||
|
||||
def test_unicode(self):
|
||||
"""Check that files in odd encodings are accepted."""
|
||||
mydir = os.path.dirname(__file__)
|
||||
na = os.path.join(mydir, 'nonascii.py')
|
||||
_ip.magic('run "%s"' % na)
|
||||
nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
|
||||
|
||||
def test_run_py_file_attribute(self):
|
||||
"""Test handling of `__file__` attribute in `%run <file>.py`."""
|
||||
src = "t = __file__\n"
|
||||
self.mktmp(src)
|
||||
_missing = object()
|
||||
file1 = _ip.user_ns.get('__file__', _missing)
|
||||
_ip.magic('run %s' % self.fname)
|
||||
file2 = _ip.user_ns.get('__file__', _missing)
|
||||
|
||||
# Check that __file__ was equal to the filename in the script's
|
||||
# namespace.
|
||||
nt.assert_equal(_ip.user_ns['t'], self.fname)
|
||||
|
||||
# Check that __file__ was not leaked back into user_ns.
|
||||
nt.assert_equal(file1, file2)
|
||||
|
||||
def test_run_ipy_file_attribute(self):
|
||||
"""Test handling of `__file__` attribute in `%run <file.ipy>`."""
|
||||
src = "t = __file__\n"
|
||||
self.mktmp(src, ext='.ipy')
|
||||
_missing = object()
|
||||
file1 = _ip.user_ns.get('__file__', _missing)
|
||||
_ip.magic('run %s' % self.fname)
|
||||
file2 = _ip.user_ns.get('__file__', _missing)
|
||||
|
||||
# Check that __file__ was equal to the filename in the script's
|
||||
# namespace.
|
||||
nt.assert_equal(_ip.user_ns['t'], self.fname)
|
||||
|
||||
# Check that __file__ was not leaked back into user_ns.
|
||||
nt.assert_equal(file1, file2)
|
||||
|
||||
def test_run_formatting(self):
|
||||
""" Test that %run -t -N<N> does not raise a TypeError for N > 1."""
|
||||
src = "pass"
|
||||
self.mktmp(src)
|
||||
_ip.magic('run -t -N 1 %s' % self.fname)
|
||||
_ip.magic('run -t -N 10 %s' % self.fname)
|
||||
|
||||
def test_ignore_sys_exit(self):
|
||||
"""Test the -e option to ignore sys.exit()"""
|
||||
src = "import sys; sys.exit(1)"
|
||||
self.mktmp(src)
|
||||
with tt.AssertPrints('SystemExit'):
|
||||
_ip.magic('run %s' % self.fname)
|
||||
|
||||
with tt.AssertNotPrints('SystemExit'):
|
||||
_ip.magic('run -e %s' % self.fname)
|
||||
|
||||
def test_run_nb(self):
|
||||
"""Test %run notebook.ipynb"""
|
||||
from nbformat import v4, writes
|
||||
nb = v4.new_notebook(
|
||||
cells=[
|
||||
v4.new_markdown_cell("The Ultimate Question of Everything"),
|
||||
v4.new_code_cell("answer=42")
|
||||
]
|
||||
)
|
||||
src = writes(nb, version=4)
|
||||
self.mktmp(src, ext='.ipynb')
|
||||
|
||||
_ip.magic("run %s" % self.fname)
|
||||
|
||||
nt.assert_equal(_ip.user_ns['answer'], 42)
|
||||
|
||||
def test_run_nb_error(self):
|
||||
"""Test %run notebook.ipynb error"""
|
||||
from nbformat import v4, writes
|
||||
# %run when a file name isn't provided
|
||||
nt.assert_raises(Exception, _ip.magic, "run")
|
||||
|
||||
# %run when a file doesn't exist
|
||||
nt.assert_raises(Exception, _ip.magic, "run foobar.ipynb")
|
||||
|
||||
# %run on a notebook with an error
|
||||
nb = v4.new_notebook(
|
||||
cells=[
|
||||
v4.new_code_cell("0/0")
|
||||
]
|
||||
)
|
||||
src = writes(nb, version=4)
|
||||
self.mktmp(src, ext='.ipynb')
|
||||
nt.assert_raises(Exception, _ip.magic, "run %s" % self.fname)
|
||||
|
||||
def test_file_options(self):
|
||||
src = ('import sys\n'
|
||||
'a = " ".join(sys.argv[1:])\n')
|
||||
self.mktmp(src)
|
||||
test_opts = '-x 3 --verbose'
|
||||
_ip.run_line_magic("run", '{0} {1}'.format(self.fname, test_opts))
|
||||
nt.assert_equal(_ip.user_ns['a'], test_opts)
|
||||
|
||||
|
||||
class TestMagicRunWithPackage(unittest.TestCase):
|
||||
|
||||
def writefile(self, name, content):
|
||||
path = os.path.join(self.tempdir.name, name)
|
||||
d = os.path.dirname(path)
|
||||
if not os.path.isdir(d):
|
||||
os.makedirs(d)
|
||||
with open(path, 'w') as f:
|
||||
f.write(textwrap.dedent(content))
|
||||
|
||||
def setUp(self):
|
||||
self.package = package = 'tmp{0}'.format(''.join([random.choice(string.ascii_letters) for i in range(10)]))
|
||||
"""Temporary (probably) valid python package name."""
|
||||
|
||||
self.value = int(random.random() * 10000)
|
||||
|
||||
self.tempdir = TemporaryDirectory()
|
||||
self.__orig_cwd = os.getcwd()
|
||||
sys.path.insert(0, self.tempdir.name)
|
||||
|
||||
self.writefile(os.path.join(package, '__init__.py'), '')
|
||||
self.writefile(os.path.join(package, 'sub.py'), """
|
||||
x = {0!r}
|
||||
""".format(self.value))
|
||||
self.writefile(os.path.join(package, 'relative.py'), """
|
||||
from .sub import x
|
||||
""")
|
||||
self.writefile(os.path.join(package, 'absolute.py'), """
|
||||
from {0}.sub import x
|
||||
""".format(package))
|
||||
self.writefile(os.path.join(package, 'args.py'), """
|
||||
import sys
|
||||
a = " ".join(sys.argv[1:])
|
||||
""".format(package))
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.__orig_cwd)
|
||||
sys.path[:] = [p for p in sys.path if p != self.tempdir.name]
|
||||
self.tempdir.cleanup()
|
||||
|
||||
def check_run_submodule(self, submodule, opts=''):
|
||||
_ip.user_ns.pop('x', None)
|
||||
_ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts))
|
||||
self.assertEqual(_ip.user_ns['x'], self.value,
|
||||
'Variable `x` is not loaded from module `{0}`.'
|
||||
.format(submodule))
|
||||
|
||||
def test_run_submodule_with_absolute_import(self):
|
||||
self.check_run_submodule('absolute')
|
||||
|
||||
def test_run_submodule_with_relative_import(self):
|
||||
"""Run submodule that has a relative import statement (#2727)."""
|
||||
self.check_run_submodule('relative')
|
||||
|
||||
def test_prun_submodule_with_absolute_import(self):
|
||||
self.check_run_submodule('absolute', '-p')
|
||||
|
||||
def test_prun_submodule_with_relative_import(self):
|
||||
self.check_run_submodule('relative', '-p')
|
||||
|
||||
def with_fake_debugger(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwds):
|
||||
with patch.object(debugger.Pdb, 'run', staticmethod(eval)):
|
||||
return func(*args, **kwds)
|
||||
return wrapper
|
||||
|
||||
@with_fake_debugger
|
||||
def test_debug_run_submodule_with_absolute_import(self):
|
||||
self.check_run_submodule('absolute', '-d')
|
||||
|
||||
@with_fake_debugger
|
||||
def test_debug_run_submodule_with_relative_import(self):
|
||||
self.check_run_submodule('relative', '-d')
|
||||
|
||||
def test_module_options(self):
|
||||
_ip.user_ns.pop('a', None)
|
||||
test_opts = '-x abc -m test'
|
||||
_ip.run_line_magic('run', '-m {0}.args {1}'.format(self.package, test_opts))
|
||||
nt.assert_equal(_ip.user_ns['a'], test_opts)
|
||||
|
||||
def test_module_options_with_separator(self):
|
||||
_ip.user_ns.pop('a', None)
|
||||
test_opts = '-x abc -m test'
|
||||
_ip.run_line_magic('run', '-m {0}.args -- {1}'.format(self.package, test_opts))
|
||||
nt.assert_equal(_ip.user_ns['a'], test_opts)
|
||||
|
||||
def test_run__name__():
|
||||
with TemporaryDirectory() as td:
|
||||
path = pjoin(td, 'foo.py')
|
||||
with open(path, 'w') as f:
|
||||
f.write("q = __name__")
|
||||
|
||||
_ip.user_ns.pop('q', None)
|
||||
_ip.magic('run {}'.format(path))
|
||||
nt.assert_equal(_ip.user_ns.pop('q'), '__main__')
|
||||
|
||||
_ip.magic('run -n {}'.format(path))
|
||||
nt.assert_equal(_ip.user_ns.pop('q'), 'foo')
|
||||
|
||||
try:
|
||||
_ip.magic('run -i -n {}'.format(path))
|
||||
nt.assert_equal(_ip.user_ns.pop('q'), 'foo')
|
||||
finally:
|
||||
_ip.magic('reset -f')
|
||||
|
||||
|
||||
def test_run_tb():
|
||||
"""Test traceback offset in %run"""
|
||||
with TemporaryDirectory() as td:
|
||||
path = pjoin(td, 'foo.py')
|
||||
with open(path, 'w') as f:
|
||||
f.write('\n'.join([
|
||||
"def foo():",
|
||||
" return bar()",
|
||||
"def bar():",
|
||||
" raise RuntimeError('hello!')",
|
||||
"foo()",
|
||||
]))
|
||||
with capture_output() as io:
|
||||
_ip.magic('run {}'.format(path))
|
||||
out = io.stdout
|
||||
nt.assert_not_in("execfile", out)
|
||||
nt.assert_in("RuntimeError", out)
|
||||
nt.assert_equal(out.count("---->"), 3)
|
||||
del ip.user_ns['bar']
|
||||
del ip.user_ns['foo']
|
||||
|
||||
|
||||
def test_multiprocessing_run():
|
||||
"""Set we can run mutiprocesgin without messing up up main namespace
|
||||
|
||||
Note that import `nose.tools as nt` mdify the value s
|
||||
sys.module['__mp_main__'] so wee need to temporarily set it to None to test
|
||||
the issue.
|
||||
"""
|
||||
with TemporaryDirectory() as td:
|
||||
mpm = sys.modules.get('__mp_main__')
|
||||
assert mpm is not None
|
||||
sys.modules['__mp_main__'] = None
|
||||
try:
|
||||
path = pjoin(td, 'test.py')
|
||||
with open(path, 'w') as f:
|
||||
f.write("import multiprocessing\nprint('hoy')")
|
||||
with capture_output() as io:
|
||||
_ip.run_line_magic('run', path)
|
||||
_ip.run_cell("i_m_undefined")
|
||||
out = io.stdout
|
||||
nt.assert_in("hoy", out)
|
||||
nt.assert_not_in("AttributeError", out)
|
||||
nt.assert_in("NameError", out)
|
||||
nt.assert_equal(out.count("---->"), 1)
|
||||
except:
|
||||
raise
|
||||
finally:
|
||||
sys.modules['__mp_main__'] = mpm
|
||||
|
||||
@dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows")
|
||||
def test_script_tb():
|
||||
"""Test traceback offset in `ipython script.py`"""
|
||||
with TemporaryDirectory() as td:
|
||||
path = pjoin(td, 'foo.py')
|
||||
with open(path, 'w') as f:
|
||||
f.write('\n'.join([
|
||||
"def foo():",
|
||||
" return bar()",
|
||||
"def bar():",
|
||||
" raise RuntimeError('hello!')",
|
||||
"foo()",
|
||||
]))
|
||||
out, err = tt.ipexec(path)
|
||||
nt.assert_not_in("execfile", out)
|
||||
nt.assert_in("RuntimeError", out)
|
||||
nt.assert_equal(out.count("---->"), 3)
|
||||
|
||||
60
venv/Lib/site-packages/IPython/core/tests/test_shellapp.py
Normal file
60
venv/Lib/site-packages/IPython/core/tests/test_shellapp.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Tests for shellapp module.
|
||||
|
||||
Authors
|
||||
-------
|
||||
* Bradley Froehle
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2012 The IPython Development Team
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
import unittest
|
||||
|
||||
from IPython.testing import decorators as dec
|
||||
from IPython.testing import tools as tt
|
||||
|
||||
sqlite_err_maybe = dec.module_not_available('sqlite3')
|
||||
SQLITE_NOT_AVAILABLE_ERROR = ('WARNING: IPython History requires SQLite,'
|
||||
' your history will not be saved\n')
|
||||
|
||||
class TestFileToRun(tt.TempFileMixin, unittest.TestCase):
|
||||
"""Test the behavior of the file_to_run parameter."""
|
||||
|
||||
def test_py_script_file_attribute(self):
|
||||
"""Test that `__file__` is set when running `ipython file.py`"""
|
||||
src = "print(__file__)\n"
|
||||
self.mktmp(src)
|
||||
|
||||
err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
|
||||
tt.ipexec_validate(self.fname, self.fname, err)
|
||||
|
||||
def test_ipy_script_file_attribute(self):
|
||||
"""Test that `__file__` is set when running `ipython file.ipy`"""
|
||||
src = "print(__file__)\n"
|
||||
self.mktmp(src, ext='.ipy')
|
||||
|
||||
err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
|
||||
tt.ipexec_validate(self.fname, self.fname, err)
|
||||
|
||||
# The commands option to ipexec_validate doesn't work on Windows, and it
|
||||
# doesn't seem worth fixing
|
||||
@dec.skip_win32
|
||||
def test_py_script_file_attribute_interactively(self):
|
||||
"""Test that `__file__` is not set after `ipython -i file.py`"""
|
||||
src = "True\n"
|
||||
self.mktmp(src)
|
||||
|
||||
out, err = tt.ipexec(self.fname, options=['-i'],
|
||||
commands=['"__file__" in globals()', 'print(123)', 'exit()'])
|
||||
if 'False' not in out:
|
||||
print("Subprocess stderr:")
|
||||
print(err)
|
||||
print('-----')
|
||||
raise AssertionError("'False' not found in %r" % out)
|
||||
38
venv/Lib/site-packages/IPython/core/tests/test_splitinput.py
Normal file
38
venv/Lib/site-packages/IPython/core/tests/test_splitinput.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# coding: utf-8
|
||||
import nose.tools as nt
|
||||
|
||||
from IPython.core.splitinput import split_user_input, LineInfo
|
||||
from IPython.testing import tools as tt
|
||||
|
||||
tests = [
|
||||
('x=1', ('', '', 'x', '=1')),
|
||||
('?', ('', '?', '', '')),
|
||||
('??', ('', '??', '', '')),
|
||||
(' ?', (' ', '?', '', '')),
|
||||
(' ??', (' ', '??', '', '')),
|
||||
('??x', ('', '??', 'x', '')),
|
||||
('?x=1', ('', '?', 'x', '=1')),
|
||||
('!ls', ('', '!', 'ls', '')),
|
||||
(' !ls', (' ', '!', 'ls', '')),
|
||||
('!!ls', ('', '!!', 'ls', '')),
|
||||
(' !!ls', (' ', '!!', 'ls', '')),
|
||||
(',ls', ('', ',', 'ls', '')),
|
||||
(';ls', ('', ';', 'ls', '')),
|
||||
(' ;ls', (' ', ';', 'ls', '')),
|
||||
('f.g(x)', ('', '', 'f.g', '(x)')),
|
||||
('f.g (x)', ('', '', 'f.g', '(x)')),
|
||||
('?%hist1', ('', '?', '%hist1', '')),
|
||||
('?%%hist2', ('', '?', '%%hist2', '')),
|
||||
('??%hist3', ('', '??', '%hist3', '')),
|
||||
('??%%hist4', ('', '??', '%%hist4', '')),
|
||||
('?x*', ('', '?', 'x*', '')),
|
||||
]
|
||||
tests.append((u"Pérez Fernando", (u'', u'', u'Pérez', u'Fernando')))
|
||||
|
||||
def test_split_user_input():
|
||||
return tt.check_pairs(split_user_input, tests)
|
||||
|
||||
def test_LineInfo():
|
||||
"""Simple test for LineInfo construction and str()"""
|
||||
linfo = LineInfo(' %cd /home')
|
||||
nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
|
||||
470
venv/Lib/site-packages/IPython/core/tests/test_ultratb.py
Normal file
470
venv/Lib/site-packages/IPython/core/tests/test_ultratb.py
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
# encoding: utf-8
|
||||
"""Tests for IPython.core.ultratb
|
||||
"""
|
||||
import io
|
||||
import logging
|
||||
import sys
|
||||
import os.path
|
||||
from textwrap import dedent
|
||||
import traceback
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
import IPython.core.ultratb as ultratb
|
||||
from IPython.core.ultratb import ColorTB, VerboseTB, find_recursion
|
||||
|
||||
|
||||
from IPython.testing import tools as tt
|
||||
from IPython.testing.decorators import onlyif_unicode_paths
|
||||
from IPython.utils.syspathcontext import prepended_to_syspath
|
||||
from IPython.utils.tempdir import TemporaryDirectory
|
||||
|
||||
file_1 = """1
|
||||
2
|
||||
3
|
||||
def f():
|
||||
1/0
|
||||
"""
|
||||
|
||||
file_2 = """def f():
|
||||
1/0
|
||||
"""
|
||||
|
||||
|
||||
def recursionlimit(frames):
|
||||
"""
|
||||
decorator to set the recursion limit temporarily
|
||||
"""
|
||||
|
||||
def inner(test_function):
|
||||
def wrapper(*args, **kwargs):
|
||||
_orig_rec_limit = ultratb._FRAME_RECURSION_LIMIT
|
||||
ultratb._FRAME_RECURSION_LIMIT = 50
|
||||
|
||||
rl = sys.getrecursionlimit()
|
||||
sys.setrecursionlimit(frames)
|
||||
try:
|
||||
return test_function(*args, **kwargs)
|
||||
finally:
|
||||
sys.setrecursionlimit(rl)
|
||||
ultratb._FRAME_RECURSION_LIMIT = _orig_rec_limit
|
||||
|
||||
return wrapper
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
class ChangedPyFileTest(unittest.TestCase):
|
||||
def test_changing_py_file(self):
|
||||
"""Traceback produced if the line where the error occurred is missing?
|
||||
|
||||
https://github.com/ipython/ipython/issues/1456
|
||||
"""
|
||||
with TemporaryDirectory() as td:
|
||||
fname = os.path.join(td, "foo.py")
|
||||
with open(fname, "w") as f:
|
||||
f.write(file_1)
|
||||
|
||||
with prepended_to_syspath(td):
|
||||
ip.run_cell("import foo")
|
||||
|
||||
with tt.AssertPrints("ZeroDivisionError"):
|
||||
ip.run_cell("foo.f()")
|
||||
|
||||
# Make the file shorter, so the line of the error is missing.
|
||||
with open(fname, "w") as f:
|
||||
f.write(file_2)
|
||||
|
||||
# For some reason, this was failing on the *second* call after
|
||||
# changing the file, so we call f() twice.
|
||||
with tt.AssertNotPrints("Internal Python error", channel='stderr'):
|
||||
with tt.AssertPrints("ZeroDivisionError"):
|
||||
ip.run_cell("foo.f()")
|
||||
with tt.AssertPrints("ZeroDivisionError"):
|
||||
ip.run_cell("foo.f()")
|
||||
|
||||
iso_8859_5_file = u'''# coding: iso-8859-5
|
||||
|
||||
def fail():
|
||||
"""дбИЖ"""
|
||||
1/0 # дбИЖ
|
||||
'''
|
||||
|
||||
class NonAsciiTest(unittest.TestCase):
|
||||
@onlyif_unicode_paths
|
||||
def test_nonascii_path(self):
|
||||
# Non-ascii directory name as well.
|
||||
with TemporaryDirectory(suffix=u'é') as td:
|
||||
fname = os.path.join(td, u"fooé.py")
|
||||
with open(fname, "w") as f:
|
||||
f.write(file_1)
|
||||
|
||||
with prepended_to_syspath(td):
|
||||
ip.run_cell("import foo")
|
||||
|
||||
with tt.AssertPrints("ZeroDivisionError"):
|
||||
ip.run_cell("foo.f()")
|
||||
|
||||
def test_iso8859_5(self):
|
||||
with TemporaryDirectory() as td:
|
||||
fname = os.path.join(td, 'dfghjkl.py')
|
||||
|
||||
with io.open(fname, 'w', encoding='iso-8859-5') as f:
|
||||
f.write(iso_8859_5_file)
|
||||
|
||||
with prepended_to_syspath(td):
|
||||
ip.run_cell("from dfghjkl import fail")
|
||||
|
||||
with tt.AssertPrints("ZeroDivisionError"):
|
||||
with tt.AssertPrints(u'дбИЖ', suppress=False):
|
||||
ip.run_cell('fail()')
|
||||
|
||||
def test_nonascii_msg(self):
|
||||
cell = u"raise Exception('é')"
|
||||
expected = u"Exception('é')"
|
||||
ip.run_cell("%xmode plain")
|
||||
with tt.AssertPrints(expected):
|
||||
ip.run_cell(cell)
|
||||
|
||||
ip.run_cell("%xmode verbose")
|
||||
with tt.AssertPrints(expected):
|
||||
ip.run_cell(cell)
|
||||
|
||||
ip.run_cell("%xmode context")
|
||||
with tt.AssertPrints(expected):
|
||||
ip.run_cell(cell)
|
||||
|
||||
ip.run_cell("%xmode minimal")
|
||||
with tt.AssertPrints(u"Exception: é"):
|
||||
ip.run_cell(cell)
|
||||
|
||||
# Put this back into Context mode for later tests.
|
||||
ip.run_cell("%xmode context")
|
||||
|
||||
class NestedGenExprTestCase(unittest.TestCase):
|
||||
"""
|
||||
Regression test for the following issues:
|
||||
https://github.com/ipython/ipython/issues/8293
|
||||
https://github.com/ipython/ipython/issues/8205
|
||||
"""
|
||||
def test_nested_genexpr(self):
|
||||
code = dedent(
|
||||
"""\
|
||||
class SpecificException(Exception):
|
||||
pass
|
||||
|
||||
def foo(x):
|
||||
raise SpecificException("Success!")
|
||||
|
||||
sum(sum(foo(x) for _ in [0]) for x in [0])
|
||||
"""
|
||||
)
|
||||
with tt.AssertPrints('SpecificException: Success!', suppress=False):
|
||||
ip.run_cell(code)
|
||||
|
||||
|
||||
indentationerror_file = """if True:
|
||||
zoon()
|
||||
"""
|
||||
|
||||
class IndentationErrorTest(unittest.TestCase):
|
||||
def test_indentationerror_shows_line(self):
|
||||
# See issue gh-2398
|
||||
with tt.AssertPrints("IndentationError"):
|
||||
with tt.AssertPrints("zoon()", suppress=False):
|
||||
ip.run_cell(indentationerror_file)
|
||||
|
||||
with TemporaryDirectory() as td:
|
||||
fname = os.path.join(td, "foo.py")
|
||||
with open(fname, "w") as f:
|
||||
f.write(indentationerror_file)
|
||||
|
||||
with tt.AssertPrints("IndentationError"):
|
||||
with tt.AssertPrints("zoon()", suppress=False):
|
||||
ip.magic('run %s' % fname)
|
||||
|
||||
se_file_1 = """1
|
||||
2
|
||||
7/
|
||||
"""
|
||||
|
||||
se_file_2 = """7/
|
||||
"""
|
||||
|
||||
class SyntaxErrorTest(unittest.TestCase):
|
||||
def test_syntaxerror_without_lineno(self):
|
||||
with tt.AssertNotPrints("TypeError"):
|
||||
with tt.AssertPrints("line unknown"):
|
||||
ip.run_cell("raise SyntaxError()")
|
||||
|
||||
def test_syntaxerror_no_stacktrace_at_compile_time(self):
|
||||
syntax_error_at_compile_time = """
|
||||
def foo():
|
||||
..
|
||||
"""
|
||||
with tt.AssertPrints("SyntaxError"):
|
||||
ip.run_cell(syntax_error_at_compile_time)
|
||||
|
||||
with tt.AssertNotPrints("foo()"):
|
||||
ip.run_cell(syntax_error_at_compile_time)
|
||||
|
||||
def test_syntaxerror_stacktrace_when_running_compiled_code(self):
|
||||
syntax_error_at_runtime = """
|
||||
def foo():
|
||||
eval("..")
|
||||
|
||||
def bar():
|
||||
foo()
|
||||
|
||||
bar()
|
||||
"""
|
||||
with tt.AssertPrints("SyntaxError"):
|
||||
ip.run_cell(syntax_error_at_runtime)
|
||||
# Assert syntax error during runtime generate stacktrace
|
||||
with tt.AssertPrints(["foo()", "bar()"]):
|
||||
ip.run_cell(syntax_error_at_runtime)
|
||||
del ip.user_ns['bar']
|
||||
del ip.user_ns['foo']
|
||||
|
||||
def test_changing_py_file(self):
|
||||
with TemporaryDirectory() as td:
|
||||
fname = os.path.join(td, "foo.py")
|
||||
with open(fname, 'w') as f:
|
||||
f.write(se_file_1)
|
||||
|
||||
with tt.AssertPrints(["7/", "SyntaxError"]):
|
||||
ip.magic("run " + fname)
|
||||
|
||||
# Modify the file
|
||||
with open(fname, 'w') as f:
|
||||
f.write(se_file_2)
|
||||
|
||||
# The SyntaxError should point to the correct line
|
||||
with tt.AssertPrints(["7/", "SyntaxError"]):
|
||||
ip.magic("run " + fname)
|
||||
|
||||
def test_non_syntaxerror(self):
|
||||
# SyntaxTB may be called with an error other than a SyntaxError
|
||||
# See e.g. gh-4361
|
||||
try:
|
||||
raise ValueError('QWERTY')
|
||||
except ValueError:
|
||||
with tt.AssertPrints('QWERTY'):
|
||||
ip.showsyntaxerror()
|
||||
|
||||
import sys
|
||||
if sys.version_info < (3,9):
|
||||
"""
|
||||
New 3.9 Pgen Parser does not raise Memory error, except on failed malloc.
|
||||
"""
|
||||
class MemoryErrorTest(unittest.TestCase):
|
||||
def test_memoryerror(self):
|
||||
memoryerror_code = "(" * 200 + ")" * 200
|
||||
with tt.AssertPrints("MemoryError"):
|
||||
ip.run_cell(memoryerror_code)
|
||||
|
||||
|
||||
class Python3ChainedExceptionsTest(unittest.TestCase):
|
||||
DIRECT_CAUSE_ERROR_CODE = """
|
||||
try:
|
||||
x = 1 + 2
|
||||
print(not_defined_here)
|
||||
except Exception as e:
|
||||
x += 55
|
||||
x - 1
|
||||
y = {}
|
||||
raise KeyError('uh') from e
|
||||
"""
|
||||
|
||||
EXCEPTION_DURING_HANDLING_CODE = """
|
||||
try:
|
||||
x = 1 + 2
|
||||
print(not_defined_here)
|
||||
except Exception as e:
|
||||
x += 55
|
||||
x - 1
|
||||
y = {}
|
||||
raise KeyError('uh')
|
||||
"""
|
||||
|
||||
SUPPRESS_CHAINING_CODE = """
|
||||
try:
|
||||
1/0
|
||||
except Exception:
|
||||
raise ValueError("Yikes") from None
|
||||
"""
|
||||
|
||||
def test_direct_cause_error(self):
|
||||
with tt.AssertPrints(["KeyError", "NameError", "direct cause"]):
|
||||
ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE)
|
||||
|
||||
def test_exception_during_handling_error(self):
|
||||
with tt.AssertPrints(["KeyError", "NameError", "During handling"]):
|
||||
ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE)
|
||||
|
||||
def test_suppress_exception_chaining(self):
|
||||
with tt.AssertNotPrints("ZeroDivisionError"), \
|
||||
tt.AssertPrints("ValueError", suppress=False):
|
||||
ip.run_cell(self.SUPPRESS_CHAINING_CODE)
|
||||
|
||||
def test_plain_direct_cause_error(self):
|
||||
with tt.AssertPrints(["KeyError", "NameError", "direct cause"]):
|
||||
ip.run_cell("%xmode Plain")
|
||||
ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE)
|
||||
ip.run_cell("%xmode Verbose")
|
||||
|
||||
def test_plain_exception_during_handling_error(self):
|
||||
with tt.AssertPrints(["KeyError", "NameError", "During handling"]):
|
||||
ip.run_cell("%xmode Plain")
|
||||
ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE)
|
||||
ip.run_cell("%xmode Verbose")
|
||||
|
||||
def test_plain_suppress_exception_chaining(self):
|
||||
with tt.AssertNotPrints("ZeroDivisionError"), \
|
||||
tt.AssertPrints("ValueError", suppress=False):
|
||||
ip.run_cell("%xmode Plain")
|
||||
ip.run_cell(self.SUPPRESS_CHAINING_CODE)
|
||||
ip.run_cell("%xmode Verbose")
|
||||
|
||||
|
||||
class RecursionTest(unittest.TestCase):
|
||||
DEFINITIONS = """
|
||||
def non_recurs():
|
||||
1/0
|
||||
|
||||
def r1():
|
||||
r1()
|
||||
|
||||
def r3a():
|
||||
r3b()
|
||||
|
||||
def r3b():
|
||||
r3c()
|
||||
|
||||
def r3c():
|
||||
r3a()
|
||||
|
||||
def r3o1():
|
||||
r3a()
|
||||
|
||||
def r3o2():
|
||||
r3o1()
|
||||
"""
|
||||
def setUp(self):
|
||||
ip.run_cell(self.DEFINITIONS)
|
||||
|
||||
def test_no_recursion(self):
|
||||
with tt.AssertNotPrints("frames repeated"):
|
||||
ip.run_cell("non_recurs()")
|
||||
|
||||
@recursionlimit(150)
|
||||
def test_recursion_one_frame(self):
|
||||
with tt.AssertPrints("1 frames repeated"):
|
||||
ip.run_cell("r1()")
|
||||
|
||||
@recursionlimit(150)
|
||||
def test_recursion_three_frames(self):
|
||||
with tt.AssertPrints("3 frames repeated"):
|
||||
ip.run_cell("r3o2()")
|
||||
|
||||
@recursionlimit(150)
|
||||
def test_find_recursion(self):
|
||||
captured = []
|
||||
def capture_exc(*args, **kwargs):
|
||||
captured.append(sys.exc_info())
|
||||
with mock.patch.object(ip, 'showtraceback', capture_exc):
|
||||
ip.run_cell("r3o2()")
|
||||
|
||||
self.assertEqual(len(captured), 1)
|
||||
etype, evalue, tb = captured[0]
|
||||
self.assertIn("recursion", str(evalue))
|
||||
|
||||
records = ip.InteractiveTB.get_records(tb, 3, ip.InteractiveTB.tb_offset)
|
||||
for r in records[:10]:
|
||||
print(r[1:4])
|
||||
|
||||
# The outermost frames should be:
|
||||
# 0: the 'cell' that was running when the exception came up
|
||||
# 1: r3o2()
|
||||
# 2: r3o1()
|
||||
# 3: r3a()
|
||||
# Then repeating r3b, r3c, r3a
|
||||
last_unique, repeat_length = find_recursion(etype, evalue, records)
|
||||
self.assertEqual(last_unique, 2)
|
||||
self.assertEqual(repeat_length, 3)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# module testing (minimal)
|
||||
def test_handlers():
|
||||
def spam(c, d_e):
|
||||
(d, e) = d_e
|
||||
x = c + d
|
||||
y = c * d
|
||||
foo(x, y)
|
||||
|
||||
def foo(a, b, bar=1):
|
||||
eggs(a, b + bar)
|
||||
|
||||
def eggs(f, g, z=globals()):
|
||||
h = f + g
|
||||
i = f - g
|
||||
return h / i
|
||||
|
||||
buff = io.StringIO()
|
||||
|
||||
buff.write('')
|
||||
buff.write('*** Before ***')
|
||||
try:
|
||||
buff.write(spam(1, (2, 3)))
|
||||
except:
|
||||
traceback.print_exc(file=buff)
|
||||
|
||||
handler = ColorTB(ostream=buff)
|
||||
buff.write('*** ColorTB ***')
|
||||
try:
|
||||
buff.write(spam(1, (2, 3)))
|
||||
except:
|
||||
handler(*sys.exc_info())
|
||||
buff.write('')
|
||||
|
||||
handler = VerboseTB(ostream=buff)
|
||||
buff.write('*** VerboseTB ***')
|
||||
try:
|
||||
buff.write(spam(1, (2, 3)))
|
||||
except:
|
||||
handler(*sys.exc_info())
|
||||
buff.write('')
|
||||
|
||||
from IPython.testing.decorators import skipif
|
||||
|
||||
class TokenizeFailureTest(unittest.TestCase):
|
||||
"""Tests related to https://github.com/ipython/ipython/issues/6864."""
|
||||
|
||||
# that appear to test that we are handling an exception that can be thrown
|
||||
# by the tokenizer due to a bug that seem to have been fixed in 3.8, though
|
||||
# I'm unsure if other sequences can make it raise this error. Let's just
|
||||
# skip in 3.8 for now
|
||||
@skipif(sys.version_info > (3,8))
|
||||
def testLogging(self):
|
||||
message = "An unexpected error occurred while tokenizing input"
|
||||
cell = 'raise ValueError("""a\nb""")'
|
||||
|
||||
stream = io.StringIO()
|
||||
handler = logging.StreamHandler(stream)
|
||||
logger = logging.getLogger()
|
||||
loglevel = logger.level
|
||||
logger.addHandler(handler)
|
||||
self.addCleanup(lambda: logger.removeHandler(handler))
|
||||
self.addCleanup(lambda: logger.setLevel(loglevel))
|
||||
|
||||
logger.setLevel(logging.INFO)
|
||||
with tt.AssertNotPrints(message):
|
||||
ip.run_cell(cell)
|
||||
self.assertNotIn(message, stream.getvalue())
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
with tt.AssertNotPrints(message):
|
||||
ip.run_cell(cell)
|
||||
self.assertIn(message, stream.getvalue())
|
||||
Loading…
Add table
Add a link
Reference in a new issue