Author: Matti Picus <[email protected]>
Branch: missing-tp_new
Changeset: r88553:1bdb2e50a3ba
Date: 2016-11-22 22:13 +0200
http://bitbucket.org/pypy/pypy/changeset/1bdb2e50a3ba/

Log:    merge default into branch

diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py
--- a/_pytest/_code/code.py
+++ b/_pytest/_code/code.py
@@ -601,7 +601,7 @@
 class TerminalRepr:
     def __str__(self):
         s = self.__unicode__()
-        if sys.version_info[0] < 3:
+        if sys.version_info[0] < 3 and isinstance(s, unicode):
             s = s.encode('utf-8')
         return s
 
diff --git a/_pytest/_code/source.py b/_pytest/_code/source.py
--- a/_pytest/_code/source.py
+++ b/_pytest/_code/source.py
@@ -416,6 +416,8 @@
             trysource = source[start:end]
             if trysource.isparseable():
                 return start, end
+            if end == start + 100:   # XXX otherwise, it takes forever
+                break                # XXX
     raise SyntaxError("no valid source range around line %d " % (lineno,))
 
 
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -302,24 +302,7 @@
             size = space.r_longlong_w(w_size)
         stream.truncate(size)
 
-    def direct_write(self, w_data):
-        space = self.space
-        self.check_writable()
-        if self.binary:
-            data = space.getarg_w('s*', w_data).as_str()
-        else:
-            if space.isinstance_w(w_data, space.w_unicode):
-                w_errors = w_encoding = None
-                if self.encoding:
-                    w_encoding = space.wrap(self.encoding)
-                if self.errors:
-                    w_errors = space.wrap(self.errors)
-                w_data = space.call_method(w_data, "encode",
-                                           w_encoding, w_errors)
-            data = space.charbuf_w(w_data)
-        self.do_direct_write(data)
-
-    def do_direct_write(self, data):
+    def direct_write_str(self, data):
         self.softspace = 0
         self.getstream().write(data)
 
@@ -349,7 +332,7 @@
     _exposed_method_names = []
 
     def _decl(class_scope, name, docstring,
-              wrapresult="space.wrap(result)"):
+              wrapresult="space.wrap(result)", exposed=True):
         # hack hack to build a wrapper around the direct_xxx methods.
         # The wrapper adds lock/unlock calls and a space.wrap() on
         # the result, conversion of stream errors to OperationErrors,
@@ -389,7 +372,8 @@
         exec str(src) in globals(), class_scope
         if unwrap_spec is not None:
             class_scope['file_' + name].unwrap_spec = unwrap_spec
-        class_scope['_exposed_method_names'].append(name)
+        if exposed:
+            class_scope['_exposed_method_names'].append(name)
 
 
     _decl(locals(), "__init__", """Opens a file.""")
@@ -466,11 +450,8 @@
 
 Size defaults to the current file position, as returned by tell().""")
 
-    _decl(locals(), "write",
-        """write(str) -> None.  Write string str to file.
-
-Note that due to buffering, flush() or close() may be needed before
-the file on disk reflects the data written.""")
+    _decl(locals(), "write_str", "Interp-level only, see file_write()",
+          exposed=False)
 
     _decl(locals(), "__iter__",
         """Iterating over files, as in 'for line in f:', returns each line of
@@ -501,6 +482,26 @@
         else:
             return space.str_w(space.repr(w_name))
 
+    def file_write(self, w_data):
+        """write(str) -> None.  Write string str to file.
+
+Note that due to buffering, flush() or close() may be needed before
+the file on disk reflects the data written."""
+        space = self.space
+        self.check_writable()
+        if self.binary:
+            data = space.getarg_w('s*', w_data).as_str()
+        else:
+            if space.isinstance_w(w_data, space.w_unicode):
+                # note: "encode" is called before we acquire the lock
+                # for this file, which is done in file_write_str().
+                # Use a specific space method because we don't want
+                # to call user-defined "encode" methods here.
+                w_data = space.encode_unicode_object(w_data,
+                     self.encoding, self.errors)
+            data = space.charbuf_w(w_data)
+        self.file_write_str(data)
+
     def file_writelines(self, w_lines):
         """writelines(sequence_of_strings) -> None.  Write the strings to the 
file.
 
@@ -612,6 +613,7 @@
                               cls=W_File,
                               doc="Support for 'print'."),
     __repr__ = interp2app(W_File.file__repr__),
+    write      = interp2app(W_File.file_write),
     writelines = interp2app(W_File.file_writelines),
     __exit__ = interp2app(W_File.file__exit__),
     __weakref__ = make_weakref_descr(W_File),
diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py
--- a/pypy/module/bz2/interp_bz2.py
+++ b/pypy/module/bz2/interp_bz2.py
@@ -293,7 +293,7 @@
 same_attributes_as_in_file.remove('__init__')
 same_attributes_as_in_file.extend([
     'name', 'mode', 'encoding', 'closed', 'newlines', 'softspace',
-    'writelines', '__exit__', '__weakref__'])
+    'writelines', '__exit__', '__weakref__', 'write'])
 
 W_BZ2File.typedef = TypeDef(
     "BZ2File",
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
@@ -252,7 +252,10 @@
 def PyObject_Format(space, w_obj, w_format_spec):
     if w_format_spec is None:
         w_format_spec = space.wrap('')
-    return space.call_method(w_obj, '__format__', w_format_spec)
+    w_ret = space.call_method(w_obj, '__format__', w_format_spec)
+    if space.isinstance_w(w_format_spec, space.w_unicode):
+        return space.unicode_from_object(w_ret)
+    return w_ret
 
 @cpython_api([PyObject], PyObject)
 def PyObject_Unicode(space, w_obj):
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -350,7 +350,6 @@
                 PyObject * obj;
                 char * data;
                 int len;
-                PyType_Ready(&PyStringArrType_Type);
 
                 data = PyString_AS_STRING(args);
                 len = PyString_GET_SIZE(args);
@@ -434,6 +433,7 @@
                 PyStringArrType_Type.tp_flags = 
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
                 PyStringArrType_Type.tp_itemsize = sizeof(char);
                 PyStringArrType_Type.tp_base = &PyString_Type;
+                if (PyType_Ready(&PyStringArrType_Type) < 0) INITERROR;
             ''')
 
         a = module.newsubstr('abc')
diff --git a/pypy/module/cpyext/test/test_getargs.py 
b/pypy/module/cpyext/test/test_getargs.py
--- a/pypy/module/cpyext/test/test_getargs.py
+++ b/pypy/module/cpyext/test/test_getargs.py
@@ -139,13 +139,6 @@
             return result;
             ''')
         assert 'foo\0bar\0baz' == pybuffer(buffer('foo\0bar\0baz'))
-        import sys
-        if '__pypy__' not in sys.builtin_module_names:
-            class A(object):
-                def __buffer__(self, flags):
-                    return buffer('123')
-            assert pybuffer(A()) == '123'
-
 
     def test_pyarg_parse_string_fails(self):
         """
diff --git a/pypy/module/cpyext/test/test_intobject.py 
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -85,7 +85,6 @@
                 if (!PyArg_ParseTuple(args, "Oi", &name, &intval))
                     return NULL;
 
-                PyType_Ready(&Enum_Type);
                 enumObj = PyObject_New(EnumObject, &Enum_Type);
                 if (!enumObj) {
                     return NULL;
@@ -160,7 +159,8 @@
                 /*tp_new*/              0
             };
             """, more_init = '''
-            Enum_Type.tp_base = &PyInt_Type;
+                Enum_Type.tp_base = &PyInt_Type;
+                if (PyType_Ready(&Enum_Type) < 0) INITERROR;
             ''')
 
         a = module.newEnum("ULTIMATE_ANSWER", 42)
diff --git a/pypy/module/cpyext/test/test_iterator.py 
b/pypy/module/cpyext/test/test_iterator.py
--- a/pypy/module/cpyext/test/test_iterator.py
+++ b/pypy/module/cpyext/test/test_iterator.py
@@ -29,11 +29,6 @@
            ("test", "METH_NOARGS",
             '''
                 PyObject *obj;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                Foo_Type.tp_as_mapping = &tp_as_mapping;
-                tp_as_mapping.mp_length = mp_length;
-                tp_as_mapping.mp_subscript = mp_subscript;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''
@@ -44,8 +39,7 @@
                     PySequence_Check(args) +
                     PyMapping_Check(args) * 2);
             ''')
-            ],
-            '''
+            ], prologue = '''
             static PyObject *
             mp_subscript(PyObject *self, PyObject *key)
             {
@@ -61,6 +55,12 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            ''', more_init = '''
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                Foo_Type.tp_as_mapping = &tp_as_mapping;
+                tp_as_mapping.mp_length = mp_length;
+                tp_as_mapping.mp_subscript = mp_subscript;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             ''')
         obj = module.test()
         assert obj["hi there"] == 42
@@ -80,11 +80,6 @@
            ("test", "METH_NOARGS",
             '''
                 PyObject *obj;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                Foo_Type.tp_as_sequence = &tp_as_sequence;
-                tp_as_sequence.sq_length = sq_length;
-                tp_as_sequence.sq_item = sq_item;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''),
@@ -94,8 +89,7 @@
                     PySequence_Check(args) +
                     PyMapping_Check(args) * 2);
             ''')
-            ],
-            '''
+            ], prologue='''
             static PyObject *
             sq_item(PyObject *self, Py_ssize_t size)
             {
@@ -111,6 +105,12 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            ''', more_init='''
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                Foo_Type.tp_as_sequence = &tp_as_sequence;
+                tp_as_sequence.sq_length = sq_length;
+                tp_as_sequence.sq_item = sq_item;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             ''')
         obj = module.test()
         assert obj[1] == 42
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py 
b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -233,9 +233,9 @@
         if cls.runappdirect:
             try:
                 import numpy
-                cls.w_numpy_include = [numpy.get_include()]
-            except:
+            except ImportError:
                 skip('numpy not importable')
+            cls.w_numpy_include = [numpy.get_include()]
         else:
             numpy_incl = os.path.abspath(os.path.dirname(__file__) +
                                          '/../include/_numpypy')
@@ -306,9 +306,6 @@
                 ),
                 ], include_dirs=self.numpy_include,
                    prologue='''
-                #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>
-                #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
                 #ifdef PYPY_VERSION
@@ -351,9 +348,6 @@
                 '''),
                 ], include_dirs=self.numpy_include,
                    prologue='''
-                #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>
-                #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
                 ''',
@@ -409,9 +403,6 @@
                 """),
                 ], include_dirs=self.numpy_include,
                    prologue='''
-                #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>
-                #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
                 #ifndef PYPY_VERSION
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
@@ -312,6 +312,16 @@
         assert isinstance(dict(), collections.Mapping)
         assert module.ismapping(dict())
 
+    def test_format_returns_unicode(self):
+        module = self.import_extension('foo', [
+            ("empty_format", "METH_O",
+            """
+                PyObject* empty_unicode = PyUnicode_FromStringAndSize("", 0);
+                PyObject* obj = PyObject_Format(args, empty_unicode);
+                return obj;
+            """)])
+        a = module.empty_format('hello')
+        assert isinstance(a, unicode)
 
 class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
     """
diff --git a/pypy/module/cpyext/test/test_typeobject.py 
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -713,15 +713,10 @@
            ("new_obj", "METH_NOARGS",
             '''
                 PyObject *obj;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                Foo_Type.tp_as_mapping = &tp_as_mapping;
-                tp_as_mapping.mp_ass_subscript = mp_ass_subscript;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''
-            )],
-            '''
+            )], prologue='''
             static int
             mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
             {
@@ -736,6 +731,11 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            ''', more_init = '''
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                Foo_Type.tp_as_mapping = &tp_as_mapping;
+                tp_as_mapping.mp_ass_subscript = mp_ass_subscript;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             ''')
         obj = module.new_obj()
         raises(ZeroDivisionError, obj.__setitem__, 5, None)
@@ -747,15 +747,10 @@
            ("new_obj", "METH_NOARGS",
             '''
                 PyObject *obj;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                Foo_Type.tp_as_sequence = &tp_as_sequence;
-                tp_as_sequence.sq_contains = sq_contains;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''
-            )],
-            '''
+            )], prologue='''
             static int
             sq_contains(PyObject *self, PyObject *value)
             {
@@ -766,6 +761,11 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            ''', more_init='''
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                Foo_Type.tp_as_sequence = &tp_as_sequence;
+                tp_as_sequence.sq_contains = sq_contains;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             ''')
         obj = module.new_obj()
         res = "foo" in obj
@@ -906,11 +906,6 @@
                 if (!PyArg_ParseTuple(args, "l", &intval))
                     return NULL;
 
-                IntLike_Type.tp_as_number = &intlike_as_number;
-                IntLike_Type.tp_flags |= Py_TPFLAGS_DEFAULT | 
Py_TPFLAGS_CHECKTYPES;
-                intlike_as_number.nb_add = intlike_nb_add;
-                intlike_as_number.nb_power = intlike_nb_pow;
-                if (PyType_Ready(&IntLike_Type) < 0) return NULL;
                 intObj = PyObject_New(IntLikeObject, &IntLike_Type);
                 if (!intObj) {
                     return NULL;
@@ -927,8 +922,6 @@
                 if (!PyArg_ParseTuple(args, "l", &intval))
                     return NULL;
 
-                IntLike_Type_NoOp.tp_flags |= Py_TPFLAGS_DEFAULT | 
Py_TPFLAGS_CHECKTYPES;
-                if (PyType_Ready(&IntLike_Type_NoOp) < 0) return NULL;
                 intObjNoOp = PyObject_New(IntLikeObjectNoOp, 
&IntLike_Type_NoOp);
                 if (!intObjNoOp) {
                     return NULL;
@@ -936,8 +929,7 @@
 
                 intObjNoOp->ival = intval;
                 return (PyObject *)intObjNoOp;
-             """)], prologue=
-            """
+             """)], prologue="""
             #include <math.h>
             typedef struct
             {
@@ -989,6 +981,14 @@
                 /*tp_name*/             "IntLikeNoOp",
                 /*tp_basicsize*/        sizeof(IntLikeObjectNoOp),
             };
+            """, more_init="""
+                IntLike_Type.tp_as_number = &intlike_as_number;
+                IntLike_Type.tp_flags |= Py_TPFLAGS_DEFAULT | 
Py_TPFLAGS_CHECKTYPES;
+                intlike_as_number.nb_add = intlike_nb_add;
+                intlike_as_number.nb_power = intlike_nb_pow;
+                if (PyType_Ready(&IntLike_Type) < 0) INITERROR;
+                IntLike_Type_NoOp.tp_flags |= Py_TPFLAGS_DEFAULT | 
Py_TPFLAGS_CHECKTYPES;
+                if (PyType_Ready(&IntLike_Type_NoOp) < 0) INITERROR;
             """)
         a = module.newInt(1)
         b = module.newInt(2)
@@ -1039,19 +1039,11 @@
         else:
             raise AssertionError("did not get TypeError!")
 
-    def test_call_tp_dealloc_when_created_from_python(self):
+    def test_call_tp_dealloc(self):
         module = self.import_extension('foo', [
             ("fetchFooType", "METH_VARARGS",
              """
                 PyObject *o;
-                Foo_Type.tp_basicsize = sizeof(FooObject);
-                Foo_Type.tp_dealloc = &dealloc_foo;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES
-                                    | Py_TPFLAGS_BASETYPE;
-                Foo_Type.tp_new = &new_foo;
-                Foo_Type.tp_free = &PyObject_Del;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
-
                 o = PyObject_New(PyObject, &Foo_Type);
                 init_foo(o);
                 Py_DECREF(o);   /* calls dealloc_foo immediately */
@@ -1070,8 +1062,7 @@
             ("getCounter", "METH_VARARGS",
              """
                 return PyInt_FromLong(foo_counter);
-             """)], prologue=
-            """
+             """)], prologue="""
             typedef struct {
                 PyObject_HEAD
                 int someval[99];
@@ -1105,6 +1096,14 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            """, more_init="""
+                Foo_Type.tp_basicsize = sizeof(FooObject);
+                Foo_Type.tp_dealloc = &dealloc_foo;
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES
+                                    | Py_TPFLAGS_BASETYPE;
+                Foo_Type.tp_new = &new_foo;
+                Foo_Type.tp_free = &PyObject_Del;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             """)
         Foo = module.fetchFooType()
         assert module.getCounter() == 1010
@@ -1146,14 +1145,10 @@
            ("new_obj", "METH_NOARGS",
             '''
                 PyObject *obj;
-                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                Foo_Type.tp_call = &my_tp_call;
-                if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''
-            )],
-            '''
+            )], prologue='''
             static PyObject *
             my_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
             {
@@ -1163,6 +1158,10 @@
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.foo",
             };
+            ''', more_init='''
+                Foo_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                Foo_Type.tp_call = &my_tp_call;
+                if (PyType_Ready(&Foo_Type) < 0) INITERROR;
             ''')
         x = module.new_obj()
         assert x() == 42
@@ -1172,18 +1171,18 @@
         module = self.import_extension('foo', [
            ("getMetaClass", "METH_NOARGS",
             '''
-                FooType_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-                FooType_Type.tp_base = &PyType_Type;
-                if (PyType_Ready(&FooType_Type) < 0) return NULL;
                 Py_INCREF(&FooType_Type);
                 return (PyObject *)&FooType_Type;
             '''
-            )],
-            '''
+            )], prologue='''
             static PyTypeObject FooType_Type = {
                 PyVarObject_HEAD_INIT(NULL, 0)
                 "foo.Type",
             };
+            ''', more_init='''
+                FooType_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+                FooType_Type.tp_base = &PyType_Type;
+                if (PyType_Ready(&FooType_Type) < 0) INITERROR;
             ''')
         FooType = module.getMetaClass()
         if not self.runappdirect:
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -240,7 +240,7 @@
 def update_all_slots(space, w_type, pto):
     # fill slots in pto
     # Not very sure about it, but according to
-    # test_call_tp_dealloc_when_created_from_python, we should not
+    # test_call_tp_dealloc, we should not
     # overwrite slots that are already set: these ones are probably
     # coming from a parent C type.
 
diff --git a/pypy/module/marshal/interp_marshal.py 
b/pypy/module/marshal/interp_marshal.py
--- a/pypy/module/marshal/interp_marshal.py
+++ b/pypy/module/marshal/interp_marshal.py
@@ -120,7 +120,7 @@
 
 class DirectStreamWriter(StreamReaderWriter):
     def write(self, data):
-        self.file.do_direct_write(data)
+        self.file.direct_write_str(data)
 
 class DirectStreamReader(StreamReaderWriter):
     def read(self, n):
diff --git a/pypy/module/operator/app_operator.py 
b/pypy/module/operator/app_operator.py
--- a/pypy/module/operator/app_operator.py
+++ b/pypy/module/operator/app_operator.py
@@ -130,9 +130,12 @@
 
 
 class methodcaller(object):
-    def __init__(self, method_name, *args, **kwargs):
+    def __init__(*args, **kwargs):
+        if len(args) < 2:
+            raise TypeError("methodcaller() called with not enough arguments")
+        self, method_name = args[:2]
         self._method_name = method_name
-        self._args = args
+        self._args = args[2:]
         self._kwargs = kwargs
 
     def __call__(self, obj):
diff --git a/pypy/module/operator/test/test_operator.py 
b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -244,6 +244,13 @@
         assert methodcaller("method", 4, 5)(x) == (4, 5)
         assert methodcaller("method", 4, arg2=42)(x) == (4, 42)
 
+    def test_methodcaller_self(self):
+        from operator import methodcaller
+        class X:
+            def method(myself, self):
+                return self * 6
+        assert methodcaller("method", self=7)(X()) == 42
+
     def test_index(self):
         import operator
         assert operator.index(42) == 42
diff --git a/pypy/module/select/conftest.py b/pypy/module/select/conftest.py
deleted file mode 100644
--- a/pypy/module/select/conftest.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import py
-
-def pytest_collect_directory():
-    py.test.importorskip("ctypes")
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py 
b/pypy/module/test_lib_pypy/ctypes_tests/support.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/support.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/support.py
@@ -2,8 +2,6 @@
 import sys
 import ctypes
 
-py.test.importorskip("ctypes", "1.0.2")
-
 try:
     import _rawffi
 except ImportError:
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
@@ -3,7 +3,10 @@
 import ctypes
 from _ctypes import function
 
-_rawffi = py.test.importorskip("_rawffi")
+try:
+    import _rawffi
+except ImportError:
+    py.test.skip("app-level test only for PyPy")
 
 class TestErrno:
 
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_functional.py 
b/pypy/module/test_lib_pypy/pyrepl/test_functional.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_functional.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_functional.py
@@ -9,7 +9,9 @@
 
 def pytest_funcarg__child(request):
     try:
-        pexpect = pytest.importorskip('pexpect')
+        import pexpect
+    except ImportError:
+        pytest.skip("no pexpect module")
     except SyntaxError:
         pytest.skip('pexpect wont work on py3k')
     child = pexpect.spawn(sys.executable, ['-S'], timeout=10)
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -330,6 +330,9 @@
     def unicode_from_object(self, w_obj):
         return w_some_obj()
 
+    def encode_unicode_object(self, w_unicode, encoding, errors):
+        return w_some_obj()
+
     def _try_fetch_pycode(self, w_func):
         return None
 
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
@@ -626,6 +626,10 @@
         from pypy.objspace.std.unicodeobject import unicode_from_object
         return unicode_from_object(self, w_obj)
 
+    def encode_unicode_object(self, w_unicode, encoding, errors):
+        from pypy.objspace.std.unicodeobject import encode_object
+        return encode_object(self, w_unicode, encoding, errors)
+
     def call_method(self, w_obj, methname, *arg_w):
         return callmethod.call_method_opt(self, w_obj, methname, *arg_w)
 
diff --git a/pypy/tool/cpyext/extbuild.py b/pypy/tool/cpyext/extbuild.py
--- a/pypy/tool/cpyext/extbuild.py
+++ b/pypy/tool/cpyext/extbuild.py
@@ -83,8 +83,11 @@
     def import_extension(self, modname, functions, prologue="",
             include_dirs=None, more_init="", PY_SSIZE_T_CLEAN=False):
         body = prologue + make_methods(functions, modname)
-        init = """Py_InitModule("%s", methods);""" % (modname,)
+        init = """Py_InitModule("%s", methods);
+               """ % (modname,)
         if more_init:
+            init += """#define INITERROR return
+                    """
             init += more_init
         return self.import_module(
             name=modname, init=init, body=body, include_dirs=include_dirs,
diff --git a/rpython/annotator/test/test_model.py 
b/rpython/annotator/test/test_model.py
--- a/rpython/annotator/test/test_model.py
+++ b/rpython/annotator/test/test_model.py
@@ -192,6 +192,20 @@
     assert union(union(s1, s2), s3) == union(s1, union(s2, s3))
 
 
[email protected]
+@given(st_annotation, st_annotation)
+def test_generalize_isinstance(annotator, s1, s2):
+    try:
+        s_12 = union(s1, s2)
+    except UnionError:
+        assume(False)
+    assume(s1 != s_ImpossibleValue)
+    from rpython.annotator.unaryop import s_isinstance
+    s_int = annotator.bookkeeper.immutablevalue(int)
+    s_res_12 = s_isinstance(annotator, s_12, s_int, [])
+    s_res_1 = s_isinstance(annotator, s1, s_int, [])
+    assert s_res_12.contains(s_res_1)
+
 def compile_function(function, annotation=[]):
     t = TranslationContext()
     t.buildannotator().build_types(function, annotation)
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -613,8 +613,11 @@
             return
         cs = effectinfo.call_shortcut
         ptr_box = op.getarg(1 + cs.argnum)
-        value_box = self.emit_getfield(ptr_box, descr=cs.fielddescr,
-                                       raw=(ptr_box.type == 'i'))
+        if cs.fielddescr is not None:
+            value_box = self.emit_getfield(ptr_box, descr=cs.fielddescr,
+                                           raw=(ptr_box.type == 'i'))
+        else:
+            value_box = ptr_box
         self.replace_op_with(op, ResOperation(cond_call_opnum,
                                               [value_box] + op.getarglist(),
                                               descr=descr))
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -88,6 +88,13 @@
         call_shortcut_descr = get_call_descr(self.gc_ll_descr,
             [lltype.Ptr(T)], lltype.Signed,
             effectinfo)
+        call_shortcut_2 = CallShortcut(0, None)
+        effectinfo_2 = EffectInfo(None, None, None, None, None, None,
+                                EffectInfo.EF_RANDOM_EFFECTS,
+                                call_shortcut=call_shortcut_2)
+        call_shortcut_descr_2 = get_call_descr(self.gc_ll_descr,
+            [lltype.Signed], lltype.Signed,
+            effectinfo_2)
         #
         A = lltype.GcArray(lltype.Signed)
         adescr = get_array_descr(self.gc_ll_descr, A)
@@ -1451,3 +1458,14 @@
             i1 = cond_call_value_i(i2, 123, p0, descr=call_shortcut_descr)
             jump(i1)
         """)
+
+    def test_handle_call_shortcut_2(self):
+        self.check_rewrite("""
+            [i0]
+            i1 = call_i(123, i0, descr=call_shortcut_descr_2)
+            jump(i1)
+        """, """
+            [i0]
+            i1 = cond_call_value_i(i0, 123, i0, descr=call_shortcut_descr_2)
+            jump(i1)
+        """)
diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py
--- a/rpython/jit/codewriter/call.py
+++ b/rpython/jit/codewriter/call.py
@@ -388,15 +388,23 @@
                    return y.field          if r: return r
         """
         block = graph.startblock
-        if len(block.operations) == 0:
-            return
-        op = block.operations[0]
-        if op.opname != 'getfield':
-            return
-        [v_inst, c_fieldname] = op.args
+        operations = block.operations
+        c_fieldname = None
+        if not operations:
+            v_inst = v_result = block.exitswitch
+        else:
+            op = operations[0]
+            if len(op.args) == 0:
+                return
+            if op.opname != 'getfield':  # check for this form:
+                v_inst = op.args[0]      #     if y is not None;
+                v_result = v_inst        #          return y
+            else:
+                operations = operations[1:]
+                [v_inst, c_fieldname] = op.args
+                v_result = op.result
         if not isinstance(v_inst, Variable):
             return
-        v_result = op.result
         if v_result.concretetype != graph.getreturnvar().concretetype:
             return
         if v_result.concretetype == lltype.Void:
@@ -409,7 +417,7 @@
         PSTRUCT = v_inst.concretetype
         v_check = v_result
         fastcase = True
-        for op in block.operations[1:]:
+        for op in operations:
             if (op.opname in ('int_is_true', 'ptr_nonzero', 'same_as')
                     and v_check is op.args[0]):
                 v_check = op.result
@@ -439,5 +447,8 @@
         if not link.target.is_final_block():
             return
 
-        fielddescr = self.cpu.fielddescrof(PSTRUCT.TO, c_fieldname.value)
+        if c_fieldname is not None:
+            fielddescr = self.cpu.fielddescrof(PSTRUCT.TO, c_fieldname.value)
+        else:
+            fielddescr = None
         return CallShortcut(argnum, fielddescr)
diff --git a/rpython/jit/codewriter/test/test_call.py 
b/rpython/jit/codewriter/test/test_call.py
--- a/rpython/jit/codewriter/test/test_call.py
+++ b/rpython/jit/codewriter/test/test_call.py
@@ -424,6 +424,21 @@
             r = b.foobar = 123
         return r
 
+    def f6(b):
+        if b is not None:
+            return b
+        return B()
+
+    def f7(c, a):
+        if a:
+            return a
+        return 123
+
+    def b_or_none(c):
+        if c > 15:
+            return B()
+        return None
+
     def f(a, c):
         b = B()
         f1(a, b, c)
@@ -432,6 +447,8 @@
         r = lltype.malloc(RAW, flavor='raw')
         f4(r)
         f5(b)
+        f6(b_or_none(c))
+        f7(c, a)
 
     rtyper = support.annotate(f, [10, 20])
     f1_graph = rtyper.annotator.translator._graphof(f1)
@@ -444,6 +461,10 @@
     assert cc.find_call_shortcut(f4_graph) == CallShortcut(0, "xdescr")
     f5_graph = rtyper.annotator.translator._graphof(f5)
     assert cc.find_call_shortcut(f5_graph) == CallShortcut(0, "foobardescr")
+    f6_graph = rtyper.annotator.translator._graphof(f6)
+    assert cc.find_call_shortcut(f6_graph) == CallShortcut(0, None)
+    f7_graph = rtyper.annotator.translator._graphof(f7)
+    assert cc.find_call_shortcut(f7_graph) == CallShortcut(1, None)
 
 def test_cant_find_call_shortcut():
     from rpython.jit.backend.llgraph.runner import LLGraphCPU
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1874,7 +1874,9 @@
 # Support for f... and ...at families of POSIX functions
 
 class CConfig:
-    _compilation_info_ = eci
+    _compilation_info_ = eci.merge(ExternalCompilationInfo(
+        includes=['sys/statvfs.h'],
+    ))
     for _name in """faccessat fchdir fchmod fchmodat fchown fchownat fexecve
             fdopendir fpathconf fstat fstatat fstatvfs ftruncate
             futimens futimes futimesat linkat chflags lchflags lchmod lchown
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -173,6 +173,12 @@
     state = State()
 
 HAS_CLOCK_GETTIME = (CLOCK_MONOTONIC is not None)
+if sys.platform == 'darwin':
+    HAS_CLOCK_GETTIME = False
+    # ^^^ https://bitbucket.org/pypy/pypy/issues/2432 and others
+    # (change it manually if you *know* you want to build and run on
+    # OS/X 10.12 or later)
+
 if HAS_CLOCK_GETTIME:
     # Linux and other POSIX systems with clock_gettime()
     # TIMESPEC:
diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py
--- a/rpython/rtyper/rtyper.py
+++ b/rpython/rtyper/rtyper.py
@@ -78,7 +78,6 @@
             self.log.info(s)
         except:
             self.seed = 0
-        self.order = None
 
     def getconfig(self):
         return self.annotator.translator.config
@@ -218,15 +217,9 @@
                 r = random.Random(self.seed)
                 r.shuffle(pending)
 
-            if self.order:
-                tracking = self.order(self.annotator, pending)
-            else:
-                tracking = lambda block: None
-
             previous_percentage = 0
             # specialize all blocks in the 'pending' list
             for block in pending:
-                tracking(block)
                 blockcount += 1
                 self.specialize_block(block)
                 self.already_seen[block] = True
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to