Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/xml/sax/saxutils.py

    r2 r391  
    55
    66import os, urlparse, urllib, types
     7import io
     8import sys
    79import handler
    810import xmlreader
     
    1214except AttributeError:
    1315    _StringTypes = [types.StringType]
    14 
    15 # See whether the xmlcharrefreplace error handler is
    16 # supported
    17 try:
    18     from codecs import xmlcharrefreplace_errors
    19     _error_handling = "xmlcharrefreplace"
    20     del xmlcharrefreplace_errors
    21 except ImportError:
    22     _error_handling = "strict"
    2316
    2417def __dict_replace(s, d):
     
    8275
    8376
     77def _gettextwriter(out, encoding):
     78    if out is None:
     79        import sys
     80        out = sys.stdout
     81
     82    if isinstance(out, io.RawIOBase):
     83        buffer = io.BufferedIOBase(out)
     84        # Keep the original file open when the TextIOWrapper is
     85        # destroyed
     86        buffer.close = lambda: None
     87    else:
     88        # This is to handle passed objects that aren't in the
     89        # IOBase hierarchy, but just have a write method
     90        buffer = io.BufferedIOBase()
     91        buffer.writable = lambda: True
     92        buffer.write = out.write
     93        try:
     94            # TextIOWrapper uses this methods to determine
     95            # if BOM (for UTF-16, etc) should be added
     96            buffer.seekable = out.seekable
     97            buffer.tell = out.tell
     98        except AttributeError:
     99            pass
     100    # wrap a binary writer with TextIOWrapper
     101    class UnbufferedTextIOWrapper(io.TextIOWrapper):
     102        def write(self, s):
     103            super(UnbufferedTextIOWrapper, self).write(s)
     104            self.flush()
     105    return UnbufferedTextIOWrapper(buffer, encoding=encoding,
     106                                   errors='xmlcharrefreplace',
     107                                   newline='\n')
     108
    84109class XMLGenerator(handler.ContentHandler):
    85110
    86111    def __init__(self, out=None, encoding="iso-8859-1"):
    87         if out is None:
    88             import sys
    89             out = sys.stdout
    90112        handler.ContentHandler.__init__(self)
    91         self._out = out
     113        out = _gettextwriter(out, encoding)
     114        self._write = out.write
     115        self._flush = out.flush
    92116        self._ns_contexts = [{}] # contains uri -> prefix dicts
    93117        self._current_context = self._ns_contexts[-1]
     
    95119        self._encoding = encoding
    96120
    97     def _write(self, text):
    98         if isinstance(text, str):
    99             self._out.write(text)
    100         else:
    101             self._out.write(text.encode(self._encoding, _error_handling))
    102 
    103121    def _qname(self, name):
    104122        """Builds a qualified name from a (ns_url, localname) pair"""
    105123        if name[0]:
     124            # Per http://www.w3.org/XML/1998/namespace, The 'xml' prefix is
     125            # bound by definition to http://www.w3.org/XML/1998/namespace.  It
     126            # does not need to be declared and will not usually be found in
     127            # self._current_context.
     128            if 'http://www.w3.org/XML/1998/namespace' == name[0]:
     129                return 'xml:' + name[1]
    106130            # The name is in a non-empty namespace
    107131            prefix = self._current_context[name[0]]
     
    115139
    116140    def startDocument(self):
    117         self._write('<?xml version="1.0" encoding="%s"?>\n' %
     141        self._write(u'<?xml version="1.0" encoding="%s"?>\n' %
    118142                        self._encoding)
     143
     144    def endDocument(self):
     145        self._flush()
    119146
    120147    def startPrefixMapping(self, prefix, uri):
     
    128155
    129156    def startElement(self, name, attrs):
    130         self._write('<' + name)
     157        self._write(u'<' + name)
    131158        for (name, value) in attrs.items():
    132             self._write(' %s=%s' % (name, quoteattr(value)))
    133         self._write('>')
     159            self._write(u' %s=%s' % (name, quoteattr(value)))
     160        self._write(u'>')
    134161
    135162    def endElement(self, name):
    136         self._write('</%s>' % name)
     163        self._write(u'</%s>' % name)
    137164
    138165    def startElementNS(self, name, qname, attrs):
    139         self._write('<' + self._qname(name))
     166        self._write(u'<' + self._qname(name))
    140167
    141168        for prefix, uri in self._undeclared_ns_maps:
    142169            if prefix:
    143                 self._out.write(' xmlns:%s="%s"' % (prefix, uri))
     170                self._write(u' xmlns:%s="%s"' % (prefix, uri))
    144171            else:
    145                 self._out.write(' xmlns="%s"' % uri)
     172                self._write(u' xmlns="%s"' % uri)
    146173        self._undeclared_ns_maps = []
    147174
    148175        for (name, value) in attrs.items():
    149             self._write(' %s=%s' % (self._qname(name), quoteattr(value)))
    150         self._write('>')
     176            self._write(u' %s=%s' % (self._qname(name), quoteattr(value)))
     177        self._write(u'>')
    151178
    152179    def endElementNS(self, name, qname):
    153         self._write('</%s>' % self._qname(name))
     180        self._write(u'</%s>' % self._qname(name))
    154181
    155182    def characters(self, content):
     183        if not isinstance(content, unicode):
     184            content = unicode(content, self._encoding)
    156185        self._write(escape(content))
    157186
    158187    def ignorableWhitespace(self, content):
     188        if not isinstance(content, unicode):
     189            content = unicode(content, self._encoding)
    159190        self._write(content)
    160191
    161192    def processingInstruction(self, target, data):
    162         self._write('<?%s %s?>' % (target, data))
     193        self._write(u'<?%s %s?>' % (target, data))
    163194
    164195
     
    288319
    289320    if source.getByteStream() is None:
    290         sysid = source.getSystemId()
    291         basehead = os.path.dirname(os.path.normpath(base))
    292         sysidfilename = os.path.join(basehead, sysid)
    293         if os.path.isfile(sysidfilename):
     321        try:
     322            sysid = source.getSystemId()
     323            basehead = os.path.dirname(os.path.normpath(base))
     324            encoding = sys.getfilesystemencoding()
     325            if isinstance(sysid, unicode):
     326                if not isinstance(basehead, unicode):
     327                    try:
     328                        basehead = basehead.decode(encoding)
     329                    except UnicodeDecodeError:
     330                        sysid = sysid.encode(encoding)
     331            else:
     332                if isinstance(basehead, unicode):
     333                    try:
     334                        sysid = sysid.decode(encoding)
     335                    except UnicodeDecodeError:
     336                        basehead = basehead.encode(encoding)
     337            sysidfilename = os.path.join(basehead, sysid)
     338            isfile = os.path.isfile(sysidfilename)
     339        except UnicodeError:
     340            isfile = False
     341        if isfile:
    294342            source.setSystemId(sysidfilename)
    295343            f = open(sysidfilename, "rb")
    296344        else:
    297             source.setSystemId(urlparse.urljoin(base, sysid))
     345            source.setSystemId(urlparse.urljoin(base, source.getSystemId()))
    298346            f = urllib.urlopen(source.getSystemId())
    299347
Note: See TracChangeset for help on using the changeset viewer.