Author: mattip <matti.pi...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit