예제 #1
0
class SafeStringTests(unittest.TestCase):
    # the error message in EnvironmentError instances comes from the OS
    # and in some locales (e.g. ru_RU), contains high bit chars.
    # -> see the test in test_error_reporting.py

    # test data:
    bs = b('\xfc')     # unicode(bs) fails, str(bs) in Python 3 return repr()
    us = u'\xfc'       # bytes(us) fails; str(us) fails in Python 2
    be = Exception(bs) # unicode(be) fails
    ue = Exception(us) # bytes(ue) fails, str(ue) fails in Python 2;
                       # unicode(ue) fails in Python < 2.6 (issue2517_)
                       # .. _issue2517: http://bugs.python.org/issue2517
    # wrapped test data:
    wbs = SafeString(bs)
    wus = SafeString(us)
    wbe = SafeString(be)
    wue = SafeString(ue)

    def test_7bit(self):
        # wrapping (not required with 7-bit chars) must not change the
        # result of conversions:
        bs7 = b('foo')
        us7 = u'foo'
        be7 = Exception(bs7)
        ue7 = Exception(us7)
        self.assertEqual(str(42), str(SafeString(42)))
        self.assertEqual(str(bs7), str(SafeString(bs7)))
        self.assertEqual(str(us7), str(SafeString(us7)))
        self.assertEqual(str(be7), str(SafeString(be7)))
        self.assertEqual(str(ue7), str(SafeString(ue7)))
        self.assertEqual(unicode(7), unicode(SafeString(7)))
        self.assertEqual(unicode(bs7), unicode(SafeString(bs7)))
        self.assertEqual(unicode(us7), unicode(SafeString(us7)))
        self.assertEqual(unicode(be7), unicode(SafeString(be7)))
        self.assertEqual(unicode(ue7), unicode(SafeString(ue7)))

    def test_ustr(self):
        """Test conversion to a unicode-string."""
        # unicode(self.bs) fails
        self.assertEqual(unicode, type(unicode(self.wbs)))
        self.assertEqual(unicode(self.us), unicode(self.wus))
        # unicode(self.be) fails
        self.assertEqual(unicode, type(unicode(self.wbe)))
        # unicode(ue) fails in Python < 2.6 (issue2517_)
        self.assertEqual(unicode, type(unicode(self.wue)))
        self.assertEqual(self.us, unicode(self.wue))

    def test_str(self):
        """Test conversion to a string (bytes in Python 2, unicode in Python 3)."""
        self.assertEqual(str(self.bs), str(self.wbs))
        self.assertEqual(str(self.be), str(self.be))
        # str(us) fails in Python 2
        self.assertEqual(str, type(str(self.wus)))
        # str(ue) fails in Python 2
        self.assertEqual(str, type(str(self.wue)))
예제 #2
0
파일: misc.py 프로젝트: jesobreira/casanova
 def run(self):
     """Include a file as part of the content of this reST file."""
     if not self.state.document.settings.file_insertion_enabled:
         raise self.warning('"%s" directive disabled.' % self.name)
     source = self.state_machine.input_lines.source(
         self.lineno - self.state_machine.input_offset - 1)
     source_dir = os.path.dirname(os.path.abspath(source))
     path = directives.path(self.arguments[0])
     if path.startswith('<') and path.endswith('>'):
         path = os.path.join(self.standard_include_path, path[1:-1])
     path = os.path.normpath(os.path.join(source_dir, path))
     path = utils.relative_path(None, path)
     path = nodes.reprunicode(path)
     encoding = self.options.get(
         'encoding', self.state.document.settings.input_encoding)
     tab_width = self.options.get('tab-width',
                                  self.state.document.settings.tab_width)
     try:
         self.state.document.settings.record_dependencies.add(path)
         include_file = io.FileInput(
             source_path=path, encoding=encoding,
             error_handler=(self.state.document.settings.\
                            input_encoding_error_handler),
             handle_io_errors=None)
     except UnicodeEncodeError, error:
         raise self.severe(u'Problems with "%s" directive path:\n'
                           'Cannot encode input file path "%s" '
                           '(wrong locale?).' %
                           (self.name, SafeString(path)))
예제 #3
0
 def test_unicode(self):
     self.assertEqual(u'Exception: spam',
                      unicode(ErrorString(Exception(u'spam'))))
     self.assertEqual(u'IndexError: '+self.us,
                      unicode(ErrorString(IndexError(self.us))))
     self.assertEqual(u'ImportError: %s' % SafeString(self.bs),
                      unicode(ErrorString(ImportError(self.bs))))
예제 #4
0
 def test_str(self):
     self.assertEqual('Exception: spam',
                      str(ErrorString(Exception('spam'))))
     self.assertEqual('IndexError: '+str(self.bs),
                      str(ErrorString(IndexError(self.bs))))
     self.assertEqual('ImportError: %s' % SafeString(self.us),
                      str(ErrorString(ImportError(self.us))))
예제 #5
0
class Role(Directive):

    has_content = True

    argument_pattern = re.compile(r'(%s)\s*(\(\s*(%s)\s*\)\s*)?$' %
                                  ((states.Inliner.simplename, ) * 2))

    def run(self):
        """Dynamically create and register a custom interpreted text role."""
        if self.content_offset > self.lineno or not self.content:
            raise self.error('"%s" directive requires arguments on the first '
                             'line.' % self.name)
        args = self.content[0]
        match = self.argument_pattern.match(args)
        if not match:
            raise self.error('"%s" directive arguments not valid role names: '
                             '"%s".' % (self.name, args))
        new_role_name = match.group(1)
        base_role_name = match.group(3)
        messages = []
        if base_role_name:
            base_role, messages = roles.role(base_role_name,
                                             self.state_machine.language,
                                             self.lineno, self.state.reporter)
            if base_role is None:
                error = self.state.reporter.error(
                    'Unknown interpreted text role "%s".' % base_role_name,
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return messages + [error]
        else:
            base_role = roles.generic_custom_role
        assert not hasattr(base_role, 'arguments'), (
            'Supplemental directive arguments for "%s" directive not '
            'supported (specified by "%r" role).' % (self.name, base_role))
        try:
            converted_role = convert_directive_function(base_role)
            (arguments, options, content,
             content_offset) = (self.state.parse_directive_block(
                 self.content[1:],
                 self.content_offset,
                 converted_role,
                 option_presets={}))
        except states.MarkupError, detail:
            error = self.state_machine.reporter.error(
                'Error in "%s" directive:\n%s.' % (self.name, detail),
                nodes.literal_block(self.block_text, self.block_text),
                line=self.lineno)
            return messages + [error]
        if 'class' not in options:
            try:
                options['class'] = directives.class_option(new_role_name)
            except ValueError, detail:
                error = self.state_machine.reporter.error(
                    u'Invalid argument for "%s" directive:\n%s.' %
                    (self.name, SafeString(detail)),
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return messages + [error]
예제 #6
0
 def test_7bit(self):
     # wrapping (not required with 7-bit chars) must not change the
     # result of conversions:
     bs7 = b('foo')
     us7 = u'foo'
     be7 = Exception(bs7)
     ue7 = Exception(us7)
     self.assertEqual(str(42), str(SafeString(42)))
     self.assertEqual(str(bs7), str(SafeString(bs7)))
     self.assertEqual(str(us7), str(SafeString(us7)))
     self.assertEqual(str(be7), str(SafeString(be7)))
     self.assertEqual(str(ue7), str(SafeString(ue7)))
     self.assertEqual(unicode(7), unicode(SafeString(7)))
     self.assertEqual(unicode(bs7), unicode(SafeString(bs7)))
     self.assertEqual(unicode(us7), unicode(SafeString(us7)))
     self.assertEqual(unicode(be7), unicode(SafeString(be7)))
     self.assertEqual(unicode(ue7), unicode(SafeString(ue7)))
    def system_message(self, level, message, *children, **kwargs):
        """
        Return a system_message object.

        Raise an exception or generate a warning if appropriate.
        """
        # `message` can be a `string`, `unicode`, or `Exception` instance.
        if isinstance(message, Exception):
            message = SafeString(message)

        attributes = kwargs.copy()
        if 'base_node' in kwargs:
            source, line = get_source_line(kwargs['base_node'])
            del attributes['base_node']
            if source is not None:
                attributes.setdefault('source', source)
            if line is not None:
                attributes.setdefault('line', line)
                # assert source is not None, "node has line- but no source-argument"
        if not 'source' in attributes:  # 'line' is absolute line number
            try:  # look up (source, line-in-source)
                source, line = self.locator(attributes.get('line'))
                # print "locator lookup", kwargs.get('line'), "->", source, line
            except AttributeError:
                source, line = None, None
            if source is not None:
                attributes['source'] = source
            if line is not None:
                attributes['line'] = line
        # assert attributes['line'] is not None, (message, kwargs)
        # assert attributes['source'] is not None, (message, kwargs)
        attributes.setdefault('source', self.source)

        msg = nodes.system_message(message,
                                   level=level,
                                   type=self.levels[level],
                                   *children,
                                   **attributes)
        if self.stream and (level >= self.report_level
                            or self.debug_flag and level == self.DEBUG_LEVEL
                            or level >= self.halt_level):
            self.stream.write(msg.astext() + '\n')
        if level >= self.halt_level:
            raise SystemMessage(msg, level)
        if level > self.DEBUG_LEVEL or self.debug_flag:
            self.notify_observers(msg)
        self.max_level = max(level, self.max_level)
        return msg
 def get_csv_data(self):
     """
     Get CSV data from the directive content, from an external
     file, or from a URL reference.
     """
     encoding = self.options.get(
         'encoding', self.state.document.settings.input_encoding)
     if self.content:
         # CSV data is from directive content.
         if 'file' in self.options or 'url' in self.options:
             error = self.state_machine.reporter.error(
                 '"%s" directive may not both specify an external file and'
                 ' have content.' % self.name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(error)
         source = self.content.source(0)
         csv_data = self.content
     elif 'file' in self.options:
         # CSV data is from an external file.
         if 'url' in self.options:
             error = self.state_machine.reporter.error(
                 'The "file" and "url" options may not be simultaneously'
                 ' specified for the "%s" directive.' % self.name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(error)
         source_dir = os.path.dirname(
             os.path.abspath(self.state.document.current_source))
         source = os.path.normpath(
             os.path.join(source_dir, self.options['file']))
         source = utils.relative_path(None, source)
         try:
             self.state.document.settings.record_dependencies.add(source)
             csv_file = io.FileInput(
                 source_path=source, encoding=encoding,
                 error_handler=(self.state.document.settings.\
                                input_encoding_error_handler),
                 handle_io_errors=None)
             csv_data = csv_file.read().splitlines()
         except IOError, error:
             severe = self.state_machine.reporter.severe(
                 u'Problems with "%s" directive path:\n%s.' %
                 (self.name, SafeString(error)),
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(severe)
             nodes.literal_block(self.block_text, self.block_text),
             line=self.lineno)
         raise SystemMessagePropagation(severe)
 elif 'url' in self.options:
     # CSV data is from a URL.
     # Do not import urllib2 at the top of the module because
     # it may fail due to broken SSL dependencies, and it takes
     # about 0.15 seconds to load.
     import urllib2
     source = self.options['url']
     try:
         csv_text = urllib2.urlopen(source).read()
     except (urllib2.URLError, IOError, OSError, ValueError), error:
         severe = self.state_machine.reporter.severe(
             'Problems with "%s" directive URL "%s":\n%s.' %
             (self.name, self.options['url'], SafeString(error)),
             nodes.literal_block(self.block_text, self.block_text),
             line=self.lineno)
         raise SystemMessagePropagation(severe)
     csv_file = io.StringInput(
         source=csv_text, source_path=source, encoding=encoding,
         error_handler=(self.state.document.settings.\
                        input_encoding_error_handler))
     csv_data = csv_file.read().splitlines()
 else:
     error = self.state_machine.reporter.warning(
         'The "%s" directive requires content; none supplied.' %
         self.name,
         nodes.literal_block(self.block_text, self.block_text),
         line=self.lineno)
     raise SystemMessagePropagation(error)
예제 #10
0
    def run(self):
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        path = os.path.normpath(os.path.join(source_dir, path))
        path = utils.relative_path(None, path)
        path = nodes.reprunicode(path)
        encoding = self.options.get(
            'encoding', self.state.document.settings.input_encoding)
        tab_width = self.options.get(
            'tab-width', self.state.document.settings.tab_width)
        try:
            self.state.document.settings.record_dependencies.add(path)
            include_file = io.FileInput(
                source_path=path, encoding=encoding,
                error_handler=(self.state.document.settings.\
                               input_encoding_error_handler),
                handle_io_errors=None)
        except UnicodeEncodeError as error:
            raise self.severe('Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                      (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext, tab_width,
                                                  convert_whitespace=True)
        if 'literal' in self.options:
            # Convert tabs to spaces, if `tab_width` is positive.
            if tab_width >= 0:
                text = rawtext.expandtabs(tab_width)
            else:
                text = rawtext
            literal_block = nodes.literal_block(rawtext, source=path,
                                    classes=self.options.get('class', []))
            literal_block.line = 1
            self.add_name(literal_block)
            if 'number-lines' in self.options:
                try:
                    startline = int(self.options['number-lines'] or 1)
                except ValueError:
                    raise self.error(':number-lines: with non-integer '
                                     'start value')
                endline = startline + len(include_lines)
                if text.endswith('\n'):
                    text = text[:-1]
                tokens = NumberLines([([], text)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value, value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value, value)
            else:
                literal_block += nodes.Text(text, text)
            return [literal_block]
        if 'code' in self.options:
            self.options['source'] = path
            codeblock = CodeBlock(self.name,
                                  [self.options.pop('code')], # arguments
                                  self.options,
                                  include_lines, # content
                                  self.lineno,
                                  self.content_offset,
                                  self.block_text,
                                  self.state,
                                  self.state_machine)
            return codeblock.run()
        self.state_machine.insert_input(include_lines, path)
        return []
예제 #11
0
 def get_csv_data(self):
     """
     Get CSV data from the directive content, from an external
     file, or from a URL reference.
     """
     encoding = self.options.get(
         'encoding', self.state.document.settings.input_encoding)
     if self.content:
         # CSV data is from directive content.
         if 'file' in self.options or 'url' in self.options:
             error = self.state_machine.reporter.error(
                 '"%s" directive may not both specify an external file and'
                 ' have content.' % self.name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(error)
         source = self.content.source(0)
         csv_data = self.content
     elif 'file' in self.options:
         # CSV data is from an external file.
         if 'url' in self.options:
             error = self.state_machine.reporter.error(
                 'The "file" and "url" options may not be simultaneously'
                 ' specified for the "%s" directive.' % self.name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(error)
         source_dir = os.path.dirname(
             os.path.abspath(self.state.document.current_source))
         source = os.path.normpath(
             os.path.join(source_dir, self.options['file']))
         source = utils.relative_path(None, source)
         try:
             self.state.document.settings.record_dependencies.add(source)
             csv_file = io.FileInput(
                 source_path=source, encoding=encoding,
                 error_handler=(self.state.document.settings.\
                                input_encoding_error_handler),
                 handle_io_errors=None)
             csv_data = csv_file.read().splitlines()
         except IOError as error:
             severe = self.state_machine.reporter.severe(
                 'Problems with "%s" directive path:\n%s.' %
                 (self.name, SafeString(error)),
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(severe)
     elif 'url' in self.options:
         # CSV data is from a URL.
         # Do not import urllib2 at the top of the module because
         # it may fail due to broken SSL dependencies, and it takes
         # about 0.15 seconds to load.
         import urllib.request, urllib.error, urllib.parse
         source = self.options['url']
         try:
             csv_text = urllib.request.urlopen(source).read()
         except (urllib.error.URLError, IOError, OSError,
                 ValueError) as error:
             severe = self.state_machine.reporter.severe(
                 'Problems with "%s" directive URL "%s":\n%s.' %
                 (self.name, self.options['url'], SafeString(error)),
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             raise SystemMessagePropagation(severe)
         csv_file = io.StringInput(
             source=csv_text, source_path=source, encoding=encoding,
             error_handler=(self.state.document.settings.\
                            input_encoding_error_handler))
         csv_data = csv_file.read().splitlines()
     else:
         error = self.state_machine.reporter.warning(
             'The "%s" directive requires content; none supplied.' %
             self.name,
             nodes.literal_block(self.block_text, self.block_text),
             line=self.lineno)
         raise SystemMessagePropagation(error)
     return csv_data, source
예제 #12
0
            uioe = e
    try:
        os.chdir(b('\xfc'))
    except OSError, e:
        bose = e
    try:
        os.chdir(u'\xfc')
    except OSError, e:
        uose = e
    except UnicodeEncodeError:
        try:
            os.chdir(u'\xfc'.encode(sys.getfilesystemencoding(), 'replace'))
        except OSError, e:
            uose = e
    # wrapped test data:
    wbioe = SafeString(bioe)
    wuioe = SafeString(uioe)
    wbose = SafeString(bose)
    wuose = SafeString(uose)
    # reset locale
    if testlocale:
        locale.setlocale(locale.LC_ALL, oldlocale)

    def test_ustr(self):
        """Test conversion to a unicode-string."""
        # unicode(bioe) fails with e.g. 'ru_RU.utf8' locale
        self.assertEqual(unicode, type(unicode(self.wbioe)))
        self.assertEqual(unicode, type(unicode(self.wuioe)))
        self.assertEqual(unicode, type(unicode(self.wbose)))
        self.assertEqual(unicode, type(unicode(self.wuose)))