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

arigo pypy.commits at gmail.com
Sun Jul 16 07:44:55 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r91889:b58d747dcf74
Date: 2017-07-16 13:44 +0200
http://bitbucket.org/pypy/pypy/changeset/b58d747dcf74/

Log:	hg merge default

diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -580,6 +580,7 @@
                  "getentropy() does not use a file descriptor")
 class URandomFDTests(unittest.TestCase):
     @unittest.skipUnless(resource, "test requires the resource module")
+    @test_support.impl_detail(pypy=False)    # on Linux, may use getrandom()
     def test_urandom_failure(self):
         # Check urandom() failing when it is not able to open /dev/random.
         # We spawn a new process to make the test more robust (if getrlimit()
diff --git a/pypy/interpreter/test/test_generator.py b/pypy/interpreter/test/test_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/test_generator.py
@@ -531,6 +531,13 @@
             assert next(gen) is 1
         assert next(gen) is 2
 
+    def test_multiple_invalid_sends(self):
+        def mygen():
+            yield 42
+        g = mygen()
+        raises(TypeError, g.send, 2)
+        raises(TypeError, g.send, 2)
+
 
 def test_should_not_inline(space):
     from pypy.interpreter.generator import should_not_inline
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -10,7 +10,7 @@
 from pypy.module.cpyext.api import (
     CONST_STRING, METH_CLASS, METH_COEXIST, METH_KEYWORDS, METH_NOARGS, METH_O,
     METH_STATIC, METH_VARARGS, PyObject, bootstrap_function,
-    build_type_checkers, cpython_api, generic_cpy_call,
+    build_type_checkers, cpython_api, generic_cpy_call, CANNOT_FAIL,
     PyTypeObjectPtr, slot_function, cts)
 from pypy.module.cpyext.pyobject import (
     Py_DecRef, from_ref, make_ref, as_pyobj, make_typedescr)
@@ -106,8 +106,14 @@
             self.space, u"built-in method '%s' of '%s' object" %
             (self.name.decode('utf-8'), self.w_objclass.getname(self.space)))
 
-PyCFunction_Check, PyCFunction_CheckExact = build_type_checkers(
-    "CFunction", W_PyCFunctionObject)
+ at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyCFunction_Check(space, w_obj):
+    from pypy.interpreter.function import BuiltinFunction
+    if w_obj is None:
+        return False
+    if isinstance(w_obj, W_PyCFunctionObject):
+        return True
+    return isinstance(w_obj, BuiltinFunction)
 
 class W_PyCClassMethodObject(W_PyCFunctionObject):
     w_self = None
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
@@ -442,15 +442,19 @@
 Py_PRINT_RAW = 1 # No string quotes etc.
 
 @cpython_api([PyObject, FILEP, rffi.INT_real], rffi.INT_real, error=-1)
-def PyObject_Print(space, w_obj, fp, flags):
+def PyObject_Print(space, pyobj, fp, flags):
     """Print an object o, on file fp.  Returns -1 on error.  The flags argument
     is used to enable certain printing options.  The only option currently
     supported is Py_PRINT_RAW; if given, the str() of the object is written
     instead of the repr()."""
-    if rffi.cast(lltype.Signed, flags) & Py_PRINT_RAW:
-        w_str = space.str(w_obj)
+    if not pyobj:
+        w_str = space.newtext("<nil>")
     else:
-        w_str = space.repr(w_obj)
+        w_obj = from_ref(space, pyobj)
+        if rffi.cast(lltype.Signed, flags) & Py_PRINT_RAW:
+            w_str = space.str(w_obj)
+        else:
+            w_str = space.repr(w_obj)
 
     count = space.len_w(w_str)
     data = space.text_w(w_str)
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
@@ -455,7 +455,7 @@
                           ('tp_iter', '__iter__'),
                           ]:
         if name == tp_name:
-            slot_fn = w_type.getdictvalue(space, attr)
+            slot_fn = w_type.lookup(attr)
             if slot_fn is None:
                 return
 
@@ -470,7 +470,7 @@
                           ('tp_as_mapping.c_mp_length', '__len__'),
                          ]:
         if name == tp_name:
-            slot_fn = w_type.getdictvalue(space, attr)
+            slot_fn = w_type.lookup(attr)
             if slot_fn is None:
                 return
             @slot_function([PyObject], lltype.Signed, error=-1)
@@ -497,7 +497,7 @@
                           ('tp_as_mapping.c_mp_subscript', '__getitem__'),
                           ]:
         if name == tp_name:
-            slot_fn = w_type.getdictvalue(space, attr)
+            slot_fn = w_type.lookup(attr)
             if slot_fn is None:
                 return
 
@@ -514,7 +514,7 @@
                           ('tp_as_sequence.c_sq_inplace_repeat', '__imul__'),
                           ]:
         if name == tp_name:
-            slot_fn = w_type.getdictvalue(space, attr)
+            slot_fn = w_type.lookup(attr)
             if slot_fn is None:
                 return
 
@@ -528,7 +528,7 @@
     for tp_name, attr in [('tp_as_number.c_nb_power', '__pow__'),
                           ]:
         if name == tp_name:
-            slot_fn = w_type.getdictvalue(space, attr)
+            slot_fn = w_type.lookup(attr)
             if slot_fn is None:
                 return
 
@@ -541,10 +541,10 @@
     for tp_name, attr in [('tp_as_mapping.c_mp_ass_subscript', '__setitem__'),
                          ]:
         if name == tp_name:
-            slot_ass = w_type.getdictvalue(space, attr)
+            slot_ass = w_type.lookup(attr)
             if slot_ass is None:
                 return
-            slot_del = w_type.getdictvalue(space, '__delitem__')
+            slot_del = w_type.lookup('__delitem__')
             if slot_del is None:
                 return
 
@@ -562,10 +562,10 @@
     for tp_name, attr in [('tp_as_sequence.c_sq_ass_item', '__setitem__'),
                          ]:
         if name == tp_name:
-            slot_ass = w_type.getdictvalue(space, attr)
+            slot_ass = w_type.lookup(attr)
             if slot_ass is None:
                 return
-            slot_del = w_type.getdictvalue(space, '__delitem__')
+            slot_del = w_type.lookup('__delitem__')
             if slot_del is None:
                 return
 
@@ -582,8 +582,8 @@
     if handled:
         pass
     elif name == 'tp_setattro':
-        setattr_fn = w_type.getdictvalue(space, '__setattr__')
-        delattr_fn = w_type.getdictvalue(space, '__delattr__')
+        setattr_fn = w_type.lookup('__setattr__')
+        delattr_fn = w_type.lookup('__delattr__')
         if setattr_fn is None:
             return
 
@@ -598,7 +598,7 @@
             return 0
         slot_func = slot_tp_setattro
     elif name == 'tp_getattro':
-        getattr_fn = w_type.getdictvalue(space, '__getattribute__')
+        getattr_fn = w_type.lookup('__getattribute__')
         if getattr_fn is None:
             return
 
@@ -609,7 +609,7 @@
         slot_func = slot_tp_getattro
 
     elif name == 'tp_call':
-        call_fn = w_type.getdictvalue(space, '__call__')
+        call_fn = w_type.lookup('__call__')
         if call_fn is None:
             return
 
@@ -622,7 +622,7 @@
         slot_func = slot_tp_call
 
     elif name == 'tp_iternext':
-        iternext_fn = w_type.getdictvalue(space, '__next__')
+        iternext_fn = w_type.lookup('__next__')
         if iternext_fn is None:
             return
 
@@ -638,7 +638,7 @@
         slot_func = slot_tp_iternext
 
     elif name == 'tp_init':
-        init_fn = w_type.getdictvalue(space, '__init__')
+        init_fn = w_type.lookup('__init__')
         if init_fn is None:
             return
 
@@ -651,7 +651,7 @@
             return 0
         slot_func = slot_tp_init
     elif name == 'tp_new':
-        new_fn = w_type.getdictvalue(space, '__new__')
+        new_fn = w_type.lookup('__new__')
         if new_fn is None:
             return
 
@@ -663,7 +663,7 @@
             return space.call_args(space.get(new_fn, w_self), args)
         slot_func = slot_tp_new
     elif name == 'tp_as_buffer.c_bf_getbuffer':
-        buff_fn = w_type.getdictvalue(space, '__buffer__')
+        buff_fn = w_type.lookup('__buffer__')
         if buff_fn is not None:
             buff_w = slot_from___buffer__(space, typedef, buff_fn)
         elif typedef.buffer:
@@ -672,7 +672,7 @@
             return
         slot_func = buff_w
     elif name == 'tp_descr_get':
-        get_fn = w_type.getdictvalue(space, '__get__')
+        get_fn = w_type.lookup('__get__')
         if get_fn is None:
             return
 
@@ -684,8 +684,8 @@
             return space.call_function(get_fn, w_self, w_obj, w_value)
         slot_func = slot_tp_descr_get
     elif name == 'tp_descr_set':
-        set_fn = w_type.getdictvalue(space, '__set__')
-        delete_fn = w_type.getdictvalue(space, '__delete__')
+        set_fn = w_type.lookup('__set__')
+        delete_fn = w_type.lookup('__delete__')
         if set_fn is None and delete_fn is None:
             return
 
diff --git a/pypy/module/cpyext/test/test_boolobject.py b/pypy/module/cpyext/test/test_boolobject.py
--- a/pypy/module/cpyext/test/test_boolobject.py
+++ b/pypy/module/cpyext/test/test_boolobject.py
@@ -26,3 +26,20 @@
             ])
         assert module.get_true() == True
         assert module.get_false() == False
+
+    def test_toint(self):
+        module = self.import_extension('foo', [
+            ("to_int", "METH_O",
+            '''
+                if (args->ob_type->tp_as_number && args->ob_type->tp_as_number->nb_int) {
+                    return args->ob_type->tp_as_number->nb_int(args);
+                }
+                else {
+                    PyErr_SetString(PyExc_TypeError,"cannot convert bool to int");
+                    return NULL;
+                }
+            '''), ])
+        assert module.to_int(False) == 0
+        assert module.to_int(True) == 1
+
+            
diff --git a/pypy/module/cpyext/test/test_methodobject.py b/pypy/module/cpyext/test/test_methodobject.py
--- a/pypy/module/cpyext/test/test_methodobject.py
+++ b/pypy/module/cpyext/test/test_methodobject.py
@@ -77,6 +77,31 @@
             assert mod.isSameFunction(mod.getarg_O)
         raises(SystemError, mod.isSameFunction, 1)
 
+    def test_check(self):
+        mod = self.import_extension('foo', [
+            ('check', 'METH_O',
+            '''
+                return PyLong_FromLong(PyCFunction_Check(args));
+            '''),
+            ])
+        from math import degrees
+        assert mod.check(degrees) == 1
+        assert mod.check(list) == 0
+        assert mod.check(sorted) == 1
+        def func():
+            pass
+        class A(object):
+            def meth(self):
+                pass
+            @staticmethod
+            def stat():
+                pass
+        assert mod.check(func) == 0
+        assert mod.check(A) == 0
+        assert mod.check(A.meth) == 0
+        assert mod.check(A.stat) == 0
+ 
+
 class TestPyCMethodObject(BaseApiTest):
     def test_repr(self, space, api):
         """
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
@@ -288,13 +288,20 @@
                  if (fp == NULL)
                      Py_RETURN_NONE;
                  ret = PyObject_Print(obj, fp, Py_PRINT_RAW);
+                 if (ret < 0) {
+                     fclose(fp);
+                     return NULL;
+                 }
+                 ret = PyObject_Print(NULL, fp, Py_PRINT_RAW);
+                 if (ret < 0) {
+                     fclose(fp);
+                     return NULL;
+                 }
                  fclose(fp);
-                 if (ret < 0)
-                     return NULL;
                  Py_RETURN_TRUE;
              """)])
         assert module.dump(self.tmpname, None)
-        assert open(self.tmpname).read() == 'None'
+        assert open(self.tmpname).read() == 'None<nil>'
 
     def test_issue1970(self):
         module = self.import_extension('foo', [
diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -639,7 +639,10 @@
         addresses_of_static_ptrs = (
             self.layoutbuilder.addresses_of_static_ptrs_in_nongc +
             self.layoutbuilder.addresses_of_static_ptrs)
-        log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
+        if len(addresses_of_static_ptrs) == 1:
+            log.info("found 1 static root")
+        else:
+            log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
         ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
                                                len(addresses_of_static_ptrs),
                                                immortal=True)


More information about the pypy-commit mailing list