git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[StGIT PATCH 1/4] Refactor output handling to break circular dependency

From
Karl Hasselström <kha@treskal.com>
Date
Aug 26, 2007, 20:33 UTC
Message-ID
<20070826203327.16265.62636.stgit@yoghurt>
In-Reply-To
<20070826202724.16265.85821.stgit@yoghurt>

I ran into problems when trying to use the fancy output handling in a new module that was (recursively) imported by stgit.util -- I couldn't use the out object because it wasn't defined yet.

Break out the output handler to its own module to break the circular dependency.

Signed-off-by: Karl Hasselström <kha@treskal.com>
---
 stgit/commands/applied.py    |    1 
 stgit/commands/assimilate.py |    1 
 stgit/commands/branch.py     |    1 
 stgit/commands/clean.py      |    1 
 stgit/commands/commit.py     |    1 
 stgit/commands/common.py     |    1 
 stgit/commands/delete.py     |    1 
 stgit/commands/diff.py       |    1 
 stgit/commands/export.py     |    1 
 stgit/commands/files.py      |    1 
 stgit/commands/fold.py       |    1 
 stgit/commands/hide.py       |    1 
 stgit/commands/id.py         |    1 
 stgit/commands/imprt.py      |    1 
 stgit/commands/log.py        |    1 
 stgit/commands/mail.py       |    1 
 stgit/commands/patches.py    |    1 
 stgit/commands/pick.py       |    1 
 stgit/commands/pull.py       |    1 
 stgit/commands/push.py       |    1 
 stgit/commands/refresh.py    |    1 
 stgit/commands/rename.py     |    1 
 stgit/commands/series.py     |    1 
 stgit/commands/sync.py       |    1 
 stgit/commands/top.py        |    1 
 stgit/commands/unapplied.py  |    1 
 stgit/commands/uncommit.py   |    1 
 stgit/commands/unhide.py     |    1 
 stgit/git.py                 |    1 
 stgit/gitmergeonefile.py     |    3 +
 stgit/main.py                |    2 -
 stgit/out.py                 |  100 ++++++++++++++++++++++++++++++++++++++++++
 stgit/stack.py               |    1 
 stgit/utils.py               |   81 ----------------------------------
 34 files changed, 134 insertions(+), 82 deletions(-)
diff --git a/stgit/commands/applied.py b/stgit/commands/applied.py
index 0925de0..b9bb716 100644
--- a/stgit/commands/applied.py
+++ b/stgit/commands/applied.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/assimilate.py b/stgit/commands/assimilate.py
index 5134e34..c5f4340 100644
--- a/stgit/commands/assimilate.py
+++ b/stgit/commands/assimilate.py
@@ -22,6 +22,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 help = 'StGIT-ify any GIT commits made on top of your StGIT stack'
diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index 75a9046..2d491d5 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -23,6 +23,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git, basedir
 
 
diff --git a/stgit/commands/clean.py b/stgit/commands/clean.py
index 7b57526..2e3b202 100644
--- a/stgit/commands/clean.py
+++ b/stgit/commands/clean.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/commit.py b/stgit/commands/commit.py
index 2b8d7ce..0b76c56 100644
--- a/stgit/commands/commit.py
+++ b/stgit/commands/commit.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 help = 'permanently store the applied patches into stack base'
diff --git a/stgit/commands/common.py b/stgit/commands/common.py
index dddee85..f3fa89d 100644
--- a/stgit/commands/common.py
+++ b/stgit/commands/common.py
@@ -22,6 +22,7 @@ import sys, os, os.path, re
 from optparse import OptionParser, make_option
 
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git, basedir
 from stgit.config import config, file_extensions
 
diff --git a/stgit/commands/delete.py b/stgit/commands/delete.py
index a9e2744..2121015 100644
--- a/stgit/commands/delete.py
+++ b/stgit/commands/delete.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py
index f8b19f8..aeca4ab 100644
--- a/stgit/commands/diff.py
+++ b/stgit/commands/diff.py
@@ -22,6 +22,7 @@ from pydoc import pager
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index 8424f9d..5ca07d3 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -23,6 +23,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git, templates
 
 
diff --git a/stgit/commands/files.py b/stgit/commands/files.py
index 659a82b..1a10023 100644
--- a/stgit/commands/files.py
+++ b/stgit/commands/files.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/fold.py b/stgit/commands/fold.py
index 297dfbf..d97185e 100644
--- a/stgit/commands/fold.py
+++ b/stgit/commands/fold.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/hide.py b/stgit/commands/hide.py
index 39cbd67..de19c19 100644
--- a/stgit/commands/hide.py
+++ b/stgit/commands/hide.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/id.py b/stgit/commands/id.py
index 8c717e8..f72d2f3 100644
--- a/stgit/commands/id.py
+++ b/stgit/commands/id.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py
index 98fe708..57bf2c8 100644
--- a/stgit/commands/imprt.py
+++ b/stgit/commands/imprt.py
@@ -23,6 +23,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/log.py b/stgit/commands/log.py
index ebd8cab..4d6b022 100644
--- a/stgit/commands/log.py
+++ b/stgit/commands/log.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 from pydoc import pager
 from stgit.commands.common import *
 from stgit import stack, git
+from stgit.out import *
 
 help = 'display the patch changelog'
 usage = """%prog [options] [patch]
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 71a6e4e..6202fc5 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git, version, templates
 from stgit.config import config
 
diff --git a/stgit/commands/patches.py b/stgit/commands/patches.py
index 23b3aa7..b3defb6 100644
--- a/stgit/commands/patches.py
+++ b/stgit/commands/patches.py
@@ -21,6 +21,7 @@ from pydoc import pager
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/pick.py b/stgit/commands/pick.py
index 27fdf9c..1c3ef11 100644
--- a/stgit/commands/pick.py
+++ b/stgit/commands/pick.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 from stgit.stack import Series
 
diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index fe3b67d..ad485a5 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit.config import GitConfigException
 from stgit import stack, git
 
diff --git a/stgit/commands/push.py b/stgit/commands/push.py
index 17b32f6..53cdb8f 100644
--- a/stgit/commands/push.py
+++ b/stgit/commands/push.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index 8277388..218075b 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 from stgit.config import config
 
diff --git a/stgit/commands/rename.py b/stgit/commands/rename.py
index d6c53be..2830e72 100644
--- a/stgit/commands/rename.py
+++ b/stgit/commands/rename.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/series.py b/stgit/commands/series.py
index 9e0b0ff..00a3372 100644
--- a/stgit/commands/series.py
+++ b/stgit/commands/series.py
@@ -22,6 +22,7 @@ from optparse import OptionParser, make_option
 import stgit.commands.common
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/sync.py b/stgit/commands/sync.py
index 5e33324..580b5bd 100644
--- a/stgit/commands/sync.py
+++ b/stgit/commands/sync.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 import stgit.commands.common
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/top.py b/stgit/commands/top.py
index 7cc92ca..1a9267a 100644
--- a/stgit/commands/top.py
+++ b/stgit/commands/top.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/unapplied.py b/stgit/commands/unapplied.py
index 0d330a1..c6408a3 100644
--- a/stgit/commands/unapplied.py
+++ b/stgit/commands/unapplied.py
@@ -21,6 +21,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py
index f611d29..e3bf0d8 100644
--- a/stgit/commands/uncommit.py
+++ b/stgit/commands/uncommit.py
@@ -22,6 +22,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 help = 'turn regular GIT commits into StGIT patches'
diff --git a/stgit/commands/unhide.py b/stgit/commands/unhide.py
index b6a2297..0a1dcaf 100644
--- a/stgit/commands/unhide.py
+++ b/stgit/commands/unhide.py
@@ -20,6 +20,7 @@ from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
 from stgit.utils import *
+from stgit.out import *
 from stgit import stack, git
 
 
diff --git a/stgit/git.py b/stgit/git.py
index 14b4c81..827bd61 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -23,6 +23,7 @@ from shutil import copyfile
 
 from stgit import basedir
 from stgit.utils import *
+from stgit.out import *
 from stgit.config import config
 from sets import Set
 
diff --git a/stgit/gitmergeonefile.py b/stgit/gitmergeonefile.py
index 5e51b8a..e76f9b1 100644
--- a/stgit/gitmergeonefile.py
+++ b/stgit/gitmergeonefile.py
@@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 import sys, os
 from stgit import basedir
 from stgit.config import config, file_extensions, ConfigOption
-from stgit.utils import append_string, out
+from stgit.utils import append_string
+from stgit.out import *
 
 
 class GitMergeException(Exception):
diff --git a/stgit/main.py b/stgit/main.py
index 2390110..5b9d7c4 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -22,7 +22,7 @@ import sys, os
 from optparse import OptionParser
 
 import stgit.commands
-from stgit.utils import out
+from stgit.out import *
 
 #
 # The commands map
diff --git a/stgit/out.py b/stgit/out.py
new file mode 100644
index 0000000..f80daf2
--- /dev/null
+++ b/stgit/out.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+__copyright__ = """
+Copyright (C) 2007, Karl Hasselström <kha@treskal.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import sys
+
+class MessagePrinter(object):
+    def __init__(self):
+        class Output(object):
+            def __init__(self, write, flush):
+                self.write = write
+                self.flush = flush
+                self.at_start_of_line = True
+                self.level = 0
+            def new_line(self):
+                """Ensure that we're at the beginning of a line."""
+                if not self.at_start_of_line:
+                    self.write('\n')
+                    self.at_start_of_line = True
+            def single_line(self, msg, print_newline = True,
+                            need_newline = True):
+                """Write a single line. Newline before and after are
+                separately configurable."""
+                if need_newline:
+                    self.new_line()
+                if self.at_start_of_line:
+                    self.write('  '*self.level)
+                self.write(msg)
+                if print_newline:
+                    self.write('\n')
+                    self.at_start_of_line = True
+                else:
+                    self.flush()
+                    self.at_start_of_line = False
+            def tagged_lines(self, tag, lines):
+                tag += ': '
+                for line in lines:
+                    self.single_line(tag + line)
+                    tag = ' '*len(tag)
+            def write_line(self, line):
+                """Write one line of text on a lines of its own, not
+                indented."""
+                self.new_line()
+                self.write('%s\n' % line)
+                self.at_start_of_line = True
+            def write_raw(self, string):
+                """Write an arbitrary string, possibly containing
+                newlines."""
+                self.new_line()
+                self.write(string)
+                self.at_start_of_line = string.endswith('\n')
+        self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
+        if sys.stdout.isatty():
+            self.__out = self.__stdout
+        else:
+            self.__out = Output(lambda msg: None, lambda: None)
+    def stdout(self, line):
+        """Write a line to stdout."""
+        self.__stdout.write_line(line)
+    def stdout_raw(self, string):
+        """Write a string possibly containing newlines to stdout."""
+        self.__stdout.write_raw(string)
+    def info(self, *msgs):
+        for msg in msgs:
+            self.__out.single_line(msg)
+    def note(self, *msgs):
+        self.__out.tagged_lines('Notice', msgs)
+    def warn(self, *msgs):
+        self.__out.tagged_lines('Warning', msgs)
+    def error(self, *msgs):
+        self.__out.tagged_lines('Error', msgs)
+    def start(self, msg):
+        """Start a long-running operation."""
+        self.__out.single_line('%s ... ' % msg, print_newline = False)
+        self.__out.level += 1
+    def done(self, extramsg = None):
+        """Finish long-running operation."""
+        self.__out.level -= 1
+        if extramsg:
+            msg = 'done (%s)' % extramsg
+        else:
+            msg = 'done'
+        self.__out.single_line(msg, need_newline = False)
+
+out = MessagePrinter()
diff --git a/stgit/stack.py b/stgit/stack.py
index 1ab10c5..12c5091 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 import sys, os, re
 
 from stgit.utils import *
+from stgit.out import *
 from stgit import git, basedir, templates
 from stgit.config import config
 from shutil import copyfile
diff --git a/stgit/utils.py b/stgit/utils.py
index 039b433..38dd474 100644
--- a/stgit/utils.py
+++ b/stgit/utils.py
@@ -3,6 +3,7 @@
 
 import errno, os, os.path, re, sys
 from stgit.config import config
+from stgit.out import *
 
 __copyright__ = """
 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
@@ -21,86 +22,6 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-class MessagePrinter(object):
-    def __init__(self):
-        class Output(object):
-            def __init__(self, write, flush):
-                self.write = write
-                self.flush = flush
-                self.at_start_of_line = True
-                self.level = 0
-            def new_line(self):
-                """Ensure that we're at the beginning of a line."""
-                if not self.at_start_of_line:
-                    self.write('\n')
-                    self.at_start_of_line = True
-            def single_line(self, msg, print_newline = True,
-                            need_newline = True):
-                """Write a single line. Newline before and after are
-                separately configurable."""
-                if need_newline:
-                    self.new_line()
-                if self.at_start_of_line:
-                    self.write('  '*self.level)
-                self.write(msg)
-                if print_newline:
-                    self.write('\n')
-                    self.at_start_of_line = True
-                else:
-                    self.flush()
-                    self.at_start_of_line = False
-            def tagged_lines(self, tag, lines):
-                tag += ': '
-                for line in lines:
-                    self.single_line(tag + line)
-                    tag = ' '*len(tag)
-            def write_line(self, line):
-                """Write one line of text on a lines of its own, not
-                indented."""
-                self.new_line()
-                self.write('%s\n' % line)
-                self.at_start_of_line = True
-            def write_raw(self, string):
-                """Write an arbitrary string, possibly containing
-                newlines."""
-                self.new_line()
-                self.write(string)
-                self.at_start_of_line = string.endswith('\n')
-        self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
-        if sys.stdout.isatty():
-            self.__out = self.__stdout
-        else:
-            self.__out = Output(lambda msg: None, lambda: None)
-    def stdout(self, line):
-        """Write a line to stdout."""
-        self.__stdout.write_line(line)
-    def stdout_raw(self, string):
-        """Write a string possibly containing newlines to stdout."""
-        self.__stdout.write_raw(string)
-    def info(self, *msgs):
-        for msg in msgs:
-            self.__out.single_line(msg)
-    def note(self, *msgs):
-        self.__out.tagged_lines('Notice', msgs)
-    def warn(self, *msgs):
-        self.__out.tagged_lines('Warning', msgs)
-    def error(self, *msgs):
-        self.__out.tagged_lines('Error', msgs)
-    def start(self, msg):
-        """Start a long-running operation."""
-        self.__out.single_line('%s ... ' % msg, print_newline = False)
-        self.__out.level += 1
-    def done(self, extramsg = None):
-        """Finish long-running operation."""
-        self.__out.level -= 1
-        if extramsg:
-            msg = 'done (%s)' % extramsg
-        else:
-            msg = 'done'
-        self.__out.single_line(msg, need_newline = False)
-
-out = MessagePrinter()
-
 def mkdir_file(filename, mode):
     """Opens filename with the given mode, creating the directory it's
     in if it doesn't already exist."""
Previous: Karl HasselströmNext: Karl Hasselström
Message 2 of 14 in “Clean up subprocess calling”
  1. 0/4 Clean up subprocess callingKarl Hasselström, Aug 26, 2007
  2. 1/4 Refactor output handling to break circular dependencyKarl Hasselström, Aug 26, 2007
  3. 2/4 Refactor subprocess creationKarl Hasselström, Aug 26, 2007
  4. 3/4 Assert that the argument to Run is a sequence of stringsKarl Hasselström, Aug 26, 2007
  5. 4/4 Add optional logging of subprocess executionKarl Hasselström, Aug 26, 2007
  6. Catalin MarinasAug 29, 2007
  7. Karl HasselströmAug 29, 2007
  8. Karl HasselströmAug 29, 2007
  9. Catalin MarinasSep 3, 2007
  10. Catalin MarinasSep 3, 2007
  11. Karl HasselströmSep 3, 2007
  12. 0/2 Break Python 2.3 compatibilityKarl Hasselström, Sep 3, 2007
  13. 1/2 Use subprocess.Popen to call git executablesKarl Hasselström, Sep 3, 2007
  14. 2/2 Use the builtin set() instead of sets.Set()Karl Hasselström, Sep 3, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.