Commits

Armin Rigo committed 1c370a3 Merge

hg merge default

Comments (0)

Files changed (21)

 20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0
 0000000000000000000000000000000000000000 release-2.3.0
 394146e9bb673514c61f0150ab2013ccf78e8de7 release-2.3
+32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
+32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1
+32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
+0000000000000000000000000000000000000000 release-2.2=3.1

pypy/config/pypyoption.py

             try:
                 for name in modlist:
                     __import__(name)
-            except (ImportError, CompilationError, py.test.skip.Exception), e:
+            except (ImportError, CompilationError, py.test.skip.Exception) as e:
                 errcls = e.__class__.__name__
                 raise Exception(
                     "The module %r is disabled\n" % (modname,) +

pypy/doc/coding-guide.rst

         while True:
             try:
                 w_key = space.next(w_iter)
-            except OperationError, e:
+            except OperationError as e:
                 if not e.match(space, space.w_StopIteration):
                     raise       # re-raise other app-level exceptions
                 break
 
     try:
         ...
-    except OperationError, e:
+    except OperationError as e:
         if not e.match(space, space.w_XxxError):
             raise
         ...

pypy/doc/index-of-release-notes.rst

 
 .. toctree::
 
+   release-2.3.1.rst
    release-2.3.0.rst
    release-2.2.1.rst
    release-2.2.0.rst

pypy/doc/index.rst

 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 2.3.0`_: the latest official release
+* `Release 2.3.1`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 2.3.0`: http://pypy.org/download.html
+.. _`Release 2.3.1`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html

pypy/doc/whatsnew-head.rst

 =======================
 
 .. this is a revision shortly after release-2.3.x
-.. startrev: 87fdc76bccb4
+.. startrev: ca9b7cf02cf4
 
 

pypy/module/micronumpy/tool/numready/page.html

         <h3>numpy compatability test results, generated automatically by running</br>
         <code>pypy/module/micronumpy/tool/numready/main.py &lt;path-to-latest-pypy&gt;</code></h3>
         <h3>Overall: {{ msg }}</h3>
+        <h3><i><b>Warning:</b> a positive result does not mean the function is actually working!  It only means that the function/module/constant is present.  It may be missing other things.</h3>
         <table>
             <thead>
                 <tr>

rpython/annotator/test/test_annrpython.py

         assert isinstance(s, annmodel.SomeTuple)
         assert s.items[1].const == 42
 
+    def test_unpack_none_gets_a_blocked_block(self):
+        def f(x):
+            a, b = x
+        a = self.RPythonAnnotator()
+        py.test.raises(annmodel.AnnotatorError,
+                       a.build_types, f, [annmodel.s_None])
+
 
 def g(n):
     return [0, 1, 2, n]

rpython/annotator/unaryop.py

         s.const = False
 
     def len(self):
-        # XXX: this None could later be generalized into an empty list,
-        # whose length is the constant 0; so let's tentatively answer 0.
-        return immutablevalue(0)
+        # This None could later be generalized into a list, for example.
+        # For now, we give the impossible answer (because len(None) would
+        # really crash translated code).  It can be generalized later.
+        return SomeImpossibleValue()
 
 #_________________________________________
 # weakrefs

rpython/config/config.py

     def setoption(self, config, value, who):
         try:
             super(IntOption, self).setoption(config, int(value), who)
-        except TypeError, e:
+        except TypeError as e:
             raise ConfigError(*e.args)
 
 
     def setoption(self, config, value, who):
         try:
             super(FloatOption, self).setoption(config, float(value), who)
-        except TypeError, e:
+        except TypeError as e:
             raise ConfigError(*e.args)
 
 
     def setoption(self, config, value, who):
         try:
             super(StrOption, self).setoption(config, value, who)
-        except TypeError, e:
+        except TypeError as e:
             raise ConfigError(*e.args)
 
 
         try:
             value = self.convert_from_cmdline(value)
             self.config.setoption(self.option._name, value, who='cmdline')
-        except ConfigError, e:
+        except ConfigError as e:
             # This OptionValueError is going to exit the translate.py process.
             # Now is the last chance to print the warnings, which might give
             # more information...  hack.

rpython/jit/metainterp/heapcache.py

         # escaped the trace or not (True means the box never escaped, False
         # means it did escape), its presences in the mapping shows that it was
         # allocated inside the trace
+        self.new_boxes = {}
         if reset_virtuals:
-            self.new_boxes = {}
+            self.likely_virtuals = {}      # only for jit.isvirtual()
         # Tracks which boxes should be marked as escaped when the key box
         # escapes.
         self.dependencies = {}
               opnum != rop.PTR_NE and
               opnum != rop.INSTANCE_PTR_EQ and
               opnum != rop.INSTANCE_PTR_NE):
-            idx = 0
             for box in argboxes:
-                # setarrayitem_gc don't escape its first argument
-                if not (idx == 0 and opnum in [rop.SETARRAYITEM_GC]):
-                    self._escape(box)
-                idx += 1
+                self._escape(box)
 
     def _escape(self, box):
         try:
             if unescaped:
                 self.new_boxes[box] = False
         try:
+            del self.likely_virtuals[box]
+        except KeyError:
+            pass
+        try:
             deps = self.dependencies.pop(box)
         except KeyError:
             pass
             opnum == rop.SETARRAYITEM_RAW or
             opnum == rop.SETINTERIORFIELD_GC or
             opnum == rop.COPYSTRCONTENT or
-            opnum == rop.COPYUNICODECONTENT):
+            opnum == rop.COPYUNICODECONTENT or
+            opnum == rop.STRSETITEM or
+            opnum == rop.UNICODESETITEM or
+            opnum == rop.SETFIELD_RAW or
+            opnum == rop.SETARRAYITEM_RAW or
+            opnum == rop.SETINTERIORFIELD_RAW or
+            opnum == rop.RAW_STORE):
             return
         if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST or
             rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST or
                                 if not self.is_unescaped(frombox):
                                     del cache[frombox]
                     return
-            else:
-                # Only invalidate things that are either escaped or arguments
-                for descr, boxes in self.heap_cache.iteritems():
-                    for box in boxes.keys():
-                        if not self.is_unescaped(box) or box in argboxes:
-                            del boxes[box]
-                for descr, indices in self.heap_array_cache.iteritems():
-                    for boxes in indices.itervalues():
-                        for box in boxes.keys():
-                            if not self.is_unescaped(box) or box in argboxes:
-                                del boxes[box]
-                return
 
-        # XXX when is it useful to clear() the complete dictionaries?
-        # isn't it enough in all cases to do the same as the two
-        # loops just above?
-        self.heap_cache.clear()
-        self.heap_array_cache.clear()
+        # Only invalidate things that are either escaped or arguments
+        for descr, boxes in self.heap_cache.iteritems():
+            for box in boxes.keys():
+                if not self.is_unescaped(box) or box in argboxes:
+                    del boxes[box]
+        for descr, indices in self.heap_array_cache.iteritems():
+            for boxes in indices.itervalues():
+                for box in boxes.keys():
+                    if not self.is_unescaped(box) or box in argboxes:
+                        del boxes[box]
 
     def is_class_known(self, box):
         return box in self.known_class_boxes
     def is_unescaped(self, box):
         return self.new_boxes.get(box, False)
 
+    def is_likely_virtual(self, box):
+        return box in self.likely_virtuals
+
     def new(self, box):
         self.new_boxes[box] = True
+        self.likely_virtuals[box] = None
 
     def new_array(self, box, lengthbox):
         self.new(box)

rpython/jit/metainterp/pyjitpl.py

 
     @arguments("box")
     def _opimpl_isvirtual(self, box):
-        return ConstInt(self.metainterp.heapcache.is_unescaped(box))
+        return ConstInt(self.metainterp.heapcache.is_likely_virtual(box))
 
     opimpl_ref_isvirtual = _opimpl_isvirtual
 

rpython/jit/metainterp/test/test_heapcache.py

             []
         )
         assert h.getarrayitem(box1, index1, descr1) is box3
+
+    def test_bug_missing_ignored_operations(self):
+        h = HeapCache()
+        h.new(box1)
+        h.new(box2)
+        h.setfield(box1, box2, descr1)
+        assert h.getfield(box1, descr1) is box2
+        h.invalidate_caches(rop.STRSETITEM, None, [])
+        h.invalidate_caches(rop.UNICODESETITEM, None, [])
+        h.invalidate_caches(rop.SETFIELD_RAW, None, [])
+        h.invalidate_caches(rop.SETARRAYITEM_RAW, None, [])
+        h.invalidate_caches(rop.SETINTERIORFIELD_RAW, None, [])
+        h.invalidate_caches(rop.RAW_STORE, None, [])
+        assert h.is_unescaped(box1)
+        assert h.is_unescaped(box2)
+        assert h.getfield(box1, descr1) is box2
+
+    def test_bug_heap_cache_is_cleared_but_not_is_unescaped(self):
+        # bug if only the getfield() link is cleared (heap_cache) but not
+        # the is_unescaped() flags: we can do later a GETFIELD(box1) which
+        # will give us a fresh box3, which is actually equal to box2.  This
+        # box3 is escaped, but box2 is still unescaped.  Bug shown e.g. by
+        # calling some residual code that changes the values on box3: then
+        # the content of box2 is still cached at the old value.
+        h = HeapCache()
+        h.new(box1)
+        h.new(box2)
+        h.setfield(box1, box2, descr1)
+        h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2])
+        assert h.getfield(box1, descr1) is box2
+        h.invalidate_caches(rop.CALL_MAY_FORCE, None, [])
+        assert h.is_unescaped(box1)
+        assert h.is_unescaped(box2)
+        assert h.getfield(box1, descr1) is box2
+
+    def test_is_likely_virtual(self):
+        h = HeapCache()
+        h.new(box1)
+        assert h.is_unescaped(box1)
+        assert h.is_likely_virtual(box1)
+        h.reset(reset_virtuals=False)
+        assert not h.is_unescaped(box1)
+        assert h.is_likely_virtual(box1)
+        h._escape(box1)
+        assert not h.is_unescaped(box1)
+        assert not h.is_likely_virtual(box1)

rpython/jit/metainterp/test/test_list.py

     def test_cannot_be_virtual(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 'l'])
         def f(n):
-            l = [3] * 100
+            l = [3] * 200
             while n > 0:
                 jitdriver.can_enter_jit(n=n, l=l)
                 jitdriver.jit_merge_point(n=n, l=l)
                 x = l[n]
-                l = [3] * 100
+                l = [3] * 200
                 l[3] = x
                 l[4] = x + 1
                 n -= 1

rpython/rlib/rsre/rsre_core.py

                 marks = p.marks
                 enum = p.enum.move_to_next_result(ctx)
             #
-            # zero-width match protection
             min = ctx.pat(ppos+1)
-            if self.num_pending >= min:
-                while enum is not None and ptr == ctx.match_end:
-                    enum = enum.move_to_next_result(ctx)
-                    # matched marks for zero-width assertions
-                    marks = ctx.match_marks
-            #
             if enum is not None:
                 # matched one more 'item'.  record it and continue.
+                last_match_length = ctx.match_end - ptr
                 self.pending = Pending(ptr, marks, enum, self.pending)
                 self.num_pending += 1
                 ptr = ctx.match_end
                 marks = ctx.match_marks
-                match_more = True
-            else:
-                # 'item' no longer matches.
-                if self.num_pending >= min:
-                    # try to match 'tail' if we have enough 'item'
-                    result = sre_match(ctx, tailppos, ptr, marks)
-                    if result is not None:
-                        self.subresult = result
-                        self.cur_ptr = ptr
-                        self.cur_marks = marks
-                        return self
-                match_more = False
+                if last_match_length == 0 and self.num_pending >= min:
+                    # zero-width protection: after an empty match, if there
+                    # are enough matches, don't try to match more.  Instead,
+                    # fall through to trying to match 'tail'.
+                    pass
+                else:
+                    match_more = True
+                    continue
+
+            # 'item' no longer matches.
+            if self.num_pending >= min:
+                # try to match 'tail' if we have enough 'item'
+                result = sre_match(ctx, tailppos, ptr, marks)
+                if result is not None:
+                    self.subresult = result
+                    self.cur_ptr = ptr
+                    self.cur_marks = marks
+                    return self
+            match_more = False
 
 class MinUntilMatchResult(AbstractUntilMatchResult):
 

rpython/rlib/rsre/test/test_match.py

         match = rsre_core.match(r, "abbbbbbbbbcdef")
         assert match
         assert match.match_end == 11
+
+    def test_empty_maxuntil(self):
+        r = get_code("\\{\\{((?:.*?)+)\\}\\}")
+        match = rsre_core.match(r, "{{a}}{{b}}")
+        assert match.group(1) == "a"

rpython/rlib/rsre/test/test_search.py

     def test_empty_maxuntil(self):
         r_code, r = get_code_and_re(r'(a?)+y')
         assert r.match('y')
+        assert r.match('aaayaaay').span() == (0, 4)
         res = rsre_core.match(r_code, 'y')
         assert res
+        res = rsre_core.match(r_code, 'aaayaaay')
+        assert res and res.span() == (0, 4)
         #
         r_code, r = get_code_and_re(r'(a?){4,6}y')
         assert r.match('y')
         res = rsre_core.match(r_code, 'y')
         assert res
 
+    def test_empty_maxuntil_2(self):
+        r_code, r = get_code_and_re(r'X(.*?)+X')
+        assert r.match('XfooXbarX').span() == (0, 5)
+        assert r.match('XfooXbarX').span(1) == (4, 4)
+        res = rsre_core.match(r_code, 'XfooXbarX')
+        assert res.span() == (0, 5)
+        assert res.span(1) == (4, 4)
+
     def test_empty_minuntil(self):
         r_code, r = get_code_and_re(r'(a?)+?y')
         #assert not r.match('z') -- CPython bug (at least 2.5) eats all memory

rpython/rtyper/lltypesystem/rffi.py

             lltype.Void,
             releasegil=False
         )
-
-from rpython.rtyper.annlowlevel import llstr
-from rpython.rtyper.lltypesystem.rstr import STR
-
-def get_buffer_from_str(data):
-    lldata = llstr(data)
-    data_start = cast_ptr_to_adr(lldata) + \
-      offsetof(STR, 'chars') + itemoffsetof(STR.chars, 0)
-    return cast(CCHARP, data_start)

rpython/rtyper/rlist.py

 #  done with it.  So in the sequel we don't bother checking for overflow
 #  when we compute "ll_length() + 1".
 
-@jit.look_inside_iff(lambda LIST, count, item: jit.isconstant(count) and count < 15)
+
+# jit note: this is normally special-cased by the oopspec,
+# but if item != const(0), then the special-casing fails and
+# we fall back to the look_inside_iff.
+@jit.look_inside_iff(lambda LIST, count, item: jit.isconstant(count) and count < 137)
 @jit.oopspec("newlist(count, item)")
 def ll_alloc_and_set(LIST, count, item):
     if count < 0:
         check = item
     # as long as malloc is known to zero the allocated memory avoid zeroing
     # twice
-    if (not malloc_zero_filled) or check:
+    if jit.we_are_jitted() or (not malloc_zero_filled) or check:
         i = 0
         while i < count:
             l.ll_setitem_fast(i, item)

rpython/tool/runsubprocess.py

         args = eval(operation)
         try:
             results = _run(*args)
-        except EnvironmentError, e:
+        except EnvironmentError as e:
             results = (None, str(e))
         sys.stdout.write('%r\n' % (results,))
         sys.stdout.flush()

rpython/tool/version.py

     try:
         p = Popen([str(hgexe), 'version', '-q'],
                   stdout=PIPE, stderr=PIPE, env=env)
-    except OSError, e:
+    except OSError as e:
         maywarn(e)
         return default_retval
 
             [str(gitexe), 'rev-parse', 'HEAD'],
             stdout=PIPE, stderr=PIPE, cwd=root
             )
-    except OSError, e:
+    except OSError as e:
         maywarn(e, 'Git')
         return default_retval
     if p.wait() != 0: