Author: mattip <[email protected]>
Branch: numpy-fixes
Changeset: r77303:0a9ce2fd743a
Date: 2015-05-13 07:45 +0300
http://bitbucket.org/pypy/pypy/changeset/0a9ce2fd743a/
Log: merge default into branch
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -145,6 +145,34 @@
name = hostname
return name
+class RefCountingWarning(UserWarning):
+ pass
+
+def _do_reuse_or_drop(socket, methname):
+ try:
+ method = getattr(socket, methname)
+ except (AttributeError, TypeError):
+ warnings.warn("""'%s' object has no _reuse/_drop methods
+{{
+ You make use (or a library you are using makes use) of the internal
+ classes '_socketobject' and '_fileobject' in socket.py, initializing
+ them with custom objects. On PyPy, these custom objects need two
+ extra methods, _reuse() and _drop(), that maintain an explicit
+ reference counter. When _drop() has been called as many times as
+ _reuse(), then the object should be freed.
+
+ Without these methods, you get the warning here. This is to
+ prevent the following situation: if your (or the library's) code
+ relies on reference counting for prompt closing, then on PyPy, the
+ __del__ method will be called later than on CPython. You can
+ easily end up in a situation where you open and close a lot of
+ (high-level) '_socketobject' or '_fileobject', but the (low-level)
+ custom objects will accumulate before their __del__ are called.
+ You quickly risk running out of file descriptors, for example.
+}}""" % (socket.__class__.__name__,), RefCountingWarning, stacklevel=3)
+ else:
+ method()
+
_socketmethods = (
'bind', 'connect', 'connect_ex', 'fileno', 'listen',
@@ -182,19 +210,7 @@
if _sock is None:
_sock = _realsocket(family, type, proto)
else:
- # PyPy note about refcounting: implemented with _reuse()/_drop()
- # on the class '_socket.socket'. Python 3 did it differently
- # with a reference counter on this class 'socket._socketobject'
- # instead, but it is a less compatible change.
-
- # Note that a few libraries (like eventlet) poke at the
- # private implementation of socket.py, passing custom
- # objects to _socketobject(). These libraries need the
- # following fix for use on PyPy: the custom objects need
- # methods _reuse() and _drop() that maintains an explicit
- # reference counter, starting at 0. When it drops back to
- # zero, close() must be called.
- _sock._reuse()
+ _do_reuse_or_drop(_sock, '_reuse')
self._sock = _sock
@@ -228,13 +244,13 @@
def close(self):
s = self._sock
self._sock = _closedsocket()
- s._drop()
+ _do_reuse_or_drop(s, '_drop')
close.__doc__ = _realsocket.close.__doc__
def accept(self):
sock, addr = self._sock.accept()
sockobj = _socketobject(_sock=sock)
- sock._drop() # already a copy in the _socketobject()
+ _do_reuse_or_drop(sock, '_drop') # already a copy in the
_socketobject()
return sockobj, addr
accept.__doc__ = _realsocket.accept.__doc__
@@ -290,14 +306,7 @@
"_close"]
def __init__(self, sock, mode='rb', bufsize=-1, close=False):
- # Note that a few libraries (like eventlet) poke at the
- # private implementation of socket.py, passing custom
- # objects to _fileobject(). These libraries need the
- # following fix for use on PyPy: the custom objects need
- # methods _reuse() and _drop() that maintains an explicit
- # reference counter, starting at 0. When it drops back to
- # zero, close() must be called.
- sock._reuse()
+ _do_reuse_or_drop(sock, '_reuse')
self._sock = sock
self.mode = mode # Not actually used in this version
if bufsize < 0:
@@ -338,7 +347,7 @@
if self._close:
s.close()
else:
- s._drop()
+ _do_reuse_or_drop(s, '_drop')
def __del__(self):
try:
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
@@ -533,6 +533,9 @@
return self.__class__(self.start, new_strides, new_backstrides,
new_shape,
self, orig_array)
+ def sort(self, space, w_axis, w_order):
+ from .selection import sort_array
+ return sort_array(self, space, w_axis, w_order)
class NonWritableSliceArray(SliceArray):
def descr_setitem(self, space, orig_array, w_index, w_value):
diff --git a/pypy/module/micronumpy/selection.py
b/pypy/module/micronumpy/selection.py
--- a/pypy/module/micronumpy/selection.py
+++ b/pypy/module/micronumpy/selection.py
@@ -120,7 +120,7 @@
ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length,
arg_getitem_slice, arg_lt)
- def argsort(arr, space, w_axis, itemsize):
+ def argsort(arr, space, w_axis):
if w_axis is space.w_None:
# note that it's fine ot pass None here as we're not going
# to pass the result around (None is the link to base in slices)
@@ -138,7 +138,7 @@
if len(arr.get_shape()) == 1:
for i in range(arr.get_size()):
raw_storage_setitem(storage, i * INT_SIZE, i)
- r = Repr(INT_SIZE, itemsize, arr.get_size(), arr_storage,
+ r = Repr(INT_SIZE, arr.strides[0], arr.get_size(), arr_storage,
storage, 0, arr.start)
ArgSort(r).sort()
else:
@@ -174,8 +174,7 @@
itemtype = arr.dtype.itemtype
for tp in all_types:
if isinstance(itemtype, tp[0]):
- return cache._lookup(tp)(arr, space, w_axis,
- itemtype.get_element_size())
+ return cache._lookup(tp)(arr, space, w_axis)
# XXX this should probably be changed
raise oefmt(space.w_NotImplementedError,
"sorting of non-numeric types '%s' is not implemented",
@@ -272,7 +271,7 @@
ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length,
arg_getitem_slice, arg_lt)
- def sort(arr, space, w_axis, itemsize):
+ def sort(arr, space, w_axis):
if w_axis is space.w_None:
# note that it's fine to pass None here as we're not going
# to pass the result around (None is the link to base in slices)
@@ -284,7 +283,7 @@
axis = space.int_w(w_axis)
with arr as storage:
if len(arr.get_shape()) == 1:
- r = Repr(itemsize, arr.get_size(), storage,
+ r = Repr(arr.strides[0], arr.get_size(), storage,
arr.start)
ArgSort(r).sort()
else:
@@ -313,8 +312,7 @@
"sorting of non-native byteorder not supported yet")
for tp in all_types:
if isinstance(itemtype, tp[0]):
- return cache._lookup(tp)(arr, space, w_axis,
- itemtype.get_element_size())
+ return cache._lookup(tp)(arr, space, w_axis)
# XXX this should probably be changed
raise oefmt(space.w_NotImplementedError,
"sorting of non-numeric types '%s' is not implemented",
diff --git a/pypy/module/micronumpy/test/test_selection.py
b/pypy/module/micronumpy/test/test_selection.py
--- a/pypy/module/micronumpy/test/test_selection.py
+++ b/pypy/module/micronumpy/test/test_selection.py
@@ -82,6 +82,13 @@
#assert (a == b).all(), \
# 'a,orig,dtype %r,%r,%r' % (a,c,dtype)
+ def test_sort_noncontiguous(self):
+ from numpy import array
+ x = array([[2, 10], [1, 11]])
+ assert (x[:, 0].argsort() == [1, 0]).all()
+ x[:, 0].sort()
+ assert (x == [[1, 10], [2, 11]]).all()
+
# tests from numpy/tests/test_multiarray.py
def test_sort_corner_cases(self):
# test ordering for floats and complex containing nans. It is only
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py
b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -435,7 +435,6 @@
guard_value(i4, 1, descr=...)
guard_isnull(p5, descr=...)
guard_nonnull_class(p12, ConstClass(W_IntObject), descr=...)
- guard_value(i8, 0, descr=...)
guard_value(p2, ConstPtr(ptr21), descr=...)
i22 = getfield_gc_pure(p12, descr=<FieldS
pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
i24 = int_lt(i22, 5000)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -1240,12 +1240,12 @@
escape(i2)
jump()
"""
+ # also check that the length of the forced array is known
expected = """
[]
p1 = new_array(3, descr=arraydescr)
escape(p1)
- i2 = arraylen_gc(p1)
- escape(i2)
+ escape(3)
jump()
"""
self.optimize_loop(ops, expected)
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
@@ -1688,8 +1688,7 @@
[]
p1 = new_array(3, descr=arraydescr)
escape(p1)
- i2 = arraylen_gc(p1)
- escape(i2)
+ escape(3)
jump()
"""
self.optimize_loop(ops, expected)
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -347,6 +347,7 @@
[box, ConstInt(index), subbox], None,
descr=self.arraydescr)
optforce.emit_operation(op)
+ optforce.pure(rop.ARRAYLEN_GC, [box], ConstInt(len(self._items)))
@specialize.argtype(1)
def _visitor_dispatch_virtual_type(self, visitor):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit