Antonio Cuni avatar Antonio Cuni committed 7229a88 Merge

merge heads

Comments (0)

Files changed (11)

pypy/annotation/test/test_annrpython.py

 
 
 class TestAnnotateTestCase:
-    def setup_class(cls): 
-        cls.space = FlowObjSpace() 
+    def setup_class(cls):
+        cls.space = FlowObjSpace()
 
     def teardown_method(self, meth):
         assert annmodel.s_Bool == annmodel.SomeBool()
         getcdef = a.bookkeeper.getuniqueclassdef
         assert getcdef(snippet.F).attrs.keys() == ['m']
         assert getcdef(snippet.G).attrs.keys() == ['m2']
-        assert getcdef(snippet.H).attrs.keys() == ['attr'] 
+        assert getcdef(snippet.H).attrs.keys() == ['attr']
         assert getcdef(snippet.H).about_attribute('attr') == (
                           a.bookkeeper.immutablevalue(1))
 
     def test_tuple_unpack_from_const_tuple_with_different_types(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.func_arg_unpack, [])
-        assert isinstance(s, annmodel.SomeInteger) 
-        assert s.const == 3 
+        assert isinstance(s, annmodel.SomeInteger)
+        assert s.const == 3
 
     def test_pbc_attr_preserved_on_instance(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.preserve_pbc_attr_on_instance, [bool])
         #a.simplify()
         #a.translator.view()
-        assert s == annmodel.SomeInteger(nonneg=True) 
-        #self.assertEquals(s.__class__, annmodel.SomeInteger) 
+        assert s == annmodel.SomeInteger(nonneg=True)
+        #self.assertEquals(s.__class__, annmodel.SomeInteger)
 
     def test_pbc_attr_preserved_on_instance_with_slots(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.preserve_pbc_attr_on_instance_with_slots,
                           [bool])
-        assert s == annmodel.SomeInteger(nonneg=True) 
-
-    def test_is_and_knowntype_data(self): 
+        assert s == annmodel.SomeInteger(nonneg=True)
+
+    def test_is_and_knowntype_data(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.is_and_knowntype, [str])
         #a.simplify()
         #a.translator.view()
         assert s == a.bookkeeper.immutablevalue(None)
 
-    def test_isinstance_and_knowntype_data(self): 
+    def test_isinstance_and_knowntype_data(self):
         a = self.RPythonAnnotator()
         x = a.bookkeeper.immutablevalue(snippet.apbc)
-        s = a.build_types(snippet.isinstance_and_knowntype, [x]) 
+        s = a.build_types(snippet.isinstance_and_knowntype, [x])
         #a.simplify()
         #a.translator.view()
         assert s == x
         # the annotator (it doesn't check that they operate property, though)
         for example, methname, s_example in [
             ('', 'join',    annmodel.SomeString()),
-            ([], 'append',  somelist()), 
-            ([], 'extend',  somelist()),           
+            ([], 'append',  somelist()),
+            ([], 'extend',  somelist()),
             ([], 'reverse', somelist()),
             ([], 'insert',  somelist()),
             ([], 'pop',     somelist()),
         assert isinstance(s, annmodel.SomeList)
         assert s.listdef.listitem.resized
 
+    def test_str_mul(self):
+        a = self.RPythonAnnotator()
+        def f(a_str):
+            return a_str * 3
+        s = a.build_types(f, [str])
+        assert isinstance(s, annmodel.SomeString)
+
     def test_simple_slicing(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.simple_slice, [list])
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.simple_iter, [list])
         assert isinstance(s, annmodel.SomeIterator)
-        
+
     def test_simple_iter_next(self):
         def f(x):
             i = iter(range(x))
         assert listitem(s).knowntype == tuple
         assert listitem(s).items[0].knowntype == int
         assert listitem(s).items[1].knowntype == str
-        
+
     def test_dict_copy(self):
         a = self.RPythonAnnotator()
         t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.dict_values, [])
         assert isinstance(listitem(s), annmodel.SomeString)
-    
+
     def test_dict_values2(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.dict_values2, [])
         assert isinstance(dictkey(s), annmodel.SomeString)
         assert isinstance(dictvalue(s), annmodel.SomeInteger)
         assert not dictvalue(s).nonneg
-        
+
     def test_exception_deduction(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction, [])
         assert isinstance(s, annmodel.SomeInstance)
         assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
-        
+
     def test_exception_deduction_we_are_dumb(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.exception_deduction_we_are_dumb, [])
         assert isinstance(s, annmodel.SomeInstance)
         assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
-        
+
     def test_nested_exception_deduction(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.nested_exception_deduction, [])
         assert Rdef.attrs['r'].s_value.classdef == Rdef
         assert Rdef.attrs['n'].s_value.knowntype == int
         assert Rdef.attrs['m'].s_value.knowntype == int
-    
-        
+
+
     def test_propagation_of_fresh_instances_through_attrs_rec_eo(self):
         a = self.RPythonAnnotator()
         s = a.build_types(snippet.make_eo, [int])
             f1(1,2)
             g(f2)
             g(f3)
-        
+
         a = self.RPythonAnnotator()
         s = a.build_types(h, [])
 
         famA_m = mdescA_m.getcallfamily()
         famC_m = mdescC_m.getcallfamily()
         famB_n = mdescB_n.getcallfamily()
-        
+
         assert famA_m is famC_m
         assert famB_n is not famA_m
 
         gfCinit = graphof(a, C.__init__.im_func)
 
         assert famCinit.calltables == {(1, (), False, False): [{mdescCinit.funcdesc: gfCinit}] }
-        
+
     def test_isinstance_usigned(self):
         def f(x):
             return isinstance(x, r_uint)
         s = a.build_types(f, [])
         C1df = a.bookkeeper.getuniqueclassdef(C1)
         C2df = a.bookkeeper.getuniqueclassdef(C2)
-        
+
         assert s.items[0].classdef == C1df
         assert s.items[1].classdef == C2df
 
         assert a.binding(graph2.getreturnvar()).classdef == C2df
         assert graph1 in a.translator.graphs
         assert graph2 in a.translator.graphs
-    
+
     def test_specialcase_args(self):
         class C1(object):
             pass
-        
+
         class C2(object):
             pass
-        
+
         def alloc(cls, cls2):
             i = cls()
             assert isinstance(i, cls)
             j = cls2()
             assert isinstance(j, cls2)
             return i
-        
+
         def f():
             alloc(C1, C1)
             alloc(C1, C2)
             alloc(C2, C1)
             alloc(C2, C2)
-        
+
         alloc._annspecialcase_ = "specialize:arg(0,1)"
-        
+
         a = self.RPythonAnnotator()
         C1df = a.bookkeeper.getuniqueclassdef(C1)
         C2df = a.bookkeeper.getuniqueclassdef(C2)
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int, int])
-       
+
         executedesc = a.bookkeeper.getdesc(I.execute.im_func)
-        assert len(executedesc._cache) == 2       
+        assert len(executedesc._cache) == 2
 
         assert len(executedesc._cache[(0, 'star', 2)].startblock.inputargs) == 4
         assert len(executedesc._cache[(1, 'star', 3)].startblock.inputargs) == 5
         s_item = listitem(s)
         assert isinstance(s_item, annmodel.SomeInstance)
         assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
-          
+
     def test_assert_type_is_list_doesnt_lose_info(self):
         class T(object):
             pass
             x = bool(l)
             l.append(1)
             return x, bool(l)
-        
+
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
         assert s.const == False
 
         assert s.items[0].knowntype == bool and not s.items[0].is_constant()
         assert s.items[1].knowntype == bool and not s.items[1].is_constant()
-        
+
     def test_empty_dict(self):
         def f():
             d = {}
             x = bool(d)
             d['a'] = 1
             return x, bool(d)
-        
+
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
         assert s.const == False
         def witness1(x):
             pass
         def witness2(x):
-            pass        
+            pass
         def f(x):
             if 0 < x:
                 witness1(x)
         a = self.RPythonAnnotator()
         s = a.build_types(f, [annmodel.SomeInteger(unsigned=True)])
         wg1 = graphof(a, witness1)
-        wg2 = graphof(a, witness2)        
+        wg2 = graphof(a, witness2)
         assert a.binding(wg1.getargs()[0]).unsigned is True
-        assert a.binding(wg2.getargs()[0]).unsigned is True        
-        
+        assert a.binding(wg2.getargs()[0]).unsigned is True
+
     def test_general_nonneg_cleverness_is_gentle_with_unsigned(self):
         def witness1(x):
             pass
         def witness2(x):
-            pass        
+            pass
         def f(x):
             if 0 < x:
                 witness1(x)
         a = self.RPythonAnnotator()
         s = a.build_types(f, [annmodel.SomeInteger(knowntype=r_ulonglong)])
         wg1 = graphof(a, witness1)
-        wg2 = graphof(a, witness2)        
+        wg2 = graphof(a, witness2)
         assert a.binding(wg1.getargs()[0]).knowntype is r_ulonglong
         assert a.binding(wg2.getargs()[0]).knowntype is r_ulonglong
 
         assert s.const == "bool"
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int])
-        assert s.const == "int"        
+        assert s.const == "int"
         a = self.RPythonAnnotator()
         s = a.build_types(f, [float])
-        assert s.const == "dontknow"        
-        
+        assert s.const == "dontknow"
+
     def test_hidden_method(self):
         class Base:
             def method(self):
         s = a.build_types(f, [])
         assert s.knowntype == bool
         assert not s.is_constant()
-            
+
     def test_const_dict_and_none(self):
         def g(d=None):
             return d is None
         s = a.build_types(f, [])
         assert s.knowntype == bool
         assert not s.is_constant()
-                        
+
     def test_issubtype_and_const(self):
         class A(object):
             pass
         a = annrpython.RPythonAnnotator()
         from pypy.annotation import model as annmodel
 
-        s_f = a.bookkeeper.immutablevalue(f) 
+        s_f = a.bookkeeper.immutablevalue(f)
         a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
         a.complete()
 
 
         someint = annmodel.SomeInteger()
 
-        assert (fdesc.get_s_signatures((2,(),False,False)) 
+        assert (fdesc.get_s_signatures((2,(),False,False))
                 == [([someint,someint],someint)])
 
     def test_emulated_pbc_call_callback(self):
         def callb(ann, graph):
             memo.append(annmodel.SomeInteger() == ann.binding(graph.getreturnvar()))
 
-        s_f = a.bookkeeper.immutablevalue(f) 
+        s_f = a.bookkeeper.immutablevalue(f)
         s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
                                           callback=callb)
         assert s == annmodel.SomeImpossibleValue()
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeIterator)
         assert s.variant == ('items',)
-        
+
     def test_non_none_and_none_with_isinstance(self):
         class A(object):
             pass
         def f(i):
             witness(None)
             return witness(get(i))
-            
+
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int])
         assert s.__class__ == annmodel.SomeObject
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
         assert isinstance(s.items[0], annmodel.SomeInteger)
-        assert isinstance(s.items[1], annmodel.SomeChar)        
-        assert isinstance(s.items[2], annmodel.SomeChar)        
+        assert isinstance(s.items[1], annmodel.SomeChar)
+        assert isinstance(s.items[2], annmodel.SomeChar)
 
     def test___class___attribute(self):
         class Base(object): pass
         a = self.RPythonAnnotator()
         s = a.build_types(f, [bool])
         assert s.knowntype == int
-        
+
 
         def f(x):
             return -x
             assert isinstance(s, annmodel.SomeInteger)
             assert s.knowntype == inttype
             assert s.unsigned == (inttype(-1) > 0)
-            
+
         for inttype in inttypes:
             def f():
                 return inttype(0)
     def test_helper_method_annotator(self):
         def fun():
             return 21
-        
+
         class A(object):
             def helper(self):
                 return 42
-        
+
         a = self.RPythonAnnotator()
         a.build_types(fun, [])
         a.annotate_helper_method(A, "helper", [])
 
         def c(x):
             return int(x)
-        
+
         def g(a, x):
             if x == -1:
                 a = None
                 x = x + .01
             return a(x)
 
-        #def fun(x):   
+        #def fun(x):
 
         a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
         s = a.build_types(g, [annmodel.SomeGenericCallable(
         class B(A):
             def meth(self):
                 return self
-        class C(A): 
+        class C(A):
             def meth(self):
                 return self
 
             i.x = x
 
         a = self.RPythonAnnotator()
-        py.test.raises(Exception, a.build_types, f, [])        
+        py.test.raises(Exception, a.build_types, f, [])
 
 
         class M:
                 self.l2 = []
 
         c = C()
-         
+
         def f():
             x = A()
             x = hint(x, access_directly=True)
             c.m.l.append(x)
 
         a = self.RPythonAnnotator()
-        py.test.raises(AssertionError, a.build_types, f, [])        
+        py.test.raises(AssertionError, a.build_types, f, [])
 
         def f():
             x = A()
             x = hint(x, access_directly=True)
             c.m.d[None] = x
-            
+
         a = self.RPythonAnnotator()
-        py.test.raises(AssertionError, a.build_types, f, [])        
+        py.test.raises(AssertionError, a.build_types, f, [])
 
         def f():
             x = A()
             x = hint(x, access_directly=True)
             c.m.d[x] = None
-            
+
         a = self.RPythonAnnotator()
-        py.test.raises(AssertionError, a.build_types, f, [])        
+        py.test.raises(AssertionError, a.build_types, f, [])
 
     def test_ctr_location(self):
         from pypy.rlib.jit import hint
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [])
-        assert isinstance(s, annmodel.SomeUnicodeString)        
+        assert isinstance(s, annmodel.SomeUnicodeString)
 
     def test_unicode(self):
         def g(n):
         a = self.RPythonAnnotator()
         s = a.build_types(f, [str])
         assert isinstance(s, annmodel.SomeString)
-        
+
         def f(x):
             return u'a'.replace(x, u'b')
 
                 if c == i:
                     return c
             return 'x'
-            
+
         a = self.RPythonAnnotator()
         s = a.build_types(f, [unicode, str])
         assert isinstance(s, annmodel.SomeUnicodeCodePoint)
     def test_strformatting_unicode(self):
         def f(x):
             return '%s' % unichr(x)
-            
+
         a = self.RPythonAnnotator()
         py.test.raises(NotImplementedError, a.build_types, f, [int])
         def f(x):
             return '%s' % (unichr(x) * 3)
-            
+
         a = self.RPythonAnnotator()
         py.test.raises(NotImplementedError, a.build_types, f, [int])
         def f(x):
             return '%s%s' % (1, unichr(x))
-            
+
         a = self.RPythonAnnotator()
         py.test.raises(NotImplementedError, a.build_types, f, [int])
         def f(x):
             return '%s%s' % (1, unichr(x) * 15)
-            
+
         a = self.RPythonAnnotator()
         py.test.raises(NotImplementedError, a.build_types, f, [int])
 
             called.append(True)
             assert not ann.listdef.listitem.mutated
             ann.listdef.never_resize()
-        
+
         def f():
             l = [1,2,3]
             check_annotation(l, checker)
 
     def test_listitem_no_mutating2(self):
         from pypy.rlib.debug import make_sure_not_resized
-        
+
         def f():
             return make_sure_not_resized([1,2,3])
 
                     return d1[x].meth()
                 d1[i+1] = A()
             return 0
-                
+
         a = self.RPythonAnnotator()
         s = a.build_types(g, [int, int])
         assert s.knowntype is int
-        
+
         def f(x):
             d0 = {}
             if x in d0:
     return total
 
 constant_unsigned_five = r_uint(5)
-        
+
 class Freezing:
     def _freeze_(self):
         return True

pypy/interpreter/astcompiler/assemble.py

         while True:
             extended_arg_count = 0
             offset = 0
+            force_redo = False
             # Calculate the code offset of each block.
             for block in blocks:
                 block.offset = offset
                                     instr.has_jump = False
                                     # The size of the code changed,
                                     # we have to trigger another pass
-                                    extended_arg_count += 1
+                                    force_redo = True
                                     continue
                         if absolute:
                             jump_arg = target.offset
                         instr.arg = jump_arg
                         if jump_arg > 0xFFFF:
                             extended_arg_count += 1
-            if extended_arg_count == last_extended_arg_count:
+            if extended_arg_count == last_extended_arg_count and not force_redo:
                 break
             else:
                 last_extended_arg_count = extended_arg_count

pypy/interpreter/astcompiler/test/test_compiler.py

     def error_test(self, source, exc_type):
         py.test.raises(exc_type, self.simple_test, source, None, None)
 
+    def test_issue_713(self):
+        func = "def f(_=2): return (_ if _ else _) if False else _"
+        yield self.st, func, "f()", 2
+
     def test_long_jump(self):
         func = """def f(x):
     y = 0

pypy/objspace/std/stringobject.py

 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.rlib.rstring import StringBuilder, string_repeat
+from pypy.rlib.rstring import StringBuilder
 from pypy.interpreter.buffer import StringBuffer
 
 from pypy.objspace.std.stringtype import sliced, wrapstr, wrapchar, \
     if len(input) == 1:
         s = input[0] * mul
     else:
-        s = string_repeat(input, mul)
+        s = input * mul
     # xxx support again space.config.objspace.std.withstrjoin?
     return W_StringObject(s)
 
                 space.wrap("translation table must be 256 characters long"))
 
     string = w_string._value
-    chars = []
     deletechars = space.str_w(w_deletechars)
     if len(deletechars) == 0:
+        buf = StringBuilder(len(string))
         for char in string:
-            chars.append(table[ord(char)])
+            buf.append(table[ord(char)])
     else:
+        buf = StringBuilder()
         deletion_table = [False] * 256
         for c in deletechars:
             deletion_table[ord(c)] = True
         for char in string:
             if not deletion_table[ord(char)]:
-                chars.append(table[ord(char)])
-    return W_StringObject(''.join(chars))
+                buf.append(table[ord(char)])
+    return W_StringObject(buf.build())
 
 def str_decode__String_ANY_ANY(space, w_string, w_encoding=None, w_errors=None):
     from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \

pypy/objspace/std/unicodeobject.py

 from pypy.objspace.std.tupleobject import W_TupleObject
 from pypy.rlib.rarithmetic import intmask, ovfcheck
 from pypy.rlib.objectmodel import compute_hash
-from pypy.rlib.rstring import UnicodeBuilder, string_repeat
+from pypy.rlib.rstring import UnicodeBuilder
 from pypy.rlib.runicode import unicode_encode_unicode_escape
 from pypy.module.unicodedata import unicodedb
 from pypy.tool.sourcetools import func_with_new_name
     if len(input) == 1:
         result = input[0] * times
     else:
-        result = string_repeat(input, times)
+        result = input * times
     return W_UnicodeObject(result)
 
 def mul__ANY_Unicode(space, w_times, w_uni):

pypy/rlib/rstring.py

 
 from pypy.annotation.model import SomeObject, SomeString, s_None,\
      SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString
-from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.extregistry import ExtRegistryEntry
 
 
     tp = unicode
 
 
-# XXX: This does log(mul) mallocs, the GCs probably make that efficient, but
-# some measurement should be done at some point.
-def string_repeat(s, mul):
-    """Repeat a string or unicode.  Note that this assumes that 'mul' > 0."""
-    result = None
-    factor = 1
-    assert mul > 0
-    try:
-        ovfcheck(len(s) * mul)
-    except OverflowError:
-        raise MemoryError
-    
-    limit = mul >> 1
-    while True:
-        if mul & factor:
-            if result is None:
-                result = s
-            else:
-                result = s + result
-            if factor > limit:
-                break
-        s += s
-        factor *= 2
-    return result
-string_repeat._annspecialcase_ = 'specialize:argtype(0)'
-
 # ------------------------------------------------------------
 # ----------------- implementation details -------------------
 # ------------------------------------------------------------
 
     def method_build(self):
         return SomeUnicodeString()
-    
+
     def rtyper_makerepr(self, rtyper):
         return rtyper.type_system.rbuilder.unicodebuilder_repr
 
         if self.use_unicode:
             return SomeUnicodeBuilder()
         return SomeStringBuilder()
-    
+
     def specialize_call(self, hop):
         return hop.r_result.rtyper_new(hop)
 

pypy/rlib/test/test_rstring.py

 import sys
 
-from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit, \
-    string_repeat
+from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit
 
 
 def test_split():
     assert s.getlength() == len('aabcb')
     s.append_multiple_char(u'd', 4)
     assert s.build() == 'aabcbdddd'
-    assert isinstance(s.build(), unicode)
-
-def test_string_repeat():
-    raises(MemoryError, string_repeat, "abc", sys.maxint)
+    assert isinstance(s.build(), unicode)

pypy/rpython/lltypesystem/rstr.py

 from pypy.rlib.objectmodel import _hash_string, enforceargs
 from pypy.rlib.debug import ll_assert
 from pypy.rlib.jit import purefunction, we_are_jitted
+from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
 from pypy.rpython.rmodel import inputconst, IntegerRepr
 from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
 
 
 class LLHelpers(AbstractLLHelpers):
+    @purefunction
+    def ll_str_mul(s, times):
+        if times < 0:
+            times = 0
+        try:
+            size = ovfcheck(len(s.chars) * times)
+        except OverflowError:
+            raise MemoryError
+        newstr = s.malloc(size)
+        i = 0
+        if i < size:
+            s.copy_contents(s, newstr, 0, 0, len(s.chars))
+            i += len(s.chars)
+        while i < size:
+            if i <= size - i:
+                j = i
+            else:
+                j = size - i
+            s.copy_contents(newstr, newstr, 0, i, j)
+            i += j
+        return newstr
 
     @purefunction
     def ll_char_mul(ch, times):

pypy/rpython/ootypesystem/rstr.py

 from pypy.tool.pairtype import pairtype
+from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.error import TyperError
 from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
      AbstractUniCharRepr, AbstractStringIteratorRepr,\
             i+= 1
         return buf.ll_build()
 
+    def ll_str_mul(s, times):
+        if times < 0:
+            times = 0
+        try:
+            size = ovfcheck(s.ll_strlen() * times)
+        except OverflowError:
+            raise MemoryError
+        buf = ootype.new(typeOf(s).builder)
+        buf.ll_allocate(size)
+        for i in xrange(times):
+            buf.ll_append(s)
+        return buf.ll_build()
+
     def ll_streq(s1, s2):
         if s1 is None:
             return s2 is None
         return s.ll_substring(start, s.ll_strlen() - start)
 
     def ll_stringslice_startstop(s, start, stop):
-        length = s.ll_strlen()        
+        length = s.ll_strlen()
         if stop > length:
             stop = length
         return s.ll_substring(start, stop-start)
 
     def ll_float(ll_str):
         return ootype.ooparse_float(ll_str)
-    
+
     # interface to build strings:
     #   x = ll_build_start(n)
     #   ll_build_push(x, next_string, 0)
         c8 = hop.inputconst(ootype.Signed, 8)
         c10 = hop.inputconst(ootype.Signed, 10)
         c16 = hop.inputconst(ootype.Signed, 16)
-        c_StringBuilder = hop.inputconst(ootype.Void, ootype.StringBuilder)        
+        c_StringBuilder = hop.inputconst(ootype.Void, ootype.StringBuilder)
         v_buf = hop.genop("new", [c_StringBuilder], resulttype=ootype.StringBuilder)
 
         things = cls.parse_fmt_string(s)
             hop.genop('oosend', [c_append, v_buf, vchunk], resulttype=ootype.Void)
 
         hop.exception_cannot_occur()   # to ignore the ZeroDivisionError of '%'
-        return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String)        
+        return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String)
     do_stringformat = classmethod(do_stringformat)
 
 
     return iter
 
 def ll_strnext(iter):
-    string = iter.string    
+    string = iter.string
     index = iter.index
     if index >= string.ll_strlen():
         raise StopIteration

pypy/rpython/rstr.py

 class __extend__(annmodel.SomeUnicodeString):
     def rtyper_makerepr(self, rtyper):
         return rtyper.type_system.rstr.unicode_repr
-    
+
     def rtyper_makekey(self):
         return self.__class__,
 
         v_str, = hop.inputargs(string_repr)
         hop.exception_cannot_occur()
         return hop.gendirectcall(self.ll.ll_upper, v_str)
-        
+
     def rtype_method_lower(self, hop):
         string_repr = hop.args_r[0].repr
         v_str, = hop.inputargs(string_repr)
 
     rtype_getitem_idx_key = rtype_getitem_idx
 
+    def rtype_mul((r_str, r_int), hop):
+        str_repr = r_str.repr
+        v_str, v_int = hop.inputargs(str_repr, Signed)
+        return hop.gendirectcall(r_str.ll.ll_str_mul, v_str, v_int)
+    rtype_inplace_mul = rtype_mul
+
+class __extend__(pairtype(IntegerRepr, AbstractStringRepr)):
+    def rtype_mul((r_int, r_str), hop):
+        return pair(r_str, r_int).rtype_mul(hop)
+    rtype_inplace_mul = rtype_mul
+
 
 class __extend__(AbstractStringRepr):
 
     def rtype_eq((r_str1, r_str2), hop):
         v_str1, v_str2 = hop.inputargs(r_str1.repr, r_str2.repr)
         return hop.gendirectcall(r_str1.ll.ll_streq, v_str1, v_str2)
-    
+
     def rtype_ne((r_str1, r_str2), hop):
         v_str1, v_str2 = hop.inputargs(r_str1.repr, r_str2.repr)
         vres = hop.gendirectcall(r_str1.ll.ll_streq, v_str1, v_str2)
         return value
 
     def get_ll_eq_function(self):
-        return None 
+        return None
 
     def get_ll_hash_function(self):
         return self.ll.ll_char_hash
 
 class __extend__(pairtype(AbstractCharRepr, IntegerRepr),
                  pairtype(AbstractUniCharRepr, IntegerRepr)):
-    
+
     def rtype_mul((r_chr, r_int), hop):
         char_repr = r_chr.char_repr
         v_char, v_int = hop.inputargs(char_repr, Signed)
         return value
 
     def get_ll_eq_function(self):
-        return None 
+        return None
 
     def get_ll_hash_function(self):
         return self.ll.ll_unichar_hash

pypy/rpython/test/test_rstr.py

         for i in range(3):
             res = self.interpret(fn, [i])
             assert res is True
-        
+
     def test_char_constant(self):
         const = self.const
         def fn(s):
         res = self.interpret(fn, [const('5'), 3])
         assert res == 5551
 
+    def test_str_mul(self):
+        const = self.const
+        def fn(i, mul):
+            s = ["", "a", "aba"][i]
+            return s * mul
+        for i in xrange(3):
+            for m in [0, 1, 4]:
+                res = self.interpret(fn, [i, m])
+                assert self.ll_to_string(res) == fn(i, m)
+
     def test_is_none(self):
         const = self.const
         def fn(i):
         for i, expected in enumerate([0, 1110, 2220, 3330, -1110, -1110]):
             res = self.interpret(f, [i])
             assert res == expected
-            
+
     def test_rfind(self):
         const = self.const
         def fn():
         assert res.find('>, much nicer than <D object') != -1
 
         res = self.ll_to_string(self.interpret(dummy, [0]))
-        res = res.replace('pypy.rpython.test.test_rstr.', '')        
+        res = res.replace('pypy.rpython.test.test_rstr.', '')
         assert res.find('what a nice <D object') != -1
         assert res.find('>, much nicer than <C object') != -1
 
             return const('ababa').count(const('aba'))
         res = self.interpret(fn, [])
         assert res == 1
-       
+
     def test_count_TyperError(self):
         const = self.const
         def f():
             s = const('abc')
             s.count(s, -10)
         raises(TyperError, self.interpret, f, ())
-    
+
     def test_getitem_exc(self):
         const = self.const
         def f(x):
             pass
         else:
             assert False
-    
+
         def f(x):
             s = const("z")
             try:
         res = self.interpret(f, [0])
         assert res == 'z'
         res = self.interpret(f, [1])
-        assert res == 'X'        
+        assert res == 'X'
 
         def f(x):
             s = const("z")
 
         assert self.ll_to_string(self.interpret(f, [1,
                                        self.string_to_ll('abc')])) == 'ababc'
-        
+
     def test_hlstr(self):
         const = self.const
         from pypy.rpython.annlowlevel import hlstr
 
     def test_ll_find_rfind(self):
         llstr = self.string_to_ll
-        
+
         for i in range(50):
             n1 = random.randint(0, 10)
             s1 = ''.join([random.choice("ab") for i in range(n1)])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.