diff --git a/IPython/core/magics/script.py b/IPython/core/magics/script.py index c0ad8d3..a041d58 100644 --- a/IPython/core/magics/script.py +++ b/IPython/core/magics/script.py @@ -31,14 +31,14 @@ def script_args(f): '--out', type=str, help="""The variable in which to store stdout from the script. If the script is backgrounded, this will be the stdout *pipe*, - instead of the stderr text itself. + instead of the stderr text itself and will not be auto closed. """ ), magic_arguments.argument( '--err', type=str, help="""The variable in which to store stderr from the script. If the script is backgrounded, this will be the stderr *pipe*, - instead of the stderr text itself. + instead of the stderr text itself and will not be autoclosed. """ ), magic_arguments.argument( @@ -187,11 +187,16 @@ class ScriptMagics(Magics): if args.bg: self.bg_processes.append(p) self._gc_bg_processes() + to_close = [] if args.out: self.shell.user_ns[args.out] = p.stdout + else: + to_close.append(p.stdout) if args.err: self.shell.user_ns[args.err] = p.stderr - self.job_manager.new(self._run_script, p, cell, daemon=True) + else: + to_close.append(p.stderr) + self.job_manager.new(self._run_script, p, cell, to_close, daemon=True) if args.proc: self.shell.user_ns[args.proc] = p return @@ -231,10 +236,12 @@ class ScriptMagics(Magics): sys.stderr.write(err) sys.stderr.flush() - def _run_script(self, p, cell): + def _run_script(self, p, cell, to_close): """callback for running the script in the background""" p.stdin.write(cell) p.stdin.close() + for s in to_close: + s.close() p.wait() @line_magic("killbgscripts") diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index 373f66d..b338168 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -562,17 +562,6 @@ def test_timeit_shlex(): _ip.magic('timeit -r1 -n1 f("a " + "b ")') -def test_timeit_arguments(): - "Test valid timeit arguments, should not cause SyntaxError (GH #1269)" - if sys.version_info < (3,7): - _ip.magic("timeit ('#')") - else: - # 3.7 optimize no-op statement like above out, and complain there is - # nothing in the for loop. - _ip.magic("timeit a=('#')") - - - def test_timeit_special_syntax(): "Test %%timeit with IPython special syntax" @register_line_magic @@ -839,13 +828,16 @@ def test_script_out_err(): def test_script_bg_out(): ip = get_ipython() ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'") + nt.assert_equal(ip.user_ns['output'].read(), b'hi\n') + ip.user_ns['output'].close() @dec.skip_win32 def test_script_bg_err(): ip = get_ipython() ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2") nt.assert_equal(ip.user_ns['error'].read(), b'hello\n') + ip.user_ns['error'].close() @dec.skip_win32 def test_script_bg_out_err(): @@ -853,6 +845,8 @@ def test_script_bg_out_err(): ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2") nt.assert_equal(ip.user_ns['output'].read(), b'hi\n') nt.assert_equal(ip.user_ns['error'].read(), b'hello\n') + ip.user_ns['output'].close() + ip.user_ns['error'].close() def test_script_defaults(): ip = get_ipython() @@ -1072,4 +1066,15 @@ def test_logging_magic_not_quiet(): lm.logstart(os.path.join(td, "not_quiet.log")) finally: _ip.logger.logstop() - + +## +# this is slow, put at the end for local testing. +## +def test_timeit_arguments(): + "Test valid timeit arguments, should not cause SyntaxError (GH #1269)" + if sys.version_info < (3,7): + _ip.magic("timeit ('#')") + else: + # 3.7 optimize no-op statement like above out, and complain there is + # nothing in the for loop. + _ip.magic("timeit a=('#')")