def _test_index(self, i): fmt = M.FormatString('%2$.*{0}$f'.format(i)) assert_equal(len(fmt), 1) assert_equal(len(fmt.arguments), 2) [a1], [a2] = fmt.arguments assert_equal(a1.type, 'int') assert_equal(a2.type, 'double')
def t(self, s, n, tp=M.Conversion): fmt = M.FormatString(s) conv = fmt.get_last_integer_conversion(n=n) if tp is None: tp = type(tp) assert_is_instance(conv, tp) return conv
def test_text(): fmt = M.FormatString('eggs%dbacon%dspam') assert_equal(len(fmt), 5) fmt = list(fmt) assert_equal(fmt[0], 'eggs') assert_equal(fmt[2], 'bacon') assert_equal(fmt[4], 'spam')
def test_variable(self): fmt = M.FormatString('%*s') assert_equal(len(fmt), 1) assert_equal(len(fmt.arguments), 2) [a1], [a2] = fmt.arguments assert_equal(a1.type, 'int') assert_equal(a2.type, 'const char *')
def test_variable(self): fmt = M.FormatString('%.*f') assert_equal(len(fmt), 1) assert_equal(len(fmt.arguments), 2) [a1], [a2] = fmt.arguments assert_equal(a1.type, 'int') assert_equal(a2.type, 'double')
def test_too_many_conversions(): def t(s): with assert_raises(M.ArgumentRangeError): M.FormatString(s) s = M.NL_ARGMAX * '%d' fmt = M.FormatString(s) assert_equal(len(fmt), M.NL_ARGMAX) t(s + '%f') t(s + '%*f') t(s + '%.*f')
def test_index_out_of_range(self): with assert_raises(M.ArgumentRangeError): M.FormatString('%0$d') def fs(n): s = ''.join('%{0}$d'.format(i) for i in range(1, n + 1)) return M.FormatString(s) fmt = fs(M.NL_ARGMAX) assert_equal(len(fmt), M.NL_ARGMAX) assert_equal(len(fmt.arguments), M.NL_ARGMAX) with assert_raises(M.ArgumentRangeError): fs(M.NL_ARGMAX + 1)
def check_string(self, ctx, message, s): prefix = message_repr(message, template='{}:') fmt = None try: fmt = backend.FormatString(s) except backend.MissingArgument as exc: self.tag( 'c-format-string-error', prefix, tags.safestr(exc.message), tags.safestr('{1}$'.format(*exc.args)), ) except backend.ArgumentTypeMismatch as exc: self.tag( 'c-format-string-error', prefix, tags.safestr(exc.message), tags.safestr('{1}$'.format(*exc.args)), tags.safestr(', '.join(sorted(x for x in exc.args[2]))), ) except backend.FlagError as exc: [conv, flag] = exc.args # pylint: disable=unbalanced-tuple-unpacking self.tag('c-format-string-error', prefix, tags.safestr(exc.message), flag, tags.safestr('in'), conv) except backend.Error as exc: self.tag('c-format-string-error', prefix, tags.safestr(exc.message), *exc.args[:1]) if fmt is None: return for warn in fmt.warnings: try: raise warn except backend.RedundantFlag as exc: if len(exc.args) == 2: [s, *args] = exc.args else: [s, a1, a2] = exc.args if a1 == a2: args = ['duplicate', a1] else: args = [a1, tags.safe_format('overridden by {}', a2)] args += ['in', s] self.tag('c-format-string-redundant-flag', prefix, *args) except backend.NonPortableConversion as exc: [s, c1, c2] = exc.args args = [c1, '=>', c2] if s != c1: args += ['in', s] self.tag('c-format-string-non-portable-conversion', prefix, *args) return fmt
def t(self, s, tp, warn_type=None, integer=False): fmt = M.FormatString(s) [conv] = fmt assert_is_instance(conv, M.Conversion) assert_equal(conv.type, tp) if tp == 'void': assert_sequence_equal(fmt.arguments, []) else: [[arg]] = fmt.arguments assert_equal(arg.type, tp) if warn_type is None: assert_sequence_equal(fmt.warnings, []) else: [warning] = fmt.warnings assert_is_instance(warning, warn_type) assert_equal(conv.integer, integer)
def test_overflow(self): fmt = M.FormatString('%s%d') for n in [-1, 0, 3]: with assert_raises(IndexError): fmt.get_last_integer_conversion(n=n)
def t(s): with assert_raises(M.ArgumentRangeError): M.FormatString(s)
def test_gap(self): with assert_raises(M.MissingArgument): M.FormatString('%3$d%1$d')
def t(s): with assert_raises(M.ArgumentTypeMismatch): M.FormatString(s)
def test_invalid(self): for c in '%n': with assert_raises(M.WidthError): M.FormatString('%1' + c)
def fs(n): s = ''.join('%{0}$d'.format(i) for i in range(1, n + 1)) return M.FormatString(s)
def test_invalid_conversion_spec(): with assert_raises(M.Error): M.FormatString('%!')
def t(self, s): fmt = M.FormatString(s) [exc] = fmt.warnings assert_is_instance(exc, M.RedundantFlag)
def t(self, s): with assert_raises(M.FlagError): M.FormatString(s)
def test_too_large(self): fmt = M.FormatString('%.{0}f'.format(M.INT_MAX)) assert_equal(len(fmt), 1) with assert_raises(M.PrecisionRangeError): M.FormatString('%.{0}f'.format(M.INT_MAX + 1))
def t(s): with assert_raises(M.PrecisionError): M.FormatString(s)
def t(s): fmt = M.FormatString(s) assert_equal(len(fmt), 1) assert_sequence_equal(fmt.warnings, [])
def t(s): fmt = M.FormatString(s) assert_equal(len(fmt), 1) [warning] = fmt.warnings assert_is_instance(warning, M.RedundantFlag)
def t(s): fmt = M.FormatString(s) assert_equal(len(fmt), 1)
def test_initial_gap(self): with assert_raises(M.MissingArgument): M.FormatString('%2$d')
def test_lone_percent(): with assert_raises(M.Error): M.FormatString('%')
def fs(n): s = ''.join('%{0}$d'.format(i) for i in range(2, n)) + '%1$.*{0}$f'.format(n) return M.FormatString(s)
def test_add_argument(): fmt = M.FormatString('%s') with assert_raises(RuntimeError): fmt.add_argument(2, None)
def t(s): with assert_raises(M.ArgumentNumberingMixture): M.FormatString(s)
def t(s, tp): fmt = M.FormatString(s) [args] = fmt.arguments assert_greater(len(args), 1) for arg in args: assert_equal(arg.type, tp)
def test_too_large(self): fmt = M.FormatString('%{0}d'.format(M.INT_MAX)) assert_equal(len(fmt), 1) assert_equal(len(fmt.arguments), 1) with assert_raises(M.WidthRangeError): M.FormatString('%{0}d'.format(M.INT_MAX + 1))