]> scripts.mit.edu Git - wizard.git/blobdiff - wizard/shell.py
Update TODO.
[wizard.git] / wizard / shell.py
index 8660d1ade198840e5c15d79ee1abb8fcdf30ff14..1ee9bfadf04fa2a542a44a65d1ed456004a638db 100644 (file)
@@ -87,8 +87,7 @@ class Shell(object):
         >>> sh.call("cat", input='Foobar')
         ('Foobar', '')
         """
-        if hasattr(self, "_wait"):
-            self._wait()
+        self._wait()
         kwargs.setdefault("interactive", False)
         kwargs.setdefault("strip", False)
         kwargs.setdefault("python", None)
@@ -129,10 +128,15 @@ class Shell(object):
         # SIGCHILD handler to write a single byte to the pipe to get
         # us out of select() when a subprocess exits.
         proc = subprocess.Popen(args, stdout=stdout, stderr=stderr, stdin=stdin)
-        if hasattr(self, "_async"):
-            self._async(proc, args, **kwargs)
+        if self._async(proc, args, **kwargs):
             return proc
         stdout, stderr = proc.communicate(kwargs["input"])
+        # can occur if we were doing interactive communication; i.e.
+        # we didn't pass in PIPE.
+        if stdout is None:
+            stdout = ""
+        if stderr is None:
+            stderr = ""
         if not kwargs["interactive"]:
             if kwargs["strip"]:
                 self._log(None, stderr)
@@ -143,7 +147,7 @@ class Shell(object):
             else: eclass = CallError
             raise eclass(proc.returncode, args, stdout, stderr)
         if kwargs["strip"]:
-            return stdout.rstrip("\n")
+            return str(stdout).rstrip("\n")
         return (stdout, stderr)
     def _log(self, stdout, stderr):
         """Logs the standard output and standard input from a command."""
@@ -151,6 +155,10 @@ class Shell(object):
             logging.debug("STDOUT:\n" + stdout)
         if stderr:
             logging.debug("STDERR:\n" + stderr)
+    def _wait(self):
+        pass
+    def _async(self, *args, **kwargs):
+        return False
     def callAsUser(self, *args, **kwargs):
         """
         Performs a system call as a different user.  This is only possible
@@ -265,6 +273,7 @@ class ParallelShell(Shell):
         execution.  See :meth:`Shell.call` source code for details.
         """
         self.running[proc.pid] = (proc, args, python, on_success, on_error)
+        return True # so that the parent function returns
     def _wait(self):
         """
         Blocking call that waits for an open subprocess slot.  This is
@@ -304,6 +313,12 @@ class ParallelShell(Shell):
             return
         on_success(stdout, stderr)
 
+# Setup a convenience global instance
+shell = Shell()
+call = shell.call
+callAsUser = shell.callAsUser
+safeCall = shell.safeCall
+eval = shell.eval
 
 class DummyParallelShell(ParallelShell):
     """Same API as :class:`ParallelShell`, but doesn't actually