[Idle-dev] [ idlefork-Bugs-695861 ] Unnecessary blank line in Shell

SourceForge.net noreply@sourceforge.net
Mon, 03 Mar 2003 12:19:15 -0800


Bugs item #695861, was opened at 2003-03-01 22:40
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=109579&aid=695861&group_id=9579

Category: None
Group: None
>Status: Closed
>Resolution: Fixed
Priority: 3
Submitted By: David Harris (edcdave)
Assigned to: Kurt B. Kaiser (kbk)
Summary: Unnecessary blank line in Shell

Initial Comment:
Windows XP, IDLEfork 0.9a2, Python 2.2.2

The following interactive session generates an 
unexpected blank line:

>>> word = 'letters'
>>> for c in word: print c,
                        # continuation line, pressed Enter
l e t t e r s
>>> 'h' in word
                       # unexpected blank line
0
>>> 'e' in word
1
>>>


IDLE 0.8 does not generate the unexpected blank line. 
The behavior seems to be triggered by a prior need for a 
continuation line.

----------------------------------------------------------------------

>Comment By: Kurt B. Kaiser (kbk)
Date: 2003-03-03 15:19

Message:
Logged In: YES 
user_id=149084

Yes, __stderr__ was being flushed by the trace.

Thanks for the solution!

run.py Rev 1.12

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2003-03-03 13:56

Message:
Logged In: YES 
user_id=6380

I don't follow the trace, but your first experiment might
not have been right.

"print 1," does not produce a space or newline until
something else is done to the same file. If you see it
appear immediately, that must be because something else *is*
done to the file. Since you sent it to sys.stderr, I think
that what happens is that something is done just before
printing the next prompt.

However, I was wrong about needing to write C code for this.
softspace is a normal attribute on files, and you can
implement the effect of Py_FlushLine() as follows:

if sys.stdout.softspace:
  sys.stdout.softspace = 0
  sys.stdout.write("\n")

(well, you may have to expect an AttributeError and then
skip the whole thing.)

----------------------------------------------------------------------

Comment By: Kurt B. Kaiser (kbk)
Date: 2003-03-03 13:45

Message:
Logged In: YES 
user_id=149084

It might not solve the problem?

The problem seems to be associated with the proxying of 
stdout in run.py.  If I redirect the subprocess' stdout to
__stderr__ the whitespace char is output immediately.
i.e. print 1, results in a x31 x20.  However, when redirected
via rpc.py's MethodProxy the space following the first print 1,
is held off and output before a subsequent x31. Putting a 
trace print in MethodProxy.__call__(), here's a trace of the
second "print 1,":

#C MainThread asynccall:7: exec runcode (<codeobject?
at0x83fb308, file "<pyshell#1>", line 1>,) {}
#C MainThread putmessage:7:
#S MainThread pollresponse:7:myseq:None
#S MainThread pollresponse:7:localcall:call:
#S MainThread localcall: ('call', ('exec', 'runcode', (<code object ? at 0x826d550, file "<pyshell#1>", line 1>,), {}))
** MethodProxy.__call__(oid, name, args):  stdout write (' ',)
#S MainThread remotecall:asynccall:  stdout write
#S MainThread asynccall:8: stdout write (' ',) {}
#S MainThread putmessage:8:
#S MainThread asyncreturn:8:call getresponse(): 
#S MainThread _getresponse:myseq: 8
#C MainThread pollresponse:8:myseq:7
#C MainThread pollresponse:8:localcall:call:
#C MainThread localcall: ('call', ('stdout', 'write', (' ',), {}))
#C MainThread pollresponse:8:localcall:response:('OK', None)
#C MainThread putmessage:8:
#S MainThread pollresponse:8:myseq:8
#S MainThread asyncreturn:8:response:  ('OK', None)
** MethodProxy.__call__(oid, name, args):  stdout write ('1',)
#S MainThread remotecall:asynccall:  stdout write
#S MainThread asynccall:10: stdout write ('1',) {}
#S MainThread putmessage:10:
#S MainThread asyncreturn:10:call getresponse(): 
#S MainThread _getresponse:myseq: 10
#C MainThread pollresponse:10:myseq:7
#C MainThread pollresponse:10:localcall:call:
#C MainThread localcall: ('call', ('stdout', 'write', ('1',), {}))
#C MainThread pollresponse:10:localcall:response:('OK', None)
#C MainThread putmessage:10:
#S MainThread pollresponse:10:myseq:10
#S MainThread asyncreturn:10:response:  ('OK', None)
#S MainThread pollresponse:7:localcall:response:('OK', None)
#S MainThread putmessage:7:
#C MainThread pollresponse:7:myseq:7


----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2003-03-03 08:16

Message:
Logged In: YES 
user_id=6380

You need a way to force a call to Py_FlushLine() after the
subprocess is finished. Unfortunately I don't know how to
force that without writing C code. In Python 2.3, we could
move the call in sys_displayhook() up so that it is executed
even when o equals None; then you could call
sys.displayhook(None) at the end.

Would that work? I'd be willing to add that to Python 2.3b1.
(I hope IDLEfork will be ready for inclusion in Python by
then too.)

----------------------------------------------------------------------

Comment By: Kurt B. Kaiser (kbk)
Date: 2003-03-02 20:18

Message:
Logged In: YES 
user_id=149084

Somewhat simplified:

Python 2.2.2 (#1, Mar  2 2003, 00:38:54) 
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
IDLEfork 0.9a2
>>> print 1,
1
>>> 1

1
>>> 1
1

When the code for '1' is executed the subprocess is sending
a request to print \n before its request to print '1'.   It seems that
the whitespace character is being held off somehow and 
replaced with a newline if the following statement isn't a "print".
Curious it doesn't happen with IDLE0.8.  

This is a little hard to debug and not too important compared to
some other things so I'm lowering the priority and putting it on 
the back burner.  If you want to dig in and supply a patch I'll
bet you learn a bit about Python before you're done  :-)  

----------------------------------------------------------------------

Comment By: David Harris (edcdave)
Date: 2003-03-02 12:52

Message:
Logged In: YES 
user_id=72287

I think I understand. The comma is contributing to the 
behavior, but I'm not sure that's the whole story. For example,

>>> print "test",
test
>>> print "test"
 test
>>> print "test"
test

The second output has a leading space (induced by the first 
command?). But why didn't I get a blank line like the original 
example?

My apologies for submitting what seems to be a superficial 
bug. I'm very new to Python, but I have 20 years experience 
in C and others. When I saw the on-again/off-again behavior of 
the blank line, I imagined a situation where a variable was not 
reset (which could have a wider impact than the display).

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2003-03-02 07:51

Message:
Logged In: YES 
user_id=6380

It's not a continuation line. More likely it's that the
subprocess where your code runs has an unterminated output
line for which both it and IDLE's stdout provide an extra
newline at some later point.


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=109579&aid=695861&group_id=9579