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