diff --git a/IPython/core/iplib.py b/IPython/core/iplib.py
index b4fa3b7..065df5e 100644
--- a/IPython/core/iplib.py
+++ b/IPython/core/iplib.py
@@ -2334,7 +2334,7 @@ class InteractiveShell(Component, Magic):
with prepended_to_syspath(self.ipython_extension_dir):
__import__(module_str)
mod = sys.modules[module_str]
- self._call_load_ipython_extension(mod)
+ return self._call_load_ipython_extension(mod)
def unload_extension(self, module_str):
"""Unload an IPython extension by its module name.
@@ -2366,11 +2366,11 @@ class InteractiveShell(Component, Magic):
def _call_load_ipython_extension(self, mod):
if hasattr(mod, 'load_ipython_extension'):
- mod.load_ipython_extension(self)
+ return mod.load_ipython_extension(self)
def _call_unload_ipython_extension(self, mod):
if hasattr(mod, 'unload_ipython_extension'):
- mod.unload_ipython_extension(self)
+ return mod.unload_ipython_extension(self)
#-------------------------------------------------------------------------
# Things related to the prefilter
diff --git a/IPython/core/magic.py b/IPython/core/magic.py
index 98a844a..2f5a37f 100644
--- a/IPython/core/magic.py
+++ b/IPython/core/magic.py
@@ -3496,7 +3496,7 @@ Defaulting color scheme to 'NoColor'"""
def magic_load_ext(self, module_str):
"""Load an IPython extension by its module name."""
- self.load_extension(module_str)
+ return self.load_extension(module_str)
def magic_unload_ext(self, module_str):
"""Unload an IPython extension by its module name."""
diff --git a/IPython/core/tests/obj_del.py b/IPython/core/tests/obj_del.py
deleted file mode 100644
index d925dc6..0000000
--- a/IPython/core/tests/obj_del.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Test code for https://bugs.launchpad.net/ipython/+bug/239054
-
-WARNING: this script exits IPython! It MUST be run in a subprocess.
-
-When you run the following script from CPython it prints:
-__init__ is here
-__del__ is here
-
-and creates the __del__.txt file
-
-When you run it from IPython it prints:
-__init__ is here
-
-When you exit() or Exit from IPython neothing is printed and no file is created
-(the file thing is to make sure __del__ is really never called and not that
-just the output is eaten).
-
-Note that if you call %reset in IPython then everything is Ok.
-
-IPython should do the equivalent of %reset and release all the references it
-holds before exit. This behavior is important when working with binding objects
-that rely on __del__. If the current behavior has some use case then I suggest
-to add a configuration option to IPython to control it.
-"""
-import sys
-
-class A(object):
- def __del__(self):
- print 'obj_del.py: object A deleted'
-
-a = A()
-
-# Now, we force an exit, the caller will check that the del printout was given
-_ip = get_ipython()
-_ip.ask_exit()
diff --git a/IPython/core/tests/tclass.py b/IPython/core/tests/tclass.py
index ef2f8ea..ad2c1e6 100644
--- a/IPython/core/tests/tclass.py
+++ b/IPython/core/tests/tclass.py
@@ -24,6 +24,7 @@ else:
c = C(name)
#print >> sys.stderr, "ARGV:", sys.argv # dbg
-# This print statement is NOT debugging, we're making the check on a completely
-# separate process so we verify by capturing stdout.
+
+# 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:]
diff --git a/IPython/core/tests/test_run.py b/IPython/core/tests/test_run.py
index af0ce14..a6b07fe 100644
--- a/IPython/core/tests/test_run.py
+++ b/IPython/core/tests/test_run.py
@@ -91,24 +91,7 @@ def doctest_run_builtins():
# For some tests, it will be handy to organize them in a class with a common
# setup that makes a temp file
-class TempFileMixin(object):
- def mktmp(self, src, ext='.py'):
- """Make a valid python temp file."""
- fname, f = tt.temp_pyfile(src, ext)
- self.tmpfile = f
- self.fname = fname
-
- def teardown(self):
- self.tmpfile.close()
- try:
- os.unlink(self.fname)
- except:
- # On Windows, even though we close the file, we still can't delete
- # it. I have no clue why
- pass
-
-
-class TestMagicRunPass(TempFileMixin):
+class TestMagicRunPass(tt.TempFileMixin):
def setup(self):
"""Make a valid python temp file."""
@@ -148,7 +131,7 @@ class TestMagicRunPass(TempFileMixin):
nt.assert_equals(p2[:3], '...')
-class TestMagicRunSimple(TempFileMixin):
+class TestMagicRunSimple(tt.TempFileMixin):
def test_simpledef(self):
"""Test that simple class definitions work."""
diff --git a/IPython/extensions/parallelmagic.py b/IPython/extensions/parallelmagic.py
old mode 100644
new mode 100755
index f72b3b6..cd3b48f
--- a/IPython/extensions/parallelmagic.py
+++ b/IPython/extensions/parallelmagic.py
@@ -19,6 +19,7 @@ import new
from IPython.core.component import Component
from IPython.utils.traitlets import Bool, Any
from IPython.utils.autoattr import auto_attr
+from IPython.testing import decorators as testdec
#-----------------------------------------------------------------------------
# Definitions of magic functions for use with IPython
@@ -58,6 +59,7 @@ class ParalleMagicComponent(Component):
self.shell.define_magic('px', self.magic_px)
self.shell.define_magic('autopx', self.magic_autopx)
+ @testdec.skip_doctest
def magic_result(self, ipself, parameter_s=''):
"""Print the result of command i on all engines..
@@ -89,6 +91,7 @@ class ParalleMagicComponent(Component):
result = self.active_multiengine_client.get_result(index)
return result
+ @testdec.skip_doctest
def magic_px(self, ipself, parameter_s=''):
"""Executes the given python command in parallel.
@@ -112,6 +115,7 @@ class ParalleMagicComponent(Component):
result = self.active_multiengine_client.execute(parameter_s)
return result
+ @testdec.skip_doctest
def magic_autopx(self, ipself, parameter_s=''):
"""Toggles auto parallel mode.
diff --git a/IPython/extensions/pretty.py b/IPython/extensions/pretty.py
index 3ff1bc3..f6448e0 100644
--- a/IPython/extensions/pretty.py
+++ b/IPython/extensions/pretty.py
@@ -128,13 +128,15 @@ class PrettyResultDisplay(Component):
#-----------------------------------------------------------------------------
-def load_ipython_extension(ip):
+def load_ipython_extension(ip=None):
"""Load the extension in IPython as a hook."""
+ if ip is None: ip = get_ipython()
global _loaded
if not _loaded:
prd = PrettyResultDisplay(ip, name='pretty_result_display')
ip.set_hook('result_display', prd, priority=99)
_loaded = True
+ return prd
def unload_ipython_extension(ip):
"""Unload the extension."""
@@ -163,60 +165,3 @@ def dtype_pprinter(obj, p, cycle):
p.breakable()
p.pretty(field)
p.end_group(7, '])')
-
-
-#-----------------------------------------------------------------------------
-# Tests
-#-----------------------------------------------------------------------------
-
-
-def test_pretty():
- """
- In [1]: from IPython.extensions import ipy_pretty
-
- In [2]: ipy_pretty.activate()
-
- In [3]: class A(object):
- ...: def __repr__(self):
- ...: return 'A()'
- ...:
- ...:
-
- In [4]: a = A()
-
- In [5]: a
- Out[5]: A()
-
- In [6]: def a_pretty_printer(obj, p, cycle):
- ...: p.text('')
- ...:
- ...:
-
- In [7]: ipy_pretty.for_type(A, a_pretty_printer)
-
- In [8]: a
- Out[8]:
-
- In [9]: class B(object):
- ...: def __repr__(self):
- ...: return 'B()'
- ...:
- ...:
-
- In [10]: B.__module__, B.__name__
- Out[10]: ('__main__', 'B')
-
- In [11]: def b_pretty_printer(obj, p, cycle):
- ....: p.text('')
- ....:
- ....:
-
- In [12]: ipy_pretty.for_type_by_name('__main__', 'B', b_pretty_printer)
-
- In [13]: b = B()
-
- In [14]: b
- Out[14]:
- """
- assert False, "This should only be doctested, not run."
-
diff --git a/IPython/extensions/tests/test_pretty.py b/IPython/extensions/tests/test_pretty.py
old mode 100644
new mode 100755
index 3f9a10b..4df8f9f
--- a/IPython/extensions/tests/test_pretty.py
+++ b/IPython/extensions/tests/test_pretty.py
@@ -15,14 +15,13 @@ Simple tests for :mod:`IPython.extensions.pretty`.
# Imports
#-----------------------------------------------------------------------------
-import sys
from unittest import TestCase
from IPython.core.component import Component, masquerade_as
from IPython.core.iplib import InteractiveShell
from IPython.extensions import pretty as pretty_ext
from IPython.external import pretty
-
+from IPython.testing import tools as tt
from IPython.utils.traitlets import Bool
#-----------------------------------------------------------------------------
@@ -43,9 +42,11 @@ class TestPrettyResultDisplay(TestCase):
def setUp(self):
self.ip = InteractiveShellStub(None)
- # This allows our stub to be retrieved instead of the real InteractiveShell
+ # This allows our stub to be retrieved instead of the real
+ # InteractiveShell
masquerade_as(self.ip, InteractiveShell)
- self.prd = pretty_ext.PrettyResultDisplay(self.ip, name='pretty_result_display')
+ self.prd = pretty_ext.PrettyResultDisplay(self.ip,
+ name='pretty_result_display')
def test_for_type(self):
self.prd.for_type(A, a_pprinter)
@@ -53,4 +54,44 @@ class TestPrettyResultDisplay(TestCase):
result = pretty.pretty(a)
self.assertEquals(result, "")
+ipy_src = """
+class A(object):
+ def __repr__(self):
+ return 'A()'
+
+class B(object):
+ def __repr__(self):
+ return 'B()'
+
+a = A()
+b = B()
+
+def a_pretty_printer(obj, p, cycle):
+ p.text('')
+
+def b_pretty_printer(obj, p, cycle):
+ p.text('')
+
+
+a
+b
+
+ip = get_ipython()
+prd = ip.load_extension('pretty')
+prd.for_type(A, a_pretty_printer)
+prd.for_type_by_name(B.__module__, B.__name__, b_pretty_printer)
+
+a
+b
+"""
+ipy_out = """
+A()
+B()
+
+
+"""
+class TestPrettyInteractively(tt.TempFileMixin):
+ def test_printers(self):
+ self.mktmp(ipy_src, '.ipy')
+ tt.ipexec_validate(self.fname, ipy_out)
diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py
index 3e53885..5b0d1e0 100644
--- a/IPython/testing/tools.py
+++ b/IPython/testing/tools.py
@@ -165,12 +165,12 @@ def default_argv():
from IPython.config import default
ipcdir = os.path.dirname(default.__file__)
ipconf = os.path.join(ipcdir,'ipython_config.py')
- #print 'conf:',ipconf # dbg
return ['--colors=NoColor', '--no-term-title','--no-banner',
- '--config-file=%s' % ipconf, '--autocall=0', '--quick']
+ '--config-file=%s' % ipconf, '--autocall=0',
+ '--prompt-out=""']
-def ipexec(fname):
+def ipexec(fname, options=None):
"""Utility to call 'ipython filename'.
Starts IPython witha minimal and safe configuration to make startup as fast
@@ -183,19 +183,26 @@ def ipexec(fname):
fname : str
Name of file to be executed (should have .py or .ipy extension).
+ options : optional, list
+ Extra command-line flags to be passed to IPython.
+
Returns
-------
(stdout, stderr) of ipython subprocess.
- """
+ """
+ if options is None: options = []
+ cmdargs = ' '.join(default_argv() + options)
+
_ip = get_ipython()
test_dir = os.path.dirname(__file__)
full_fname = os.path.join(test_dir, fname)
ipython_cmd = platutils.find_cmd('ipython')
- cmdargs = ' '.join(default_argv())
- return genutils.getoutputerror('%s %s' % (ipython_cmd, full_fname))
+ full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
+ return genutils.getoutputerror(full_cmd)
-def ipexec_validate(fname, expected_out, expected_err=None):
+def ipexec_validate(fname, expected_out, expected_err=None,
+ options=None):
"""Utility to call 'ipython filename' and validate output/error.
This function raises an AssertionError if the validation fails.
@@ -210,6 +217,12 @@ def ipexec_validate(fname, expected_out, expected_err=None):
expected_out : str
Expected stdout of the process.
+ expected_err : optional, str
+ Expected stderr of the process.
+
+ options : optional, list
+ Extra command-line flags to be passed to IPython.
+
Returns
-------
None
@@ -219,3 +232,25 @@ def ipexec_validate(fname, expected_out, expected_err=None):
nt.assert_equals(out.strip(), expected_out.strip())
if expected_err:
nt.assert_equals(err.strip(), expected_err.strip())
+
+
+class TempFileMixin(object):
+ """Utility class to create temporary Python/IPython files.
+
+ Meant as a mixin class for test cases."""
+
+ def mktmp(self, src, ext='.py'):
+ """Make a valid python temp file."""
+ fname, f = temp_pyfile(src, ext)
+ self.tmpfile = f
+ self.fname = fname
+
+ def teardown(self):
+ self.tmpfile.close()
+ try:
+ os.unlink(self.fname)
+ except:
+ # On Windows, even though we close the file, we still can't delete
+ # it. I have no clue why
+ pass
+