# Path: src/strutils.py
# def py3_b(value, encoding=None, desperate=True, coerce=False, fs=False):
#     """
#     Convert (if necessary) the given value to a "string of bytes", agnostic to
#     any character encoding.
# 
#     :param value: the value to be converted to a string of bytes
#     :param encoding: the character set to first try to encode to; if None, will
#                      use the system default (from the locale).
#     :type encoding: str
#     :param desperate: if True and encoding to the given (or default) charset
#                       fails, will also try utf-8 and latin-1 (in that order),
#                       and if those fail, will encode to the preferred charset,
#                       replacing unknown characters with \\\\uFFFD.
#     :type desperate: bool
#     :param coerce: if True, will coerce numeric types to a bytes object; if
#                    False, such values will be returned untouched.
#     :type coerce: bool
#     :param fs: indicates value is a file name or other environment string; if True,
#                the encoding (if not explicitly specified) will be the encoding
#                given by ``sys.getfilesystemencoding()`` and the error handler
#                used will be ``surrogateescape`` if supported.
#     :type fs: bool
#     :returns: the value as a string of bytes, or the original value if coerce is
#               False and the value was not a bytes or string.
# 
#     .. note:: The notion of "bytes" was introduced in Python 3 (and included
#        in Python 2.6 as an alias to str), hence the ``py3_`` prefix.  On Python
#        2, the returned value is a *str* object while on Python 3, the returned
#        value is a *bytes* object.
#     """
#     if isinstance(value, BYTES_TYPE):
#         # Nothing to do.
#         return value
#     elif isinstance(value, (int, long, float)):
#         return bl(str(value)) if coerce else value
#     elif not isinstance(value, UNICODE_TYPE):
#         # Need to coerce to a unicode before converting to bytes.  We can't just
#         # feed it to bytes() in case the default character set can't encode it.
#         value = py3_str(value, coerce=coerce)
# 
#     errors = 'strict'
#     if fs:
#         if not encoding:
#             encoding = sys.getfilesystemencoding()
#         errors = FS_ERRORS
# 
#     for c in (encoding or ENCODING, 'utf-8', 'latin-1'):
#         try:
#             return value.encode(c, errors)
#         except UnicodeError:
#             pass
#         if not desperate:
#             raise UnicodeError("Couldn't encode value to bytes (and not desperate enough to keep trying)")
# 
#     return value.encode(encoding or ENCODING, 'replace')
# 
# def py3_str(value, encoding=None, desperate=True, coerce=False, fs=False):
#     """
#     Convert (if necessary) the given value to a (unicode) string.
# 
#     :param value: the value to be converted to a unicode string
#     :param encoding: the character set to first try to decode as; if None, will
#                      use the system default (from the locale).
#     :type encoding: str
#     :param desperate: if True and decoding to the given (or default) charset
#                       fails, will also try utf-8 and latin-1 (in that order),
#                       and if those fail, will decode as the preferred charset,
#                       replacing unknown characters with \\\\uFFFD.
#     :type desperate: bool
#     :param coerce: if True, will coerce numeric types to a unicode string; if
#                    False, such values will be returned untouched.
#     :type coerce: bool
#     :param fs: indicates value is a file name or other environment string; if True,
#                the encoding (if not explicitly specified) will be the encoding
#                given by ``sys.getfilesystemencoding()`` and the error handler
#                used will be ``surrogateescape`` if supported.
#     :type fs: bool
#     :returns: the value as a (unicode) string, or the original value if coerce is
#               False and the value was not a bytes or string.
# 
#     .. note:: The naming of ``str`` is relative Python 3's notion of a *str* object,
#        hence the ``py3_`` prefix.  On Python 2, the returned value is a *unicode*
#        object while on Python 3, the returned value is a *str* object.
#     """
#     if isinstance(value, UNICODE_TYPE):
#         # Nothing to do.
#         return value
#     elif isinstance(value, (int, long, float)):
#         return UNICODE_TYPE(value) if coerce else value
#     elif not isinstance(value, BYTES_TYPE):
#         # Need to coerce this value.  Try the direct approach.
#         try:
#             return UNICODE_TYPE(value)
#         except UnicodeError:
#             # Could be that value.__repr__ returned a non-unicode and
#             # non-8bit-clean string.  Be a bit more brute force about it.
#             return py3_str(repr(value), desperate=desperate)
# 
#     errors = 'strict'
#     if fs:
#         if not encoding:
#             encoding = sys.getfilesystemencoding()
#         errors = FS_ERRORS
# 
#     # We now have a bytes object to decode.
#     for c in (encoding or ENCODING, 'utf-8', 'latin-1'):
#         try:
#             return value.decode(c, errors)
#         except UnicodeError:
#             pass
#         if not desperate:
#             raise UnicodeError("Couldn't decode value to unicode (and not desperate enough to keep trying)")
# 
#     return value.decode(encoding or ENCODING, 'replace')


import sys
import os
import codecs
import xml.sax
import xml.sax.saxutils
    from io import StringIO
    from StringIO import StringIO
from .strutils import py3_b, py3_str
        if self.xmlns:
            result += ' xmlns="%s"' % self.xmlns
        for key, value in self._attr.items():
            if value is None:
                continue
            value = py3_str(value)
            result += ' %s=%s' % (key, xml.sax.saxutils.quoteattr(value))
        if not self._children and not self._content:
            return result + '/>'
        result += '>'
        for child in self._children:
            if not isinstance(child, Element):
                child = child.__xml__()
            result += py3_str(child)
        return result + xml.sax.saxutils.escape(self._content.strip()) + '</%s>' % self.tagname


    def __str__(self):
        """
        Convert the element into an XML string using the current
        string encoding.
        """
        if sys.hexversion >= 0x03000000:
            return self.__unicode__()
        else:
            return py3_b(self.__unicode__())


    def __bytes__(self):
        # Python 3+

# Path: src/strutils.py
# def py3_b(value, encoding=None, desperate=True, coerce=False, fs=False):
#     """
#     Convert (if necessary) the given value to a "string of bytes", agnostic to
#     any character encoding.
# 
#     :param value: the value to be converted to a string of bytes
#     :param encoding: the character set to first try to encode to; if None, will
#                      use the system default (from the locale).
#     :type encoding: str
#     :param desperate: if True and encoding to the given (or default) charset
#                       fails, will also try utf-8 and latin-1 (in that order),
#                       and if those fail, will encode to the preferred charset,
#                       replacing unknown characters with \\\\uFFFD.
#     :type desperate: bool
#     :param coerce: if True, will coerce numeric types to a bytes object; if
#                    False, such values will be returned untouched.
#     :type coerce: bool
#     :param fs: indicates value is a file name or other environment string; if True,
#                the encoding (if not explicitly specified) will be the encoding
#                given by ``sys.getfilesystemencoding()`` and the error handler
#                used will be ``surrogateescape`` if supported.
#     :type fs: bool
#     :returns: the value as a string of bytes, or the original value if coerce is
#               False and the value was not a bytes or string.
# 
#     .. note:: The notion of "bytes" was introduced in Python 3 (and included
#        in Python 2.6 as an alias to str), hence the ``py3_`` prefix.  On Python
#        2, the returned value is a *str* object while on Python 3, the returned
#        value is a *bytes* object.
#     """
#     if isinstance(value, BYTES_TYPE):
#         # Nothing to do.
#         return value
#     elif isinstance(value, (int, long, float)):
#         return bl(str(value)) if coerce else value
#     elif not isinstance(value, UNICODE_TYPE):
#         # Need to coerce to a unicode before converting to bytes.  We can't just
#         # feed it to bytes() in case the default character set can't encode it.
#         value = py3_str(value, coerce=coerce)
# 
#     errors = 'strict'
#     if fs:
#         if not encoding:
#             encoding = sys.getfilesystemencoding()
#         errors = FS_ERRORS
# 
#     for c in (encoding or ENCODING, 'utf-8', 'latin-1'):
#         try:
#             return value.encode(c, errors)
#         except UnicodeError:
#             pass
#         if not desperate:
#             raise UnicodeError("Couldn't encode value to bytes (and not desperate enough to keep trying)")
# 
#     return value.encode(encoding or ENCODING, 'replace')
# 
# def py3_str(value, encoding=None, desperate=True, coerce=False, fs=False):
#     """
#     Convert (if necessary) the given value to a (unicode) string.
# 
#     :param value: the value to be converted to a unicode string
#     :param encoding: the character set to first try to decode as; if None, will
#                      use the system default (from the locale).
#     :type encoding: str
#     :param desperate: if True and decoding to the given (or default) charset
#                       fails, will also try utf-8 and latin-1 (in that order),
#                       and if those fail, will decode as the preferred charset,
#                       replacing unknown characters with \\\\uFFFD.
#     :type desperate: bool
#     :param coerce: if True, will coerce numeric types to a unicode string; if
#                    False, such values will be returned untouched.
#     :type coerce: bool
#     :param fs: indicates value is a file name or other environment string; if True,
#                the encoding (if not explicitly specified) will be the encoding
#                given by ``sys.getfilesystemencoding()`` and the error handler
#                used will be ``surrogateescape`` if supported.
#     :type fs: bool
#     :returns: the value as a (unicode) string, or the original value if coerce is
#               False and the value was not a bytes or string.
# 
#     .. note:: The naming of ``str`` is relative Python 3's notion of a *str* object,
#        hence the ``py3_`` prefix.  On Python 2, the returned value is a *unicode*
#        object while on Python 3, the returned value is a *str* object.
#     """
#     if isinstance(value, UNICODE_TYPE):
#         # Nothing to do.
#         return value
#     elif isinstance(value, (int, long, float)):
#         return UNICODE_TYPE(value) if coerce else value
#     elif not isinstance(value, BYTES_TYPE):
#         # Need to coerce this value.  Try the direct approach.
#         try:
#             return UNICODE_TYPE(value)
#         except UnicodeError:
#             # Could be that value.__repr__ returned a non-unicode and
#             # non-8bit-clean string.  Be a bit more brute force about it.
#             return py3_str(repr(value), desperate=desperate)
# 
#     errors = 'strict'
#     if fs:
#         if not encoding:
#             encoding = sys.getfilesystemencoding()
#         errors = FS_ERRORS
# 
#     # We now have a bytes object to decode.
#     for c in (encoding or ENCODING, 'utf-8', 'latin-1'):
#         try:
#             return value.decode(c, errors)
#         except UnicodeError:
#             pass
#         if not desperate:
#             raise UnicodeError("Couldn't decode value to unicode (and not desperate enough to keep trying)")
# 
#     return value.decode(encoding or ENCODING, 'replace')


# Path: src/saxutils.py
import sys
import os
import codecs
import xml.sax
import xml.sax.saxutils
    from io import StringIO
    from StringIO import StringIO
from .strutils import py3_b, py3_str

        if self.xmlns:
            result += ' xmlns="%s"' % self.xmlns
        for key, value in self._attr.items():
            if value is None:
                continue
            value = py3_str(value)
            result += ' %s=%s' % (key, xml.sax.saxutils.quoteattr(value))
        if not self._children and not self._content:
            return result + '/>'
        result += '>'
        for child in self._children:
            if not isinstance(child, Element):
                child = child.__xml__()
            result += py3_str(child)
        return result + xml.sax.saxutils.escape(self._content.strip()) + '</%s>' % self.tagname


    def __str__(self):
        """
        Convert the element into an XML string using the current
        string encoding.
        """
        if sys.hexversion >= 0x03000000:
            return self.__unicode__()
        else:
            return py3_b(self.__unicode__())


    def __bytes__(self):
        # Python 3+

        return py3_b(self.__unicode__())