[pypy-commit] pypy py3.5: hg merge default

arigo pypy.commits at gmail.com
Wed Aug 23 12:55:53 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r92235:d4535b1f44cd
Date: 2017-08-23 18:55 +0200
http://bitbucket.org/pypy/pypy/changeset/d4535b1f44cd/

Log:	hg merge default

diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -364,7 +364,7 @@
                 pypy_dll = _ffi.CDLL(name, mode)
             else:
                 pypy_dll = _ffi.WinDLL(name, mode)
-            self._pypy_dll = pypy_dll
+            self.__pypy_dll__ = pypy_dll
             handle = int(pypy_dll)
             if _sys.maxint > 2 ** 32:
                 handle = int(handle)   # long -> int
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -82,7 +82,7 @@
         return False
 
     def in_dll(self, dll, name):
-        return self.from_address(dll._pypy_dll.getaddressindll(name))
+        return self.from_address(dll.__pypy_dll__.getaddressindll(name))
 
     def from_buffer(self, obj, offset=0):
         size = self._sizeofinstances()
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -430,7 +430,7 @@
             ffires = restype.get_ffi_argtype()
             return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires, self._flags_)
 
-        cdll = self.dll._pypy_dll
+        cdll = self.dll.__pypy_dll__
         try:
             ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes]
             ffi_restype = restype.get_ffi_argtype()
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -311,7 +311,7 @@
     PyErr_BadInternalCall(space)
 
 @cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
-def PyObject_RichCompareBool(space, ref1, ref2, opid_int):
+def PyObject_RichCompareBool(space, w_o1, w_o2, opid_int):
     """Compare the values of o1 and o2 using the operation specified by opid,
     which must be one of Py_LT, Py_LE, Py_EQ,
     Py_NE, Py_GT, or Py_GE, corresponding to <,
@@ -321,13 +321,13 @@
     opid."""
     # Quick result when objects are the same.
     # Guarantees that identity implies equality.
-    if ref1 is ref2:
+    if space.is_w(w_o1, w_o2):
         opid = rffi.cast(lltype.Signed, opid_int)
         if opid == Py_EQ:
             return 1
         if opid == Py_NE:
             return 0 
-    w_res = PyObject_RichCompare(space, ref1, ref2, opid_int)
+    w_res = PyObject_RichCompare(space, w_o1, w_o2, opid_int)
     return int(space.is_true(w_res))
 
 @cpython_api([PyObject], PyObject, result_is_ll=True)
diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -294,6 +294,23 @@
     def getitems_fixedsize(self, w_list):
         return self.getitems_unroll(w_list)
 
+    def copy_into(self, w_list, w_other):
+        w_other.strategy = self
+        w_other.lstorage = self.getstorage_copy(w_list)
+
+    def clone(self, w_list):
+        storage = self.getstorage_copy(w_list)
+        w_clone = W_ListObject.from_storage_and_strategy(self.space, storage,
+                                                         self)
+        return w_clone
+
+    def getitems_copy(self, w_list):
+        return self.getitems(w_list) # getitems copies anyway
+
+    def getstorage_copy(self, w_list):
+        lst = self.getitems(w_list)
+        return self.erase(CPyListStorage(w_list.space, lst))
+
     #------------------------------------------
     # all these methods fail or switch strategy and then call ListObjectStrategy's method
 
@@ -301,23 +318,9 @@
         w_list.switch_to_object_strategy()
         w_list.strategy.setslice(w_list, start, stop, step, length)
 
-    def get_sizehint(self):
-        return -1
-
     def init_from_list_w(self, w_list, list_w):
         raise NotImplementedError
 
-    def clone(self, w_list):
-        storage = w_list.lstorage  # lstorage is tuple, no need to clone
-        w_clone = W_ListObject.from_storage_and_strategy(self.space, storage,
-                                                         self)
-        w_clone.switch_to_object_strategy()
-        return w_clone
-
-    def copy_into(self, w_list, w_other):
-        w_list.switch_to_object_strategy()
-        w_list.strategy.copy_into(w_list, w_other)
-
     def _resize_hint(self, w_list, hint):
         pass
 
@@ -325,13 +328,6 @@
         w_list.switch_to_object_strategy()
         return w_list.strategy.find(w_list, w_item, start, stop)
 
-    def getitems_copy(self, w_list):
-        w_list.switch_to_object_strategy()
-        return w_list.strategy.getitems_copy(w_list)
-
-    def getstorage_copy(self, w_list):
-        raise NotImplementedError
-
     def append(self, w_list, w_item):
         w_list.switch_to_object_strategy()
         w_list.strategy.append(w_list, w_item)
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1516,13 +1516,6 @@
     raise NotImplementedError
 
 
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyType_IS_GC(space, o):
-    """Return true if the type object includes support for the cycle detector; this
-    tests the type flag Py_TPFLAGS_HAVE_GC."""
-    raise NotImplementedError
-
-
 @cpython_api([], rffi.INT_real, error=-1)
 def PyUnicode_ClearFreeList(space, ):
     """Clear the free list. Return the total number of freed items."""
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -416,7 +416,7 @@
         Py_buffer passed to it.
         """
         module = self.import_extension('foo', [
-                ("fillinfo", "METH_VARARGS",
+                ("fillinfo", "METH_NOARGS",
                  """
     Py_buffer buf;
     PyObject *str = PyBytes_FromString("hello, world.");
@@ -468,7 +468,7 @@
         object.
         """
         module = self.import_extension('foo', [
-                ("fillinfo", "METH_VARARGS",
+                ("fillinfo", "METH_NOARGS",
                  """
     Py_buffer buf;
     PyObject *str = PyBytes_FromString("hello, world.");
@@ -514,7 +514,7 @@
         PyBuffer_FillInfo fails if WRITABLE is passed but object is readonly.
         """
         module = self.import_extension('foo', [
-                ("fillinfo", "METH_VARARGS",
+                ("fillinfo", "METH_NOARGS",
                  """
     Py_buffer buf;
     PyObject *str = PyBytes_FromString("hello, world.");
@@ -541,7 +541,7 @@
         decremented by PyBuffer_Release.
         """
         module = self.import_extension('foo', [
-                ("release", "METH_VARARGS",
+                ("release", "METH_NOARGS",
                  """
     Py_buffer buf;
     buf.obj = PyBytes_FromString("release me!");
@@ -560,3 +560,20 @@
     Py_RETURN_NONE;
                  """)])
         assert module.release() is None
+
+
+class AppTestPyBuffer_Release(AppTestCpythonExtensionBase):
+    def test_richcomp_nan(self):
+        module = self.import_extension('foo', [
+               ("comp_eq", "METH_VARARGS",
+                """
+                PyObject *a = PyTuple_GetItem(args, 0);
+                PyObject *b = PyTuple_GetItem(args, 1);
+                int res = PyObject_RichCompareBool(a, b, Py_EQ);
+                return PyLong_FromLong(res);  
+                """),])
+        a = float('nan')
+        b = float('nan')
+        assert a is b
+        res = module.comp_eq(a, b)
+        assert res == 1
diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -226,6 +226,15 @@
         w_l.inplace_mul(2)
         assert space.int_w(space.len(w_l)) == 10
 
+    def test_getstorage_copy(self, space, api):
+        w = space.wrap
+        w_l = w([1, 2, 3, 4])
+        api.PySequence_Fast(w_l, "foo") # converts
+
+        w_l1 = w([])
+        space.setitem(w_l1, space.newslice(w(0), w(0), w(1)), w_l)
+        assert map(space.unwrap, space.unpackiterable(w_l1)) == [1, 2, 3, 4]
+
 
 class AppTestSequenceObject(AppTestCpythonExtensionBase):
     def test_fast(self):
diff --git a/pypy/module/test_lib_pypy/README.txt b/pypy/module/test_lib_pypy/README.txt
--- a/pypy/module/test_lib_pypy/README.txt
+++ b/pypy/module/test_lib_pypy/README.txt
@@ -1,4 +1,7 @@
 This directory contains app-level tests are supposed to be run *after*
 translation. So you run them by saying:
 
-pypy pytest.py <testfile.py>
+../../goal/pypy-c pytest.py <testfile.py>
+
+Note that if you run it with a PyPy from elsewhere, it will not pick
+up the changes to lib-python and lib_pypy.
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -546,19 +546,24 @@
         space = self.space
         if self.is_heaptype():
             return self.getdictvalue(space, '__module__')
+        elif self.is_cpytype():
+            dot = self.name.rfind('.')
         else:
             dot = self.name.find('.')
-            if dot >= 0:
-                mod = self.name[:dot]
-            else:
-                mod = "builtins"
-            return space.newtext(mod)
+        if dot >= 0:
+            mod = self.name[:dot]
+        else:
+            mod = "builtins"
+        return space.newtext(mod)
 
     def getname(self, space):
         if self.is_heaptype():
             result = self.name
         else:
-            dot = self.name.find('.')
+            if self.is_cpytype():
+                dot = self.name.rfind('.')
+            else:
+                dot = self.name.find('.')
             if dot >= 0:
                 result = self.name[dot+1:]
             else:
diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -552,10 +552,11 @@
             self.reg_bindings[result_v] = loc
             return loc
         if v not in self.reg_bindings:
+            # v not in a register. allocate one for result_v and move v there
             prev_loc = self.frame_manager.loc(v)
-            loc = self.force_allocate_reg(v, forbidden_vars)
+            loc = self.force_allocate_reg(result_v, forbidden_vars)
             self.assembler.regalloc_mov(prev_loc, loc)
-        assert v in self.reg_bindings
+            return loc
         if self.longevity[v][1] > self.position:
             # we need to find a new place for variable v and
             # store result in the same place
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -504,7 +504,7 @@
         clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info)
         clt.frame_info.clear() # for now
 
-        if log:
+        if log or self._debug:
             number = looptoken.number
             operations = self._inject_debugging_code(looptoken, operations,
                                                      'e', number)
@@ -589,7 +589,7 @@
                 faildescr.adr_jump_offset)
         self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
         descr_number = compute_unique_id(faildescr)
-        if log:
+        if log or self._debug:
             operations = self._inject_debugging_code(faildescr, operations,
                                                      'b', descr_number)
         arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
@@ -1618,18 +1618,6 @@
         else:
             not_implemented("save_into_mem size = %d" % size)
 
-    def _genop_getfield(self, op, arglocs, resloc):
-        base_loc, ofs_loc, size_loc, sign_loc = arglocs
-        assert isinstance(size_loc, ImmedLoc)
-        source_addr = AddressLoc(base_loc, ofs_loc)
-        self.load_from_mem(resloc, source_addr, size_loc, sign_loc)
-
-    genop_getfield_gc_i = _genop_getfield
-    genop_getfield_gc_r = _genop_getfield
-    genop_getfield_gc_f = _genop_getfield
-    genop_getfield_raw_i = _genop_getfield
-    genop_getfield_raw_f = _genop_getfield
-
     def _genop_gc_load(self, op, arglocs, resloc):
         base_loc, ofs_loc, size_loc, sign_loc = arglocs
         assert isinstance(size_loc, ImmedLoc)
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -1305,7 +1305,7 @@
         self.rm.possibly_free_var(tmpbox_high)
 
     def compute_hint_frame_locations(self, operations):
-        # optimization only: fill in the 'hint_frame_locations' dictionary
+        # optimization only: fill in the 'hint_frame_pos' dictionary
         # of 'fm' based on the JUMP at the end of the loop, by looking
         # at where we would like the boxes to be after the jump.
         op = operations[-1]
@@ -1320,7 +1320,7 @@
             self._compute_hint_frame_locations_from_descr(descr)
         #else:
         #   The loop ends in a JUMP going back to a LABEL in the same loop.
-        #   We cannot fill 'hint_frame_locations' immediately, but we can
+        #   We cannot fill 'hint_frame_pos' immediately, but we can
         #   wait until the corresponding consider_label() to know where the
         #   we would like the boxes to be after the jump.
 
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -205,6 +205,18 @@
         if not is_valid_fd(fd):
             from errno import EBADF
             raise OSError(EBADF, 'Bad file descriptor')
+
+    def _bound_for_write(fd, count):
+        if count > 32767 and c_isatty(fd):
+            # CPython Issue #11395, PyPy Issue #2636: the Windows console
+            # returns an error (12: not enough space error) on writing into
+            # stdout if stdout mode is binary and the length is greater than
+            # 66,000 bytes (or less, depending on heap usage).  Can't easily
+            # test that, because we need 'fd' to be non-redirected...
+            count = 32767
+        elif count > 0x7fffffff:
+            count = 0x7fffffff
+        return count
 else:
     def is_valid_fd(fd):
         return 1
@@ -213,6 +225,9 @@
     def validate_fd(fd):
         pass
 
+    def _bound_for_write(fd, count):
+        return count
+
 def closerange(fd_low, fd_high):
     # this behaves like os.closerange() from Python 2.6.
     for fd in xrange(fd_low, fd_high):
@@ -449,6 +464,7 @@
 def write(fd, data):
     count = len(data)
     validate_fd(fd)
+    count = _bound_for_write(fd, count)
     with rffi.scoped_nonmovingbuffer(data) as buf:
         return handle_posix_error('write', c_write(fd, buf, count))
 
diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py
--- a/rpython/rtyper/tool/rffi_platform.py
+++ b/rpython/rtyper/tool/rffi_platform.py
@@ -710,7 +710,8 @@
         size, _ = expected_size_and_sign
         return lltype.FixedSizeArray(fieldtype.OF, size/_sizeof(fieldtype.OF))
     raise TypeError("conflict between translating python and compiler field"
-                    " type %r for %r" % (fieldtype, fieldname))
+                    " type %r for symbol %r, expected size+sign %r" % (
+                        fieldtype, fieldname, expected_size_and_sign))
 
 def expose_value_as_rpython(value):
     if intmask(value) == value:


More information about the pypy-commit mailing list