Command-line tool able to take multiple commands at one time?

Bengt Richter bokr at oz.net
Sat Nov 12 01:53:11 CET 2005


On Fri, 11 Nov 2005 01:05:56 GMT, Peter A. Schott <paschott at no.yahoo.spamm.com> wrote:

>Per subject - I realize I can copy/paste a line at a time into an interactive
>session when I'm trying to debug, but was wondering if there is any tool out
>there that allows me to copy sections of working Python scripts to paste into my
>interactive console and let those run so I don't have to copy line-by-line.
What are you pasting into? Idle? win32 console? via telnet?
The win32 console you get by running python.exe from the cmd.exe windows shell
permits multi-line copying and pasting (Alt-spacebar,e,k,<hold shift down>
<select-motions></hold shift down>,Enter and Alt-spacebar,e,p respectively).
(You can also use <hold left mouse down> and move mouse for <select-motions>
instead of arrow keys, as a substitute for <hold shift down>)

The trick is that unlike executing file-based source lines as in import or execfile,
compilation has to be triggered by something acting like EOF. In the interactive mode
that is statement by statement until a statement is followed by an indented suite.
Then the compilation and execution of the indented suite is postponed until a blank line.

This is not really a good substitute for EOF or some other explicit EOF-emulating escape
from the suite input mode, because you can't switch to an editor and copy something that might have
arbitrary blank lines and compacted code that would import fine and expect it to paste fine.
IMO this is a wart of the interactive mode that could be improved (e.g, once into a multiline
sequence of input, terminate on ctl-something instead of blank line).

By experimentation you can see what chunks you can paste. E.g., try two function defs in a
single paste of the four lines:
def foo():
    print 'foo'
def bar():
    print 'bar'

 >>> def foo():
 ...     print 'foo'
 ... def bar():
   File "<stdin>", line 3
     def bar():
       ^
 SyntaxError: invalid syntax
 >>>     print 'bar'
   File "<stdin>", line 1
     print 'bar'
     ^
 SyntaxError: invalid syntax

vs pasting them as five lines including a separting blank line:
def foo():
    print 'foo'

def bar():
    print 'bar'

 >>> def foo():
 ...     print 'foo'
 ...
 >>> def bar():
 ...     print 'bar'
 ...
 >>>

(I indent the paste here of interactive stuff one space to avoid
false quote highlighting in newsreaders).

>
>Not sure if iPython would meet that criteria or not or even if such a beast
>exists.  It would be helpful for debugging some of my simpler, yet still lengthy
>at times, scripts.

Plain vanilla gvim (popular editor) will let you invoke a program as filter on
anything you select in your editing window, and it will cut the selection and paste
the execution output in its place, so e.g., the above, starting with a screen like

# select starts on next line
def foo():
    print 'foo'
def bar():
    print 'bar'
#select ends at end of last line

and selecting the four lines and then typing :!python and pressing Enter,

what you get is
# select starts on next line
#select ends at beginning of this line (includes \n of last line)

Seems not very useful, since no output was generated by correct execution of the defs.
If there had been a syntax error, the same would have happened, unless stderr is captured
into the output stream.

Since my version of windows (ancient NT4) has the infamous redirection problem, I have to
invoke scripts via a single-line command file that runs python explicitly in order to capture
output by piping or redirection. So I have two versions, one that redirects stderr also. E.g.,

py24.cmd contains the single line
@d:\python-2.4b1\mingw\python24.exe %*

and py24e.cmd contains the single line
@d:\python-2.4b1\mingw\python24.exe %* 2>&1

So, now if there had been a syntax error, e.g., (restoring previous by hitting u key for undo
and editing in and example error)

# select starts on next line
def foo():
    print 'foo'
def bar() # make syntax error (:)
    print 'bar'
#select ends at beginning of this line (includes \n of last line)

Then we do the same and use py24e and get:

# select starts on next line
  File "<stdin>", line 3
    def bar() # make syntax error (:)
                                    ^
SyntaxError: invalid syntax
#select ends at beginning of this line (includes \n of last line)

And an undo will get us back.
Executing this way (as a filter action) you don't have to worry about
putting blank lines or not in the pasted material.

If we fix the error and put in a print for actual output, we'll get that:

# select starts on next line
def foo():
    print 'foo'
def bar(): # fixed syntax error (:)
    print 'bar'
foo(); bar() # expect output
#select ends at beginning of this line (includes \n of last line)

And then :!py24e after selecting the five lines gets

# select starts on next line
foo
bar
#select ends at beginning of this line (includes \n of last line)


Of course, you can do these two things in parallel. Not to mention extremely
flexible possibilities of mapping keys or key-sequences to almost anything
imaginable, if you want to go beyond plain vanilla. E.g., non-destructive
results in a split window is nicer.

But filters are easy and fun to invoke.

        Of csuroe, you can  do tsehe two  thgnis
        in paellarl.  Not to  menotin  emxteerly
        fblleixe pistisibleios  of mpipang  keys
        or  kqs-ycuneeees  to  aosmlt   annhytig
        inmgibalae, if  you  wnat to  go  bnyoed
        pilan  vlnaila.  E.g.,   nnoi-csudvttere
        rteluss in a spilt wdionw is neicr.

(last paragraph filtered through scramble and a paragraph-justifying
script specifying 8 margin 40 wide and justify to both edges ;-)

So what platform are you on?

Regards,
Bengt Richter



More information about the Python-list mailing list