Author: Matti Picus <[email protected]>
Branch: missing-tp_new
Changeset: r89569:a69e2a0fae65
Date: 2017-01-14 23:18 +0200
http://bitbucket.org/pypy/pypy/changeset/a69e2a0fae65/

Log:    merge default into branch

diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -220,7 +220,7 @@
         self.__statements_counter = 0
         self.__rawstatements = set()
         self._statement_cache = _StatementCache(self, cached_statements)
-        self.__statements_already_committed = weakref.WeakSet()
+        self.__statements_already_committed = []
 
         self.__func_cache = {}
         self.__aggregates = {}
@@ -365,10 +365,12 @@
                     cursor._reset = True
 
     def _reset_already_committed_statements(self):
-        lst = list(self.__statements_already_committed)
-        self.__statements_already_committed.clear()
-        for statement in lst:
-            statement._reset()
+        lst = self.__statements_already_committed
+        self.__statements_already_committed = []
+        for weakref in lst:
+            statement = weakref()
+            if statement is not None:
+                statement._reset()
 
     @_check_thread_wrap
     @_check_closed_wrap
@@ -432,14 +434,11 @@
         # the way and cause the "drop table" to fail.  On CPython the
         # problem is much less important because typically all the old
         # statements are freed already by reference counting.  So here,
-        # we add all the still-alive statements to a WeakSet which is
-        # usually ignored, except if we get SQLITE_LOCKED
+        # we copy all the still-alive statements to another list which
+        # is usually ignored, except if we get SQLITE_LOCKED
         # afterwards---at which point we reset all statements in this
-        # WeakSet.
-        for weakref in self.__statements:
-            statement = weakref()
-            if statement is not None:
-                self.__statements_already_committed.add(statement)
+        # list.
+        self.__statements_already_committed = self.__statements[:]
 
         statement_star = _ffi.new('sqlite3_stmt **')
         ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1,
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -102,6 +102,10 @@
 Do not recreate the object in PyMemoryView_FromBuffer, rather pass it to
 the returned PyMemoryViewObject, to take ownership of it. Fixes a ref leak.
 
+.. branch: issue2464
+
+Give (almost?) all GetSetProperties a valid __objclass__.
+
 .. branch: missing-tp_new
 
 Improve mixing app-level classes in c-extensions, especially if the app-level
diff --git a/pypy/interpreter/test/test_typedef.py 
b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -140,7 +140,11 @@
             pass
         def fget(self, space, w_self):
             assert self is prop
-        prop = typedef.GetSetProperty(fget, use_closure=True)
+        # NB. this GetSetProperty is not copied when creating the
+        # W_TypeObject because of 'cls'.  Without it, a duplicate of the
+        # GetSetProperty is taken and it is given the w_objclass that is
+        # the W_TypeObject
+        prop = typedef.GetSetProperty(fget, use_closure=True, cls=W_SomeType)
         W_SomeType.typedef = typedef.TypeDef(
             'some_type',
             x=prop)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -276,12 +276,15 @@
         self.use_closure = use_closure
 
     def copy_for_type(self, w_objclass):
-        new = instantiate(GetSetProperty)
-        new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
-                  None, self.use_closure)
-        new.name = self.name
-        new.w_objclass = w_objclass
-        return new
+        if self.objclass_getter is None:
+            new = instantiate(GetSetProperty)
+            new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
+                      None, self.use_closure)
+            new.name = self.name
+            new.w_objclass = w_objclass
+            return new
+        else:
+            return self
 
     @unwrap_spec(w_cls = WrappedDefault(None))
     def descr_property_get(self, space, w_obj, w_cls=None):
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -90,11 +90,10 @@
     return 0
 
 @cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
-def PyList_GET_SIZE(space, w_list):
+def PyList_GET_SIZE(space, w_obj):
     """Macro form of PyList_Size() without error checking.
     """
-    assert isinstance(w_list, W_ListObject)
-    return w_list.length()
+    return space.len_w(w_obj)
 
 
 @cpython_api([PyObject], Py_ssize_t, error=-1)
diff --git a/pypy/module/cpyext/unicodeobject.py 
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -206,9 +206,8 @@
 
 @cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PyUnicode_GET_SIZE(space, w_obj):
-    """Return the size of the object.  o has to be a PyUnicodeObject (not
+    """Return the size of the object.  obj is a PyUnicodeObject (not
     checked)."""
-    assert isinstance(w_obj, unicodeobject.W_UnicodeObject)
     return space.len_w(w_obj)
 
 @cpython_api([rffi.VOIDP], rffi.CWCHARP, error=CANNOT_FAIL)
diff --git a/pypy/objspace/std/test/test_typeobject.py 
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1329,3 +1329,6 @@
             pass
         assert X.__dict__['__dict__'].__objclass__ is X
         assert X.__dict__['__weakref__'].__objclass__ is X
+        assert object.__dict__['__class__'].__objclass__ is object
+        assert int.__dict__['imag'].__objclass__ is int
+        assert file.closed.__objclass__ is file
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -1312,10 +1312,13 @@
     def build(self, typedef):
         "NOT_RPYTHON: initialization-time only."
         from pypy.objspace.std.objectobject import W_ObjectObject
+        from pypy.interpreter.typedef import GetSetProperty
+        from rpython.rlib.objectmodel import instantiate
 
         space = self.space
         rawdict = typedef.rawdict
         lazyloaders = {}
+        w_type = instantiate(W_TypeObject)
 
         # compute the bases
         if typedef is W_ObjectObject.typedef:
@@ -1327,13 +1330,16 @@
         # wrap everything
         dict_w = {}
         for descrname, descrvalue in rawdict.items():
+            # special case for GetSetProperties' __objclass__:
+            if isinstance(descrvalue, GetSetProperty):
+                descrvalue = descrvalue.copy_for_type(w_type)
             dict_w[descrname] = space.wrap(descrvalue)
 
         if typedef.applevel_subclasses_base is not None:
             overridetypedef = typedef.applevel_subclasses_base.typedef
         else:
             overridetypedef = typedef
-        w_type = W_TypeObject(space, typedef.name, bases_w, dict_w,
+        w_type.__init__(space, typedef.name, bases_w, dict_w,
                               overridetypedef=overridetypedef,
                               is_heaptype=overridetypedef.heaptype)
         if typedef is not overridetypedef:
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py 
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -350,6 +350,14 @@
             self.send_extra_operation(jump_op.copy_and_change(rop.JUMP,
                                       args=args + extra,
                                       descr=target_token))
+
+            # XXX see test_issue2465 for a case where the following occurs
+            # XXX (it would be better to really understand the problem
+            # XXX and fix it, but I am failing so far)
+            if label_op is not None and len(args + extra) != 
label_op.numargs():
+                del self.optimizer._newoperations[-1]    # remove the JUMP
+                raise InvalidLoop
+
             return None # explicit because the return can be non-None
         return virtual_state
 
diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -4620,3 +4620,19 @@
             time.clock()
             return 0
         self.interp_operations(g, [])
+
+    def test_issue2465(self):
+        driver = JitDriver(greens=[], reds=['i', 'a', 'b'])
+        class F(object):
+            def __init__(self, floatval):
+                self.floatval = floatval
+        def f(i):
+            a = F(0.0)
+            b = None
+            while i > 0:
+                driver.jit_merge_point(i=i, a=a, b=b)
+                b = F(a.floatval / 1.)
+                i -= 1
+            return i
+
+        self.meta_interp(f, [10])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to