text: 
  import os
  import sys
  import time
  import traceback
  import six
  import re
  from os import path
  from six.moves import StringIO
  
  from .unittest import TestResult, _TextTestResult, failfast
  
  
  # Matches invalid XML1.0 unicode characters, like control characters:
  # http://www.w3.org/TR/2006/REC-xml-20060816/#charsets
  # http://stackoverflow.com/questions/1707890/fast-way-to-filter-illegal-xml-unicode-chars-in-python
  
  _illegal_unichrs = [
      (0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F), 
      (0x7F, 0x84), (0x86, 0x9F), 
      (0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF),
  ] 
  if sys.maxunicode >= 0x10000:  # not narrow build 
      _illegal_unichrs.extend([
          (0x1FFFE, 0x1FFFF), (0x2FFFE, 0x2FFFF), 
          (0x3FFFE, 0x3FFFF), (0x4FFFE, 0x4FFFF), 
          (0x5FFFE, 0x5FFFF), (0x6FFFE, 0x6FFFF), 
          (0x7FFFE, 0x7FFFF), (0x8FFFE, 0x8FFFF), 
          (0x9FFFE, 0x9FFFF), (0xAFFFE, 0xAFFFF), 
          (0xBFFFE, 0xBFFFF), (0xCFFFE, 0xCFFFF), 
          (0xDFFFE, 0xDFFFF), (0xEFFFE, 0xEFFFF), 
          (0xFFFFE, 0xFFFFF), (0x10FFFE, 0x10FFFF),
      ]) 
  
  _illegal_ranges = [
      "%s-%s" % (six.unichr(low), six.unichr(high))
      for (low, high) in _illegal_unichrs
  ]
  
  INVALID_XML_1_0_UNICODE_RE = re.compile(u'[%s]' % u''.join(_illegal_ranges)) 
  
  
  STDOUT_LINE = '\nStdout:\n%s'
  STDERR_LINE = '\nStderr:\n%s'
  
  
  def xml_safe_unicode(base, encoding='utf-8'):
      """Return a unicode string containing only valid XML characters.
  
      encoding - if base is a byte string it is first decoded to unicode
          using this encoding.
      """
      if isinstance(base, six.binary_type):
          base = base.decode(encoding)
      return INVALID_XML_1_0_UNICODE_RE.sub('', base)
  
  
  def to_unicode(data):
      """Returns unicode in Python2 and str in Python3"""
      if six.PY3:
          return six.text_type(data)
      try:
          # Try utf8
          return six.text_type(data)
      except UnicodeDecodeError:
          return repr(data).decode('utf8', 'replace')
  
  
  def safe_unicode(data, encoding=None):
      return xml_safe_unicode(to_unicode(data), encoding)
  
  
  def testcase_name(test_method):
      testcase = type(test_method)
  
      # Ignore module name if it is '__main__'
      module = testcase.__module__ + '.'
      if module == '__main__.':
          module = ''
      result = module + testcase.__name__
      return result
  
  
  class _TestInfo(object):
      """
      This class keeps useful information about the execution of a
      test method.
      """
  
      # Possible test outcomes
      (SUCCESS, FAILURE, ERROR, SKIP) = range(4)
  
      def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=None):
          self.test_result = test_result
          self.outcome = outcome
          self.elapsed_time = 0
          self.err = err
          self.stdout = test_result._stdout_data
          self.stderr = test_result._stderr_data
  
          self.test_description = self.test_result.getDescription(test_method)
          self.test_exception_info = (
              '' if outcome in (self.SUCCESS, self.SKIP)
              else self.test_result._exc_info_to_string(
                      self.err, test_method)
          )
  
          self.test_name = testcase_name(test_method)
          self.test_id = test_method.id()
          if subTest:
              self.test_id = subTest.id()
  
      def id(self):
          return self.test_id
  
      def test_finished(self):
          """Save info that can only be calculated once a test has run.
          """
          self.elapsed_time = \
              self.test_result.stop_time - self.test_result.start_time
  
      def get_description(self):
          """
          Return a text representation of the test method.
          """
          return self.test_description
  
      def get_error_info(self):
          """
          Return a text representation of an exception thrown by a test
          method.
          """
          return self.test_exception_info
  
  
  class _XMLTestResult(_TextTestResult):
      """
      A test result class that can express test results in a XML report.
  
      Used by XMLTestRunner.
      """
      def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1,
                   elapsed_times=True, properties=None, infoclass=None):
          _TextTestResult.__init__(self, stream, descriptions, verbosity)
          self.buffer = True  # we are capturing test output
          self._stdout_data = None
          self._stderr_data = None
          self.successes = []
          self.callback = None
          self.elapsed_times = elapsed_times
          self.properties = properties  # junit testsuite properties
          if infoclass is None:
              self.infoclass = _TestInfo
          else:
              self.infoclass = infoclass
  
      def _prepare_callback(self, test_info, target_list, verbose_str,
                            short_str):
          """
          Appends a `infoclass` to the given target list and sets a callback
          method to be called by stopTest method.
          """
          target_list.append(test_info)
  
          def callback():
              """Prints the test method outcome to the stream, as well as
              the elapsed time.
              """
  
              test_info.test_finished()
  
              # Ignore the elapsed times for a more reliable unit testing
              if not self.elapsed_times:
                  self.start_time = self.stop_time = 0
  
              if self.showAll:
                  self.stream.writeln(
                      '%s (%.3fs)' % (verbose_str, test_info.elapsed_time)
                  )
              elif self.dots:
                  self.stream.write(short_str)
          self.callback = callback
  
      def startTest(self, test):
          """
          Called before execute each test method.
          """
          self.start_time = time.time()
          TestResult.startTest(self, test)
  
          if self.showAll:
              self.stream.write('  ' + self.getDescription(test))
              self.stream.write(" ... ")
  
      def _save_output_data(self):
          # Only try to get sys.stdout and sys.sterr as they not be
          # StringIO yet, e.g. when test fails during __call__
          try:
              self._stdout_data = sys.stdout.getvalue()
              self._stderr_data = sys.stderr.getvalue()
          except AttributeError:
              pass
  
      def stopTest(self, test):
          """
          Called after execute each test method.
          """
          self._save_output_data()
          # self._stdout_data = sys.stdout.getvalue()
          # self._stderr_data = sys.stderr.getvalue()
  
          _TextTestResult.stopTest(self, test)
          self.stop_time = time.time()
  
          if self.callback and callable(self.callback):
              self.callback()
              self.callback = None
  
      def addSuccess(self, test):
          """
          Called when a test executes successfully.
          """
          self._save_output_data()
          self._prepare_callback(
              self.infoclass(self, test), self.successes, 'OK', '.'
          )
  
      @failfast
      def addFailure(self, test, err):
          """
          Called when a test method fails.
          """
          self._save_output_data()
          testinfo = self.infoclass(
              self, test, self.infoclass.FAILURE, err)
          self.failures.append((
              testinfo,
              self._exc_info_to_string(err, test)
          ))
          self._prepare_callback(testinfo, [], 'FAIL', 'F')
  
      @failfast
      def addError(self, test, err):
          """
          Called when a test method raises an error.
          """
          self._save_output_data()
          testinfo = self.infoclass(
              self, test, self.infoclass.ERROR, err)
          self.errors.append((
              testinfo,
              self._exc_info_to_string(err, test)
          ))
          self._prepare_callback(testinfo, [], 'ERROR', 'E')
  
      def addSubTest(self, testcase, test, err):
          """
          Called when a subTest method raises an error.
          """
          if err is not None:
              self._save_output_data()
              testinfo = self.infoclass(
                  self, testcase, self.infoclass.ERROR, err, subTest=test)
              self.errors.append((
                  testinfo,
                  self._exc_info_to_string(err, testcase)
              ))
              self._prepare_callback(testinfo, [], 'ERROR', 'E')
  
      def addSkip(self, test, reason):
          """
          Called when a test method was skipped.
          """
          self._save_output_data()
          testinfo = self.infoclass(
              self, test, self.infoclass.SKIP, reason)
          self.skipped.append((testinfo, reason))
          self._prepare_callback(testinfo, [], 'SKIP', 'S')
  
      def printErrorList(self, flavour, errors):
          """
          Writes information about the FAIL or ERROR to the stream.
          """
          for test_info, dummy in errors:
              self.stream.writeln(self.separator1)
              self.stream.writeln(
                  '%s [%.3fs]: %s' % (flavour, test_info.elapsed_time,
                                      test_info.get_description())
              )
              self.stream.writeln(self.separator2)
              self.stream.writeln('%s' % test_info.get_error_info())
  
      def _get_info_by_testcase(self):
          """
          Organizes test results by TestCase module. This information is
          used during the report generation, where a XML report will be created
          for each TestCase.
          """
          tests_by_testcase = {}
  
          for tests in (self.successes, self.failures, self.errors,
                        self.skipped):
              for test_info in tests:
                  if isinstance(test_info, tuple):
                      # This is a skipped, error or a failure test case
                      test_info = test_info[0]
                  testcase_name = test_info.test_name
                  if testcase_name not in tests_by_testcase:
                      tests_by_testcase[testcase_name] = []
                  tests_by_testcase[testcase_name].append(test_info)
  
          return tests_by_testcase
  
      def _report_testsuite_properties(xml_testsuite, xml_document, properties):
          if properties:
              xml_properties = xml_document.createElement('properties')
              xml_testsuite.appendChild(xml_properties)
              for key, value in properties.items():
                  prop = xml_document.createElement('property')
                  prop.setAttribute('name', str(key))
                  prop.setAttribute('value', str(value))
                  xml_properties.appendChild(prop)
  
      _report_testsuite_properties = staticmethod(_report_testsuite_properties)
  
      def _report_testsuite(suite_name, tests, xml_document, parentElement,
                            properties):
          """
          Appends the testsuite section to the XML document.
          """
          testsuite = xml_document.createElement('testsuite')
          parentElement.appendChild(testsuite)
  
          testsuite.setAttribute('name', suite_name)
          testsuite.setAttribute('tests', str(len(tests)))
  
          testsuite.setAttribute(
              'time', '%.3f' % sum(map(lambda e: e.elapsed_time, tests))
          )
          failures = filter(lambda e: e.outcome == e.FAILURE, tests)
          testsuite.setAttribute('failures', str(len(list(failures))))
  
          errors = filter(lambda e: e.outcome == e.ERROR, tests)
          testsuite.setAttribute('errors', str(len(list(errors))))
  
          skips = filter(lambda e: e.outcome == _TestInfo.SKIP, tests)
          testsuite.setAttribute('skipped', str(len(list(skips))))
   
          _XMLTestResult._report_testsuite_properties(
              testsuite, xml_document, properties)
  
          for test in tests:
              _XMLTestResult._report_testcase(test, testsuite, xml_document)
  
          systemout = xml_document.createElement('system-out')
          testsuite.appendChild(systemout)
  
          stdout = StringIO()
          for test in tests:
              # Merge the stdout from the tests in a class
              if test.stdout is not None:
                  stdout.write(test.stdout)
          _XMLTestResult._createCDATAsections(
              xml_document, systemout, stdout.getvalue())
  
          systemerr = xml_document.createElement('system-err')
          testsuite.appendChild(systemerr)
  
          stderr = StringIO()
          for test in tests:
              # Merge the stderr from the tests in a class
              if test.stderr is not None:
                  stderr.write(test.stderr)
          _XMLTestResult._createCDATAsections(
              xml_document, systemerr, stderr.getvalue())
  
          return testsuite
  
      _report_testsuite = staticmethod(_report_testsuite)
  
      def _test_method_name(test_id):
          """
          Returns the test method name.
          """
          return test_id.split('.')[-1]
  
      _test_method_name = staticmethod(_test_method_name)
  
      def _createCDATAsections(xmldoc, node, text):
          text = safe_unicode(text)
          pos = text.find(']]>')
          while pos >= 0:
              tmp = text[0:pos+2]
              cdata = xmldoc.createCDATASection(tmp)
              node.appendChild(cdata)
              text = text[pos+2:]
              pos = text.find(']]>')
          cdata = xmldoc.createCDATASection(text)
          node.appendChild(cdata)
  
      _createCDATAsections = staticmethod(_createCDATAsections)
  
      def _report_testcase(test_result, xml_testsuite, xml_document):
          """
          Appends a testcase section to the XML document.
          """
          testcase = xml_document.createElement('testcase')
          xml_testsuite.appendChild(testcase)
  
          class_name = re.sub(r'^__main__.', '', test_result.id())
          class_name = class_name.rpartition('.')[0]
          testcase.setAttribute('classname', class_name)
          testcase.setAttribute(
              'name', _XMLTestResult._test_method_name(test_result.test_id)
          )
          testcase.setAttribute('time', '%.3f' % test_result.elapsed_time)
  
          if (test_result.outcome != test_result.SUCCESS):
              elem_name = ('failure', 'error', 'skipped')[test_result.outcome-1]
              failure = xml_document.createElement(elem_name)
              testcase.appendChild(failure)
              if test_result.outcome != test_result.SKIP:
                  failure.setAttribute(
                      'type',
                      safe_unicode(test_result.err[0].__name__)
                  )
                  failure.setAttribute(
                      'message',
                      safe_unicode(test_result.err[1])
                  )
                  error_info = safe_unicode(test_result.get_error_info())
                  _XMLTestResult._createCDATAsections(
                      xml_document, failure, error_info)
              else:
                  failure.setAttribute('type', 'skip')
                  failure.setAttribute('message', safe_unicode(test_result.err))
  
      _report_testcase = staticmethod(_report_testcase)
  
      def generate_reports(self, test_runner):
          """
          Generates the XML reports to a given XMLTestRunner object.
          """
          from xml.dom.minidom import Document
          all_results = self._get_info_by_testcase()
  
          outputHandledAsString = \
              isinstance(test_runner.output, six.string_types)
  
          if (outputHandledAsString and not os.path.exists(test_runner.output)):
              os.makedirs(test_runner.output)
  
          if not outputHandledAsString:
              doc = Document()
              testsuite = doc.createElement('testsuites')
              doc.appendChild(testsuite)
              parentElement = testsuite
  
          for suite, tests in all_results.items():
              if outputHandledAsString:
                  doc = Document()
                  parentElement = doc
  
              suite_name = suite
              if test_runner.outsuffix:
                  # not checking with 'is not None', empty means no suffix.
                  suite_name = '%s-%s' % (suite, test_runner.outsuffix)
  
              # Build the XML file
              testsuite = _XMLTestResult._report_testsuite(
                  suite_name, tests, doc, parentElement, self.properties
              )
              xml_content = doc.toprettyxml(
                  indent='\t',
                  encoding=test_runner.encoding
              )
  
              if outputHandledAsString:
                  filename = path.join(
                      test_runner.output,
                      'TEST-%s.xml' % suite_name)
                  with open(filename, 'wb') as report_file:
                      report_file.write(xml_content)
  
          if not outputHandledAsString:
              # Assume that test_runner.output is a stream
              test_runner.output.write(xml_content)
  
      def _exc_info_to_string(self, err, test):
          """Converts a sys.exc_info()-style tuple of values into a string."""
          if six.PY3:
              # It works fine in python 3
              try:
                  return super(_XMLTestResult, self)._exc_info_to_string(
                      err, test)
              except AttributeError:
                  # We keep going using the legacy python <= 2 way
                  pass
  
          # This comes directly from python2 unittest
          exctype, value, tb = err
          # Skip test runner traceback levels
          while tb and self._is_relevant_tb_level(tb):
              tb = tb.tb_next
  
          if exctype is test.failureException:
              # Skip assert*() traceback levels
              length = self._count_relevant_tb_levels(tb)
              msgLines = traceback.format_exception(exctype, value, tb, length)
          else:
              msgLines = traceback.format_exception(exctype, value, tb)
  
          if self.buffer:
              # Only try to get sys.stdout and sys.sterr as they not be
              # StringIO yet, e.g. when test fails during __call__
              try:
                  output = sys.stdout.getvalue()
              except AttributeError:
                  output = None
              try:
                  error = sys.stderr.getvalue()
              except AttributeError:
                  error = None
              if output:
                  if not output.endswith('\n'):
                      output += '\n'
                  msgLines.append(STDOUT_LINE % output)
              if error:
                  if not error.endswith('\n'):
                      error += '\n'
                  msgLines.append(STDERR_LINE % error)
          # This is the extra magic to make sure all lines are str
          encoding = getattr(sys.stdout, 'encoding', 'utf-8')
          lines = []
          for line in msgLines:
              if not isinstance(line, str):
                  # utf8 shouldnt be hard-coded, but not sure f
                  line = line.encode(encoding)
              lines.append(line)
  
          return ''.join(lines)
  