Author: Alex Gaynor <alex.gay...@gmail.com> Branch: Changeset: r71698:bddbc93c6eab Date: 2014-05-24 12:21 -0500 http://bitbucket.org/pypy/pypy/changeset/bddbc93c6eab/
Log: merged upstream diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -748,11 +748,11 @@ self.lockcounter = 0 def lock_held_by_someone_else(self): - return self.lockowner is not None and not self.lock_held() + me = self.space.getexecutioncontext() # used as thread ident + return self.lockowner is not None and self.lockowner is not me - def lock_held(self): - me = self.space.getexecutioncontext() # used as thread ident - return self.lockowner is me + def lock_held_by_anyone(self): + return self.lockowner is not None def acquire_lock(self): # this function runs with the GIL acquired so there is no race diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -165,7 +165,7 @@ def lock_held(space): if space.config.objspace.usemodules.thread: - return space.wrap(importing.getimportlock(space).lock_held()) + return space.wrap(importing.getimportlock(space).lock_held_by_anyone()) else: return space.w_False diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -15,6 +15,7 @@ 'empty': 'ctors.zeros', 'empty_like': 'ctors.empty_like', 'fromstring': 'ctors.fromstring', + 'frombuffer': 'ctors.frombuffer', 'concatenate': 'arrayops.concatenate', 'count_nonzero': 'arrayops.count_nonzero', diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py --- a/pypy/module/micronumpy/ctors.py +++ b/pypy/module/micronumpy/ctors.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import unwrap_spec, WrappedDefault +from rpython.rlib.buffer import SubBuffer from rpython.rlib.rstring import strip_spaces from rpython.rtyper.lltypesystem import lltype, rffi from pypy.module.micronumpy import descriptor, loop @@ -191,3 +192,62 @@ return _fromstring_bin(space, s, count, length, dtype) else: return _fromstring_text(space, s, count, sep, length, dtype) + + +def _getbuffer(space, w_buffer): + try: + return space.writebuf_w(w_buffer) + except OperationError as e: + if not e.match(space, space.w_TypeError): + raise + return space.readbuf_w(w_buffer) + + +@unwrap_spec(count=int, offset=int) +def frombuffer(space, w_buffer, w_dtype=None, count=-1, offset=0): + dtype = space.interp_w(descriptor.W_Dtype, + space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) + if dtype.elsize == 0: + raise oefmt(space.w_ValueError, "itemsize cannot be zero in type") + + try: + buf = _getbuffer(space, w_buffer) + except OperationError as e: + if not e.match(space, space.w_TypeError): + raise + w_buffer = space.getattr(w_buffer, space.wrap('__buffer__')) + buf = _getbuffer(space, w_buffer) + + ts = buf.getlength() + if offset < 0 or offset > ts: + raise oefmt(space.w_ValueError, + "offset must be non-negative and no greater than " + "buffer length (%d)", ts) + + s = ts - offset + if offset: + buf = SubBuffer(buf, offset, s) + + n = count + itemsize = dtype.elsize + assert itemsize > 0 + if n < 0: + if s % itemsize != 0: + raise oefmt(space.w_ValueError, + "buffer size must be a multiple of element size") + n = s / itemsize + else: + if s < n * itemsize: + raise oefmt(space.w_ValueError, + "buffer is smaller than requested size") + + try: + storage = buf.get_raw_address() + except ValueError: + a = W_NDimArray.from_shape(space, [n], dtype=dtype) + loop.fromstring_loop(space, a, dtype, itemsize, buf.as_str()) + return a + else: + writable = not buf.readonly + return W_NDimArray.from_shape_and_storage(space, [n], storage, dtype=dtype, + w_base=w_buffer, writable=writable) diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py --- a/pypy/module/micronumpy/test/test_ndarray.py +++ b/pypy/module/micronumpy/test/test_ndarray.py @@ -3132,6 +3132,8 @@ class AppTestSupport(BaseNumpyAppTest): + spaceconfig = {'usemodules': ['micronumpy', 'array']} + def setup_class(cls): import struct BaseNumpyAppTest.setup_class.im_func(cls) @@ -3142,6 +3144,44 @@ cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4)) cls.w_ulongval = cls.space.wrap(struct.pack('L', 12)) + def test_frombuffer(self): + import numpy as np + exc = raises(AttributeError, np.frombuffer, None) + assert str(exc.value) == "'NoneType' object has no attribute '__buffer__'" + exc = raises(AttributeError, np.frombuffer, memoryview(self.data)) + assert str(exc.value) == "'memoryview' object has no attribute '__buffer__'" + exc = raises(ValueError, np.frombuffer, self.data, 'S0') + assert str(exc.value) == "itemsize cannot be zero in type" + exc = raises(ValueError, np.frombuffer, self.data, offset=-1) + assert str(exc.value) == "offset must be non-negative and no greater than buffer length (32)" + exc = raises(ValueError, np.frombuffer, self.data, count=100) + assert str(exc.value) == "buffer is smaller than requested size" + for data in [self.data, buffer(self.data)]: + a = np.frombuffer(data) + for i in range(4): + assert a[i] == i + 1 + + import array + data = array.array('c', 'testing') + a = np.frombuffer(data, 'c') + assert a.base is data + a[2] = 'Z' + assert data.tostring() == 'teZting' + + data = buffer(data) + a = np.frombuffer(data, 'c') + assert a.base is data + exc = raises(ValueError, "a[2] = 'Z'") + assert str(exc.value) == "assignment destination is read-only" + + class A(object): + __buffer__ = 'abc' + + data = A() + a = np.frombuffer(data, 'c') + #assert a.base is data.__buffer__ + assert a.tostring() == 'abc' + def test_fromstring(self): import sys from numpypy import fromstring, dtype diff --git a/pypy/module/thread/test/test_import_lock.py b/pypy/module/thread/test/test_import_lock.py --- a/pypy/module/thread/test/test_import_lock.py +++ b/pypy/module/thread/test/test_import_lock.py @@ -62,6 +62,28 @@ self.waitfor(lambda: done) assert done + def test_lock_held_by_another_thread(self): + import thread, imp + lock_held = thread.allocate_lock() + test_complete = thread.allocate_lock() + lock_released = thread.allocate_lock() + def other_thread(): + imp.acquire_lock() # 3 + assert imp.lock_held() + lock_held.release() # 4 + test_complete.acquire() # 7 + imp.release_lock() # 8 + lock_released.release() # 9 + lock_held.acquire() + test_complete.acquire() + lock_released.acquire() + # + thread.start_new_thread(other_thread, ()) # 1 + lock_held.acquire() # 2 + assert imp.lock_held() # 5 + test_complete.release() # 6 + lock_released.acquire() # 10 + class TestImportLock: def test_lock(self, space, monkeypatch): from pypy.module.imp.importing import getimportlock, importhook _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit