Repository: ipython/ipython

Issue:
`print stuff,` should avoid newline
In an IPython interpreter:

``` py
In [4]: print 1,
1

In [5]: print 1
1

In [6]: print 1,; print 2
1
2
```

In a regular Python interpreter:

``` py
>>> print 1,
1
>>> print 1
1
>>> print 1,;print 2
1 2
```



Discussion:
The problem, of course, lies with `InteractiveShell.run_code`...

```
In [118]: cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
: import ast
: code_ast = compile("print 1,; print 2", "<unknown>", "exec", ast.PyCF_ONLY_AST, 1)
: p1, p2 = code_ast.body
: c1 = compile(ast.Module([p1]), "<unknown>", "exec", 0, 1)
: c2 = compile(ast.Module([p2]), "<unknown>", "exec", 0, 1)
:
: print "exec:"
: exec 'exec c1; exec c2'
:
: print
: print "ip.run_code:"
: ip = get_ipython()
: exec "ip.run_code(c1); ip.run_code(c2)"
:<EOF>
exec:
1 2

ip.run_code:
1
2
```

In particular, it arises from the softspace handling:

```
    def run_code(self, code_obj):
        # ...
        exec code_obj in self.user_global_ns, self.user_ns
        # ...
        if softspace(sys.stdout, 0):
                print
```

Perhaps we need a `flush_softspace` option, which can control whether we flush the softspace and print the new line?  It should default to True, but we could force it to be False when running lines with multiple commands.


Resolving patch:
diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -2563,6 +2563,11 @@ def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
                 code = self.compile(mod, cell_name, "single")
                 if self.run_code(code):
                     return True
+
+            # Flush softspace
+            if softspace(sys.stdout, 0):
+                print
+
         except:
             # It's possible to have exceptions raised here, typically by
             # compilation of odd code (such as a naked 'return' outside a
@@ -2622,9 +2627,6 @@ def run_code(self, code_obj):
             self.showtraceback()
         else:
             outflag = 0
-            if softspace(sys.stdout, 0):
-                print
-
         return outflag
 
     # For backwards compatibility


Test patch:
diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py
--- a/IPython/core/tests/test_interactiveshell.py
+++ b/IPython/core/tests/test_interactiveshell.py
@@ -28,6 +28,7 @@
 import sys
 from StringIO import StringIO
 
+from IPython.testing.decorators import skipif
 from IPython.utils import io
 
 #-----------------------------------------------------------------------------
@@ -254,6 +255,18 @@ def test_bad_var_expand(self):
         # ZeroDivisionError
         self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
 
+    @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
+    def test_print_softspace(self):
+        """Verify that softspace is handled correctly when executing multiple
+        statements.
+
+        In [1]: print 1; print 2
+        1
+        2
+
+        In [2]: print 1,; print 2
+        1 2
+        """
 
 class TestSafeExecfileNonAsciiPath(unittest.TestCase):