lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Gettexted messages encoding with Python 2.5


From: John Mandereau
Subject: [PATCH] Gettexted messages encoding with Python 2.5
Date: Tue, 03 Jul 2007 01:47:36 +0200

Hi,

I've hit character encoding issues when calling lilypond-book compiled
locally.  It seems that optparse implementation has changed between
Python 2.4 and 2.5 in a way that OptionParser.print_help wants to
convert string encoding before writing to stdout.  The problem is,
Python knows only two internal string encodings: ASCII and Unicode --
and the encoding used to store Unicode strings is not always UTF-8 (it
is not on my Linux box).  Strings outputted by gettext (or lgettext)
have no particular encoding for Python, so Python assumes ASCII; as
these strings are actually in UTF-8, the following call (in
OptionParser.print_help) crashes:

file.write(self.format_help().encode(encoding, "replace"))

In lilypond-book/convert-ly, file is sys.stderr, and encoding is defined
with file.encoding, which is 'UTF-8' on my computer.

To fix this, we must use ugettext instead of gettext in lilylib.py.
Unfortunately, this fix implies that each gettexted string must be
converted from Python internal Unicode to stdout/stderr encoding before
being written to stdout/stderr.

May I commit and push the following patch, that intends to solve all
problems above?
I've tested it with my default locale (fr_FR.UTF-8) and also
fr_FR.ISO-8859-1: all sorts of messages given by
'lilypond-book --help', 'lilypond-book -w' and
'lilypond-book this-file-dont-exist.tely' look good.


diff --git a/python/lilylib.py b/python/lilylib.py
index 156c9b7..6e613c0 100644
--- a/python/lilylib.py
+++ b/python/lilylib.py
@@ -43,14 +43,17 @@ sys.path.insert (0, os.path.join (datadir,
'python'))
 localedir = '@localedir@'
 try:
     import gettext
-    gettext.bindtextdomain ('lilypond', localedir)
-    gettext.textdomain ('lilypond')
-    _ = gettext.gettext
+    t = gettext.translation ('lilypond', localedir)
+    _ = t.ugettext
 except:
     def _ (s):
        return s
 underscore = _
-progress = sys.stderr.write 
+
+def stderr_write (s):
+    sys.stderr.write (s.encode (sys.stderr.encoding))
+
+progress = stderr_write
 
 # Modified version of the commands.mkarg(x), which always uses 
 # double quotes (since Windows can't handle the single quotes:
diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py
index cf67f9f..22baa15 100644
--- a/scripts/convert-ly.py
+++ b/scripts/convert-ly.py
@@ -43,11 +43,17 @@ copyright = ('Jan Nieuwenhuizen <address@hidden>',
 program_name = os.path.basename (sys.argv[0])
 program_version = '@TOPLEVEL_VERSION@'
 
+# This is necessary to output Unicode gettexted messages
+def stderr_write (s):
+    sys.stderr.write (s.encode (sys.stderr.encoding))
+def stdout_write (s):
+    sys.stdout.write (s.encode (sys.stdout.encoding))
+
 def warning (s):
-    sys.stderr.write (program_name + ": " + _ ("warning: %s") % s +
'\n')
+    stderr_write (program_name + ": " + _ ("warning: %s") % s + '\n')
 
 def error (s):
-    sys.stderr.write (program_name + ": " + _ ("error: %s") % s + '\n')
+    stderr_write (program_name + ": " + _ ("error: %s") % s + '\n')
 
 def identify (port=sys.stderr):
     port.write ('%s (GNU LilyPond) %s\n' % (program_name,
program_version))
@@ -178,8 +184,8 @@ class UnknownVersion:
     pass
 
 def do_one_file (infile_name):
-    sys.stderr.write (_ ("Processing `%s\'... ") % infile_name)
-    sys.stderr.write ('\n')
+    stderr_write (_ ("Processing `%s\'... ") % infile_name)
+    stderr_write ('\n')
 
     from_version = None
     to_version = None
@@ -274,6 +280,6 @@ def main ():
         except UnknownVersion:
             error (_ ("cannot determine version for `%s'.  Skipping") %
f)
 
-    sys.stderr.write ('\n')
+    stderr_write ('\n')
 
 main ()
diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py
index 2ff452f..91dfd6f 100644
--- a/scripts/lilypond-book.py
+++ b/scripts/lilypond-book.py
@@ -73,17 +73,23 @@ def exit (i):
     else:
         sys.exit (i)
 
+# This is necessary to output Unicode gettexted messages
+def stderr_write (s):
+    sys.stderr.write (s.encode (sys.stderr.encoding))
+def stdout_write (s):
+    sys.stdout.write (s.encode (sys.stdout.encoding))
+
 def identify ():
     sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name,
program_version))
 
 def progress (s):
-    sys.stderr.write (s)
+    stderr_write (s)
 
 def warning (s):
-    sys.stderr.write (program_name + ": " + _ ("warning: %s") % s +
'\n')
+    stderr_write (program_name + ": " + _ ("warning: %s") % s + '\n')
 
 def error (s):
-    sys.stderr.write (program_name + ": " + _ ("error: %s") % s + '\n')
+    stderr_write (program_name + ": " + _ ("error: %s") % s + '\n')
 
 def ps_page_count (ps_name):
     header = open (ps_name).read (1024)
@@ -94,7 +100,7 @@ def ps_page_count (ps_name):
 
 def warranty ():
     identify ()
-    sys.stdout.write ('''
+    stdout_write ('''
 %s
 
 %s
@@ -1398,8 +1404,8 @@ def filter_pipe (input, cmd):
         exit_status = status >> 8
         error (_ ("`%s' failed (%d)") % (cmd, exit_status))
         error (_ ("The error log is as follows:"))
-        sys.stderr.write (error)
-        sys.stderr.write (stderr.read ())
+        stderr_write (error)
+        stderr_write (stderr.read ())
         exit (status)
 
     if global_options.verbose:






reply via email to

[Prev in Thread] Current Thread [Next in Thread]