rsclib 0.65__py3-none-any.whl → 0.67__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rsclib/execute.py CHANGED
@@ -1,6 +1,5 @@
1
- #!/usr/bin/python
2
- # -*- coding: iso-8859-1 -*-
3
- # Copyright (C) 2009-17 Dr. Ralf Schlatterbeck Open Source Consulting.
1
+ #!/usr/bin/python3
2
+ # Copyright (C) 2009-24 Dr. Ralf Schlatterbeck Open Source Consulting.
4
3
  # Reichergasse 131, A-3411 Weidling.
5
4
  # Web: http://www.runtux.com Email: office@runtux.com
6
5
  # All rights reserved
@@ -33,32 +32,32 @@ from traceback import format_exc
33
32
  from subprocess import Popen, PIPE
34
33
  from rsclib.autosuper import autosuper
35
34
 
36
- class Exec_Error (RuntimeError) : pass
35
+ class Exec_Error (RuntimeError): pass
37
36
 
38
- class _Named (autosuper) :
37
+ class _Named (autosuper):
39
38
  @property
40
- def clsname (self) :
39
+ def clsname (self):
41
40
  return self.__class__.__name__.lower ().replace ('_', '-')
42
41
  # end def clsname
43
42
  # end class _Named
44
43
 
45
- class Log (_Named) :
44
+ class Log (_Named):
46
45
  """ Logger mixin. Sets up a log prefix automagically but can take
47
46
  arguments for setting log_level and log_prefix.
48
47
  Use as self.log.debug (msg), self.log.info (msg) etc.
49
48
  """
50
49
  logprefix = ''
51
- def __init__ (self, log_level = None, log_prefix = None, *args, **kw) :
50
+ def __init__ (self, log_level = None, log_prefix = None, *args, **kw):
52
51
  log_prefix = log_prefix or '%s%s' % (self.logprefix, self.clsname)
53
52
  self.log_prefix = log_prefix
54
53
  self.log = logging.getLogger (log_prefix)
55
- if not len (self.log.handlers) :
54
+ if not len (self.log.handlers):
56
55
  log_level = log_level or logging.DEBUG
57
56
  formatter = logging.Formatter \
58
57
  ('%s[%%(process)d]: %%(message)s' % log_prefix)
59
- if 'log_handler' in args :
58
+ if 'log_handler' in args:
60
59
  handler = args ['log_handler']
61
- else :
60
+ else:
62
61
  handler = SysLogHandler ('/dev/log', 'daemon')
63
62
  handler.setLevel (log_level)
64
63
  handler.setFormatter (formatter)
@@ -81,21 +80,21 @@ class Log (_Named) :
81
80
  self.stderr_handler = handler
82
81
  # end def add_stderr_handler
83
82
 
84
- def log_exception (self) :
85
- for l in format_exc ().split ('\n') :
86
- if l :
83
+ def log_exception (self):
84
+ for l in format_exc ().split ('\n'):
85
+ if l:
87
86
  self.log.error (l)
88
87
  # end def log_exception
89
88
 
90
- def print_exception (self) :
91
- for l in format_exc ().split ('\n') :
92
- if l :
89
+ def print_exception (self):
90
+ for l in format_exc ().split ('\n'):
91
+ if l:
93
92
  print ("%s\r" % l)
94
93
  # end def print_exception
95
94
  # end class Log
96
95
 
97
- class Exec (Log) :
98
- def error (self, msg) :
96
+ class Exec (Log):
97
+ def error (self, msg):
99
98
  """ Just print error here, a derived class may want to do
100
99
  cleanup actions.
101
100
  """
@@ -108,9 +107,10 @@ class Exec (Log) :
108
107
  , ignore_err = False
109
108
  , shell = False
110
109
  , charset = 'utf-8'
111
- ) :
110
+ , do_split = True
111
+ ):
112
112
  popen_stdin = None
113
- if stdin is not None :
113
+ if stdin is not None:
114
114
  popen_stdin = PIPE
115
115
  p = Popen \
116
116
  ( args
@@ -121,48 +121,50 @@ class Exec (Log) :
121
121
  )
122
122
  stdout, stderr = (x.decode (charset) for x in p.communicate (stdin))
123
123
  self.stderr = err = ' '.join (stderr.rstrip ().split ('\n'))
124
- if p.returncode != 0 :
124
+ if p.returncode != 0:
125
125
  arg = args [0]
126
- if shell :
126
+ if shell:
127
127
  arg = args
128
128
  msg = "Nonzero exitcode %s from %s: %s" % (p.returncode, arg, err)
129
129
  self.error (msg)
130
- for e in stderr.rstrip ().split ('\n') :
130
+ for e in stderr.rstrip ().split ('\n'):
131
131
  self.error (e)
132
- if not ignore_err :
132
+ if not ignore_err:
133
133
  raise Exec_Error (msg, p.returncode)
134
- return stdout.rstrip ().split ('\n')
134
+ if do_split:
135
+ return stdout.rstrip ().split ('\n')
136
+ return stdout
135
137
  # end def exec_pipe
136
138
  # end class Exec
137
139
 
138
- class Lock_Mixin (_Named) :
139
- def __init__ (self, do_lock = True, *args, **kw) :
140
+ class Lock_Mixin (_Named):
141
+ def __init__ (self, do_lock = True, *args, **kw):
140
142
  self.need_unlock = False
141
143
  self.__super.__init__ (*args, **kw)
142
144
  lockdir = os.environ.get ('LOCKDIR', '/var/lock')
143
- if getattr (self, 'lockfile', None) :
145
+ if getattr (self, 'lockfile', None):
144
146
  lf = self.lockfile
145
- if not lf.startswith ('/') :
147
+ if not lf.startswith ('/'):
146
148
  lf = os.path.join (lockdir, lf)
147
- if not lf.endswith ('.lock') :
149
+ if not lf.endswith ('.lock'):
148
150
  lf += '.lock'
149
151
  self.lockfile = lf
150
- else :
152
+ else:
151
153
  self.lockfile = os.path.join (lockdir, '%s.lock' % self.clsname)
152
- if do_lock :
154
+ if do_lock:
153
155
  self.lock ()
154
156
  # end def __init__
155
157
 
156
- def lock (self) :
158
+ def lock (self):
157
159
  atexit.register (self.unlock)
158
160
  self.need_unlock = True
159
- try :
161
+ try:
160
162
  fd = os.open (self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
161
163
  f = os.fdopen (fd, 'w')
162
164
  f.write ("%s\n" % os.getpid())
163
165
  f.close ()
164
166
  except OSError as e:
165
- if e.errno != errno.EEXIST :
167
+ if e.errno != errno.EEXIST:
166
168
  self.log_exception ()
167
169
  raise
168
170
  self.need_unlock = False
@@ -170,57 +172,57 @@ class Lock_Mixin (_Named) :
170
172
  self.lock_fail ()
171
173
  # end def lock
172
174
 
173
- def lock_fail (self) :
175
+ def lock_fail (self):
174
176
  """ By default we exit when locking fails. A derived class may
175
177
  want to override this.
176
178
  """
177
179
  sys.exit (1)
178
180
  # end def lock_fail
179
181
 
180
- def unlock (self) :
181
- if self.need_unlock :
182
+ def unlock (self):
183
+ if self.need_unlock:
182
184
  os.unlink (self.lockfile)
183
185
  self.need_unlock = False # prevent second attempt at removal
184
186
  # end def unlock
185
187
  __del__ = unlock
186
188
 
187
- def __exit__ (self, tp, value, tb) :
188
- if tb :
189
+ def __exit__ (self, tp, value, tb):
190
+ if tb:
189
191
  self.log_exception ()
190
192
  # We do *not* return True, we didn't handle the exception
191
193
  # end def __exit__
192
194
 
193
- def __enter__ (self) :
195
+ def __enter__ (self):
194
196
  assert not self.need_unlock
195
197
  self.lock ()
196
198
  # end def __enter__
197
199
 
198
200
  # end class Lock_Mixin
199
201
 
200
- class Lock (Log, Lock_Mixin) :
202
+ class Lock (Log, Lock_Mixin):
201
203
 
202
- def __init__ (self, lockfile = None, ** kw) :
204
+ def __init__ (self, lockfile = None, ** kw):
203
205
  self.lockfile = lockfile
204
206
  prefix = None
205
- if lockfile :
207
+ if lockfile:
206
208
  prefix = lockfile.replace ('/', '-')
207
209
  self.__super.__init__ (do_lock = False, log_prefix = prefix, ** kw)
208
210
  # end def __init__
209
211
 
210
212
  # end class Lock
211
213
 
212
- def exitstatus (cmd, status) :
213
- if not status :
214
+ def exitstatus (cmd, status):
215
+ if not status:
214
216
  return ''
215
217
  sig = ''
216
- if os.WIFSIGNALED (status) :
218
+ if os.WIFSIGNALED (status):
217
219
  sig = " (caught signal %d)" % os.WTERMSIG (status)
218
220
  s = os.WEXITSTATUS (status)
219
- if not s : s = ''
221
+ if not s: s = ''
220
222
  return 'WARNING: %s returned nonzero exit status %s%s' % (cmd, s, sig)
221
223
  # end def exitstatus
222
224
 
223
- class Process (Log) :
225
+ class Process (Log):
224
226
  """ A process in a (multi-)pipe
225
227
  Note that the file descriptors can take several different
226
228
  values:
@@ -246,7 +248,7 @@ class Process (Log) :
246
248
  , close_stdout = False
247
249
  , close_stderr = False
248
250
  , **kw
249
- ) :
251
+ ):
250
252
  self.__super.__init__ (**kw)
251
253
  self.stdin = stdin
252
254
  self.stdout = stdout
@@ -272,20 +274,20 @@ class Process (Log) :
272
274
  # after forking off the child with the PIPE end.
273
275
  self.toclose = []
274
276
  self.sibling_files = []
275
- if not self.name :
277
+ if not self.name:
276
278
  self.name = self.clsname
277
279
  self.__super.__init__ (log_prefix = self.log_prefix, **kw)
278
280
  # end def __init__
279
281
 
280
- def fork (self) :
282
+ def fork (self):
281
283
  rclose = []
282
- if self.stdin == 'PIPE' :
284
+ if self.stdin == 'PIPE':
283
285
  pipe = os.pipe ()
284
286
  self.stdin = os.fdopen (pipe [0], 'r')
285
287
  self.stdin_w = os.fdopen (pipe [1], 'w')
286
288
  self.toclose.append (self.stdin_w)
287
289
  self.close_stdin = True
288
- if self.stdout == 'PIPE' :
290
+ if self.stdout == 'PIPE':
289
291
  pipe = os.pipe ()
290
292
  self.stdout = os.fdopen (pipe [1], 'w')
291
293
  # to close after fork:
@@ -293,40 +295,40 @@ class Process (Log) :
293
295
  self.stdout_r = os.fdopen (pipe [0], 'r')
294
296
  rclose.append (self.stdout_r)
295
297
  self.close_stdout = True
296
- elif self.close_stdout and self.stdout :
298
+ elif self.close_stdout and self.stdout:
297
299
  self.stdouts [self.stdout] = 0
298
- if self.stderr == 'PIPE' :
300
+ if self.stderr == 'PIPE':
299
301
  pipe = os.pipe ()
300
302
  self.stderr = os.fdopen (pipe [1], 'w')
301
303
  self.stderr_r = os.fdopen (pipe [0], 'r')
302
304
  rclose.append (self.stderr_r)
303
305
  self.close_stderr = True
304
306
  pid = os.fork ()
305
- if pid : # parent
307
+ if pid: # parent
306
308
  self.pid = pid
307
309
  self.log.debug ("fork: pid: %s" % self.pid)
308
310
  self.by_pid [pid] = self
309
- if self.stderr and self.close_stderr :
311
+ if self.stderr and self.close_stderr:
310
312
  self.log.debug \
311
313
  ("fork: closing stderr: %s" % self.stderr.fileno ())
312
314
  self.stderr.close ()
313
- if self.stdin and self.close_stdin :
315
+ if self.stdin and self.close_stdin:
314
316
  self.log.debug \
315
317
  ("fork: closing stdin: %s" % self.stdin.fileno ())
316
318
  self.stdin.close ()
317
- if hasattr (self, 'stdouts') :
318
- for f in self.stdouts :
319
+ if hasattr (self, 'stdouts'):
320
+ for f in self.stdouts:
319
321
  self.log.debug ("fork: aux closing: %s" % f.fileno ())
320
322
  f.close ()
321
- else : # child
322
- for f in self.sibling_files :
323
+ else: # child
324
+ for f in self.sibling_files:
323
325
  self.log.debug ("fork: child closing sibling: %s" % f.fileno ())
324
326
  f.close ()
325
- for f in self.toclose :
327
+ for f in self.toclose:
326
328
  self.log.debug ("fork: child closing toclose: %s" % f.fileno ())
327
329
  f.close ()
328
330
  # close children read descriptors in parent
329
- for c in self.children :
331
+ for c in self.children:
330
332
  self.log.debug \
331
333
  ( "closing stdin of %s->%s: %s"
332
334
  % (self.name, c.name, c.stdin.fileno ())
@@ -341,46 +343,46 @@ class Process (Log) :
341
343
  return rclose
342
344
  # end def fork
343
345
 
344
- def method (self) :
346
+ def method (self):
345
347
  raise NotImplementedError
346
348
  # end def method
347
349
 
348
- def redirect (self) :
350
+ def redirect (self):
349
351
  self.log.debug ("In redirect")
350
- if self.stdin :
352
+ if self.stdin:
351
353
  self.log.debug \
352
354
  ( "stdin dup2: %s->%s"
353
355
  % (self.stdin.fileno (), sys.stdin.fileno ())
354
356
  )
355
357
  os.dup2 (self.stdin.fileno (), sys.stdin.fileno ())
356
- if self.stdout :
358
+ if self.stdout:
357
359
  self.log.debug \
358
360
  ( "stdout dup2: %s->%s"
359
361
  % (self.stdout.fileno (), sys.stdout.fileno ())
360
362
  )
361
363
  os.dup2 (self.stdout.fileno (), sys.stdout.fileno ())
362
- if self.stderr :
364
+ if self.stderr:
363
365
  self.log.debug \
364
366
  ( "stderr dup2: %s->%s"
365
367
  % (self.stderr.fileno (), sys.stderr.fileno ()))
366
368
  os.dup2 (self.stderr.fileno (), sys.stderr.fileno ())
367
- if self.stdin :
369
+ if self.stdin:
368
370
  self.stdin.close ()
369
- elif self.close_stdin :
371
+ elif self.close_stdin:
370
372
  sys.stdin.close ()
371
- if self.stdout :
373
+ if self.stdout:
372
374
  self.stdout.close ()
373
- elif self.close_stdout :
375
+ elif self.close_stdout:
374
376
  sys.stdout.close ()
375
- if self.stderr :
377
+ if self.stderr:
376
378
  self.stderr.close ()
377
- elif self.close_stderr :
379
+ elif self.close_stderr:
378
380
  sys.stderr.close ()
379
381
  # end def redirect
380
382
 
381
- def run (self) :
383
+ def run (self):
382
384
  sibling_files = []
383
- for c in reversed (self.children) :
385
+ for c in reversed (self.children):
384
386
  pipe = os.pipe ()
385
387
  self.stdouts [os.fdopen (pipe [1], 'w')] = c
386
388
  c.stdin = os.fdopen (pipe [0], 'r')
@@ -393,9 +395,9 @@ class Process (Log) :
393
395
  c.sibling_files.extend (self.sibling_files)
394
396
  sibling_files.append (c.stdin)
395
397
  # For dup2 in redirect to do its job:
396
- if len (self.children) == 1 :
397
- self.stdout = self.stdouts.keys () [0]
398
- if self.stderr_child :
398
+ if len (self.children) == 1:
399
+ self.stdout = list (self.stdouts) [0]
400
+ if self.stderr_child:
399
401
  pipe = os.pipe ()
400
402
  self.stderr = os.fdopen (pipe [1], 'w')
401
403
  self.close_stderr = True
@@ -405,7 +407,7 @@ class Process (Log) :
405
407
  self.stderr_child.sibling_files.extend (self.sibling_files)
406
408
  self.children.insert (0, self.stderr_child)
407
409
  toclose = self.fork ()
408
- for child in self.children :
410
+ for child in self.children:
409
411
  self.log.debug \
410
412
  ( "passing toclose to %s: %s"
411
413
  % (child.name, [x.fileno () for x in self.toclose + toclose])
@@ -418,12 +420,12 @@ class Process (Log) :
418
420
  # end def run
419
421
 
420
422
  @classmethod
421
- def wait (cls) :
422
- while cls.by_pid :
423
+ def wait (cls):
424
+ while cls.by_pid:
423
425
  pid, status = os.wait ()
424
- if pid > 0 :
426
+ if pid > 0:
425
427
  process = cls.by_pid [pid]
426
- if status :
428
+ if status:
427
429
  process.log.info \
428
430
  ( "pid: %s: %s"
429
431
  % (pid, exitstatus (process.name, status))
@@ -432,53 +434,53 @@ class Process (Log) :
432
434
  del cls.by_pid [pid]
433
435
  # end def wait
434
436
 
435
- def _add_buffer_process (self, found = False) :
436
- if self.stderr == 'PIPE' :
437
+ def _add_buffer_process (self, found = False):
438
+ if self.stderr == 'PIPE':
437
439
  self.log.debug ("found stderr PIPE: %s", self.name)
438
- if found :
440
+ if found:
439
441
  self.stderr = None
440
442
  self.set_stderr_process (Buffer_Process (stderr = 'PIPE'))
441
443
  found = True
442
- if self.stdout == 'PIPE' :
444
+ if self.stdout == 'PIPE':
443
445
  self.log.debug ("found stdout PIPE: %s", self.name)
444
- if found :
446
+ if found:
445
447
  self.stdout = None
446
448
  self.append (Buffer_Process (stdout = 'PIPE'))
447
449
  found = True
448
- else :
449
- for c in self.children :
450
+ else:
451
+ for c in self.children:
450
452
  found = c._add_buffer_process (found)
451
453
  return found
452
454
  # end def _add_buffer_process
453
455
 
454
- def _read_outputs (self) :
456
+ def _read_outputs (self):
455
457
  stdout = ''
456
458
  stderr = ''
457
- if self.stderr_r :
459
+ if self.stderr_r:
458
460
  self.log.debug ("reading stderr: %s", self.name)
459
461
  stderr = self.stderr_r.read ()
460
- if self.stdout_r :
462
+ if self.stdout_r:
461
463
  self.log.debug ("reading stdout: %s", self.name)
462
464
  stdout = self.stdout_r.read ()
463
465
  sout_l = [stdout]
464
466
  serr_l = [stderr]
465
- for c in self.children :
467
+ for c in self.children:
466
468
  sout, serr = c._read_outputs ()
467
469
  sout_l.append (sout)
468
470
  serr_l.append (serr)
469
471
  return ''.join (sout_l), ''.join (serr_l)
470
472
  # end def _read_outputs
471
473
 
472
- def __repr__ (self) :
474
+ def __repr__ (self):
473
475
  r = []
474
476
  r.append ('%s:' % self.name)
475
- if self.stdin :
477
+ if self.stdin:
476
478
  r.append (' stdin set')
477
- if self.stdout :
479
+ if self.stdout:
478
480
  r.append (' stdout set')
479
- if self.stderr :
481
+ if self.stderr:
480
482
  r.append (' stderr set')
481
- if self.bufsize :
483
+ if self.bufsize:
482
484
  r.append (' bufsize = %s' % self.bufsize)
483
485
  return '\n'.join (r)
484
486
  # end def __repr__
@@ -486,80 +488,80 @@ class Process (Log) :
486
488
 
487
489
  # end class Process
488
490
 
489
- class Tee (Process) :
491
+ class Tee (Process):
490
492
  """ A tee in a pipe (like the unix command "tee" but copies to several
491
493
  sub-processes)
492
494
  """
493
- def __init__ (self, children, **kw) :
495
+ def __init__ (self, children, **kw):
494
496
  self.stdouts = {}
495
497
  self.__super.__init__ (**kw)
496
498
  self.children = children
497
499
  # end def __init__
498
500
 
499
- def method (self) :
500
- while 1 :
501
+ def method (self):
502
+ while 1:
501
503
  buf = sys.stdin.read (self.bufsize)
502
- if not buf :
504
+ if not buf:
503
505
  self.log.debug ("Tee: empty read, terminating")
504
506
  return
505
507
  # use items () here, we want to modify dict
506
508
  written = False
507
- for stdout, child in self.stdouts.items () :
508
- if not child :
509
+ for stdout, child in self.stdouts.items ():
510
+ if not child:
509
511
  continue
510
- try :
512
+ try:
511
513
  stdout.write (buf)
512
514
  written = True
513
515
  #self.log.debug ("written: %s" % len (buf))
514
- except IOError as cause :
516
+ except IOError as cause:
515
517
  # this client died, no longer try to send to it
516
- if cause.errno != errno.EPIPE :
518
+ if cause.errno != errno.EPIPE:
517
519
  raise
518
520
  self.log.debug ("%s: dead" % child.name)
519
521
  stdout.close ()
520
522
  del self.stdouts [stdout]
521
523
  # still clients existing?
522
- if not written :
523
- if len (self.stdouts) :
524
+ if not written:
525
+ if len (self.stdouts):
524
526
  self.log.err ("All children had sigpipe ?!?")
525
527
  return
526
528
  # end def method
527
529
 
528
530
  # end class Tee
529
531
 
530
- class Method_Process (Process) :
532
+ class Method_Process (Process):
531
533
  """ A process in a (multi-)pipe which runs a given method
532
534
  """
533
- def __init__ (self, name = None, **kw) :
535
+ def __init__ (self, name = None, **kw):
534
536
  self.tee = None
535
- if 'method' in kw :
537
+ if 'method' in kw:
536
538
  self.method = kw ['method']
537
539
  self.name = name
538
- if not self.name :
540
+ if not self.name:
539
541
  self.name = self.method.__name__
540
542
  self.__super.__init__ (name = self.name, **kw)
541
543
  # end def __init__
542
544
 
543
- def append (self, child) :
545
+ def append (self, child):
544
546
  assert self.stdout is None
545
547
  assert child.stdin is None
546
- if self.children :
548
+ if self.children:
547
549
  assert len (self.children) == 1
548
- if not self.tee :
550
+ if not self.tee:
549
551
  self.tee = Tee \
550
552
  (self.children, bufsize = self.bufsize)
551
553
  self.children = [self.tee]
552
554
  self.tee.children.append (child)
553
- else :
555
+ else:
554
556
  self.children.append (child)
555
557
  # end def append
556
558
 
557
- def communicate (self, input = None) :
559
+ def communicate (self, input = None):
558
560
  assert input is None or self.stdin == 'PIPE'
559
561
  p = self
560
- if self.stdin == 'PIPE' :
562
+ if self.stdin == 'PIPE':
561
563
  self.stdin = None
562
- if self.input is not None :
564
+ if self.input is not None:
563
565
  p = Echo_Process (message = str (input))
564
566
  p.append (self)
565
567
  # Add a Buffer_Process for each PIPE output in tree order.
@@ -572,7 +574,7 @@ class Method_Process (Process) :
572
574
  return stdout, stderr
573
575
  # end def communicate
574
576
 
575
- def set_stderr_process (self, child) :
577
+ def set_stderr_process (self, child):
576
578
  assert self.stderr is None
577
579
  assert self.stderr_child is None
578
580
  assert child.stdin is None
@@ -581,22 +583,22 @@ class Method_Process (Process) :
581
583
 
582
584
  # end class Method_Process
583
585
 
584
- class Buffer_Process (Method_Process) :
586
+ class Buffer_Process (Method_Process):
585
587
  """ First read *everything* from stdin, then write this to stdout.
586
588
  So everything is buffered in-memory. Used to decouple reading
587
589
  from multiple streams.
588
590
  """
589
591
 
590
- def __init__ (self, ** kw) :
592
+ def __init__ (self, ** kw):
591
593
  self.__super.__init__ (method = self.copy, ** kw)
592
- if self.stdout == 'PIPE' :
594
+ if self.stdout == 'PIPE':
593
595
  self.io = sys.stdout
594
- else :
596
+ else:
595
597
  assert self.stderr == 'PIPE'
596
598
  self.io = sys.stderr
597
599
  # end def __init__
598
600
 
599
- def copy (self) :
601
+ def copy (self):
600
602
  buf = sys.stdin.read ()
601
603
  self.log.debug ("read: %s" % len (buf))
602
604
  self.log.debug ("write: fd=%s" % self.io.fileno ())
@@ -606,12 +608,12 @@ class Buffer_Process (Method_Process) :
606
608
 
607
609
  # end class Buffer_Process
608
610
 
609
- class Echo_Process (Method_Process) :
611
+ class Echo_Process (Method_Process):
610
612
  """ Simply echo a message given in constructor to stdout.
611
613
  Useful for specifying a constant input to a pipeline.
612
614
  """
613
615
 
614
- def __init__ (self, message, ** kw) :
616
+ def __init__ (self, message, ** kw):
615
617
  self.message = message
616
618
  self.__super.__init__ \
617
619
  ( method = self.echo
@@ -620,40 +622,40 @@ class Echo_Process (Method_Process) :
620
622
  )
621
623
  # end def __init__
622
624
 
623
- def echo (self) :
625
+ def echo (self):
624
626
  sys.stdout.write (self.message)
625
627
  # end def echo
626
628
 
627
629
  # end class Echo_Process
628
630
 
629
- class Exec_Process (Method_Process) :
631
+ class Exec_Process (Method_Process):
630
632
  """ Process that execs a subcommand """
631
- def __init__ (self, cmd, args = None, name = None, **kw) :
633
+ def __init__ (self, cmd, args = None, name = None, **kw):
632
634
  self.cmd = cmd
633
635
  self.args = args
634
- if not args :
636
+ if not args:
635
637
  self.args = [cmd]
636
- if not name :
638
+ if not name:
637
639
  name = self.cmd
638
640
  self.__super.__init__ (name = name, **kw)
639
641
  # end def __init__
640
642
 
641
- def method (self) :
643
+ def method (self):
642
644
  os.execv (self.cmd, self.args)
643
645
  # end def method
644
646
 
645
- def __repr__ (self) :
647
+ def __repr__ (self):
646
648
  r = [self.__super.__repr__ ()]
647
649
  r.append (' cmd = %s' % self.cmd)
648
650
  r.append (' args =')
649
- for a in self.args :
651
+ for a in self.args:
650
652
  r.append (' %s' % a)
651
653
  return '\n'.join (r)
652
654
  # end def __repr__
653
655
 
654
656
  # end class Exec_Process
655
657
 
656
- def run_process (cmd, ** kw) :
658
+ def run_process (cmd, ** kw):
657
659
  """ Convenience function that sets up a single Exec_Process, calls
658
660
  it, and returns a suitable error message if any.
659
661
  """