Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: py3.5
Changeset: r91274:f539c4765bcd
Date: 2017-05-12 21:20 +0100
http://bitbucket.org/pypy/pypy/changeset/f539c4765bcd/

Log:    hg merge default

diff --git a/include/README b/include/README
--- a/include/README
+++ b/include/README
@@ -1,7 +1,11 @@
 This directory contains all the include files needed to build cpython
 extensions with PyPy.  Note that these are just copies of the original headers
-that are in pypy/module/cpyext/include: they are automatically copied from
-there during translation.
+that are in pypy/module/cpyext/{include,parse}: they are automatically copied
+from there during translation.
 
-Moreover, pypy_decl.h and pypy_macros.h are automatically generated, also
-during translation.
+Moreover, some pypy-specific files are automatically generated, also during
+translation. Currently they are:
+* pypy_decl.h
+* pypy_macros.h
+* pypy_numpy.h
+* pypy_structmember_decl.h
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -514,7 +514,14 @@
   the rest is kept.  If you return an unexpected string from
   ``__hex__()`` you get an exception (or a crash before CPython 2.7.13).
 
-* PyPy3: ``__class__`` attritube assignment between heaptypes and non 
heaptypes.
+* In PyPy, dictionaries passed as ``**kwargs`` can contain only string keys,
+  even for ``dict()`` and ``dict.update()``.  CPython 2.7 allows non-string
+  keys in these two cases (and only there, as far as we know).  E.g. this
+  code produces a ``TypeError``, on CPython 3.x as well as on any PyPy:
+  ``dict(**{1: 2})``.  (Note that ``dict(**d1)`` is equivalent to
+  ``dict(d1)``.)
+
+* PyPy3: ``__class__`` attribute assignment between heaptypes and non 
heaptypes.
   CPython allows that for module subtypes, but not for e.g. ``int``
   or ``float`` subtypes. Currently PyPy does not support the
   ``__class__`` attribute assignment for any non heaptype subtype.
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
@@ -34,3 +34,8 @@
 .. branch: controller-refactor
 
 Refactor rpython.rtyper.controllerentry.
+
+.. branch: PyBuffer-backport
+
+Internal refactoring of buffers and memoryviews. Memoryviews will now be
+accepted in a few more places, e.g. in compile().
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -11,7 +11,7 @@
 
 To build pypy-c you need a working python environment, and a C compiler.
 It is possible to translate with a CPython 2.6 or later, but this is not
-the preferred way, because it will take a lot longer to run &#8211; depending
+the preferred way, because it will take a lot longer to run &#65533; depending
 on your architecture, between two and three times as long. So head to
 `our downloads`_ and get the latest stable version.
 
@@ -120,7 +120,7 @@
 Download the versions of all the external packages from
 https://bitbucket.org/pypy/pypy/downloads/local_5.8.zip
 (for post-5.7.1 builds) with sha256 checksum 
-``f1510452293f22e84d6059464e11f4c62ffd0e2ee97a52be9195bec8a70c6dce`` or
+``fbe769bf3a4ab6f5a8b0a05b61930fc7f37da2a9a85a8f609cf5a9bad06e2554`` or
 https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip
 (for 2.4 release and later) or
 https://bitbucket.org/pypy/pypy/downloads/local.zip
@@ -128,9 +128,9 @@
 Then expand it into the base directory (base_dir) and modify your environment
 to reflect this::
 
-    set PATH=<base_dir>\bin;<base_dir>\tcltk\bin;%PATH%
-    set INCLUDE=<base_dir>\include;<base_dir>\tcltk\include;%INCLUDE%
-    set LIB=<base_dir>\lib;<base_dir>\tcltk\lib;%LIB%
+    set PATH=<base_dir>\bin;%PATH%
+    set INCLUDE=<base_dir>\include;%INCLUDE%
+    set LIB=<base_dir>\lib;%LIB%
 
 Now you should be good to go. If you choose this method, you do not need
 to download/build anything else. 
@@ -236,6 +236,9 @@
     copy out32\*.lib <somewhere in LIB>
     xcopy /S include\openssl <somewhere in INCLUDE>
 
+For tests you will also need the dlls::
+    nmake -f ms\ntdll.mak install
+    copy out32dll\*.dll <somewhere in PATH>
 
 TkInter module support
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -245,18 +248,17 @@
 directory found for the release script, create the dlls, libs, headers and
 runtime by running::
 
-       svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85
-       svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85
-       cd tcl85\win
-       nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 
INSTALLDIR=..\..\tcltk clean all
-       nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install
-       cd ..\..\tk85\win
-       nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 
INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all
-       nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 
INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install
-
-Now you should have a tcktk\bin, tcltk\lib, and tcltk\include directory ready
-for use. The release packaging script will pick up the tcltk runtime in the lib
-directory and put it in the archive.
+    svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85
+    svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85
+    cd tcl85\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 
INSTALLDIR=..\..\tcltk clean all
+    nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install
+    cd ..\..\tk85\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 
INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 
INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install
+    copy ..\..\tcltk\bin\* <somewhere in PATH>
+    copy ..\..\tcltk\lib\*.lib <somewhere in LIB>
+    xcopy /S ..\..\tcltk\include <somewhere in INCLUDE>
 
 The lzma compression library
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -341,9 +343,9 @@
 integer.  The simplest fix is to make sure that it is so, but it will
 give the following incompatibility between CPython and PyPy on Win64:
 
-CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1``
+CPython: ``sys.maxint == 2**31-1, sys.maxsize == 2**63-1``
 
-PyPy: ``sys.maxint == sys.maxsize == 2**64-1``
+PyPy: ``sys.maxint == sys.maxsize == 2**63-1``
 
 ...and, correspondingly, PyPy supports ints up to the larger value of
 sys.maxint before they are converted to ``long``.  The first decision
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -79,7 +79,7 @@
 
     def getname(self, space):
         try:
-            return space.unicode_w(space.getattr(self, 
space.newtext('__name__')))
+            return space.text_w(space.getattr(self, space.newtext('__name__')))
         except OperationError as e:
             if e.match(space, space.w_TypeError) or e.match(space, 
space.w_AttributeError):
                 return u'?'
diff --git a/pypy/module/__builtin__/compiling.py 
b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -43,6 +43,8 @@
                     "compile() arg 3 must be 'exec', 'eval' or 'single'")
 
     if space.isinstance_w(w_source, space.gettypeobject(ast.W_AST.typedef)):
+        if flags & consts.PyCF_ONLY_AST:
+            return w_source
         ast_node = ast.mod.from_object(space, w_source)
         ec.compiler.validate_ast(ast_node)
         return ec.compiler.compile_ast(ast_node, filename, mode, flags,
diff --git a/pypy/module/__builtin__/test/test_compile.py 
b/pypy/module/__builtin__/test/test_compile.py
--- a/pypy/module/__builtin__/test/test_compile.py
+++ b/pypy/module/__builtin__/test/test_compile.py
@@ -2,6 +2,7 @@
 class AppTestCompile:
 
     def test_simple(self):
+        import sys
         co = compile('1+2', '?', 'eval')
         assert eval(co) == 3
         co = compile(memoryview(b'1+2'), '?', 'eval')
@@ -66,7 +67,8 @@
         co1 = compile('print(1)', '<string>', 'exec', _ast.PyCF_ONLY_AST)
         raises(TypeError, compile, co1, '<ast>', 'eval')
         co2 = compile('1+1', '<string>', 'eval', _ast.PyCF_ONLY_AST)
-        compile(co2, '<ast>', 'eval')
+        tree = compile(co2, '<ast>', 'eval')
+        assert compile(co2, '<ast>', 'eval', _ast.PyCF_ONLY_AST) is co2
 
     def test_leading_newlines(self):
         src = """
diff --git a/pypy/module/_codecs/test/test_codecs.py 
b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -10,7 +10,7 @@
         raises(TypeError, _codecs.register, 1)
 
     def test_bigU_codecs(self):
-        u = '\U00010001\U00020002\U00030003\U00040004\U00050005'
+        u = u'\U00010001\U00020002\U00030003\U00040004\U00050005'
         for encoding in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be',
                          'utf-32', 'utf-32-le', 'utf-32-be',
                          'raw_unicode_escape',
@@ -18,7 +18,7 @@
             assert str(u.encode(encoding),encoding) == u
 
     def test_ucs4(self):
-        x = '\U00100000'
+        x = u'\U00100000'
         y = x.encode("raw-unicode-escape").decode("raw-unicode-escape")
         assert x == y
 
@@ -146,21 +146,21 @@
         import _codecs
         encoding = 'utf-8'
         check_partial = [
-                "\x00",
-                "\x00",
-                "\x00\xff",
-                "\x00\xff",
-                "\x00\xff\u07ff",
-                "\x00\xff\u07ff",
-                "\x00\xff\u07ff",
-                "\x00\xff\u07ff\u0800",
-                "\x00\xff\u07ff\u0800",
-                "\x00\xff\u07ff\u0800",
-                "\x00\xff\u07ff\u0800\uffff",
-                "\x00\xff\u07ff\u0800\uffff",
-                "\x00\xff\u07ff\u0800\uffff",
-                "\x00\xff\u07ff\u0800\uffff",
-                "\x00\xff\u07ff\u0800\uffff\U00010000",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800",
+                u"\x00\xff\u07ff\u0800\uffff",
+                u"\x00\xff\u07ff\u0800\uffff",
+                u"\x00\xff\u07ff\u0800\uffff",
+                u"\x00\xff\u07ff\u0800\uffff",
+                u"\x00\xff\u07ff\u0800\uffff\U00010000",
             ]
 
         buffer = b''
@@ -177,20 +177,20 @@
         import _codecs
         encoding = 'utf-16'
         check_partial = [
-                    "", # first byte of BOM read
-                    "", # second byte of BOM read => byteorder known
-                    "",
-                    "\x00",
-                    "\x00",
-                    "\x00\xff",
-                    "\x00\xff",
-                    "\x00\xff\u0100",
-                    "\x00\xff\u0100",
-                    "\x00\xff\u0100\uffff",
-                    "\x00\xff\u0100\uffff",
-                    "\x00\xff\u0100\uffff",
-                    "\x00\xff\u0100\uffff",
-                    "\x00\xff\u0100\uffff\U00010000",
+                    u"", # first byte of BOM read
+                    u"", # second byte of BOM read => byteorder known
+                    u"",
+                    u"\x00",
+                    u"\x00",
+                    u"\x00\xff",
+                    u"\x00\xff",
+                    u"\x00\xff\u0100",
+                    u"\x00\xff\u0100",
+                    u"\x00\xff\u0100\uffff",
+                    u"\x00\xff\u0100\uffff",
+                    u"\x00\xff\u0100\uffff",
+                    u"\x00\xff\u0100\uffff",
+                    u"\x00\xff\u0100\uffff\U00010000",
                 ]
         buffer = b''
         result = ""
@@ -205,9 +205,9 @@
     def test_bug1098990_a(self):
         import codecs, io
         self.encoding = 'utf-8'
-        s1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n"
-        s2 = "offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj 
laskd fjasklfzzzzaa%whereisthis!!!\r\n"
-        s3 = "next line.\r\n"
+        s1 = u"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n"
+        s2 = u"offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj 
laskd fjasklfzzzzaa%whereisthis!!!\r\n"
+        s3 = u"next line.\r\n"
 
         s = (s1+s2+s3).encode(self.encoding)
         stream = io.BytesIO(s)
@@ -215,16 +215,16 @@
         assert reader.readline() == s1
         assert reader.readline() == s2
         assert reader.readline() == s3
-        assert reader.readline() == ""
+        assert reader.readline() == u""
 
     def test_bug1098990_b(self):
         import codecs, io
         self.encoding = 'utf-8'
-        s1 = "aaaaaaaaaaaaaaaaaaaaaaaa\r\n"
-        s2 = "bbbbbbbbbbbbbbbbbbbbbbbb\r\n"
-        s3 = "stillokay:bbbbxx\r\n"
-        s4 = "broken!!!!badbad\r\n"
-        s5 = "againokay.\r\n"
+        s1 = u"aaaaaaaaaaaaaaaaaaaaaaaa\r\n"
+        s2 = u"bbbbbbbbbbbbbbbbbbbbbbbb\r\n"
+        s3 = u"stillokay:bbbbxx\r\n"
+        s4 = u"broken!!!!badbad\r\n"
+        s5 = u"againokay.\r\n"
 
         s = (s1+s2+s3+s4+s5).encode(self.encoding)
         stream = io.BytesIO(s)
@@ -234,7 +234,7 @@
         assert reader.readline() == s3
         assert reader.readline() == s4
         assert reader.readline() == s5
-        assert reader.readline() == ""
+        assert reader.readline() == u""
 
     def test_seek_utf16le(self):
         # all codecs should be able to encode these
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
@@ -470,10 +470,10 @@
         size = generic_cpy_call(space, func_target, w_self, index, ptr)
         if size < 0:
             space.fromcache(State).check_and_raise_exception(always=True)
-        buf = CPyBuffer(space, ptr[0], size, w_self,
+        view = CPyBuffer(space, ptr[0], size, w_self,
                                releasebufferproc=rbp)
-        fq.register_finalizer(buf)
-        return buf.wrap(space)
+        fq.register_finalizer(view)
+        return space.newbuffer(CBuffer(view))
 
 def wrap_getwritebuffer(space, w_self, w_args, func):
     func_target = rffi.cast(readbufferproc, func)
@@ -488,10 +488,10 @@
         size = generic_cpy_call(space, func_target, w_self, index, ptr)
         if size < 0:
             space.fromcache(State).check_and_raise_exception(always=True)
-        buf = CPyBuffer(space, ptr[0], size, w_self, readonly=False,
+        view = CPyBuffer(space, ptr[0], size, w_self, readonly=False,
                                releasebufferproc=rbp)
-        fq.register_finalizer(buf)
-        return buf.wrap(space)
+        fq.register_finalizer(view)
+        return space.newbuffer(CBuffer(view))
 
 def wrap_getbuffer(space, w_self, w_args, func):
     func_target = rffi.cast(getbufferproc, func)
diff --git a/pypy/module/cpyext/test/buffer_test.c 
b/pypy/module/cpyext/test/buffer_test.c
--- a/pypy/module/cpyext/test/buffer_test.c
+++ b/pypy/module/cpyext/test/buffer_test.c
@@ -344,6 +344,7 @@
 #endif
     if (m == NULL)
         INITERROR;
+    PyMyArrayType.tp_new = PyType_GenericNew;
     if (PyType_Ready(&PyMyArrayType) < 0)
         INITERROR;
     Py_INCREF(&PyMyArrayType);
diff --git a/pypy/module/cpyext/test/test_memoryobject.py 
b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -133,7 +133,7 @@
                 PyObject* obj = PyTuple_GetItem(args, 0);
                 PyObject* memoryview = PyMemoryView_FromObject(obj);
                 if (memoryview == NULL)
-                    return PyLong_FromLong(-1);
+                    return NULL;
                 view = PyMemoryView_GET_BUFFER(memoryview);
                 Py_DECREF(memoryview);
                 return PyLong_FromLong(view->len / view->itemsize);
diff --git a/pypy/module/cpyext/test/test_userslots.py 
b/pypy/module/cpyext/test/test_userslots.py
--- a/pypy/module/cpyext/test/test_userslots.py
+++ b/pypy/module/cpyext/test/test_userslots.py
@@ -47,6 +47,33 @@
         w_year = space.getattr(w_obj, space.newtext('year'))
         assert space.int_w(w_year) == 1
 
+    def test_descr_slots(self, space, api):
+        w_descr = space.appexec([], """():
+            class Descr(object):
+                def __get__(self, obj, type):
+                    return 42
+                def __set__(self, obj, value):
+                    obj.append('set')
+                def __delete__(self, obj):
+                    obj.append('del')
+            return Descr()
+            """)
+        w_descrtype = space.type(w_descr)
+        py_descr = make_ref(space, w_descr)
+        py_descrtype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_descrtype))
+        w_obj = space.newlist([])
+        py_obj = make_ref(space, w_obj)
+        w_res = generic_cpy_call(space, py_descrtype.c_tp_descr_get,
+                                 py_descr, py_obj, py_obj)
+        assert space.int_w(w_res) == 42
+        assert generic_cpy_call(
+            space, py_descrtype.c_tp_descr_set,
+            py_descr, py_obj, make_ref(space, space.w_None)) == 0
+        assert generic_cpy_call(
+            space, py_descrtype.c_tp_descr_set,
+            py_descr, py_obj, None) == 0
+        assert space.eq_w(w_obj, space.wrap(['set', 'del']))
+
 class AppTestUserSlots(AppTestCpythonExtensionBase):
     def test_tp_hash_from_python(self):
         # to see that the functions are being used,
diff --git a/pypy/module/cpyext/tupleobject.py 
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -34,7 +34,7 @@
 cpython_struct("PyTupleObject", PyTupleObjectFields, PyTupleObjectStruct)
 
 @bootstrap_function
-def init_stringobject(space):
+def init_tupleobject(space):
     "Type description of PyTupleObject"
     make_typedescr(space.w_tuple.layout.typedef,
                    basestruct=PyTupleObject.TO,
diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py
--- a/pypy/module/cpyext/userslot.py
+++ b/pypy/module/cpyext/userslot.py
@@ -109,4 +109,14 @@
 def slot_tp_getattr(space, w_obj1, w_obj2):
     return space.getattr(w_obj1, w_obj2)
 
+@slot_function([PyObject, PyObject, PyObject], PyObject)
+def slot_tp_descr_get(space, w_self, w_obj, w_type):
+    return space.get(w_self, w_obj, w_type)
 
+@slot_function([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
+def slot_tp_descr_set(space, w_self, w_obj, w_value):
+    if w_value is not None:
+        space.set(w_self, w_obj, w_value)
+    else:
+        space.delete(w_self, w_obj)
+    return 0
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -527,6 +527,17 @@
         assert a == []
         assert b == [(True, 9)]
 
+    def test_groupby_question_43905804(self):
+        # http://stackoverflow.com/questions/43905804/
+        import itertools
+
+        inputs = ((x > 5, x) for x in range(10))
+        (_, a), (_, b) = itertools.groupby(inputs, key=lambda x: x[0])
+        a = list(a)
+        b = list(b)
+        assert a == []
+        assert b == [(True, 9)]
+
     def test_iterables(self):
         import itertools
 
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
@@ -3,6 +3,7 @@
 from rpython.rlib import jit, rgc
 from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rlib.listsort import make_timsort_class
+from rpython.rlib.buffer import Buffer
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage, \
@@ -701,10 +702,8 @@
     def __del__(self):
         free_raw_storage(self.storage)
 
-
-class ArrayView(BufferView):
+class ArrayData(Buffer):
     _immutable_ = True
-
     def __init__(self, impl, readonly):
         self.impl = impl
         self.readonly = readonly
@@ -725,6 +724,28 @@
         from rpython.rtyper.lltypesystem import rffi
         return rffi.ptradd(self.impl.storage, self.impl.start)
 
+
+class ArrayView(BufferView):
+    _immutable_ = True
+
+    def __init__(self, impl, readonly):
+        self.impl = impl
+        self.readonly = readonly
+        self.data = ArrayData(impl, readonly)
+
+    def getlength(self):
+        return self.data.getlength()
+
+    def getbytes(self, start, size):
+        return self.data[start:start + size]
+
+    def as_readbuf(self):
+        return ArrayData(self.impl, readonly=True)
+
+    def as_writebuf(self):
+        assert not self.readonly
+        return ArrayData(self.impl, readonly=False)
+
     def getformat(self):
         sb = StringBuilder()
         self.impl.dtype.getformat(sb)
@@ -742,4 +763,5 @@
     def getstrides(self):
         return self.impl.strides
 
-
+    def get_raw_address(self):
+        return self.data.get_raw_address()
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
@@ -3,6 +3,7 @@
     WrappedDefault
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, \
     make_weakref_descr
+from pypy.interpreter.buffer import SimpleView
 from rpython.rlib import jit
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rawstorage import RAW_STORAGE_PTR
@@ -808,7 +809,8 @@
         return self.implementation.get_buffer(space, flags)
 
     def descr_get_data(self, space):
-        return self.implementation.get_buffer(space, 
space.BUF_FULL).wrap(space)
+        return space.newmemoryview(
+            self.implementation.get_buffer(space, space.BUF_FULL))
 
     @unwrap_spec(offset=int, axis1=int, axis2=int)
     def descr_diagonal(self, space, offset=0, axis1=0, axis2=1):
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
@@ -3602,8 +3602,6 @@
         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)
@@ -3675,7 +3673,7 @@
             assert y.format == 'T{b:a:xxxi:b:T{b:f0:i:f1:}:sub:xxxi:c:}'
         else:
             assert y.format == 'T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxx@i:c:}'
- 
+
 
         dt1 = np.dtype(
              [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
@@ -3686,7 +3684,7 @@
             assert y.format == 'T{b:a:xxxi:b:T{b:f0:i:f1:}:sub:xxxi:c:}'
         else:
             assert y.format == 'T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxx@i:c:}'
- 
+
 
     def test_fromstring(self):
         import sys
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -454,8 +454,8 @@
             return Float64(self.space).box(self.unbox(v))
         # numpy 1.10 compatibility
         raise oefmt(self.space.w_TypeError, "ufunc casting failure")
-            
-            
+
+
 
 class Integer(Primitive):
     _mixin_ = True
diff --git a/pypy/module/struct/interp_struct.py 
b/pypy/module/struct/interp_struct.py
--- a/pypy/module/struct/interp_struct.py
+++ b/pypy/module/struct/interp_struct.py
@@ -1,9 +1,9 @@
 from rpython.rlib import jit
+from rpython.rlib.buffer import SubBuffer
 from rpython.rlib.rstruct.error import StructError, StructOverflowError
 from rpython.rlib.rstruct.formatiterator import CalcSizeFormatIterator
 
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.buffer import SubBuffer
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
@@ -177,16 +177,17 @@
 class W_Struct(W_Root):
     _immutable_fields_ = ["format", "size"]
 
-    def __init__(self, space, format):
+    format = ""
+    size = -1
+
+    def descr__new__(space, w_subtype, __args__):
+        return space.allocate_instance(W_Struct, w_subtype)
+
+    def descr__init__(self, space, w_format):
+        format = text_or_bytes_w(space, w_format)
         self.format = format
         self.size = _calcsize(space, format)
 
-    def descr__new__(space, w_subtype, w_format):
-        format = text_or_bytes_w(space, w_format)
-        self = space.allocate_instance(W_Struct, w_subtype)
-        W_Struct.__init__(self, space, format)
-        return self
-
     def descr_pack(self, space, args_w):
         return do_pack(space, jit.promote_string(self.format), args_w)
 
@@ -206,6 +207,7 @@
 
 W_Struct.typedef = TypeDef("Struct",
     __new__=interp2app(W_Struct.descr__new__.im_func),
+    __init__=interp2app(W_Struct.descr__init__),
     format=interp_attrproperty("format", cls=W_Struct, wrapfn="newbytes"),
     size=interp_attrproperty("size", cls=W_Struct, wrapfn="newint"),
 
@@ -223,8 +225,8 @@
 )
 
 def iter_unpack(space, w_format, w_buffer):
-    format = text_or_bytes_w(space, w_format)
-    w_struct = W_Struct(space, format)
+    w_struct = W_Struct()
+    w_struct.descr__init__(space, w_format)
     return W_UnpackIter(space, w_struct, w_buffer)
 
 def clearcache(space):
diff --git a/pypy/module/struct/test/test_struct.py 
b/pypy/module/struct/test/test_struct.py
--- a/pypy/module/struct/test/test_struct.py
+++ b/pypy/module/struct/test/test_struct.py
@@ -455,6 +455,14 @@
         assert s.unpack(s.pack(42)) == (42,)
         assert s.unpack_from(memoryview(s.pack(42))) == (42,)
 
+    def test_struct_subclass(self):
+        class S(self.struct.Struct):
+            def __init__(self):
+                assert self.size == -1
+                super(S, self).__init__('b')
+                assert self.size == 1
+        assert S().unpack(b'a') == (ord(b'a'),)
+
     def test_overflow(self):
         raises(self.struct.error, self.struct.pack, 'i', 1<<65)
 
diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -26,7 +26,6 @@
 from pypy.objspace.std.formatting import mod_format, FORMAT_BYTEARRAY
 
 
-
 class W_BytearrayObject(W_Root):
     import_from_mixin(StringMethods)
     _KIND1 = "bytearray"
@@ -1277,10 +1276,10 @@
 
 class BytearrayBuffer(Buffer):
     _immutable_ = True
-    readonly = False
 
-    def __init__(self, ba):
+    def __init__(self, ba, readonly=False):
         self.ba = ba     # the W_BytearrayObject
+        self.readonly = readonly
 
     def getlength(self):
         return self.ba._len()
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -768,7 +768,7 @@
     # use r_uint to perform a single comparison (this whole function is
     # getting inlined into every caller so keeping the branching to a
     # minimum is a good idea)
-    index = r_uint(x - lower)
+    index = r_uint(x) - r_uint(lower)
     if index >= r_uint(upper - lower):
         w_res = instantiate(W_IntObject)
     else:
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
@@ -371,6 +371,9 @@
     def newmemoryview(self, w_obj):
         return W_MemoryView(w_obj)
 
+    def newmemoryview(self, view):
+        return W_MemoryView(view)
+
     def newbytes(self, s):
         assert isinstance(s, str)
         return W_BytesObject(s)
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -160,9 +160,9 @@
                 tktcldir = p.dirpath().join('..').join('lib')
                 shutil.copytree(str(tktcldir), str(pypydir.join('tcl')))
             except WindowsError:
-                print >>sys.stderr, """Packaging Tk runtime failed.
-tk85.dll and tcl85.dll found, expecting to find runtime in ..\\lib
-directory next to the dlls, as per build instructions."""
+                print >>sys.stderr, r"""Packaging Tk runtime failed.
+tk85.dll and tcl85.dll found in %s, expecting to find runtime in %s
+directory next to the dlls, as per build instructions.""" %(p, tktcldir)
                 import traceback;traceback.print_exc()
                 raise MissingDependenciesError('Tk runtime')
 
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -12,7 +12,7 @@
     _immutable_ = True
 
     def getlength(self):
-        """Returns the size in bytes (even if getitemsize() > 1)."""
+        """Return the size in bytes."""
         raise NotImplementedError
 
     def __len__(self):
diff --git a/rpython/translator/platform/windows.py 
b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -119,6 +119,31 @@
     log.error("Could not find a Microsoft Compiler")
     # Assume that the compiler is already part of the environment
 
+# copied from distutils.spawn
+def _find_executable(executable, path=None):
+    """Tries to find 'executable' in the directories listed in 'path'.
+
+    A string listing directories separated by 'os.pathsep'; defaults to
+    os.environ['PATH'].  Returns the complete filename or None if not found.
+    """
+    if path is None:
+        path = os.environ['PATH']
+    paths = path.split(os.pathsep)
+
+    for ext in '.exe', '':
+        newexe = executable + ext
+
+        if os.path.isfile(newexe):
+            return newexe
+        else:
+            for p in paths:
+                f = os.path.join(p, newexe)
+                if os.path.isfile(f):
+                    # the file exists, we have a shot at spawn working
+                    return f
+    return None
+
+
 class MsvcPlatform(Platform):
     name = "msvc"
     so_ext = 'dll'
@@ -128,6 +153,9 @@
 
     cc = 'cl.exe'
     link = 'link.exe'
+    make = 'nmake'
+    if _find_executable('jom.exe'):
+        make = 'jom.exe'
 
     cflags = ('/MD', '/O2', '/Zi')
     link_flags = ('/debug','/LARGEADDRESSAWARE')
@@ -483,11 +511,11 @@
             path = path_to_makefile.makefile_dir
         else:
             path = path_to_makefile
-        log.execute('make %s in %s' % (" ".join(extra_opts), path))
+        log.execute('%s %s in %s' % (self.make, " ".join(extra_opts), path))
         oldcwd = path.chdir()
         try:
             returncode, stdout, stderr = _run_subprocess(
-                'nmake',
+                self.make,
                 ['/nologo', '/f', str(path.join('Makefile'))] + extra_opts,
                 env = self.c_environ)
         finally:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to