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()")
def test_macro(self): ip.push({'a': 10}) # The AST transformation makes this do a+=-1 ip.define_macro("amacro", "a+=1\nprint(a)") with tt.AssertPrints("9"): ip.run_cell("amacro") with tt.AssertPrints("8"): ip.run_cell("amacro")
def test_syntaxerror_input_transformer(self): with tt.AssertPrints('1234'): ip.run_cell('1234') with tt.AssertPrints('SyntaxError: invalid syntax'): ip.run_cell('1 2 3') # plain python syntax error with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'): ip.run_cell( '2345 # syntaxerror') # input transformer syntax error with tt.AssertPrints('3456'): ip.run_cell('3456')
def test_time(): ip = get_ipython() with tt.AssertPrints("Wall time: "): ip.run_cell("%time None") ip.run_cell("def f(kmjy):\n" " %time print (2*kmjy)") with tt.AssertPrints("Wall time: "): with tt.AssertPrints("hihi", suppress=False): ip.run_cell("f('hi')")
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_warning_suppression(): ip.run_cell("import warnings") try: with tt.AssertPrints("UserWarning: asdf", channel="stderr"): ip.run_cell("warnings.warn('asdf')") # Here's the real test -- if we run that again, we should get the # warning again. Traditionally, each warning was only issued once per # yap_ipython session (approximately), even if the user typed in new and # different code that should have also triggered the warning, leading # to much confusion. with tt.AssertPrints("UserWarning: asdf", channel="stderr"): ip.run_cell("warnings.warn('asdf')") finally: ip.run_cell("del warnings")
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)
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)
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)
def test_bad_custom_tb(self): """Check that InteractiveShell is protected from bad custom exception handlers""" ip.set_custom_exc((IOError, ), lambda etype, value, tb: 1 / 0) self.assertEqual(ip.custom_exceptions, (IOError, )) with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): ip.run_cell(u'raise IOError("foo")') self.assertEqual(ip.custom_exceptions, ())
def test_macro_run(): """Test that we can run a multi-line macro successfully.""" ip = get_ipython() ip.history_manager.reset() cmds = [ "a=10", "a+=1", py3compat.doctest_refactor_print("print a"), "%macro test 2-3" ] for cmd in cmds: ip.run_cell(cmd, store_history=True) nt.assert_equal(ip.user_ns["test"].value, py3compat.doctest_refactor_print("a+=1\nprint a\n")) with tt.AssertPrints("12"): ip.run_cell("test") with tt.AssertPrints("13"): ip.run_cell("test")
def test_timeit(self): called = set() def f(x): called.add(x) ip.push({'f': f}) with tt.AssertPrints("std. dev. of"): ip.run_line_magic("timeit", "-n1 f(1)") self.assertEqual(called, {(1, )}) called.clear() with tt.AssertPrints("std. dev. of"): ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)") self.assertEqual(called, {(2, ), (3, )})
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()
def test_bad_custom_tb_return(self): """Check that InteractiveShell is protected from bad return types in custom exception handlers""" ip.set_custom_exc((NameError, ), lambda etype, value, tb, tb_offset=None: 1) self.assertEqual(ip.custom_exceptions, (NameError, )) with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): ip.run_cell(u'a=abracadabra') self.assertEqual(ip.custom_exceptions, ())
def test_run_cell(self): with tt.AssertPrints('-34'): ip.run_cell('print (12 + 22)') # A named reference to a number shouldn't be transformed. ip.user_ns['n'] = 55 with tt.AssertNotPrints('-55'): ip.run_cell('print (n)')
def test_unregistering(self): err_transformer = ErrorTransformer() ip.ast_transformers.append(err_transformer) with tt.AssertPrints("unregister", channel='stderr'): ip.run_cell("1 + 2") # This should have been removed. nt.assert_not_in(err_transformer, ip.ast_transformers)
def test_time(self): called = [] def f(x): called.append(x) ip.push({'f': f}) # Test with an expression with tt.AssertPrints("Wall time: "): ip.run_line_magic("time", "f(5+9)") self.assertEqual(called, [-14]) called[:] = [] # Test with a statement (different code path) with tt.AssertPrints("Wall time: "): ip.run_line_magic("time", "a = f(-3 + -2)") self.assertEqual(called, [5])
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_logging_magic_not_quiet(): _ip.config.LoggingMagics.quiet = False lm = logging.LoggingMagics(shell=_ip) with TemporaryDirectory() as td: try: with tt.AssertPrints(re.compile("Activating.*")): lm.logstart(os.path.join(td, "not_quiet.log")) finally: _ip.logger.logstop()
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_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_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_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)
def test_input_rejection(self): """Check that NodeTransformers can reject input.""" expect_exception_tb = tt.AssertPrints("InputRejected: test") expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False) # Run the same check twice to verify that the transformer is not # disabled after raising. with expect_exception_tb, expect_no_cell_output: ip.run_cell("'unsafe'") with expect_exception_tb, expect_no_cell_output: res = ip.run_cell("'unsafe'") self.assertIsInstance(res.error_before_exec, InputRejected)
def test_deprecation_warning(): ip.run_cell(""" import warnings def wrn(): warnings.warn( "I AM A WARNING", DeprecationWarning ) """) try: with tt.AssertPrints("I AM A WARNING", channel="stderr"): ip.run_cell("wrn()") finally: ip.run_cell("del warnings") ip.run_cell("del wrn")
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 func(): with tt.AssertPrints("abc"): print("acd") print("def") print(b"ghi")
def test_passing(self): with tt.AssertPrints("abc"): print("abcd") print("def") print(b"ghi")
def _check_smoketest(self, use_aimport=True): """ Functional test for the automatic reloader using either '%autoreload 1' or '%autoreload 2' """ mod_name, mod_fn = self.new_module(""" x = 9 z = 123 # this item will be deleted def foo(y): return y + 3 class Baz(object): def __init__(self, x): self.x = x def bar(self, y): return self.x + y @property def quux(self): return 42 def zzz(self): '''This method will be deleted below''' return 99 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7 def foo(self): return 1 """) # # Import module, and mark for reloading # if use_aimport: self.shell.magic_autoreload("1") self.shell.magic_aimport(mod_name) stream = StringIO() self.shell.magic_aimport("", stream=stream) nt.assert_in(("Modules to reload:\n%s" % mod_name), stream.getvalue()) with nt.assert_raises(ImportError): self.shell.magic_aimport("tmpmod_as318989e89ds") else: self.shell.magic_autoreload("2") self.shell.run_code("import %s" % mod_name) stream = StringIO() self.shell.magic_aimport("", stream=stream) nt.assert_true( "Modules to reload:\nall-except-skipped" in stream.getvalue()) nt.assert_in(mod_name, self.shell.ns) mod = sys.modules[mod_name] # # Test module contents # old_foo = mod.foo old_obj = mod.Baz(9) old_obj2 = mod.Bar() def check_module_contents(): nt.assert_equal(mod.x, 9) nt.assert_equal(mod.z, 123) nt.assert_equal(old_foo(0), 3) nt.assert_equal(mod.foo(0), 3) obj = mod.Baz(9) nt.assert_equal(old_obj.bar(1), 10) nt.assert_equal(obj.bar(1), 10) nt.assert_equal(obj.quux, 42) nt.assert_equal(obj.zzz(), 99) obj2 = mod.Bar() nt.assert_equal(old_obj2.foo(), 1) nt.assert_equal(obj2.foo(), 1) check_module_contents() # # Simulate a failed reload: no reload should occur and exactly # one error message should be printed # self.write_file(mod_fn, """ a syntax error """) with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'): self.shell.run_code("pass") # trigger reload with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'): self.shell.run_code("pass") # trigger another reload check_module_contents() # # Rewrite module (this time reload should succeed) # self.write_file( mod_fn, """ x = 10 def foo(y): return y + 4 class Baz(object): def __init__(self, x): self.x = x def bar(self, y): return self.x + y + 1 @property def quux(self): return 43 class Bar: # old-style class def foo(self): return 2 """) def check_module_contents(): nt.assert_equal(mod.x, 10) nt.assert_false(hasattr(mod, 'z')) nt.assert_equal(old_foo(0), 4) # superreload magic! nt.assert_equal(mod.foo(0), 4) obj = mod.Baz(9) nt.assert_equal(old_obj.bar(1), 11) # superreload magic! nt.assert_equal(obj.bar(1), 11) nt.assert_equal(old_obj.quux, 43) nt.assert_equal(obj.quux, 43) nt.assert_false(hasattr(old_obj, 'zzz')) nt.assert_false(hasattr(obj, 'zzz')) obj2 = mod.Bar() nt.assert_equal(old_obj2.foo(), 2) nt.assert_equal(obj2.foo(), 2) self.shell.run_code("pass") # trigger reload check_module_contents() # # Another failure case: deleted file (shouldn't reload) # os.unlink(mod_fn) self.shell.run_code("pass") # trigger reload check_module_contents() # # Disable autoreload and rewrite module: no reload should occur # if use_aimport: self.shell.magic_aimport("-" + mod_name) stream = StringIO() self.shell.magic_aimport("", stream=stream) nt.assert_true(("Modules to skip:\n%s" % mod_name) in stream.getvalue()) # This should succeed, although no such module exists self.shell.magic_aimport("-tmpmod_as318989e89ds") else: self.shell.magic_autoreload("0") self.write_file(mod_fn, """ x = -99 """) self.shell.run_code("pass") # trigger reload self.shell.run_code("pass") check_module_contents() # # Re-enable autoreload: reload should now occur # if use_aimport: self.shell.magic_aimport(mod_name) else: self.shell.magic_autoreload("") self.shell.run_code("pass") # trigger reload nt.assert_equal(mod.x, -99)