[gobject-introspection] giscanner: Use StringIO instead of cStringIO in Python 2



commit 0211bda3da384818c0f99b5a468022c7529fed7e
Author: Simon Feltman <sfeltman src gnome org>
Date:   Mon Apr 28 23:35:41 2014 -0700

    giscanner: Use StringIO instead of cStringIO in Python 2
    
    Replace usage of the Python 2 cStringIO module with StringIO and
    conditionally use io.StringIO for Python 3. This is needed to build
    up a unicode version of the XML since cStringIO does not support
    unicode. Add XMLWriter.get_encoded_xml() which returns a utf-8 encoded
    bytes object of the XML data.
    Open files for reading/writing in binary mode since we explicitly
    encode and decode as utf-8.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679438

 giscanner/scannermain.py |   11 ++++++-----
 giscanner/testcodegen.py |    8 +++++++-
 giscanner/xmlwriter.py   |   27 +++++++++++++++++++++------
 3 files changed, 34 insertions(+), 12 deletions(-)
---
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 4d2fcbf..b1b0ff6 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -255,7 +255,7 @@ def passthrough_gir(path, f):
     parser.parse(path)
 
     writer = GIRWriter(parser.get_namespace())
-    f.write(writer.get_xml())
+    f.write(writer.get_encoded_xml())
 
 
 def test_codegen(optstring,
@@ -444,15 +444,16 @@ def create_source_scanner(options, args):
 
 
 def write_output(data, options):
+    """Write encoded XML 'data' to the filename specified in 'options'."""
     if options.output == "-":
         output = sys.stdout
     elif options.reparse_validate_gir:
         main_f, main_f_name = tempfile.mkstemp(suffix='.gir')
-        with os.fdopen(main_f, 'w') as main_f:
+        with os.fdopen(main_f, 'wb') as main_f:
             main_f.write(data)
 
         temp_f, temp_f_name = tempfile.mkstemp(suffix='.gir')
-        with os.fdopen(temp_f, 'w') as temp_f:
+        with os.fdopen(temp_f, 'wb') as temp_f:
             passthrough_gir(main_f_name, temp_f)
         if not utils.files_are_identical(main_f_name, temp_f_name):
             _error("Failed to re-parse gir file; scanned='%s' passthrough='%s'" % (
@@ -468,7 +469,7 @@ def write_output(data, options):
         return 0
     else:
         try:
-            output = open(options.output, "w")
+            output = open(options.output, 'wb')
         except IOError as e:
             _error("opening output for writing: %s" % (e.strerror, ))
 
@@ -564,7 +565,7 @@ def scanner_main(args):
     transformer.namespace.c_includes = options.c_includes
     transformer.namespace.exported_packages = exported_packages
     writer = Writer(transformer.namespace)
-    data = writer.get_xml()
+    data = writer.get_encoded_xml()
 
     write_output(data, options)
 
diff --git a/giscanner/testcodegen.py b/giscanner/testcodegen.py
index 35b6d45..30e508e 100644
--- a/giscanner/testcodegen.py
+++ b/giscanner/testcodegen.py
@@ -23,7 +23,13 @@ from __future__ import division
 from __future__ import print_function
 from __future__ import unicode_literals
 
-from StringIO import StringIO
+import sys
+
+if sys.version_info.major < 3:
+    from StringIO import StringIO
+else:
+    from io import StringIO
+
 from . import ast
 from .codegen import CCodeGenerator
 
diff --git a/giscanner/xmlwriter.py b/giscanner/xmlwriter.py
index 851c4c0..54419f7 100755
--- a/giscanner/xmlwriter.py
+++ b/giscanner/xmlwriter.py
@@ -25,13 +25,19 @@ from __future__ import print_function
 from __future__ import unicode_literals
 
 import os
+import sys
 
 from contextlib import contextmanager
-from cStringIO import StringIO
 from xml.sax.saxutils import escape
 
 from .libtoolimporter import LibtoolImporter
 
+if sys.version_info.major < 3:
+    from StringIO import StringIO
+else:
+    from io import StringIO
+    unicode = str
+
 
 with LibtoolImporter(None, None):
     if 'UNINSTALLED_INTROSPECTION_SRCDIR' in os.environ:
@@ -62,8 +68,12 @@ def build_xml_tag(tag_name, attributes=None, data=None, self_indent=0,
 class XMLWriter(object):
 
     def __init__(self):
+        # Build up the XML buffer as unicode strings. When writing to disk,
+        # we can assume the lack of a Byte Order Mark (BOM) and lack
+        # of an "encoding" xml property means utf-8.
+        # See: http://www.opentag.com/xfaq_enc.htm#enc_default
         self._data = StringIO()
-        self._data.write(b'<?xml version="1.0"?>\n')
+        self._data.write('<?xml version="1.0"?>\n')
         self._tag_stack = []
         self._indent = 0
         self._indent_unit = 2
@@ -92,8 +102,13 @@ class XMLWriter(object):
         self._newline_char = ''
 
     def get_xml(self):
+        """Returns a unicode string containing the XML."""
         return self._data.getvalue()
 
+    def get_encoded_xml(self):
+        """Returns a utf-8 encoded bytes object containing the XML."""
+        return self._data.getvalue().encode('utf-8')
+
     def write_line(self, line='', indent=True, do_escape=False):
         if isinstance(line, bytes):
             line = line.decode('utf-8')
@@ -101,11 +116,11 @@ class XMLWriter(object):
         if do_escape:
             line = escape(line)
         if indent:
-            self._data.write(('%s%s%s' % (self._indent_char * self._indent,
-                                          line,
-                                          self._newline_char)).encode('UTF-8'))
+            self._data.write('%s%s%s' % (self._indent_char * self._indent,
+                                         line,
+                                         self._newline_char))
         else:
-            self._data.write(('%s%s' % (line, self._newline_char)).encode('UTF-8'))
+            self._data.write('%s%s' % (line, self._newline_char))
 
     def write_comment(self, text):
         self.write_line('<!-- %s -->' % (text, ))


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