Author: Armin Rigo <[email protected]>
Branch: use-gc-del-3
Changeset: r84324:7b8178ec0f5b
Date: 2016-05-09 10:29 +0200
http://bitbucket.org/pypy/pypy/changeset/7b8178ec0f5b/
Log: hg merge default
diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py
--- a/dotviewer/graphserver.py
+++ b/dotviewer/graphserver.py
@@ -143,6 +143,11 @@
if __name__ == '__main__':
if len(sys.argv) != 2:
+ if len(sys.argv) == 1:
+ # start locally
+ import sshgraphserver
+ sshgraphserver.ssh_graph_server(['LOCAL'])
+ sys.exit(0)
print >> sys.stderr, __doc__
sys.exit(2)
if sys.argv[1] == '--stdio':
diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py
--- a/dotviewer/sshgraphserver.py
+++ b/dotviewer/sshgraphserver.py
@@ -4,11 +4,14 @@
Usage:
sshgraphserver.py hostname [more args for ssh...]
+ sshgraphserver.py LOCAL
This logs in to 'hostname' by passing the arguments on the command-line
to ssh. No further configuration is required: it works for all programs
using the dotviewer library as long as they run on 'hostname' under the
same username as the one sshgraphserver logs as.
+
+If 'hostname' is the string 'LOCAL', then it starts locally without ssh.
"""
import graphserver, socket, subprocess, random
@@ -18,12 +21,19 @@
s1 = socket.socket()
s1.bind(('127.0.0.1', socket.INADDR_ANY))
localhost, localport = s1.getsockname()
- remoteport = random.randrange(10000, 20000)
- # ^^^ and just hope there is no conflict
- args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (remoteport,
localport)]
- args = args + sshargs + ['python -u -c "exec input()"']
- print ' '.join(args[:-1])
+ if sshargs[0] != 'LOCAL':
+ remoteport = random.randrange(10000, 20000)
+ # ^^^ and just hope there is no conflict
+
+ args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (
+ remoteport, localport)]
+ args = args + sshargs + ['python -u -c "exec input()"']
+ else:
+ remoteport = localport
+ args = ['python', '-u', '-c', 'exec input()']
+
+ print ' '.join(args)
p = subprocess.Popen(args, bufsize=0,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -397,20 +397,7 @@
data. Later, when this new cdata object is garbage-collected,
'destructor(old_cdata_object)' will be called.
"""
- try:
- gcp = self._backend.gcp
- except AttributeError:
- pass
- else:
- return gcp(cdata, destructor)
- #
- with self._lock:
- try:
- gc_weakrefs = self.gc_weakrefs
- except AttributeError:
- from .gc_weakref import GcWeakrefs
- gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
- return gc_weakrefs.build(cdata, destructor)
+ return self._backend.gcp(cdata, destructor)
def _get_cached_btype(self, type):
assert self._lock.acquire(False) is False
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -460,6 +460,11 @@
return x._value
raise TypeError("character expected, got %s" %
type(x).__name__)
+ def __nonzero__(self):
+ return ord(self._value) != 0
+ else:
+ def __nonzero__(self):
+ return self._value != 0
if kind == 'float':
@staticmethod
@@ -993,6 +998,31 @@
assert onerror is None # XXX not implemented
return BType(source, error)
+ def gcp(self, cdata, destructor):
+ BType = self.typeof(cdata)
+
+ if destructor is None:
+ if not (hasattr(BType, '_gcp_type') and
+ BType._gcp_type is BType):
+ raise TypeError("Can remove destructor only on a object "
+ "previously returned by ffi.gc()")
+ cdata._destructor = None
+ return None
+
+ try:
+ gcp_type = BType._gcp_type
+ except AttributeError:
+ class CTypesDataGcp(BType):
+ __slots__ = ['_orig', '_destructor']
+ def __del__(self):
+ if self._destructor is not None:
+ self._destructor(self._orig)
+ gcp_type = BType._gcp_type = CTypesDataGcp
+ new_cdata = self.cast(gcp_type, cdata)
+ new_cdata._orig = cdata
+ new_cdata._destructor = destructor
+ return new_cdata
+
typeof = type
def getcname(self, BType, replace_with):
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
@@ -68,3 +68,19 @@
CPython).
.. branch: oefmt
+
+.. branch: cpyext-werror
+
+Compile c snippets with -Werror in cpyext
+
+.. branch: gc-del-3
+
+Add rgc.FinalizerQueue, documented in pypy/doc/discussion/finalizer-order.rst.
+It is a more flexible way to make RPython finalizers.
+
+.. branch: unpacking-cpython-shortcut
+
+.. branch: cleanups
+
+.. branch: cpyext-more-slots
+
diff --git a/pypy/interpreter/test/test_argument.py
b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -688,3 +688,21 @@
def f(x): pass
e = raises(TypeError, "f(**{u'ü' : 19})")
assert "?" in str(e.value)
+
+ def test_starstarargs_dict_subclass(self):
+ def f(**kwargs):
+ return kwargs
+ class DictSubclass(dict):
+ def __iter__(self):
+ yield 'x'
+ # CPython, as an optimization, looks directly into dict internals when
+ # passing one via **kwargs.
+ x =DictSubclass()
+ assert f(**x) == {}
+ x['a'] = 1
+ assert f(**x) == {'a': 1}
+
+ def test_starstarargs_module_dict(self):
+ def f(**kwargs):
+ return kwargs
+ assert f(**globals()) == globals()
diff --git a/pypy/module/_cffi_backend/cdataobj.py
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -71,7 +71,7 @@
def nonzero(self):
with self as ptr:
- nonzero = bool(ptr)
+ nonzero = self.ctype.nonzero(ptr)
return self.space.wrap(nonzero)
def int(self, space):
@@ -365,8 +365,16 @@
return self.ctype.size
def with_gc(self, w_destructor):
+ space = self.space
+ if space.is_none(w_destructor):
+ if isinstance(self, W_CDataGCP):
+ self.w_destructor = None
+ return space.w_None
+ raise oefmt(space.w_TypeError,
+ "Can remove destructor only on a object "
+ "previously returned by ffi.gc()")
with self as ptr:
- return W_CDataGCP(self.space, ptr, self.ctype, self, w_destructor)
+ return W_CDataGCP(space, ptr, self.ctype, self, w_destructor)
def unpack(self, length):
from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray
@@ -527,7 +535,7 @@
class W_CDataGCP(W_CData):
"""For ffi.gc()."""
_attrs_ = ['w_original_cdata', 'w_destructor']
- _immutable_fields_ = ['w_original_cdata', 'w_destructor']
+ _immutable_fields_ = ['w_original_cdata']
def __init__(self, space, cdata, ctype, w_original_cdata, w_destructor):
W_CData.__init__(self, space, cdata, ctype)
@@ -536,7 +544,10 @@
self.register_finalizer(space)
def _finalize_(self):
- self.space.call_function(self.w_destructor, self.w_original_cdata)
+ w_destructor = self.w_destructor
+ if w_destructor is not None:
+ self.w_destructor = None
+ self.space.call_function(w_destructor, self.w_original_cdata)
W_CData.typedef = TypeDef(
diff --git a/pypy/module/_cffi_backend/ctypeobj.py
b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -147,6 +147,9 @@
raise oefmt(space.w_TypeError, "cannot add a cdata '%s' and a number",
self.name)
+ def nonzero(self, cdata):
+ return bool(cdata)
+
def insert_name(self, extra, extra_position):
name = '%s%s%s' % (self.name[:self.name_position],
extra,
diff --git a/pypy/module/_cffi_backend/ctypeprim.py
b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -93,6 +93,18 @@
return self.space.newlist_int(result)
return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length)
+ def nonzero(self, cdata):
+ if self.size <= rffi.sizeof(lltype.Signed):
+ value = misc.read_raw_long_data(cdata, self.size)
+ return value != 0
+ else:
+ return self._nonzero_longlong(cdata)
+
+ def _nonzero_longlong(self, cdata):
+ # in its own function: LONGLONG may make the whole function jit-opaque
+ value = misc.read_raw_signed_data(cdata, self.size)
+ return bool(value)
+
class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
_attrs_ = []
@@ -435,6 +447,9 @@
return self.space.newlist_float(result)
return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length)
+ def nonzero(self, cdata):
+ return misc.is_nonnull_float(cdata, self.size)
+
class W_CTypePrimitiveLongDouble(W_CTypePrimitiveFloat):
_attrs_ = []
@@ -501,3 +516,7 @@
rffi.LONGDOUBLE, rffi.LONGDOUBLEP)
return True
return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
+
+ @jit.dont_look_inside
+ def nonzero(self, cdata):
+ return misc.is_nonnull_longdouble(cdata)
diff --git a/pypy/module/_cffi_backend/misc.py
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -256,7 +256,7 @@
def is_nonnull_longdouble(cdata):
return _is_nonnull_longdouble(read_raw_longdouble_data(cdata))
def is_nonnull_float(cdata, size):
- return read_raw_float_data(cdata, size) != 0.0
+ return read_raw_float_data(cdata, size) != 0.0 # note: True if a NaN
def object_as_bool(space, w_ob):
# convert and cast a Python object to a boolean. Accept an integer
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -141,9 +141,13 @@
INF = 1E200 * 1E200
for name in ["float", "double"]:
p = new_primitive_type(name)
- assert bool(cast(p, 0))
+ assert bool(cast(p, 0)) is False # since 1.7
+ assert bool(cast(p, -0.0)) is False # since 1.7
+ assert bool(cast(p, 1e-42)) is True
+ assert bool(cast(p, -1e-42)) is True
assert bool(cast(p, INF))
assert bool(cast(p, -INF))
+ assert bool(cast(p, float("nan")))
assert int(cast(p, -150)) == -150
assert int(cast(p, 61.91)) == 61
assert long(cast(p, 61.91)) == 61
@@ -202,7 +206,8 @@
def test_character_type():
p = new_primitive_type("char")
- assert bool(cast(p, '\x00'))
+ assert bool(cast(p, 'A')) is True
+ assert bool(cast(p, '\x00')) is False # since 1.7
assert cast(p, '\x00') != cast(p, -17*256)
assert int(cast(p, 'A')) == 65
assert long(cast(p, 'A')) == 65
@@ -2558,7 +2563,8 @@
BBoolP = new_pointer_type(BBool)
assert int(cast(BBool, False)) == 0
assert int(cast(BBool, True)) == 1
- assert bool(cast(BBool, False)) is True # warning!
+ assert bool(cast(BBool, False)) is False # since 1.7
+ assert bool(cast(BBool, True)) is True
assert int(cast(BBool, 3)) == 1
assert int(cast(BBool, long(3))) == 1
assert int(cast(BBool, long(10)**4000)) == 1
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py
b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -331,6 +331,25 @@
gc.collect()
assert seen == [1]
+ def test_ffi_gc_disable(self):
+ import _cffi_backend as _cffi1_backend
+ ffi = _cffi1_backend.FFI()
+ p = ffi.new("int *", 123)
+ raises(TypeError, ffi.gc, p, None)
+ seen = []
+ q1 = ffi.gc(p, lambda p: seen.append(1))
+ q2 = ffi.gc(q1, lambda p: seen.append(2))
+ import gc; gc.collect()
+ assert seen == []
+ assert ffi.gc(q1, None) is None
+ del q1, q2
+ for i in range(5):
+ if seen:
+ break
+ import gc
+ gc.collect()
+ assert seen == [2]
+
def test_ffi_new_allocator_1(self):
import _cffi_backend as _cffi1_backend
ffi = _cffi1_backend.FFI()
diff --git a/pypy/module/_multibytecodec/app_multibytecodec.py
b/pypy/module/_multibytecodec/app_multibytecodec.py
--- a/pypy/module/_multibytecodec/app_multibytecodec.py
+++ b/pypy/module/_multibytecodec/app_multibytecodec.py
@@ -44,8 +44,10 @@
self, data))
def reset(self):
- self.stream.write(MultibyteIncrementalEncoder.encode(
- self, '', final=True))
+ data = MultibyteIncrementalEncoder.encode(
+ self, '', final=True)
+ if len(data) > 0:
+ self.stream.write(data)
MultibyteIncrementalEncoder.reset(self)
def writelines(self, lines):
diff --git a/pypy/module/_multibytecodec/test/test_app_stream.py
b/pypy/module/_multibytecodec/test/test_app_stream.py
--- a/pypy/module/_multibytecodec/test/test_app_stream.py
+++ b/pypy/module/_multibytecodec/test/test_app_stream.py
@@ -90,3 +90,15 @@
w.write(u'\u304b')
w.write(u'\u309a')
assert w.stream.output == ['\x83m', '', '\x82\xf5']
+
+ def test_writer_seek_no_empty_write(self):
+ # issue #2293: codecs.py will sometimes issue a reset()
+ # on a StreamWriter attached to a file that is not opened
+ # for writing at all. We must not emit a "write('')"!
+ class FakeFile:
+ def write(self, data):
+ raise IOError("can't write!")
+ #
+ w = self.ShiftJisx0213StreamWriter(FakeFile())
+ w.reset()
+ # assert did not crash
diff --git a/pypy/module/cpyext/ndarrayobject.py
b/pypy/module/cpyext/ndarrayobject.py
--- a/pypy/module/cpyext/ndarrayobject.py
+++ b/pypy/module/cpyext/ndarrayobject.py
@@ -248,7 +248,7 @@
w_signature = rffi.charp2str(signature)
return do_ufunc(space, funcs, data, types, ntypes, nin, nout, identity,
name, doc,
check_return, w_signature)
-
+
def do_ufunc(space, funcs, data, types, ntypes, nin, nout, identity, name, doc,
check_return, w_signature):
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -374,7 +374,75 @@
header = pypy_decl
if mangle_name('', typedef.name) is None:
header = None
- if name == 'tp_setattro':
+ handled = False
+ # unary functions
+ for tp_name, attr in [('tp_as_number.c_nb_int', '__int__'),
+ ('tp_as_number.c_nb_long', '__long__'),
+ ('tp_as_number.c_nb_float', '__float__'),
+ ('tp_as_number.c_nb_negative', '__neg__'),
+ ('tp_as_number.c_nb_positive', '__pos__'),
+ ('tp_as_number.c_nb_absolute', '__abs__'),
+ ('tp_as_number.c_nb_invert', '__invert__'),
+ ('tp_as_number.c_nb_index', '__index__'),
+ ('tp_str', '__str__'),
+ ('tp_repr', '__repr__'),
+ ('tp_iter', '__iter__'),
+ ]:
+ if name == tp_name:
+ slot_fn = w_type.getdictvalue(space, attr)
+ if slot_fn is None:
+ return
+
+ @cpython_api([PyObject], PyObject, header=header)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'),
typedef.name))
+ def slot_func(space, w_self):
+ return space.call_function(slot_fn, w_self)
+ api_func = slot_func.api_func
+ handled = True
+
+ # binary functions
+ for tp_name, attr in [('tp_as_number.c_nb_add', '__add__'),
+ ('tp_as_number.c_nb_subtract', '__subtract__'),
+ ('tp_as_number.c_nb_multiply', '__mul__'),
+ ('tp_as_number.c_nb_divide', '__div__'),
+ ('tp_as_number.c_nb_remainder', '__mod__'),
+ ('tp_as_number.c_nb_divmod', '__divmod__'),
+ ('tp_as_number.c_nb_lshift', '__lshift__'),
+ ('tp_as_number.c_nb_rshift', '__rshift__'),
+ ('tp_as_number.c_nb_and', '__and__'),
+ ('tp_as_number.c_nb_xor', '__xor__'),
+ ('tp_as_number.c_nb_or', '__or__'),
+ ]:
+ if name == tp_name:
+ slot_fn = w_type.getdictvalue(space, attr)
+ if slot_fn is None:
+ return
+
+ @cpython_api([PyObject, PyObject], PyObject, header=header)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'),
typedef.name))
+ def slot_func(space, w_self, w_arg):
+ return space.call_function(slot_fn, w_self, w_arg)
+ api_func = slot_func.api_func
+ handled = True
+
+ # ternary functions
+ for tp_name, attr in [('tp_as_number.c_nb_power', ''),
+ ]:
+ if name == tp_name:
+ slot_fn = w_type.getdictvalue(space, attr)
+ if slot_fn is None:
+ return
+
+ @cpython_api([PyObject, PyObject, PyObject], PyObject,
header=header)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'),
typedef.name))
+ def slot_func(space, w_self, w_arg1, w_arg2):
+ return space.call_function(slot_fn, w_self, w_arg1, w_arg2)
+ api_func = slot_func.api_func
+ handled = True
+
+ if handled:
+ pass
+ elif name == 'tp_setattro':
setattr_fn = w_type.getdictvalue(space, '__setattr__')
delattr_fn = w_type.getdictvalue(space, '__delattr__')
if setattr_fn is None:
@@ -401,28 +469,6 @@
return space.call_function(getattr_fn, w_self, w_name)
api_func = slot_tp_getattro.api_func
- elif name == 'tp_as_number.c_nb_int':
- int_fn = w_type.getdictvalue(space, '__int__')
- if int_fn is None:
- return
-
- @cpython_api([PyObject], PyObject, header=header)
- @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
- def slot_nb_int(space, w_self):
- return space.call_function(int_fn, w_self)
- api_func = slot_nb_int.api_func
-
- elif name == 'tp_as_number.c_nb_float':
- float_fn = w_type.getdictvalue(space, '__float__')
- if float_fn is None:
- return
-
- @cpython_api([PyObject], PyObject, header=header)
- @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
- def slot_nb_float(space, w_self):
- return space.call_function(float_fn, w_self)
- api_func = slot_nb_float.api_func
-
elif name == 'tp_call':
call_fn = w_type.getdictvalue(space, '__call__')
if call_fn is None:
@@ -436,28 +482,6 @@
return space.call_args(call_fn, args)
api_func = slot_tp_call.api_func
- elif name == 'tp_str':
- str_fn = w_type.getdictvalue(space, '__str__')
- if str_fn is None:
- return
-
- @cpython_api([PyObject], PyObject, header=header)
- @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
- def slot_tp_str(space, w_self):
- return space.call_function(str_fn, w_self)
- api_func = slot_tp_str.api_func
-
- elif name == 'tp_iter':
- iter_fn = w_type.getdictvalue(space, '__iter__')
- if iter_fn is None:
- return
-
- @cpython_api([PyObject], PyObject, header=header)
- @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
- def slot_tp_iter(space, w_self):
- return space.call_function(iter_fn, w_self)
- api_func = slot_tp_iter.api_func
-
elif name == 'tp_iternext':
iternext_fn = w_type.getdictvalue(space, 'next')
if iternext_fn is None:
@@ -501,6 +525,7 @@
return space.call_args(space.get(new_fn, w_self), args)
api_func = slot_tp_new.api_func
else:
+ # missing: tp_as_number.nb_nonzero, tp_as_number.nb_coerce
return
return lambda: llhelper(api_func.functype, api_func.get_wrapper(space))
diff --git a/pypy/module/cpyext/test/test_api.py
b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -1,4 +1,4 @@
-import py
+import py, pytest
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.interpreter.baseobjspace import W_Root
from pypy.module.cpyext.state import State
@@ -100,7 +100,8 @@
PyPy_TypedefTest2(space, ppos)
lltype.free(ppos, flavor='raw')
-
[email protected](os.environ.get('USER')=='root',
+ reason='root can write to all files')
def test_copy_header_files(tmpdir):
api.copy_header_files(tmpdir, True)
def check(name):
diff --git a/pypy/module/cpyext/test/test_borrow.py
b/pypy/module/cpyext/test/test_borrow.py
--- a/pypy/module/cpyext/test/test_borrow.py
+++ b/pypy/module/cpyext/test/test_borrow.py
@@ -12,13 +12,13 @@
PyObject *t = PyTuple_New(1);
PyObject *f = PyFloat_FromDouble(42.0);
PyObject *g = NULL;
- printf("Refcnt1: %i\\n", f->ob_refcnt);
+ printf("Refcnt1: %zd\\n", f->ob_refcnt);
PyTuple_SetItem(t, 0, f); // steals reference
- printf("Refcnt2: %i\\n", f->ob_refcnt);
+ printf("Refcnt2: %zd\\n", f->ob_refcnt);
f = PyTuple_GetItem(t, 0); // borrows reference
- printf("Refcnt3: %i\\n", f->ob_refcnt);
+ printf("Refcnt3: %zd\\n", f->ob_refcnt);
g = PyTuple_GetItem(t, 0); // borrows reference again
- printf("Refcnt4: %i\\n", f->ob_refcnt);
+ printf("Refcnt4: %zd\\n", f->ob_refcnt);
printf("COMPARE: %i\\n", f == g);
fflush(stdout);
Py_DECREF(t);
diff --git a/pypy/module/cpyext/test/test_bytesobject.py
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -40,7 +40,7 @@
#endif
if(s->ob_type->tp_basicsize != expected_size)
{
- printf("tp_basicsize==%ld\\n", s->ob_type->tp_basicsize);
+ printf("tp_basicsize==%zd\\n", s->ob_type->tp_basicsize);
result = 0;
}
Py_DECREF(s);
@@ -162,7 +162,10 @@
module = self.import_extension('foo', [
("string_None", "METH_VARARGS",
'''
- return PyString_AsString(Py_None);
+ if (PyString_AsString(Py_None)) {
+ Py_RETURN_NONE;
+ }
+ return NULL;
'''
)])
raises(TypeError, module.string_None)
diff --git a/pypy/module/cpyext/test/test_classobject.py
b/pypy/module/cpyext/test/test_classobject.py
--- a/pypy/module/cpyext/test/test_classobject.py
+++ b/pypy/module/cpyext/test/test_classobject.py
@@ -29,7 +29,6 @@
assert space.unwrap(space.getattr(w_instance, space.wrap('x'))) == 1
assert space.unwrap(space.getattr(w_instance, space.wrap('y'))) == 2
assert space.unwrap(space.getattr(w_instance, space.wrap('args'))) ==
(3,)
-
def test_lookup(self, space, api):
w_instance = space.appexec([], """():
@@ -68,7 +67,7 @@
("get_classtype", "METH_NOARGS",
"""
Py_INCREF(&PyClass_Type);
- return &PyClass_Type;
+ return (PyObject*)&PyClass_Type;
""")])
class C: pass
assert module.get_classtype() is type(C)
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -72,8 +72,7 @@
else:
kwds["link_files"] = [str(api_library + '.so')]
if sys.platform.startswith('linux'):
- kwds["compile_extra"]=["-Werror=implicit-function-declaration",
- "-g", "-O0"]
+ kwds["compile_extra"]=["-Werror", "-g", "-O0"]
kwds["link_extra"]=["-g"]
modname = modname.split('.')[-1]
@@ -747,7 +746,7 @@
refcnt_after = true_obj->ob_refcnt;
Py_DECREF(true_obj);
Py_DECREF(true_obj);
- fprintf(stderr, "REFCNT %i %i\\n", refcnt, refcnt_after);
+ fprintf(stderr, "REFCNT %zd %zd\\n", refcnt, refcnt_after);
return PyBool_FromLong(refcnt_after == refcnt + 2);
}
static PyObject* foo_bar(PyObject* self, PyObject *args)
@@ -763,7 +762,7 @@
return NULL;
refcnt_after = true_obj->ob_refcnt;
Py_DECREF(tup);
- fprintf(stderr, "REFCNT2 %i %i %i\\n", refcnt, refcnt_after,
+ fprintf(stderr, "REFCNT2 %zd %zd %zd\\n", refcnt, refcnt_after,
true_obj->ob_refcnt);
return PyBool_FromLong(refcnt_after == refcnt + 1 &&
refcnt == true_obj->ob_refcnt);
diff --git a/pypy/module/cpyext/test/test_longobject.py
b/pypy/module/cpyext/test/test_longobject.py
--- a/pypy/module/cpyext/test/test_longobject.py
+++ b/pypy/module/cpyext/test/test_longobject.py
@@ -171,7 +171,7 @@
int little_endian, is_signed;
if (!PyArg_ParseTuple(args, "ii", &little_endian, &is_signed))
return NULL;
- return _PyLong_FromByteArray("\x9A\xBC", 2,
+ return _PyLong_FromByteArray((unsigned char*)"\x9A\xBC", 2,
little_endian, is_signed);
"""),
])
@@ -187,7 +187,7 @@
int little_endian, is_signed;
if (!PyArg_ParseTuple(args, "ii", &little_endian, &is_signed))
return NULL;
- return _PyLong_FromByteArray("\x9A\xBC\x41", 3,
+ return _PyLong_FromByteArray((unsigned char*)"\x9A\xBC\x41",
3,
little_endian, is_signed);
"""),
])
diff --git a/pypy/module/cpyext/test/test_pyerrors.py
b/pypy/module/cpyext/test/test_pyerrors.py
--- a/pypy/module/cpyext/test/test_pyerrors.py
+++ b/pypy/module/cpyext/test/test_pyerrors.py
@@ -168,14 +168,14 @@
PyErr_NormalizeException(&type, &val, &tb);
if (type != PyExc_TypeError)
Py_RETURN_FALSE;
- if (val->ob_type != PyExc_TypeError)
+ if ((PyObject*)Py_TYPE(val) != PyExc_TypeError)
Py_RETURN_FALSE;
/* Normalize again */
PyErr_NormalizeException(&type, &val, &tb);
if (type != PyExc_TypeError)
Py_RETURN_FALSE;
- if (val->ob_type != PyExc_TypeError)
+ if ((PyObject*)Py_TYPE(val) != PyExc_TypeError)
Py_RETURN_FALSE;
PyErr_Restore(type, val, tb);
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -437,14 +437,14 @@
("test_tp_getattro", "METH_VARARGS",
'''
PyObject *name, *obj = PyTuple_GET_ITEM(args, 0);
- PyIntObject *attr, *value = PyTuple_GET_ITEM(args, 1);
+ PyIntObject *attr, *value = (PyIntObject*)
PyTuple_GET_ITEM(args, 1);
if (!obj->ob_type->tp_getattro)
{
PyErr_SetString(PyExc_ValueError, "missing tp_getattro");
return NULL;
}
name = PyString_FromString("attr1");
- attr = obj->ob_type->tp_getattro(obj, name);
+ attr = (PyIntObject*) obj->ob_type->tp_getattro(obj, name);
if (attr->ob_ival != value->ob_ival)
{
PyErr_SetString(PyExc_ValueError,
@@ -454,7 +454,7 @@
Py_DECREF(name);
Py_DECREF(attr);
name = PyString_FromString("attr2");
- attr = obj->ob_type->tp_getattro(obj, name);
+ attr = (PyIntObject*) obj->ob_type->tp_getattro(obj, name);
if (attr == NULL &&
PyErr_ExceptionMatches(PyExc_AttributeError))
{
PyErr_Clear();
@@ -758,8 +758,9 @@
} IntLikeObject;
static int
- intlike_nb_nonzero(IntLikeObject *v)
+ intlike_nb_nonzero(PyObject *o)
{
+ IntLikeObject *v = (IntLikeObject*)o;
if (v->value == -42) {
PyErr_SetNone(PyExc_ValueError);
return -1;
@@ -920,3 +921,59 @@
' multiple bases have instance lay-out conflict')
else:
raise AssertionError("did not get TypeError!")
+
+ def test_call_tp_dealloc_when_created_from_python(self):
+ module = self.import_extension('foo', [
+ ("fetchFooType", "METH_VARARGS",
+ """
+ PyObject *o;
+ Foo_Type.tp_dealloc = &dealloc_foo;
+ Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ Foo_Type.tp_new = &new_foo;
+ Foo_Type.tp_free = &PyObject_Del;
+ if (PyType_Ready(&Foo_Type) < 0) return NULL;
+
+ o = PyObject_New(PyObject, &Foo_Type);
+ Py_DECREF(o); /* calls dealloc_foo immediately */
+
+ Py_INCREF(&Foo_Type);
+ return (PyObject *)&Foo_Type;
+ """),
+ ("getCounter", "METH_VARARGS",
+ """
+ return PyInt_FromLong(foo_counter);
+ """)], prologue=
+ """
+ static int foo_counter = 1000;
+ static void dealloc_foo(PyObject *foo) {
+ foo_counter += 10;
+ }
+ static PyObject *new_foo(PyTypeObject *t, PyObject *a, PyObject *k)
+ {
+ foo_counter += 1000;
+ return t->tp_alloc(t, 0);
+ }
+ static PyTypeObject Foo_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "foo.foo",
+ };
+ """)
+ Foo = module.fetchFooType()
+ assert module.getCounter() == 1010
+ Foo(); Foo()
+ for i in range(10):
+ if module.getCounter() >= 3030:
+ break
+ # NB. use self.debug_collect() instead of gc.collect(),
+ # otherwise rawrefcount's dealloc callback doesn't trigger
+ self.debug_collect()
+ assert module.getCounter() == 3030
+ #
+ class Bar(Foo):
+ pass
+ Bar(); Bar()
+ for i in range(10):
+ if module.getCounter() >= 5050:
+ break
+ self.debug_collect()
+ assert module.getCounter() == 5050
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -556,7 +556,14 @@
typedescr = get_typedescr(w_type.layout.typedef)
# dealloc
- pto.c_tp_dealloc = typedescr.get_dealloc(space)
+ if space.gettypeobject(w_type.layout.typedef) is w_type:
+ # only for the exact type, like 'space.w_tuple' or 'space.w_list'
+ pto.c_tp_dealloc = typedescr.get_dealloc(space)
+ else:
+ # for all subtypes, use subtype_dealloc()
+ pto.c_tp_dealloc = llhelper(
+ subtype_dealloc.api_func.functype,
+ subtype_dealloc.api_func.get_wrapper(space))
# buffer protocol
if space.is_w(w_type, space.w_str):
setup_string_buffer_procs(space, pto)
diff --git a/pypy/module/micronumpy/concrete.py
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -258,7 +258,6 @@
elif space.is_w(w_idx, space.w_None):
return [NewAxisChunk(), EllipsisChunk()]
result = []
- i = 0
has_ellipsis = False
has_filter = False
for w_item in space.fixedview(w_idx):
@@ -274,7 +273,6 @@
result.append(NewAxisChunk())
elif space.isinstance_w(w_item, space.w_slice):
result.append(SliceChunk(w_item))
- i += 1
elif isinstance(w_item, W_NDimArray) and
w_item.get_dtype().is_bool():
if has_filter:
# in CNumPy, the support for this is incomplete
@@ -287,7 +285,6 @@
result.append(IntegerChunk(w_item.descr_int(space)))
else:
result.append(IntegerChunk(w_item))
- i += 1
if not has_ellipsis:
result.append(EllipsisChunk())
return result
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -199,7 +199,7 @@
reds='auto')
def call_many_to_many(space, shape, func, in_dtypes, out_dtypes, in_args,
out_args):
- # out must hav been built. func needs no calc_type, is usually an
+ # out must have been built. func needs no calc_type, is usually an
# external ufunc
nin = len(in_args)
in_iters = [None] * nin
@@ -806,7 +806,6 @@
indexlen = len(indexes_w)
dtype = arr.get_dtype()
iter = PureShapeIter(iter_shape, indexes_w)
- indexlen = len(indexes_w)
while not iter.done():
getitem_int_driver.jit_merge_point(shapelen=shapelen,
indexlen=indexlen,
dtype=dtype, prefixlen=prefixlen)
diff --git a/pypy/module/micronumpy/ndarray.py
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -231,11 +231,11 @@
dim = i
idx = c.w_idx
chunks.pop(i)
- chunks.insert(0, SliceChunk(space.newslice(space.wrap(0),
+ chunks.insert(0, SliceChunk(space.newslice(space.wrap(0),
space.w_None, space.w_None)))
break
if dim > 0:
- view = self.implementation.swapaxes(space, self, 0, dim)
+ view = self.implementation.swapaxes(space, self, 0, dim)
if dim >= 0:
view = new_view(space, self, chunks)
view.setitem_filter(space, idx, val_arr)
@@ -563,7 +563,7 @@
l_w = []
for i in range(self.get_shape()[0]):
item_w = self.descr_getitem(space, space.wrap(i))
- if (isinstance(item_w, W_NDimArray) or
+ if (isinstance(item_w, W_NDimArray) or
isinstance(item_w, boxes.W_GenericBox)):
l_w.append(space.call_method(item_w, "tolist"))
else:
@@ -740,7 +740,7 @@
space.str_w(self.get_dtype().descr_repr(space)),
space.str_w(new_dtype.descr_repr(space)), casting)
order = order_converter(space, space.wrap(order), self.get_order())
- if (not copy and new_dtype == self.get_dtype()
+ if (not copy and new_dtype == self.get_dtype()
and (order in (NPY.KEEPORDER, NPY.ANYORDER) or order ==
self.get_order())
and (subok or type(self) is W_NDimArray)):
return self
diff --git a/pypy/module/micronumpy/strides.py
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -1,14 +1,13 @@
from pypy.interpreter.error import oefmt
from rpython.rlib import jit
-from pypy.module.micronumpy import support, constants as NPY
+from pypy.module.micronumpy import constants as NPY
from pypy.module.micronumpy.base import W_NDimArray
# structures to describe slicing
class BaseChunk(object):
- _attrs_ = ['step','out_dim']
- pass
+ _attrs_ = ['step', 'out_dim']
class Chunk(BaseChunk):
@@ -36,6 +35,7 @@
class IntegerChunk(BaseChunk):
input_dim = 1
out_dim = 0
+
def __init__(self, w_idx):
self.w_idx = w_idx
@@ -70,6 +70,7 @@
class EllipsisChunk(BaseChunk):
input_dim = 0
out_dim = 0
+
def __init__(self):
pass
@@ -80,6 +81,7 @@
class BooleanChunk(BaseChunk):
input_dim = 1
out_dim = 1
+
def __init__(self, w_idx):
self.w_idx = w_idx
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -1521,7 +1521,7 @@
# Instantiated in cpyext/ndarrayobject. It is here since ufunc calls
# set_dims_and_steps, otherwise ufunc, ndarrayobject would have circular
# imports
-npy_intpp = rffi.LONGP
+npy_intpp = rffi.INTPTR_T
LONG_SIZE = LONG_BIT / 8
CCHARP_SIZE = _get_bitsize('P') / 8
diff --git a/pypy/module/select/interp_epoll.py
b/pypy/module/select/interp_epoll.py
--- a/pypy/module/select/interp_epoll.py
+++ b/pypy/module/select/interp_epoll.py
@@ -53,6 +53,10 @@
EPOLL_CTL_MOD = cconfig["EPOLL_CTL_MOD"]
EPOLL_CTL_DEL = cconfig["EPOLL_CTL_DEL"]
+DEF_REGISTER_EVENTMASK = (public_symbols["EPOLLIN"] |
+ public_symbols["EPOLLOUT"] |
+ public_symbols["EPOLLPRI"])
+
epoll_create = rffi.llexternal(
"epoll_create", [rffi.INT], rffi.INT, compilation_info=eci,
save_err=rffi.RFFI_SAVE_ERRNO
@@ -133,7 +137,7 @@
self.close()
@unwrap_spec(eventmask=int)
- def descr_register(self, space, w_fd, eventmask=-1):
+ def descr_register(self, space, w_fd, eventmask=DEF_REGISTER_EVENTMASK):
self.check_closed(space)
self.epoll_ctl(space, EPOLL_CTL_ADD, w_fd, eventmask)
@@ -142,7 +146,7 @@
self.epoll_ctl(space, EPOLL_CTL_DEL, w_fd, 0, ignore_ebadf=True)
@unwrap_spec(eventmask=int)
- def descr_modify(self, space, w_fd, eventmask=-1):
+ def descr_modify(self, space, w_fd, eventmask):
self.check_closed(space)
self.epoll_ctl(space, EPOLL_CTL_MOD, w_fd, eventmask)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -56,7 +56,7 @@
max = int(max)
p = ffi.cast(c_decl, min)
assert p != min # no __eq__(int)
- assert bool(p) is True
+ assert bool(p) is bool(min)
assert int(p) == min
p = ffi.cast(c_decl, max)
assert int(p) == max
@@ -285,7 +285,9 @@
assert ffi.new("char*", b"\xff")[0] == b'\xff'
assert ffi.new("char*")[0] == b'\x00'
assert int(ffi.cast("char", 300)) == 300 - 256
- assert bool(ffi.cast("char", 0))
+ assert not bool(ffi.cast("char", 0))
+ assert bool(ffi.cast("char", 1))
+ assert bool(ffi.cast("char", 255))
py.test.raises(TypeError, ffi.new, "char*", 32)
py.test.raises(TypeError, ffi.new, "char*", u+"x")
py.test.raises(TypeError, ffi.new, "char*", b"foo")
@@ -326,7 +328,11 @@
py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345')
assert ffi.new("wchar_t*")[0] == u+'\x00'
assert int(ffi.cast("wchar_t", 300)) == 300
- assert bool(ffi.cast("wchar_t", 0))
+ assert not bool(ffi.cast("wchar_t", 0))
+ assert bool(ffi.cast("wchar_t", 1))
+ assert bool(ffi.cast("wchar_t", 65535))
+ if SIZE_OF_WCHAR > 2:
+ assert bool(ffi.cast("wchar_t", 65536))
py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
#
@@ -1523,21 +1529,30 @@
import gc; gc.collect(); gc.collect(); gc.collect()
assert seen == [3]
+ def test_gc_disable(self):
+ ffi = FFI(backend=self.Backend())
+ p = ffi.new("int *", 123)
+ py.test.raises(TypeError, ffi.gc, p, None)
+ seen = []
+ q1 = ffi.gc(p, lambda p: seen.append(1))
+ q2 = ffi.gc(q1, lambda p: seen.append(2))
+ import gc; gc.collect()
+ assert seen == []
+ assert ffi.gc(q1, None) is None
+ del q1, q2
+ import gc; gc.collect(); gc.collect(); gc.collect()
+ assert seen == [2]
+
def test_gc_finite_list(self):
ffi = FFI(backend=self.Backend())
- public = not hasattr(ffi._backend, 'gcp')
p = ffi.new("int *", 123)
keepalive = []
for i in range(10):
keepalive.append(ffi.gc(p, lambda p: None))
- if public:
- assert len(ffi.gc_weakrefs.data) == i + 1
del keepalive[:]
import gc; gc.collect(); gc.collect()
for i in range(10):
keepalive.append(ffi.gc(p, lambda p: None))
- if public:
- assert len(ffi.gc_weakrefs.data) == 10
def test_CData_CType(self):
ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
@@ -467,12 +467,12 @@
def test_introspect_order(self):
ffi = FFI()
- ffi.cdef("union aaa { int a; }; typedef struct ccc { int a; } b;")
- ffi.cdef("union g { int a; }; typedef struct cc { int a; } bbb;")
- ffi.cdef("union aa { int a; }; typedef struct a { int a; } bb;")
- assert ffi.list_types() == (['b', 'bb', 'bbb'],
- ['a', 'cc', 'ccc'],
- ['aa', 'aaa', 'g'])
+ ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; }
CFFIb;")
+ ffi.cdef("union CFFIg { int a; }; typedef struct CFFIcc { int a; }
CFFIbbb;")
+ ffi.cdef("union CFFIaa { int a; }; typedef struct CFFIa { int a; }
CFFIbb;")
+ assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'],
+ ['CFFIa', 'CFFIcc', 'CFFIccc'],
+ ['CFFIaa', 'CFFIaaa', 'CFFIg'])
def test_unpack(self):
ffi = FFI()
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
@@ -139,7 +139,7 @@
max = int(max)
p = ffi.cast(c_decl, min)
assert p != min # no __eq__(int)
- assert bool(p) is True
+ assert bool(p) is bool(min)
assert int(p) == min
p = ffi.cast(c_decl, max)
assert int(p) == max
@@ -351,7 +351,9 @@
assert ffi.new("char*", b"\xff")[0] == b'\xff'
assert ffi.new("char*")[0] == b'\x00'
assert int(ffi.cast("char", 300)) == 300 - 256
- assert bool(ffi.cast("char", 0))
+ assert not bool(ffi.cast("char", 0))
+ assert bool(ffi.cast("char", 1))
+ assert bool(ffi.cast("char", 255))
py.test.raises(TypeError, ffi.new, "char*", 32)
py.test.raises(TypeError, ffi.new, "char*", u+"x")
py.test.raises(TypeError, ffi.new, "char*", b"foo")
@@ -391,7 +393,11 @@
py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345')
assert ffi.new("wchar_t*")[0] == u+'\x00'
assert int(ffi.cast("wchar_t", 300)) == 300
- assert bool(ffi.cast("wchar_t", 0))
+ assert not bool(ffi.cast("wchar_t", 0))
+ assert bool(ffi.cast("wchar_t", 1))
+ assert bool(ffi.cast("wchar_t", 65535))
+ if SIZE_OF_WCHAR > 2:
+ assert bool(ffi.cast("wchar_t", 65536))
py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
#
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -1898,14 +1898,14 @@
def test_introspect_order():
ffi = FFI()
- ffi.cdef("union aaa { int a; }; typedef struct ccc { int a; } b;")
- ffi.cdef("union g { int a; }; typedef struct cc { int a; } bbb;")
- ffi.cdef("union aa { int a; }; typedef struct a { int a; } bb;")
+ ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; }
CFFIb;")
+ ffi.cdef("union CFFIg { int a; }; typedef struct CFFIcc { int a; }
CFFIbbb;")
+ ffi.cdef("union CFFIaa { int a; }; typedef struct CFFIa { int a; }
CFFIbb;")
verify(ffi, "test_introspect_order", """
- union aaa { int a; }; typedef struct ccc { int a; } b;
- union g { int a; }; typedef struct cc { int a; } bbb;
- union aa { int a; }; typedef struct a { int a; } bb;
+ union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;
+ union CFFIg { int a; }; typedef struct CFFIcc { int a; } CFFIbbb;
+ union CFFIaa { int a; }; typedef struct CFFIa { int a; } CFFIbb;
""")
- assert ffi.list_types() == (['b', 'bb', 'bbb'],
- ['a', 'cc', 'ccc'],
- ['aa', 'aaa', 'g'])
+ assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'],
+ ['CFFIa', 'CFFIcc', 'CFFIccc'],
+ ['CFFIaa', 'CFFIaaa', 'CFFIg'])
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
@@ -280,6 +280,14 @@
pass
with open("setup.py", "w") as f:
f.write("""if 1:
+ # https://bugs.python.org/issue23246
+ import sys
+ if sys.platform == 'win32':
+ try:
+ import setuptools
+ except ImportError:
+ pass
+
import cffi
ffi = cffi.FFI()
ffi.set_source("pack1.mymod", "/*code would be here*/")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
--- a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
@@ -80,8 +80,21 @@
# find a solution to that: we could hack sys.path inside the
# script run here, but we can't hack it in the same way in
# execute().
- output = self._run([sys.executable,
- os.path.join(local_dir, filename)])
+ pathname = os.path.join(path, filename)
+ with open(pathname, 'w') as g:
+ g.write('''
+# https://bugs.python.org/issue23246
+import sys
+if sys.platform == 'win32':
+ try:
+ import setuptools
+ except ImportError:
+ pass
+''')
+ with open(os.path.join(local_dir, filename), 'r') as f:
+ g.write(f.read())
+
+ output = self._run([sys.executable, pathname])
match = re.compile(r"\bFILENAME: (.+)").search(output)
assert match
dynamic_lib_name = match.group(1)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/udir.py
b/pypy/module/test_lib_pypy/cffi_tests/udir.py
--- a/pypy/module/test_lib_pypy/cffi_tests/udir.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/udir.py
@@ -1,4 +1,14 @@
# Generated by pypy/tool/import_cffi.py
import py
+import sys
udir = py.path.local.make_numbered_dir(prefix = 'ffi-')
+
+
+# Windows-only workaround for some configurations: see
+# https://bugs.python.org/issue23246 (Python 2.7.9)
+if sys.platform == 'win32':
+ try:
+ import setuptools
+ except ImportError:
+ pass
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -484,7 +484,12 @@
return None
def view_as_kwargs(self, w_dict):
- if type(w_dict) is W_DictObject:
+ # Tries to return (keys_list, values_list), or (None, None) if
+ # it fails. It can fail on some dict implementations, so don't
+ # rely on it. For dict subclasses, though, it never fails;
+ # this emulates CPython's behavior which often won't call
+ # custom __iter__() or keys() methods in dict subclasses.
+ if isinstance(w_dict, W_DictObject):
return w_dict.view_as_kwargs()
return (None, None)
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -3,7 +3,7 @@
min=1
rev=1
branchname=release-$maj.x # ==OR== release-$maj.$min.x
-tagname=release-$maj.$min # ==OR== release-$maj.$min.$rev
+tagname=release-$maj.$min.$rev # ==OR== release-$maj.$min
hg log -r $branchname || exit 1
hg log -r $tagname || exit 1
diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py
b/rpython/jit/metainterp/optimizeopt/intutils.py
--- a/rpython/jit/metainterp/optimizeopt/intutils.py
+++ b/rpython/jit/metainterp/optimizeopt/intutils.py
@@ -1,5 +1,8 @@
+import sys
from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, maxint, is_valid_int
from rpython.rlib.objectmodel import we_are_translated
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.jit.metainterp.resoperation import rop, ResOperation
from rpython.jit.metainterp.optimizeopt.info import AbstractInfo,
INFO_NONNULL,\
INFO_UNKNOWN, INFO_NULL
@@ -174,15 +177,13 @@
def div_bound(self, other):
if self.has_upper and self.has_lower and \
other.has_upper and other.has_lower and \
- not other.contains(0):
- try:
- vals = (ovfcheck(self.upper / other.upper),
- ovfcheck(self.upper / other.lower),
- ovfcheck(self.lower / other.upper),
- ovfcheck(self.lower / other.lower))
- return IntBound(min4(vals), max4(vals))
- except OverflowError:
- return IntUnbounded()
+ not other.contains(0) and self.lower > (-sys.maxint-1):
+ vals = (
+ llop.int_floordiv(lltype.Signed, self.upper, other.upper),
+ llop.int_floordiv(lltype.Signed, self.upper, other.lower),
+ llop.int_floordiv(lltype.Signed, self.lower, other.upper),
+ llop.int_floordiv(lltype.Signed, self.lower, other.lower))
+ return IntBound(min4(vals), max4(vals))
else:
return IntUnbounded()
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
@@ -240,6 +240,8 @@
def test_div_bound():
+ from rpython.rtyper.lltypesystem import lltype
+ from rpython.rtyper.lltypesystem.lloperation import llop
for _, _, b1 in some_bounds():
for _, _, b2 in some_bounds():
b3 = b1.div_bound(b2)
@@ -247,7 +249,8 @@
for n2 in nbr:
if b1.contains(n1) and b2.contains(n2):
if n2 != 0:
- assert b3.contains(n1 / n2)
+ assert b3.contains(
+ llop.int_floordiv(lltype.Signed, n1, n2))
a=bound(2, 4).div_bound(bound(1, 2))
assert not a.contains(0)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5529,6 +5529,27 @@
"""
self.optimize_loop(ops, expected)
+ def test_division_bound_bug(self):
+ ops = """
+ [i4]
+ i1 = int_ge(i4, -50)
+ guard_true(i1) []
+ i2 = int_le(i4, -40)
+ guard_true(i2) []
+ # here, -50 <= i4 <= -40
+
+ i5 = int_floordiv(i4, 30)
+ # here, we know that that i5 == -1 (C-style handling of negatives!)
+ escape_n(i5)
+ jump(i4)
+ """
+ expected = """
+ [i4, i5]
+ escape_n(-1)
+ jump(i4, -1)
+ """
+ self.optimize_loop(ops, expected)
+
def test_subsub_ovf(self):
ops = """
[i0]
diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py
--- a/rpython/rlib/runicode.py
+++ b/rpython/rlib/runicode.py
@@ -989,8 +989,6 @@
return result.build(), pos
-# Specialize on the errorhandler when it's a constant
[email protected]_or_var(4)
def str_decode_ascii(s, size, errors, final=False,
errorhandler=None):
if errorhandler is None:
@@ -1020,8 +1018,6 @@
return result.build()
-# Specialize on the errorhandler when it's a constant
[email protected]_or_var(3)
def unicode_encode_ucs1_helper(p, size, errors,
errorhandler=None, limit=256):
if errorhandler is None:
@@ -1064,12 +1060,10 @@
return result.build()
[email protected]_or_var(3)
def unicode_encode_latin_1(p, size, errors, errorhandler=None):
res = unicode_encode_ucs1_helper(p, size, errors, errorhandler, 256)
return res
[email protected]_or_var(3)
def unicode_encode_ascii(p, size, errors, errorhandler=None):
res = unicode_encode_ucs1_helper(p, size, errors, errorhandler, 128)
return res
@@ -1194,8 +1188,6 @@
builder.append(res)
return pos
-# Specialize on the errorhandler when it's a constant
[email protected]_or_var(4)
def str_decode_unicode_escape(s, size, errors, final=False,
errorhandler=None,
unicodedata_handler=None):
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -552,16 +552,16 @@
self.log.info('usession directory: %s' % (udir,))
return result
- @staticmethod
- def from_targetspec(targetspec_dic, config=None, args=None,
+ @classmethod
+ def from_targetspec(cls, targetspec_dic, config=None, args=None,
empty_translator=None,
disable=[],
default_goal=None):
if args is None:
args = []
- driver = TranslationDriver(config=config, default_goal=default_goal,
- disable=disable)
+ driver = cls(config=config, default_goal=default_goal,
+ disable=disable)
target = targetspec_dic['target']
spec = target(driver, args)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit