Shell like syntax for subprocess.Popen # overloading >, <, | | | |
Hi,
I use python quite a bit to couple different programs together.
Doing so has been a _lot_ easier since subprocess came around, but
would really like to be able to use the succinct shell syntax; >, <, |
That really shouldn't be too hard to wrap in a class, but so far I
didn't succeed to do so this well, since I'm facing some trouble with
operator precedence that I do not know how to overcome.
Consider the following:
A = 'inputString'
B = Process('process.exe')
C = cStringIO.StringIO() # output bucket
A > B > C
A is being piped to B and processed, but the output of B is not being
piped to C
executing A > B; B > C works as expected however.
Which is disappointing, since what I'm trying to achieve is a sugar
syntax for Popen processes, where directly sees the chain of
commands...
Any suggestions to overcome this issue are greatly appreciated!
cheers,
-jelle
-------------------------------------------------------------------------
class Process(Popen, object):
def __init__(self, commandString, wait=False):
assert isinstance(commandString, str)
cmd = commandString.split()
self.cmd = commandString
self.exe = cmd.pop(0)
## self.args = cmd
self.process = Popen(self.cmd, shell=True, stdin=PIPE,
stdout=PIPE, close_fds=False)
self.stdout = self.process.stdout
self.stderr = self.process.stderr
def __repr__(self):
return 'Process instance ( %s ) ' % (self.exe)
def __or__(self, other): # PIPE
'''
returns the output of Process A -> Process B
takes a Process instance as argument
'''
assert isinstance(other, Process), '%s\n is not a Process
instance' % (other)
print 'PIPE'
self > other
def __lt__(self, other): # STDIN
'''
takes a StringIO, file or string objectas argument
'''
print '>'
print 'STDIN'
if isinstance(other, str):
self.process.communicate(other)
else:
self.stdout, self.stderr =
self.process.communicate(other.read())
self.process.wait()
def __gt__(self, other): # STDOUT
'''
takes a StringIO, file or string object as argument
returns the result of an external process
'''
print '<'
print 'STDOUT'
assert hasattr(other, 'write') or isinstance(other, str)
if isinstance(other, str):
other += self.stdout
else:
other.write(self.stdout)
------------------------------------------------------------------------- | | | | re: Shell like syntax for subprocess.Popen # overloading >, <, |
On 18 Apr 2006 01:37:03 -0700, rumours say that "jelle"
<jelleferinga@gmail.com> might have written:
[color=blue]
>Hi,
>
>I use python quite a bit to couple different programs together.
>Doing so has been a _lot_ easier since subprocess came around, but
>would really like to be able to use the succinct shell syntax; >, <, |
>
>That really shouldn't be too hard to wrap in a class, but so far I
>didn't succeed to do so this well, since I'm facing some trouble with
>operator precedence that I do not know how to overcome.[/color]
[snip]
Overload the __or__ special function (ie the 'pipe' operator) instead of the
__gt__ operator.
I remember I have seen such a proposition (mentioning pump, filters and
sinks) but I couldn't find it in google.groups.com --I think Aahz had
something to do with it, but ICBW.
Ah, I found it: http://mail.python.org/pipermail/pyt...il/044205.html
I don't know why I remembered Aahz about it :)
Check this too: http://groups.google.gr/group/comp.l...7efd4d3aa490ed
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians | | | | re: Shell like syntax for subprocess.Popen # overloading >, <, |
Hi Christos,
Thanks for your pointers there, impressive to see
-that a 12 year old thread still can make an interesting read
-you being able to remember & trace it... impressive...
Thanks for your pointers.
I think the
input > process > output
Syntax is more powerful , since it would let you build chaining
commmands in a more readable fashion.
The goal of this class would be to construct command chains such as:
input > processA | processB > ouput
Something which wouldn't be possible if only one operator is
overloaded.
I'm curious to see if its doable via overloading, since no __rgt__
methods exists... | | | | re: Shell like syntax for subprocess.Popen # overloading >, <, |
On 18 Apr 2006 05:00:55 -0700, rumours say that "jelle"
<jelleferinga@gmail.com> might have written:
[color=blue]
>Hi Christos,
>
>Thanks for your pointers there, impressive to see
>-that a 12 year old thread still can make an interesting read
>-you being able to remember & trace it... impressive...
>
>Thanks for your pointers.
>I think the
>input > process > output
>Syntax is more powerful , since it would let you build chaining
>commmands in a more readable fashion.
>
>The goal of this class would be to construct command chains such as:
>
>input > processA | processB > ouput
>
>Something which wouldn't be possible if only one operator is
>overloaded.
>I'm curious to see if its doable via overloading, since no __rgt__
>methods exists...[/color]
The problem with the operators chaining is that ">" is treated differently
than "|". Check the following disassembly:
[color=blue][color=green][color=darkred]
>>> import dis
>>> dis.dis(compile("a<b<c", "", "eval"))[/color][/color][/color]
0 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 0 (<)
11 JUMP_IF_FALSE 10 (to 24)
14 POP_TOP
15 LOAD_NAME 2 (c)
18 COMPARE_OP 0 (<)
21 JUMP_FORWARD 2 (to 26)[color=blue][color=green]
>> 24 ROT_TWO[/color][/color]
25 POP_TOP[color=blue][color=green]
>> 26 RETURN_VALUE[color=darkred]
>>> dis.dis(compile("a|b|c", "", "eval"))[/color][/color][/color]
0 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 BINARY_OR
7 LOAD_NAME 2 (c)
10 BINARY_OR
11 RETURN_VALUE
The comparison operators include some logic in order to "do what I mean" (so
that 4<x<10 works like 4<x and x<10, but x<10 will never be evaluated if 4<x
is False), and that is why I suggested you use the "|" operator instead.
Of course, you can use the ">" operator, just don't chain it, in order to
avoid such unexpected behaviour.
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians | | | | re: Shell like syntax for subprocess.Popen # overloading >, <, |
jelle wrote:[color=blue]
> Hi,
>
> I use python quite a bit to couple different programs together.
> Doing so has been a _lot_ easier since subprocess came around, but
> would really like to be able to use the succinct shell syntax; >, <, |
>
> That really shouldn't be too hard to wrap in a class, but so far I
> didn't succeed to do so this well, since I'm facing some trouble with
> operator precedence that I do not know how to overcome.
>
> Consider the following:
>
> A = 'inputString'
> B = Process('process.exe')
> C = cStringIO.StringIO() # output bucket
>
> A > B > C
>
> A is being piped to B and processed, but the output of B is not being
> piped to C
> executing A > B; B > C works as expected however.
> Which is disappointing, since what I'm trying to achieve is a sugar
> syntax for Popen processes, where directly sees the chain of
> commands...
>
> Any suggestions to overcome this issue are greatly appreciated![/color]
How about good old function call?
A = Lines('inputString')
B = Process('process.exe')
C = Process('proc2.exe')
result = pipeline(A, B, C, Lines()) # Text result
result = pipeline(A, B, C, Bytes()) # Binary result
pipeline(A, B, C, file("somefile","wb")) # dump to binary file |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,366 network members.
|