To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 03721401 authored by mattip's avatar mattip
Browse files

update release from default

parents 5b2ffe01 dcbf722f
......@@ -3,7 +3,7 @@ PyPy 4.0.0
============
We're pleased and proud to unleash PyPy 4.0.0, a major update of the PyPy
python2.7.10 compatible interpreter with a Just In Time compiler.
python 2.7.10 compatible interpreter with a Just In Time compiler.
We have improved `warmup time and memory overhead used for tracing`_, added
`vectorization`_ for numpy and general loops where possible on x86 hardware
(disabled by default),
......@@ -72,15 +72,17 @@ CFFI
While not applicable only to PyPy, `cffi`_ is arguably our most significant
contribution to the python ecosystem. Armin Rigo continued improving it,
and PyPy reaps the benefits of cffi-1.3: improved manangement of object
lifetimes, __stdcall on Win32, ffi.memmove(), ...
and PyPy reaps the benefits of `cffi-1.3`_: improved manangement of object
lifetimes, __stdcall on Win32, ffi.memmove(), and percolate ``const``,
``restrict`` keywords from cdef to C code.
.. _`warmup time and memory overhead used for tracing`: http://morepypy.blogspot.com/2015/10
.. _`warmup time and memory overhead used for tracing`: http://morepypy.blogspot.com/2015/10/pypy-memory-and-warmup-improvements-2.html
.. _`vectorization`: http://pypyvecopt.blogspot.co.at/
.. _`guards`: http://rpython.readthedocs.org/en/latest/glossary.html
.. _`PyPy`: http://doc.pypy.org
.. _`RPython`: https://rpython.readthedocs.org
.. _`cffi`: https://cffi.readthedocs.org
.. _`cffi-1.3`: http://cffi.readthedocs.org/en/latest/whatsnew.html#v1-3-0
.. _`modules`: http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly
.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html
.. _`numpy`: https://bitbucket.org/pypy/numpy
......
......@@ -101,3 +101,13 @@ def test_whatsnew():
assert not not_documented
if branch == 'default':
assert not not_merged
def test_startrev_on_default():
doc = ROOT.join('pypy', 'doc')
last_whatsnew = doc.join('whatsnew-head.rst').read()
startrev, documented = parse_doc(last_whatsnew)
errcode, wc_branch = getstatusoutput(
"hg log -r %s --template '{branch}'" % startrev)
if errcode != 0:
py.test.skip('no Mercurial repo')
assert wc_branch == 'default'
......@@ -3,6 +3,8 @@ What's new in PyPy 4.0.+
=========================
.. this is a revision shortly after release-4.0.0
.. startrev: 3a8f5481dab4
.. startrev: 9397d7c6f5aa
.. branch: lazy-fast2locals
improve the performance of simple trace functions by lazily calling
fast2locals and locals2fast only if f_locals is actually accessed.
......@@ -327,10 +327,14 @@ class ExecutionContext(object):
w_arg = space.newtuple([operr.w_type, w_value,
space.wrap(operr.get_traceback())])
frame.fast2locals()
d = frame.getorcreatedebug()
if d.w_locals is not None:
# only update the w_locals dict if it exists
# if it does not exist yet and the tracer accesses it via
# frame.f_locals, it is filled by PyFrame.getdictscope
frame.fast2locals()
self.is_tracing += 1
try:
d = frame.getorcreatedebug()
try:
w_result = space.call_function(w_callback, space.wrap(frame), space.wrap(event), w_arg)
if space.is_w(w_result, space.w_None):
......@@ -343,7 +347,8 @@ class ExecutionContext(object):
raise
finally:
self.is_tracing -= 1
frame.locals2fast()
if d.w_locals is not None:
frame.locals2fast()
# Profile cases
if self.profilefunc is not None:
......
from rpython.tool import udir
from pypy.conftest import option
from pypy.interpreter.gateway import interp2app
def check_no_w_locals(space, w_frame):
return space.wrap(w_frame.getorcreatedebug().w_locals is None)
class AppTestPyFrame:
def setup_class(cls):
space = cls.space
cls.w_udir = cls.space.wrap(str(udir.udir))
cls.w_tempfile1 = cls.space.wrap(str(udir.udir.join('tempfile1')))
if not option.runappdirect:
......@@ -17,6 +21,8 @@ class AppTestPyFrame:
w_call_further.code.hidden_applevel = True # hack
cls.w_call_further = w_call_further
cls.w_check_no_w_locals = space.wrap(interp2app(check_no_w_locals))
# test for the presence of the attributes, not functionality
def test_f_locals(self):
......@@ -493,6 +499,25 @@ class AppTestPyFrame:
sys.settrace(None)
assert res == 42
def test_fast2locals_called_lazily(self):
import sys
class FrameHolder:
pass
fh = FrameHolder()
def trace(frame, what, arg):
# trivial trace function, does not access f_locals
fh.frame = frame
return trace
def f(x):
x += 1
return x
sys.settrace(trace)
res = f(1)
sys.settrace(None)
assert res == 2
if hasattr(self, "check_no_w_locals"): # not appdirect
assert self.check_no_w_locals(fh.frame)
def test_set_unset_f_trace(self):
import sys
seen = []
......
......@@ -86,11 +86,14 @@ class W_NDimArray(W_NumpyObject):
if len(strides) != len(shape):
raise oefmt(space.w_ValueError,
'strides, if given, must be the same length as shape')
last = 0
for i in range(len(strides)):
if strides[i] < 0 or strides[i]*shape[i] > storage_bytes:
raise oefmt(space.w_ValueError,
'strides is incompatible with shape of requested '
'array and size of buffer')
last += (shape[i] - 1) * strides[i]
if last > storage_bytes or start < 0 or \
start + dtype.elsize > storage_bytes:
raise oefmt(space.w_ValueError,
'strides is incompatible with shape of requested '
'array and size of buffer')
backstrides = calc_backstrides(strides, shape)
if w_base is not None:
if owning:
......
......@@ -134,13 +134,18 @@ def _array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False):
else:
imp = w_object.implementation
w_base = w_object
sz = w_base.get_size() * dtype.elsize
if imp.base() is not None:
w_base = imp.base()
if type(w_base) is W_NDimArray:
sz = w_base.get_size() * dtype.elsize
else:
# this must succeed (mmap, buffer, ...)
sz = space.int_w(space.call_method(w_base, 'size'))
with imp as storage:
sz = support.product(w_object.get_shape()) * dtype.elsize
return W_NDimArray.from_shape_and_storage(space,
w_object.get_shape(), storage, dtype, storage_bytes=sz,
w_base=w_base, start=imp.start)
w_base=w_base, strides=imp.strides, start=imp.start)
else:
# not an array
shape, elems_w = find_shape_and_elems(space, w_object, dtype)
......
......@@ -348,7 +348,7 @@ class W_NDIter(W_NumpyObject):
_immutable_fields_ = ['ndim', ]
def __init__(self, space, w_seq, w_flags, w_op_flags, w_op_dtypes,
w_casting, w_op_axes, w_itershape, buffersize=0,
order=NPY.KEEPORDER):
order=NPY.KEEPORDER, allow_backward=True):
self.external_loop = False
self.buffered = False
self.tracked_index = ''
......@@ -363,6 +363,7 @@ class W_NDIter(W_NumpyObject):
self.done = False
self.first_next = True
self.op_axes = []
self.allow_backward = allow_backward
if not space.is_w(w_casting, space.w_None):
self.casting = space.str_w(w_casting)
else:
......@@ -540,18 +541,18 @@ class W_NDIter(W_NumpyObject):
self.op_flags[i], self)
backward = imp.order != self.order
# XXX cleanup needed
if (abs(imp.strides[0]) < abs(imp.strides[-1]) and not backward) or \
(abs(imp.strides[0]) > abs(imp.strides[-1]) and backward):
# flip the strides. Is this always true for multidimension?
strides = imp.strides[:]
backstrides = imp.backstrides[:]
shape = imp.shape[:]
strides.reverse()
backstrides.reverse()
shape.reverse()
else:
strides = imp.strides
backstrides = imp.backstrides
strides = imp.strides
backstrides = imp.backstrides
if self.allow_backward:
if ((abs(imp.strides[0]) < abs(imp.strides[-1]) and not backward) or \
(abs(imp.strides[0]) > abs(imp.strides[-1]) and backward)):
# flip the strides. Is this always true for multidimension?
strides = imp.strides[:]
backstrides = imp.backstrides[:]
shape = imp.shape[:]
strides.reverse()
backstrides.reverse()
shape.reverse()
r = calculate_broadcast_strides(strides, backstrides, imp.shape,
shape, backward)
iter_shape = shape
......
......@@ -140,7 +140,6 @@ def calculate_slice_strides(space, shape, start, strides, backstrides, chunks):
extra_dims = len(shape) - used_dims
rstrides = [0] * (size + extra_dims)
rbackstrides = [0] * (size + extra_dims)
rstart = start
rshape = [0] * (size + extra_dims)
rstart = start
i = 0 # index of the current dimension in the input array
......
......@@ -309,13 +309,13 @@ class AppTestSupport(BaseNumpyAppTest):
assert c.dtype is dtype(float)
def test_array_of_subtype(self):
import numpy as N
import numpy as np
# this part of numpy's matrix class causes an infinite loop
# on cpython
import sys
if '__pypy__' not in sys.builtin_module_names:
skip('does not pass on cpython')
class matrix(N.ndarray):
class matrix(np.ndarray):
def __new__(subtype, data, dtype=None, copy=True):
print('matrix __new__')
if isinstance(data, matrix):
......@@ -326,11 +326,11 @@ class AppTestSupport(BaseNumpyAppTest):
return data
return data.astype(dtype)
if isinstance(data, N.ndarray):
if isinstance(data, np.ndarray):
if dtype is None:
intype = data.dtype
else:
intype = N.dtype(dtype)
intype = np.dtype(dtype)
new = data.view(subtype)
if intype != data.dtype:
return new.astype(intype)
......@@ -341,7 +341,7 @@ class AppTestSupport(BaseNumpyAppTest):
data = _convert_from_string(data)
# now convert data to an array
arr = N.array(data, dtype=dtype, copy=copy)
arr = np.array(data, dtype=dtype, copy=copy)
ndim = arr.ndim
shape = arr.shape
if (ndim > 2):
......@@ -358,7 +358,7 @@ class AppTestSupport(BaseNumpyAppTest):
if not (order or arr.flags.contiguous):
arr = arr.copy()
ret = N.ndarray.__new__(subtype, shape, arr.dtype,
ret = np.ndarray.__new__(subtype, shape, arr.dtype,
buffer=arr,
order=order)
return ret
......@@ -391,11 +391,11 @@ class AppTestSupport(BaseNumpyAppTest):
self._getitem = True
try:
out = N.ndarray.__getitem__(self, index)
out = np.ndarray.__getitem__(self, index)
finally:
self._getitem = False
if not isinstance(out, N.ndarray):
if not isinstance(out, np.ndarray):
return out
if out.ndim == 0:
......@@ -414,18 +414,18 @@ class AppTestSupport(BaseNumpyAppTest):
return out
a = matrix([[1., 2.], [3., 4.]])
b = N.array([a])
b = np.array([a])
assert (b == a).all()
b = N.array(a)
b = np.array(a)
assert len(b.shape) == 2
assert (b == a).all()
b = N.array(a, copy=False)
b = np.array(a, copy=False)
assert len(b.shape) == 2
assert (b == a).all()
b = N.array(a, copy=True, dtype=int)
b = np.array(a, copy=True, dtype=int)
assert len(b.shape) == 2
assert (b == a).all()
......@@ -433,9 +433,30 @@ class AppTestSupport(BaseNumpyAppTest):
assert c.base is not None
c[0, 0] = 100
assert a[0, 0] == 100
b = N.array(c, copy=True)
b = np.array(c, copy=True)
assert (b == a).all()
d = np.empty([6,2], dtype=float)
d.view(int).fill(0xdeadbeef)
e = d[0::3,:]
e[...] = [[1, 2], [3, 4]]
assert e.strides == (48, 8)
f = e.view(matrix)
assert f.strides == (48, 8)
g = np.array(f, copy=False)
assert (g == [[1, 2], [3, 4]]).all()
k = np.empty([2, 8], dtype=float)
k.view(int).fill(0xdeadbeef)
m = k[:, ::-4]
m[...] = [[1, 2], [3, 4]]
assert m.strides == (64, -32)
n = m.view(matrix)
assert n.strides == (64, -32)
p = np.array(n, copy=False)
assert (p == [[1, 2], [3, 4]]).all()
def test_setstate_no_version(self):
# Some subclasses of ndarray, like MaskedArray, do not use
# version in __setstate__
......
......@@ -202,13 +202,38 @@ class AppTestUfuncs(BaseNumpyAppTest):
ao = ufunc(ai)
assert ao.shape == (0, 1, 1)
def test_frompyfunc_not_contiguous(self):
import sys
from numpy import frompyfunc, dtype, arange, dot
if '__pypy__' not in sys.builtin_module_names:
skip('PyPy only frompyfunc extension')
def _dot(in0, in1, out):
print in0, '\nin1',in1,'\nin1.shape', in1.shape, 'in1.strides', in1.strides
out[...] = dot(in0, in1)
ufunc_dot = frompyfunc(_dot, 2, 1,
signature='(m,m),(m,n)->(m,n)',
dtypes=[dtype(float), dtype(float), dtype(float)],
stack_inputs=True,
)
a1 = arange(4, dtype=float).reshape(2,2)
# create a non-c-contiguous argument
a2 = arange(2, dtype=float).reshape(2,1)
a3 = arange(2, dtype=float).reshape(1,2).T
b1 = ufunc_dot(a1, a2, sig='dd->d')
b2 = dot(a1, a2)
assert (b1==b2).all()
print 'xxxxxxxxxxxx'
b1 = ufunc_dot(a1, a3, sig='dd->d')
b2 = dot(a1, a3)
assert (b1==b2).all()
def test_frompyfunc_needs_nditer(self):
import sys
from numpy import frompyfunc, dtype, arange
if '__pypy__' not in sys.builtin_module_names:
skip('PyPy only frompyfunc extension')
def summer(in0):
print 'in summer, in0=',in0,'in0.shape=',in0.shape
return in0.sum()
ufunc = frompyfunc([summer], 1, 1,
......@@ -242,11 +267,14 @@ class AppTestUfuncs(BaseNumpyAppTest):
stack_inputs=True,
)
ai = arange(18, dtype=int).reshape(3,2,3)
aout = ufunc_add(ai, ai[0,:,:])
assert aout.shape == (3, 2, 3)
aout = ufunc_sum(ai)
assert aout.shape == (3, 3)
aout1 = ufunc_add(ai, ai[0,:,:])
assert aout1.shape == (3, 2, 3)
aout2 = ufunc_add(ai, ai[0,:,:])
aout3 = ufunc_sum(ai)
assert aout3.shape == (3, 3)
aout4 = ufunc_add(ai, ai[0,:,:][None, :,:])
assert (aout1 == aout4).all()
def test_frompyfunc_fortran(self):
import sys
import numpy as np
......@@ -280,7 +308,7 @@ class AppTestUfuncs(BaseNumpyAppTest):
def times2_int(in0, out0):
assert in0.dtype == int
assert out0.dtype == int
# hack to assing to a 0-dim array
# hack to assigning to a 0-dim array
out0.real = in0 * 2
def times2_complex(in0, out0):
......@@ -319,6 +347,10 @@ class AppTestUfuncs(BaseNumpyAppTest):
assert out0.dtype in (int, complex)
assert (out0 == in0 * 2).all()
in0 = np.arange(4, dtype=int)
out0 = times2(in0, sig='D->D')
assert out0.dtype == complex
def test_frompyfunc_scalar(self):
import sys
import numpy as np
......@@ -354,7 +386,7 @@ class AppTestUfuncs(BaseNumpyAppTest):
assert all(res == args[0] + args[1])
raises(TypeError, adder_ufunc, *args, blah=True)
raises(TypeError, adder_ufunc, *args, extobj=True)
raises(RuntimeError, adder_ufunc, *args, sig='(d,d)->(d)', dtype=int)
raises(RuntimeError, adder_ufunc, *args, sig='dd->d', dtype=int)
def test_unary_ufunc_kwargs(self):
from numpy import array, sin, float16
......@@ -453,7 +485,7 @@ class AppTestUfuncs(BaseNumpyAppTest):
except AttributeError:
pass
except NotImplementedError:
print s
#print s
uncallable.add(s)
except TypeError:
assert s not in uncallable
......@@ -1404,7 +1436,6 @@ class AppTestUfuncs(BaseNumpyAppTest):
# dtype
a = arange(0, 3, 0.5).reshape(2, 3)
b = add.accumulate(a, dtype=int, axis=1)
print b
assert (b == [[0, 0, 1], [1, 3, 5]]).all()
assert b.dtype == int
assert add.accumulate([True]*200)[-1] == 200
......
......@@ -805,8 +805,6 @@ class W_UfuncGeneric(W_Ufunc):
raise oefmt(space.w_TypeError,
'output arg %d must be an array, not %s', i+self.nin, str(args_w[i+self.nin]))
outargs[i] = out
if sig is None:
sig = space.wrap(self.signature)
_dtypes = self.dtypes
if self.match_dtypes:
_dtypes = [i.get_dtype() for i in inargs if isinstance(i, W_NDimArray)]
......@@ -879,7 +877,7 @@ class W_UfuncGeneric(W_Ufunc):
w_itershape = space.newlist([space.wrap(i) for i in iter_shape])
nd_it = W_NDIter(space, space.newlist(inargs + outargs), w_flags,
w_op_flags, w_op_dtypes, w_casting, w_op_axes,
w_itershape)
w_itershape, allow_backward=False)
# coalesce each iterators, according to inner_dimensions
for i in range(len(inargs) + len(outargs)):
for j in range(self.core_num_dims[i]):
......@@ -942,8 +940,8 @@ class W_UfuncGeneric(W_Ufunc):
raise oefmt(space.w_RuntimeError,
"cannot specify both 'sig' and 'dtype'")
dtype = decode_w_dtype(space, dtype_w)
sig = space.newtuple([dtype])
order = kwargs_w.pop('dtype', None)
sig = dtype.char
order = kwargs_w.pop('order', None)
if not space.is_w(order, space.w_None) and not order is None:
raise oefmt(space.w_NotImplementedError, '"order" keyword not implemented')
parsed_kw = []
......@@ -952,7 +950,7 @@ class W_UfuncGeneric(W_Ufunc):
if sig:
raise oefmt(space.w_RuntimeError,
"cannot specify both 'sig' and 'dtype'")
sig = kwargs_w[kw]
sig = space.str_w(kwargs_w[kw])
parsed_kw.append(kw)
elif kw.startswith('where'):
raise oefmt(space.w_NotImplementedError,
......@@ -966,7 +964,7 @@ class W_UfuncGeneric(W_Ufunc):
# Find a match for the inargs.dtype in _dtypes, like
# linear_search_type_resolver in numpy ufunc_type_resolutions.c
# type_tup can be '', a tuple of dtypes, or a string
# of the form d,t -> D where the letters are dtype specs
# of the form 'dt->D' where the letters are dtype specs
# XXX why does the next line not pass translation?
# dtypes = [i.get_dtype() for i in inargs]
......@@ -1119,7 +1117,7 @@ class W_UfuncGeneric(W_Ufunc):
for j in range(offset, len(iter_shape)):
x = iter_shape[j + offset]
y = dims_to_broadcast[j]
if y != 0 and x != 0 and ((x > y and x % y) or y %x):
if y > 1 and x != 0 and ((x > y and x % y) or y %x):
raise oefmt(space.w_ValueError, "%s: %s operand %d has a "
"mismatch in its broadcast dimension %d "
"(size %d is different from %d)",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment