Author: Mark Young <marky1...@gmail.com>
Branch: py3k-clock_get_info
Changeset: r84756:a491593ec0e7
Date: 2016-05-20 21:22 -0400
http://bitbucket.org/pypy/pypy/changeset/a491593ec0e7/

Log:    Merge with upstream.

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -22,3 +22,4 @@
 bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1
 3260adbeba4a8b6659d1cc0d0b41f266769b74da release-5.1
 b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1
+80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2
diff --git a/lib-python/3/test/test_descr.py b/lib-python/3/test/test_descr.py
--- a/lib-python/3/test/test_descr.py
+++ b/lib-python/3/test/test_descr.py
@@ -4674,6 +4674,7 @@
 
 
 class MiscTests(unittest.TestCase):
+    @support.cpython_only
     def test_type_lookup_mro_reference(self):
         # Issue #14199: _PyType_Lookup() has to keep a strong reference to
         # the type MRO because it may be modified during the lookup, if
diff --git a/lib-python/3/test/test_socket.py b/lib-python/3/test/test_socket.py
--- a/lib-python/3/test/test_socket.py
+++ b/lib-python/3/test/test_socket.py
@@ -691,10 +691,11 @@
         # wrong number of args
         with self.assertRaises(TypeError) as cm:
             s.sendto(b'foo')
-        self.assertIn(' given)', str(cm.exception))
+        if support.check_impl_detail():
+            self.assertIn(' given)', str(cm.exception))
         with self.assertRaises(TypeError) as cm:
             s.sendto(b'foo', 0, sockname, 4)
-        self.assertIn(' given)', str(cm.exception))
+        self.assertIn(' given', str(cm.exception))
 
     def testCrucialConstants(self):
         # Testing for mission critical constants
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
@@ -93,3 +93,15 @@
 .. branch: ufunc-outer
 
 Implement ufunc.outer on numpypy
+
+.. branch: verbose-imports
+
+Support ``pypy -v``: verbose imports.  It does not log as much as
+cpython, but it should be enough to help when debugging package layout
+problems.
+
+.. branch: cpyext-macros-cast
+
+Fix some warnings when compiling CPython C extension modules
+
+.. branch: syntax_fix
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -526,6 +526,7 @@
                      unbuffered,
                      ignore_environment,
                      quiet,
+                     verbose,
                      **ignored):
     # with PyPy in top of CPython we can only have around 100
     # but we need more in the translated PyPy for the compiler package
@@ -658,6 +659,8 @@
                 inspect = True
             else:
                 # If not interactive, just read and execute stdin normally.
+                if verbose:
+                    print_banner(not no_site)
                 @hidden_applevel
                 def run_it():
                     co_stdin = compile(sys.stdin.read(), '<stdin>', 'exec',
@@ -741,10 +744,10 @@
     return status
 
 def print_banner(copyright):
-    print('Python %s on %s' % (sys.version, sys.platform))
+    print('Python %s on %s' % (sys.version, sys.platform), file=sys.stderr)
     if copyright:
         print('Type "help", "copyright", "credits" or '
-              '"license" for more information.')
+              '"license" for more information.', file=sys.stderr)
 
 STDLIB_WARNING = """\
 debug: WARNING: Library path not found, using compiled-in sys.path.
diff --git a/pypy/interpreter/test/test_argument.py 
b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -677,9 +677,9 @@
         exc = raises(TypeError, (lambda: 0), b=3)
         assert str(exc.value) == "<lambda>() got an unexpected keyword 
argument 'b'"
         exc = raises(TypeError, (lambda a, b: 0), 1, 2, 3, a=1)
-        assert str(exc.value) == "<lambda>() takes 2 positional arguments but 
3 were given"
+        assert str(exc.value) == "<lambda>() got multiple values for argument 
'a'"
         exc = raises(TypeError, (lambda a, b=1: 0), 1, 2, 3, a=1)
-        assert str(exc.value) == "<lambda>() takes from 1 to 2 positional 
arguments but 3 were given"
+        assert str(exc.value) == "<lambda>() got multiple values for argument 
'a'"
         exc = raises(TypeError, (lambda a, **kw: 0), 1, 2, 3)
         assert str(exc.value) == "<lambda>() takes 1 positional argument but 3 
were given"
         exc = raises(TypeError, (lambda a, b=1, **kw: 0), 1, 2, 3)
diff --git a/pypy/module/__pypy__/interp_magic.py 
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -51,6 +51,11 @@
                            space.newint(cache.misses.get(name, 0))])
 
 def builtinify(space, w_func):
+    """To implement at app-level modules that are, in CPython,
+    implemented in C: this decorator protects a function from being ever
+    bound like a method.  Useful because some tests do things like put
+    a "built-in" function on a class and access it via the instance.
+    """
     from pypy.interpreter.function import Function, BuiltinFunction
     func = space.interp_w(Function, w_func)
     bltn = BuiltinFunction(func)
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -12,8 +12,8 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from pypy.interpreter.typedef import (
-    GetSetProperty, TypeDef, interp_attrproperty, make_weakref_descr
-)
+    GetSetProperty, TypeDef, generic_new_descr, interp_attrproperty,
+    make_weakref_descr)
 
 
 # XXX Hack to seperate rpython and pypy
@@ -39,7 +39,7 @@
             # Linux abstract namespace
             return space.wrapbytes(path)
         else:
-            return space.wrap(path)
+            return space.wrap_fsdecoded(path)
     elif rsocket.HAS_AF_NETLINK and isinstance(addr, rsocket.NETLINKAddress):
         return space.newtuple([space.wrap(addr.get_pid()),
                                space.wrap(addr.get_groups())])
@@ -159,15 +159,14 @@
 
 
 class W_Socket(W_Root):
-    def __init__(self, space, sock):
+    def __init__(self, space, sock=None):
         self.space = space
-        self.sock = sock
-        register_socket(space, sock)
-
-    def descr_new(space, w_subtype, __args__):
-        sock = space.allocate_instance(W_Socket, w_subtype)
-        W_Socket.__init__(sock, space, RSocket.empty_rsocket())
-        return space.wrap(sock)
+        if sock is None:
+            self.sock = RSocket.empty_rsocket()
+        else:
+            register_socket(space, sock)
+            self.sock = sock
+            self.register_finalizer(space)
 
     @unwrap_spec(family=int, type=int, proto=int,
                  w_fileno=WrappedDefault(None))
@@ -184,12 +183,15 @@
             raise converted_error(space, e)
 
     def _finalize_(self):
-        self.clear_all_weakrefs()
-        if self.sock.fd != rsocket.INVALID_SOCKET:
+        sock = self.sock
+        if sock.fd != rsocket.INVALID_SOCKET:
             try:
                 self._dealloc_warn()
             finally:
-                self.close_w(self.space)
+                try:
+                    sock.close()
+                except SocketError:
+                    pass
 
     def get_type_w(self, space):
         return space.wrap(self.sock.type)
@@ -734,7 +736,7 @@
 shutdown(how) -- shut down traffic in one or both directions
 
  [*] not available on all platforms!""",
-    __new__ = interp2app(W_Socket.descr_new.im_func),
+    __new__ = generic_new_descr(W_Socket),
     __init__ = interp2app(W_Socket.descr_init),
     __repr__ = interp2app(W_Socket.descr_repr),
     type = GetSetProperty(W_Socket.get_type_w),
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -137,6 +137,11 @@
                   space.wrap(lib_str) if lib_str else space.w_None)
     return OperationError(w_exception_class, w_exception)
 
+def timeout_error(space, msg):
+    w_exc_class = interp_socket.get_error(space, 'timeout')
+    w_exc = space.call_function(w_exc_class, space.wrap(msg))
+    return OperationError(w_exc_class, w_exc)
+
 class SSLNpnProtocols(object):
 
     def __init__(self, ctx, protos):
@@ -334,7 +339,7 @@
 
         sockstate = checkwait(space, w_socket, True)
         if sockstate == SOCKET_HAS_TIMED_OUT:
-            raise ssl_error(space, "The write operation timed out")
+            raise timeout_error(space, "The write operation timed out")
         elif sockstate == SOCKET_HAS_BEEN_CLOSED:
             raise ssl_error(space, "Underlying socket has been closed.")
         elif sockstate == SOCKET_TOO_LARGE_FOR_SELECT:
@@ -355,7 +360,7 @@
                 sockstate = SOCKET_OPERATION_OK
 
             if sockstate == SOCKET_HAS_TIMED_OUT:
-                raise ssl_error(space, "The write operation timed out")
+                raise timeout_error(space, "The write operation timed out")
             elif sockstate == SOCKET_HAS_BEEN_CLOSED:
                 raise ssl_error(space, "Underlying socket has been closed.")
             elif sockstate == SOCKET_IS_NONBLOCKING:
@@ -392,7 +397,7 @@
         if not count:
             sockstate = checkwait(space, w_socket, False)
             if sockstate == SOCKET_HAS_TIMED_OUT:
-                raise ssl_error(space, "The read operation timed out")
+                raise timeout_error(space, "The read operation timed out")
             elif sockstate == SOCKET_TOO_LARGE_FOR_SELECT:
                 raise ssl_error(space,
                                 "Underlying socket too large for select().")
@@ -432,7 +437,7 @@
                     sockstate = SOCKET_OPERATION_OK
 
                 if sockstate == SOCKET_HAS_TIMED_OUT:
-                    raise ssl_error(space, "The read operation timed out")
+                    raise timeout_error(space, "The read operation timed out")
                 elif sockstate == SOCKET_IS_NONBLOCKING:
                     break
 
@@ -481,7 +486,7 @@
             else:
                 sockstate = SOCKET_OPERATION_OK
             if sockstate == SOCKET_HAS_TIMED_OUT:
-                raise ssl_error(space, "The handshake operation timed out")
+                raise timeout_error(space, "The handshake operation timed out")
             elif sockstate == SOCKET_HAS_BEEN_CLOSED:
                 raise ssl_error(space, "Underlying socket has been closed.")
             elif sockstate == SOCKET_TOO_LARGE_FOR_SELECT:
@@ -549,9 +554,9 @@
 
             if sockstate == SOCKET_HAS_TIMED_OUT:
                 if ssl_err == SSL_ERROR_WANT_READ:
-                    raise ssl_error(space, "The read operation timed out")
+                    raise timeout_error(space, "The read operation timed out")
                 else:
-                    raise ssl_error(space, "The write operation timed out")
+                    raise timeout_error(space, "The write operation timed out")
             elif sockstate == SOCKET_TOO_LARGE_FOR_SELECT:
                 raise ssl_error(space,
                                 "Underlying socket too large for select().")
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -413,7 +413,16 @@
                             arg = rffi.cast(ARG, as_pyobj(space, input_arg))
                         else:
                             arg = rffi.cast(ARG, input_arg)
-                    elif is_PyObject(ARG) and is_wrapped:
+                    elif ARG == rffi.VOIDP and not is_wrapped:
+                        # unlike is_PyObject case above, we allow any kind of
+                        # argument -- just, if it's an object, we assume the
+                        # caller meant for it to become a PyObject*.
+                        if input_arg is None or isinstance(input_arg, W_Root):
+                            keepalives += (input_arg,)
+                            arg = rffi.cast(ARG, as_pyobj(space, input_arg))
+                        else:
+                            arg = rffi.cast(ARG, input_arg)
+                    elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and 
is_wrapped:
                         # build a W_Root, possibly from a 'PyObject *'
                         if is_pyobj(input_arg):
                             arg = from_ref(space, input_arg)
@@ -725,6 +734,7 @@
 
 class WrapperGen(object):
     wrapper_second_level = None
+    A = lltype.Array(lltype.Char)
 
     def __init__(self, space, signature):
         self.space = space
@@ -737,9 +747,13 @@
         wrapper_second_level = self.wrapper_second_level
 
         name = callable.__name__
+        pname = lltype.malloc(self.A, len(name), flavor='raw', immortal=True)
+        for i in range(len(name)):
+            pname[i] = name[i]
+
         def wrapper(*args):
             # no GC here, not even any GC object
-            return wrapper_second_level(callable, name, *args)
+            return wrapper_second_level(callable, pname, *args)
 
         wrapper.__name__ = "wrapper for %r" % (callable, )
         return wrapper
@@ -747,22 +761,31 @@
 
 
 @dont_inline
+def _unpack_name(pname):
+    return ''.join([pname[i] for i in range(len(pname))])
+
+@dont_inline
 def deadlock_error(funcname):
+    funcname = _unpack_name(funcname)
     fatalerror_notb("GIL deadlock detected when a CPython C extension "
                     "module calls '%s'" % (funcname,))
 
 @dont_inline
 def no_gil_error(funcname):
+    funcname = _unpack_name(funcname)
     fatalerror_notb("GIL not held when a CPython C extension "
                     "module calls '%s'" % (funcname,))
 
 @dont_inline
 def not_supposed_to_fail(funcname):
-    raise SystemError("The function '%s' was not supposed to fail"
-                      % (funcname,))
+    funcname = _unpack_name(funcname)
+    print "Error in cpyext, CPython compatibility layer:"
+    print "The function", funcname, "was not supposed to fail"
+    raise SystemError
 
 @dont_inline
 def unexpected_exception(funcname, e, tb):
+    funcname = _unpack_name(funcname)
     print 'Fatal error in cpyext, CPython compatibility layer, 
calling',funcname
     print 'Either report a bug or consider not using this particular extension'
     if not we_are_translated():
@@ -801,9 +824,8 @@
     def invalid(err):
         "NOT_RPYTHON: translation-time crash if this ends up being called"
         raise ValueError(err)
-    invalid.__name__ = 'invalid_%s' % name
 
-    def wrapper_second_level(callable, name, *args):
+    def wrapper_second_level(callable, pname, *args):
         from pypy.module.cpyext.pyobject import make_ref, from_ref, is_pyobj
         from pypy.module.cpyext.pyobject import as_pyobj
         # we hope that malloc removal removes the newtuple() that is
@@ -814,7 +836,7 @@
         _gil_auto = (gil_auto_workaround and cpyext_glob_tid_ptr[0] != tid)
         if gil_acquire or _gil_auto:
             if cpyext_glob_tid_ptr[0] == tid:
-                deadlock_error(name)
+                deadlock_error(pname)
             rgil.acquire()
             assert cpyext_glob_tid_ptr[0] == 0
         elif pygilstate_ensure:
@@ -827,7 +849,7 @@
                 args += (pystate.PyGILState_UNLOCKED,)
         else:
             if cpyext_glob_tid_ptr[0] != tid:
-                no_gil_error(name)
+                no_gil_error(pname)
             cpyext_glob_tid_ptr[0] = 0
 
         rffi.stackcounter.stacks_counter += 1
@@ -844,6 +866,10 @@
                 if is_PyObject(typ) and is_wrapped:
                     assert is_pyobj(arg)
                     arg_conv = from_ref(space, rffi.cast(PyObject, arg))
+                elif typ == rffi.VOIDP and is_wrapped:
+                    # Many macros accept a void* so that one can pass a
+                    # PyObject* or a PySomeSubtype*.
+                    arg_conv = from_ref(space, rffi.cast(PyObject, arg))
                 else:
                     arg_conv = arg
                 boxed_args += (arg_conv, )
@@ -873,7 +899,7 @@
 
             if failed:
                 if error_value is CANNOT_FAIL:
-                    raise not_supposed_to_fail(name)
+                    raise not_supposed_to_fail(pname)
                 retval = error_value
 
             elif is_PyObject(restype):
@@ -893,7 +919,7 @@
                 retval = rffi.cast(restype, result)
 
         except Exception as e:
-            unexpected_exception(name, e, tb)
+            unexpected_exception(pname, e, tb)
             return fatal_value
 
         assert lltype.typeOf(retval) == restype
diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -178,67 +178,67 @@
 
 # Accessors
 
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_GET_YEAR(space, w_obj):
     """Return the year, as a positive int.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("year")))
 
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_GET_MONTH(space, w_obj):
     """Return the month, as an int from 1 through 12.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("month")))
 
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_GET_DAY(space, w_obj):
     """Return the day, as an int from 1 through 31.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("day")))
 
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DATE_GET_HOUR(space, w_obj):
     """Return the hour, as an int from 0 through 23.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("hour")))
 
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DATE_GET_MINUTE(space, w_obj):
     """Return the minute, as an int from 0 through 59.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("minute")))
 
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DATE_GET_SECOND(space, w_obj):
     """Return the second, as an int from 0 through 59.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("second")))
 
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DATE_GET_MICROSECOND(space, w_obj):
     """Return the microsecond, as an int from 0 through 999999.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
 
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_TIME_GET_HOUR(space, w_obj):
     """Return the hour, as an int from 0 through 23.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("hour")))
 
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_TIME_GET_MINUTE(space, w_obj):
     """Return the minute, as an int from 0 through 59.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("minute")))
 
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_TIME_GET_SECOND(space, w_obj):
     """Return the second, as an int from 0 through 59.
     """
     return space.int_w(space.getattr(w_obj, space.wrap("second")))
 
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_TIME_GET_MICROSECOND(space, w_obj):
     """Return the microsecond, as an int from 0 through 999999.
     """
@@ -248,14 +248,14 @@
 # But it does not seem possible to expose a different structure
 # for types defined in a python module like lib/datetime.py.
 
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DELTA_GET_DAYS(space, w_obj):
     return space.int_w(space.getattr(w_obj, space.wrap("days")))
 
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DELTA_GET_SECONDS(space, w_obj):
     return space.int_w(space.getattr(w_obj, space.wrap("seconds")))
 
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
 def PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj):
     return space.int_w(space.getattr(w_obj, space.wrap("microseconds")))
diff --git a/pypy/module/cpyext/floatobject.py 
b/pypy/module/cpyext/floatobject.py
--- a/pypy/module/cpyext/floatobject.py
+++ b/pypy/module/cpyext/floatobject.py
@@ -48,7 +48,7 @@
 def PyFloat_AsDouble(space, w_obj):
     return space.float_w(space.float(w_obj))
 
-@cpython_api([PyObject], lltype.Float, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], lltype.Float, error=CANNOT_FAIL)
 def PyFloat_AS_DOUBLE(space, w_float):
     """Return a C double representation of the contents of w_float, but
     without error checking."""
diff --git a/pypy/module/cpyext/include/listobject.h 
b/pypy/module/cpyext/include/listobject.h
--- a/pypy/module/cpyext/include/listobject.h
+++ b/pypy/module/cpyext/include/listobject.h
@@ -1,1 +1,1 @@
-#define PyList_GET_ITEM PyList_GetItem
+#define PyList_GET_ITEM(o, i) PyList_GetItem((PyObject*)(o), (i))
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -21,7 +21,7 @@
     """
     return space.newlist([None] * len)
 
-@cpython_api([PyObject, Py_ssize_t, PyObject], PyObject, error=CANNOT_FAIL,
+@cpython_api([rffi.VOIDP, Py_ssize_t, PyObject], PyObject, error=CANNOT_FAIL,
              result_borrowed=True)
 def PyList_SET_ITEM(space, w_list, index, w_item):
     """Macro form of PyList_SetItem() without error checking. This is normally
@@ -87,7 +87,7 @@
     space.call_method(space.w_list, "insert", w_list, space.wrap(index), 
w_item)
     return 0
 
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PyList_GET_SIZE(space, w_list):
     """Macro form of PyList_Size() without error checking.
     """
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
@@ -54,7 +54,7 @@
     except OperationError:
         raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m)))
 
-@cpython_api([PyObject, Py_ssize_t], PyObject, result_borrowed=True)
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_borrowed=True)
 def PySequence_Fast_GET_ITEM(space, w_obj, index):
     """Return the ith element of o, assuming that o was returned by
     PySequence_Fast(), o is not NULL, and that i is within bounds.
@@ -67,7 +67,7 @@
                 "PySequence_Fast_GET_ITEM called but object is not a list or "
                 "sequence")
 
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PySequence_Fast_GET_SIZE(space, w_obj):
     """Returns the length of o, assuming that o was returned by
     PySequence_Fast() and that o is not NULL.  The size can also be
@@ -82,7 +82,7 @@
                 "PySequence_Fast_GET_SIZE called but object is not a list or "
                 "sequence")
 
-@cpython_api([PyObject], PyObjectP)
+@cpython_api([rffi.VOIDP], PyObjectP)
 def PySequence_Fast_ITEMS(space, w_obj):
     """Return the underlying array of PyObject pointers.  Assumes that o was 
returned
     by PySequence_Fast() and o is not NULL.
@@ -119,7 +119,7 @@
     space.delslice(w_obj, space.wrap(start), space.wrap(end))
     return 0
 
-@cpython_api([PyObject, Py_ssize_t], PyObject)
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject)
 def PySequence_ITEM(space, w_obj, i):
     """Return the ith element of o or NULL on failure. Macro form of
     PySequence_GetItem() but without checking that
diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py
--- a/pypy/module/cpyext/setobject.py
+++ b/pypy/module/cpyext/setobject.py
@@ -74,7 +74,7 @@
     space.call_method(space.w_set, 'clear', w_set)
     return 0
 
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PySet_GET_SIZE(space, w_s):
     """Macro form of PySet_Size() without error checking."""
     return space.int_w(space.len(w_s))
diff --git a/pypy/module/cpyext/test/test_datetime.py 
b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -117,3 +117,108 @@
                                       datetime.timedelta,
                                       datetime.tzinfo)
         module.clear_types()
+
+    def test_macros(self):
+        module = self.import_extension('foo', [
+            ("test_date_macros", "METH_NOARGS",
+             """
+                 PyObject* obj;
+                 PyDateTime_Date* d;
+                 PyDateTime_IMPORT;
+                 if (!PyDateTimeAPI) {
+                     PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI");
+                     return NULL;
+                 }
+                 obj = PyDate_FromDate(2000, 6, 6);
+                 d = (PyDateTime_Date*)obj;
+
+                 PyDateTime_GET_YEAR(obj);
+                 PyDateTime_GET_YEAR(d);
+
+                 PyDateTime_GET_MONTH(obj);
+                 PyDateTime_GET_MONTH(d);
+
+                 PyDateTime_GET_DAY(obj);
+                 PyDateTime_GET_DAY(d);
+
+                 return obj;
+             """),
+            ("test_datetime_macros", "METH_NOARGS",
+             """
+                 PyDateTime_IMPORT;
+                 if (!PyDateTimeAPI) {
+                     PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI");
+                     return NULL;
+                 }
+                 PyObject* obj = PyDateTime_FromDateAndTime(2000, 6, 6, 6, 6, 
6, 6);
+                 PyDateTime_DateTime* dt = (PyDateTime_DateTime*)obj;
+
+                 PyDateTime_GET_YEAR(obj);
+                 PyDateTime_GET_YEAR(dt);
+
+                 PyDateTime_GET_MONTH(obj);
+                 PyDateTime_GET_MONTH(dt);
+
+                 PyDateTime_GET_DAY(obj);
+                 PyDateTime_GET_DAY(dt);
+
+                 PyDateTime_DATE_GET_HOUR(obj);
+                 PyDateTime_DATE_GET_HOUR(dt);
+
+                 PyDateTime_DATE_GET_MINUTE(obj);
+                 PyDateTime_DATE_GET_MINUTE(dt);
+
+                 PyDateTime_DATE_GET_SECOND(obj);
+                 PyDateTime_DATE_GET_SECOND(dt);
+
+                 PyDateTime_DATE_GET_MICROSECOND(obj);
+                 PyDateTime_DATE_GET_MICROSECOND(dt);
+
+                 return obj;
+             """),
+            ("test_time_macros", "METH_NOARGS",
+             """
+                 PyDateTime_IMPORT;
+                 if (!PyDateTimeAPI) {
+                     PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI");
+                     return NULL;
+                 }
+                 PyObject* obj = PyTime_FromTime(6, 6, 6, 6);
+                 PyDateTime_Time* t = (PyDateTime_Time*)obj;
+
+                 PyDateTime_TIME_GET_HOUR(obj);
+                 PyDateTime_TIME_GET_HOUR(t);
+
+                 PyDateTime_TIME_GET_MINUTE(obj);
+                 PyDateTime_TIME_GET_MINUTE(t);
+
+                 PyDateTime_TIME_GET_SECOND(obj);
+                 PyDateTime_TIME_GET_SECOND(t);
+
+                 PyDateTime_TIME_GET_MICROSECOND(obj);
+                 PyDateTime_TIME_GET_MICROSECOND(t);
+
+                 return obj;
+             """),
+            ("test_delta_macros", "METH_NOARGS",
+             """
+                 PyDateTime_IMPORT;
+                 if (!PyDateTimeAPI) {
+                     PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI");
+                     return NULL;
+                 }
+                 PyObject* obj = PyDelta_FromDSU(6, 6, 6);
+                 PyDateTime_Delta* delta = (PyDateTime_Delta*)obj;
+
+                 PyDateTime_DELTA_GET_DAYS(obj);
+                 PyDateTime_DELTA_GET_DAYS(delta);
+
+                 PyDateTime_DELTA_GET_SECONDS(obj);
+                 PyDateTime_DELTA_GET_SECONDS(delta);
+
+                 PyDateTime_DELTA_GET_MICROSECONDS(obj);
+                 PyDateTime_DELTA_GET_MICROSECONDS(delta);
+
+                 return obj;
+             """),
+            ])
diff --git a/pypy/module/cpyext/test/test_floatobject.py 
b/pypy/module/cpyext/test/test_floatobject.py
--- a/pypy/module/cpyext/test/test_floatobject.py
+++ b/pypy/module/cpyext/test/test_floatobject.py
@@ -77,3 +77,19 @@
         neginf = module.return_neginf()
         assert neginf < 0
         assert math.isinf(neginf)
+
+    def test_macro_accepts_wrong_pointer_type(self):
+        import math
+
+        module = self.import_extension('foo', [
+            ("test_macros", "METH_NOARGS",
+             """
+             PyObject* o = PyFloat_FromDouble(1.0);
+             // no PyFloatObject
+             char* dumb_pointer = (char*)o;
+
+             PyFloat_AS_DOUBLE(o);
+             PyFloat_AS_DOUBLE(dumb_pointer);
+
+             Py_RETURN_NONE;"""),
+            ])
diff --git a/pypy/module/cpyext/test/test_listobject.py 
b/pypy/module/cpyext/test/test_listobject.py
--- a/pypy/module/cpyext/test/test_listobject.py
+++ b/pypy/module/cpyext/test/test_listobject.py
@@ -137,6 +137,33 @@
         module.setlistitem(l,0)
         assert l == [None, 2, 3]
 
+    def test_list_macros(self):
+        """The PyList_* macros cast, and calls expecting that build."""
+        module = self.import_extension('foo', [
+            ("test_macro_invocations", "METH_NOARGS",
+             """
+             PyObject* o = PyList_New(2);
+             PyListObject* l = (PyListObject*)o;
+
+
+             Py_INCREF(o);
+             PyList_SET_ITEM(o, 0, o);
+             Py_INCREF(o);
+             PyList_SET_ITEM(l, 1, o);
+
+             PyList_GET_ITEM(o, 0);
+             PyList_GET_ITEM(l, 1);
+
+             PyList_GET_SIZE(o);
+             PyList_GET_SIZE(l);
+
+             return o;
+             """
+            )
+        ])
+        x = module.test_macro_invocations()
+        assert x[0] is x[1] is x
+
     def test_get_item_macro(self):
         module = self.import_extension('foo', [
              ("test_get_item", "METH_NOARGS",
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
@@ -155,6 +155,29 @@
         result = api.PySequence_Index(w_gen, w_tofind)
         assert result == 4
 
+class AppTestSetObject(AppTestCpythonExtensionBase):
+    def test_sequence_macro_cast(self):
+        module = self.import_extension('foo', [
+            ("test_macro_cast", "METH_NOARGS",
+             """
+             PyObject *o = PyList_New(0);
+             PyListObject* l;
+             PyList_Append(o, o);
+             l = (PyListObject*)o;
+
+             PySequence_Fast_GET_ITEM(o, 0);
+             PySequence_Fast_GET_ITEM(l, 0);
+
+             PySequence_Fast_GET_SIZE(o);
+             PySequence_Fast_GET_SIZE(l);
+
+             PySequence_ITEM(o, 0);
+             PySequence_ITEM(l, 0);
+
+             return o;
+             """
+            )
+        ])
 class TestCPyListStrategy(BaseApiTest):
     def test_getitem_setitem(self, space, api):
         w_l = space.wrap([1, 2, 3, 4])
diff --git a/pypy/module/cpyext/test/test_setobject.py 
b/pypy/module/cpyext/test/test_setobject.py
--- a/pypy/module/cpyext/test/test_setobject.py
+++ b/pypy/module/cpyext/test/test_setobject.py
@@ -2,6 +2,7 @@
 
 from pypy.module.cpyext.pyobject import PyObject, PyObjectP, make_ref, from_ref
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from rpython.rtyper.lltypesystem import rffi, lltype
 
 
@@ -45,3 +46,20 @@
         w_frozenset = space.newfrozenset([space.wrap(i) for i in [1, 2, 3, 4]])
         assert api.PyAnySet_CheckExact(w_set)
         assert api.PyAnySet_CheckExact(w_frozenset)
+
+class AppTestSetObject(AppTestCpythonExtensionBase):
+    def test_set_macro_cast(self):
+        module = self.import_extension('foo', [
+            ("test_macro_cast", "METH_NOARGS",
+             """
+             PyObject* o = PySet_New(NULL);
+             // no PySetObject
+             char* dumb_pointer = (char*) o;
+
+             PySet_GET_SIZE(o);
+             PySet_GET_SIZE(dumb_pointer);
+
+             return o;
+             """
+            )
+        ])
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py 
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -160,6 +160,26 @@
         assert module.compare("abc", b"") == 1
 
 
+    def test_unicode_macros(self):
+        """The PyUnicode_* macros cast, and calls expecting that build."""
+        module = self.import_extension('foo', [
+             ("test_macro_invocations", "METH_NOARGS",
+             """
+                PyObject* o = PyUnicode_FromString("");
+                PyUnicodeObject* u = (PyUnicodeObject*)o;
+
+                PyUnicode_GET_SIZE(u);
+                PyUnicode_GET_SIZE(o);
+
+                PyUnicode_GET_DATA_SIZE(u);
+                PyUnicode_GET_DATA_SIZE(o);
+
+                PyUnicode_AS_UNICODE(o);
+                PyUnicode_AS_UNICODE(u);
+                return o;
+             """)])
+        assert module.test_macro_invocations() == u''
+
 class TestUnicode(BaseApiTest):
     def test_unicodeobject(self, space, api):
         assert api.PyUnicode_GET_SIZE(space.wrap(u'sp&#228;m')) == 4
diff --git a/pypy/module/cpyext/test/test_weakref.py 
b/pypy/module/cpyext/test/test_weakref.py
--- a/pypy/module/cpyext/test/test_weakref.py
+++ b/pypy/module/cpyext/test/test_weakref.py
@@ -7,7 +7,6 @@
         w_ref = api.PyWeakref_NewRef(w_obj, space.w_None)
         assert w_ref is not None
         assert space.is_w(api.PyWeakref_GetObject(w_ref), w_obj)
-        assert space.is_w(api.PyWeakref_GET_OBJECT(w_ref), w_obj)
         assert space.is_w(api.PyWeakref_LockObject(w_ref), w_obj)
 
         w_obj = space.newtuple([])
@@ -34,3 +33,26 @@
         del w_obj
         import gc; gc.collect()
         assert space.is_w(api.PyWeakref_LockObject(w_ref), space.w_None)
+
+
+class AppTestWeakReference(AppTestCpythonExtensionBase):
+
+    def test_weakref_macro(self):
+        module = self.import_extension('foo', [
+            ("test_macro_cast", "METH_NOARGS",
+             """
+             // PyExc_Warning is some weak-reffable PyObject*.
+             char* dumb_pointer;
+             PyObject* weakref_obj = PyWeakref_NewRef(PyExc_Warning, NULL);
+             if (!weakref_obj) return weakref_obj;
+             // No public PyWeakReference type.
+             dumb_pointer = (char*) weakref_obj;
+
+             PyWeakref_GET_OBJECT(weakref_obj);
+             PyWeakref_GET_OBJECT(dumb_pointer);
+
+             return weakref_obj;
+             """
+            )
+        ])
+        module.test_macro_cast()
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
@@ -18,8 +18,9 @@
     Py_TPFLAGS_HEAPTYPE, METH_VARARGS, METH_KEYWORDS, CANNOT_FAIL,
     Py_TPFLAGS_HAVE_GETCHARBUFFER, build_type_checkers, StaticObjectBuilder,
     PyObjectFields, Py_TPFLAGS_BASETYPE, Py_buffer)
-from pypy.module.cpyext.methodobject import (
-    PyDescr_NewWrapper, PyCFunction_NewEx, PyCFunction_typedef, PyMethodDef)
+from pypy.module.cpyext.methodobject import (W_PyCClassMethodObject,
+    PyDescr_NewWrapper, PyCFunction_NewEx, PyCFunction_typedef, PyMethodDef,
+    W_PyCMethodObject, W_PyCFunctionObject)
 from pypy.module.cpyext.modsupport import convert_method_defs
 from pypy.module.cpyext.pyobject import (
     PyObject, make_ref, create_ref, from_ref, get_typedescr, make_typedescr,
@@ -125,6 +126,14 @@
 cpython_struct("PyGetSetDescrObject", PyGetSetDescrObjectFields,
                PyGetSetDescrObjectStruct, level=2)
 
+PyMethodDescrObjectStruct = lltype.ForwardReference()
+PyMethodDescrObject = lltype.Ptr(PyMethodDescrObjectStruct)
+PyMethodDescrObjectFields = PyDescrObjectFields + (
+    ("d_method", lltype.Ptr(PyMethodDef)),
+    )
+cpython_struct("PyMethodDescrObject", PyMethodDescrObjectFields,
+               PyMethodDescrObjectStruct, level=2)
+
 @bootstrap_function
 def init_memberdescrobject(space):
     make_typedescr(W_MemberDescr.typedef,
@@ -136,6 +145,16 @@
                    basestruct=PyGetSetDescrObject.TO,
                    attach=getsetdescr_attach,
                    )
+    make_typedescr(W_PyCClassMethodObject.typedef,
+                   basestruct=PyMethodDescrObject.TO,
+                   attach=methoddescr_attach,
+                   realize=classmethoddescr_realize,
+                   )
+    make_typedescr(W_PyCMethodObject.typedef,
+                   basestruct=PyMethodDescrObject.TO,
+                   attach=methoddescr_attach,
+                   realize=methoddescr_realize,
+                   )
 
 def memberdescr_attach(space, py_obj, w_obj):
     """
@@ -166,6 +185,30 @@
     assert isinstance(w_obj, W_GetSetPropertyEx)
     py_getsetdescr.c_d_getset = w_obj.getset
 
+def methoddescr_attach(space, py_obj, w_obj):
+    py_methoddescr = rffi.cast(PyMethodDescrObject, py_obj)
+    # XXX assign to d_dname, d_type?
+    assert isinstance(w_obj, W_PyCFunctionObject)
+    py_methoddescr.c_d_method = w_obj.ml
+
+def classmethoddescr_realize(space, obj):
+    # XXX NOT TESTED When is this ever called? 
+    method = rffi.cast(lltype.Ptr(PyMethodDef), obj)
+    w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+    w_obj = space.allocate_instance(W_PyCClassMethodObject, w_type)
+    w_obj.__init__(space, method, w_type)
+    track_reference(space, obj, w_obj)
+    return w_obj
+
+def methoddescr_realize(space, obj):
+    # XXX NOT TESTED When is this ever called? 
+    method = rffi.cast(lltype.Ptr(PyMethodDef), obj)
+    w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+    w_obj = space.allocate_instance(W_PyCMethodObject, w_type)
+    w_obj.__init__(space, method, w_type)
+    track_reference(space, obj, w_obj)
+    return w_obj
+
 def convert_getset_defs(space, dict_w, getsets, w_type):
     getsets = rffi.cast(rffi.CArrayPtr(PyGetSetDef), getsets)
     if getsets:
diff --git a/pypy/module/cpyext/unicodeobject.py 
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -183,19 +183,19 @@
     """Get the maximum ordinal for a Unicode character."""
     return runicode.UNICHR(runicode.MAXUNICODE)
 
-@cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.CCHARP, error=CANNOT_FAIL)
 def PyUnicode_AS_DATA(space, ref):
     """Return a pointer to the internal buffer of the object. o has to be a
     PyUnicodeObject (not checked)."""
     return rffi.cast(rffi.CCHARP, PyUnicode_AS_UNICODE(space, ref))
 
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PyUnicode_GET_DATA_SIZE(space, w_obj):
     """Return the size of the object's internal buffer in bytes.  o has to be a
     PyUnicodeObject (not checked)."""
     return rffi.sizeof(lltype.UniChar) * PyUnicode_GET_SIZE(space, w_obj)
 
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
 def PyUnicode_GET_SIZE(space, w_obj):
     """Return the size of the object.  o has to be a PyUnicodeObject (not
     checked)."""
@@ -222,7 +222,7 @@
     ref_unicode = rffi.cast(PyUnicodeObject, ref)
     if not ref_unicode.c_buffer:
         # Copy unicode buffer
-        w_unicode = from_ref(space, ref)
+        w_unicode = from_ref(space, rffi.cast(PyObject, ref))
         u = space.unicode_w(w_unicode)
         ref_unicode.c_buffer = rffi.unicode2wcharp(u)
     return ref_unicode.c_buffer
@@ -235,7 +235,7 @@
     w_type = from_ref(space, rffi.cast(PyObject, ref.c_ob_type))
     if not space.is_true(space.issubtype(w_type, space.w_unicode)):
         raise oefmt(space.w_TypeError, "expected unicode object")
-    return PyUnicode_AS_UNICODE(space, ref)
+    return PyUnicode_AS_UNICODE(space, rffi.cast(rffi.VOIDP, ref))
 
 @cpython_api([PyObject], rffi.CCHARP)
 def _PyUnicode_AsString(space, ref):
@@ -267,8 +267,8 @@
     string may or may not be 0-terminated.  It is the responsibility of the 
caller
     to make sure that the wchar_t string is 0-terminated in case this is
     required by the application."""
-    c_buffer = PyUnicode_AS_UNICODE(space, ref)
     ref = rffi.cast(PyUnicodeObject, ref)
+    c_buffer = PyUnicode_AS_UNICODE(space, rffi.cast(rffi.VOIDP, ref))
     c_length = ref.c_length
 
     # If possible, try to copy the 0-termination as well
diff --git a/pypy/module/cpyext/weakrefobject.py 
b/pypy/module/cpyext/weakrefobject.py
--- a/pypy/module/cpyext/weakrefobject.py
+++ b/pypy/module/cpyext/weakrefobject.py
@@ -1,6 +1,7 @@
 from pypy.module.cpyext.api import cpython_api
 from pypy.module.cpyext.pyobject import PyObject
 from pypy.module._weakref.interp__weakref import W_Weakref, proxy
+from rpython.rtyper.lltypesystem import rffi
 
 @cpython_api([PyObject, PyObject], PyObject)
 def PyWeakref_NewRef(space, w_obj, w_callback):
@@ -37,7 +38,7 @@
     """
     return space.call_function(w_ref)     # borrowed ref
 
-@cpython_api([PyObject], PyObject, result_borrowed=True)
+@cpython_api([rffi.VOIDP], PyObject, result_borrowed=True)
 def PyWeakref_GET_OBJECT(space, w_ref):
     """Similar to PyWeakref_GetObject(), but implemented as a macro that does 
no
     error checking.
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -41,6 +41,14 @@
 
     return '.' + soabi + SO
 
+def log_pyverbose(space, level, message):
+    if space.sys.w_initialdict is None:
+        return # sys module not initialised, avoid recursion
+    verbose = space.sys.get_flag('verbose')
+    if verbose >= level:
+        w_stderr = space.sys.get('stderr')
+        space.call_method(w_stderr, "write", space.wrap(message))
+
 def has_so_extension(space):
     return (space.config.objspace.usemodules.cpyext or
             space.config.objspace.usemodules._cffi_backend)
@@ -354,6 +362,9 @@
     Load a module from a compiled file, execute it, and return its
     module object.
     """
+    log_pyverbose(space, 1, "import %s # compiled from %s\n" %
+                  (space.str_w(w_modulename), cpathname))
+
     if magic != get_pyc_magic(space):
         raise oefmt(space.w_ImportError, "Bad magic number in %s", cpathname)
     #print "loading pyc file:", cpathname
diff --git a/pypy/module/imp/test/support.py b/pypy/module/imp/test/support.py
--- a/pypy/module/imp/test/support.py
+++ b/pypy/module/imp/test/support.py
@@ -4,14 +4,57 @@
 
     def setup_class(cls):
         space = cls.space
-        testfn = u'test_tmp'
-        testfn_unencodable = None
+        cls.w_testfn_unencodable = space.wrap(get_unencodable())
+        cls.w_special_char = space.wrap(get_special_char())
 
-        if sys.platform == 'win32':
-            testfn_unencodable = testfn + u"-\u5171\u0141\u2661\u0363\uDC80"
-        elif sys.platform != 'darwin':
-            try:
-                '\xff'.decode(sys.getfilesystemencoding())
-            except UnicodeDecodeError:
-                testfn_unencodable = testfn + u'-\udcff'
-        cls.w_testfn_unencodable = space.wrap(testfn_unencodable)
+def get_unencodable():
+    """Copy of the stdlib's support.TESTFN_UNENCODABLE:
+
+    A filename (py3k str type) that should *not* be able to be encoded
+    by the filesystem encoding (in strict mode). It can be None if we
+    cannot generate such filename.
+    """
+    testfn_unencodable = None
+    testfn = u'test_tmp'
+
+    if sys.platform == 'win32':
+        testfn_unencodable = testfn + u"-\u5171\u0141\u2661\u0363\uDC80"
+    elif sys.platform != 'darwin':
+        try:
+            '\xff'.decode(sys.getfilesystemencoding())
+        except UnicodeDecodeError:
+            testfn_unencodable = testfn + u'-\udcff'
+    return testfn_unencodable
+
+def get_special_char():
+    """Copy of the stdlib's test_imp.test_issue5604 special_char:
+
+    A non-ascii filename (py3k str type) that *should* be able to be
+    encoded by the filesystem encoding (in strict mode). It can be None
+    if we cannot generate such filename.
+    """
+    fsenc = sys.getfilesystemencoding()
+    # covers utf-8 and Windows ANSI code pages one non-space symbol from
+    # every page (http://en.wikipedia.org/wiki/Code_page)
+    known_locales = {
+        'utf-8' : b'\xc3\xa4',
+        'cp1250' : b'\x8C',
+        'cp1251' : b'\xc0',
+        'cp1252' : b'\xc0',
+        'cp1253' : b'\xc1',
+        'cp1254' : b'\xc0',
+        'cp1255' : b'\xe0',
+        'cp1256' : b'\xe0',
+        'cp1257' : b'\xc0',
+        'cp1258' : b'\xc0',
+        }
+
+    if sys.platform == 'darwin':
+        # Mac OS X uses the Normal Form D decomposition
+        # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
+        special_char = b'a\xcc\x88'
+    else:
+        special_char = known_locales.get(fsenc)
+
+    if special_char:
+        return special_char.decode(fsenc)
diff --git a/pypy/module/imp/test/test_import.py 
b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -46,15 +46,13 @@
     if pkgname:
         p = p.join(*pkgname.split('.'))
     p.ensure(dir=1)
-    f = p.join("__init__.py").open('w')
-    print >> f, "# package"
-    f.close()
+    with p.join("__init__.py").open('w') as f:
+        print >> f, "# package"
     for filename, content in entries.items():
         filename += '.py'
-        f = p.join(filename).open('w')
-        print >> f, '#', filename
-        print >> f, content
-        f.close()
+        with p.join(filename).open('w') as f:
+            print >> f, '#', filename
+            print >> f, content
     return p
 
 def setup_directory_structure(cls):
@@ -123,6 +121,9 @@
         'a=5\nb=6\rc="""hello\r\nworld"""\r', mode='wb')
     p.join('mod.py').write(
         'a=15\nb=16\rc="""foo\r\nbar"""\r', mode='wb')
+    setuppkg("verbose1pkg", verbosemod='a = 1729')
+    setuppkg("verbose2pkg", verbosemod='a = 1729')
+    setuppkg("verbose0pkg", verbosemod='a = 1729')
     setuppkg("test_bytecode",
              a = '',
              b = '',
@@ -132,34 +133,11 @@
              line2 = "# encoding: iso-8859-1\n",
              bad = "# encoding: uft-8\n")
 
-    fsenc = sys.getfilesystemencoding()
-    # covers utf-8 and Windows ANSI code pages one non-space symbol from
-    # every page (http://en.wikipedia.org/wiki/Code_page)
-    known_locales = {
-        'utf-8' : b'\xc3\xa4',
-        'cp1250' : b'\x8C',
-        'cp1251' : b'\xc0',
-        'cp1252' : b'\xc0',
-        'cp1253' : b'\xc1',
-        'cp1254' : b'\xc0',
-        'cp1255' : b'\xe0',
-        'cp1256' : b'\xe0',
-        'cp1257' : b'\xc0',
-        'cp1258' : b'\xc0',
-        }
-
-    if sys.platform == 'darwin':
-        # Mac OS X uses the Normal Form D decomposition
-        # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
-        special_char = b'a\xcc\x88'
-    else:
-        special_char = known_locales.get(fsenc)
-
-    if special_char:
+    w_special_char = getattr(cls, 'w_special_char', None)
+    if not space.is_none(w_special_char):
+        special_char = space.unicode_w(w_special_char).encode(
+            sys.getfilesystemencoding())
         p.join(special_char + '.py').write('pass')
-        cls.w_special_char = space.wrap(special_char.decode(fsenc))
-    else:
-        cls.w_special_char = space.w_None
 
     # create a .pyw file
     p = setuppkg("windows", x = "x = 78")
@@ -588,9 +566,8 @@
         import test_reload
         import time, imp
         time.sleep(1)
-        f = open(test_reload.__file__, "w")
-        f.write("a = 10 // 0\n")
-        f.close()
+        with open(test_reload.__file__, "w") as f:
+            f.write("a = 10 // 0\n")
 
         # A failing reload should leave the previous module in sys.modules
         raises(ZeroDivisionError, imp.reload, test_reload)
@@ -733,7 +710,8 @@
         import pkg
         import os
         pathname = os.path.join(os.path.dirname(pkg.__file__), 'a.py')
-        module = imp.load_module('a', open(pathname),
+        with open(pathname) as fid:
+            module = imp.load_module('a', fid,
                                  'invalid_path_name', ('.py', 'r', 
imp.PY_SOURCE))
         assert module.__name__ == 'a'
         assert module.__file__ == 'invalid_path_name'
@@ -768,6 +746,68 @@
             else:
                 raise AssertionError("should have failed")
 
+    def test_verbose_flag_1(self):
+        output = []
+        class StdErr(object):
+            def write(self, line):
+                output.append(line)
+
+        import sys, imp
+        old_flags = sys.flags
+
+        class Flags(object):
+            verbose = 1
+            def __getattr__(self, name):
+                return getattr(old_flags, name)
+
+        sys.flags = Flags()
+        sys.stderr = StdErr()
+        try:
+            import verbose1pkg.verbosemod
+        finally:
+            imp.reload(sys)
+        assert 'import verbose1pkg # ' in output[-2]
+        assert 'import verbose1pkg.verbosemod # ' in output[-1]
+
+    def test_verbose_flag_2(self):
+        output = []
+        class StdErr(object):
+            def write(self, line):
+                output.append(line)
+
+        import sys, imp
+        old_flags = sys.flags
+
+        class Flags(object):
+            verbose = 2
+            def __getattr__(self, name):
+                return getattr(old_flags, name)
+
+        sys.flags = Flags()
+        sys.stderr = StdErr()
+        try:
+            import verbose2pkg.verbosemod
+        finally:
+            imp.reload(sys)
+        assert any('import verbose2pkg # ' in line
+                   for line in output[:-2])
+        assert output[-2].startswith('# trying')
+        assert 'import verbose2pkg.verbosemod # ' in output[-1]
+
+    def test_verbose_flag_0(self):
+        output = []
+        class StdErr(object):
+            def write(self, line):
+                output.append(line)
+
+        import sys, imp
+        sys.stderr = StdErr()
+        try:
+            import verbose0pkg.verbosemod
+        finally:
+            imp.reload(sys)
+        assert not output
+
     def test_source_encoding(self):
         import imp
         import encoded
@@ -781,9 +821,9 @@
         raises(SyntaxError, imp.find_module, 'bad', encoded.__path__)
 
     def test_find_module_fsdecode(self):
-        import sys
         name = self.special_char
         if not name:
+            import sys
             skip("can't run this test with %s as filesystem encoding"
                  % sys.getfilesystemencoding())
         import imp
diff --git a/pypy/module/zipimport/test/test_zipimport.py 
b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -349,14 +349,23 @@
         assert sys.path_hooks.count(zipimport.zipimporter) == 1
 
     def w__make_unicode_filename(self):
+        if not self.testfn_unencodable:
+            import sys
+            skip("can't run this test with %s as filesystem encoding"
+                 % sys.getfilesystemencoding())
         import os
         head, tail = os.path.split(self.zipfile)
-        self.zipfile = head + os.path.sep + tail[:4] + '_&#228;' + tail[4:]
+        self.zipfile = (head + os.path.sep + tail[:4] +
+                        self.testfn_unencodable + tail[4:])
 
     def test_unicode_filename_notfound(self):
+        if not self.special_char:
+            import sys
+            skip("can't run this test with %s as filesystem encoding"
+                 % sys.getfilesystemencoding())
         import zipimport
         raises(zipimport.ZipImportError,
-               zipimport.zipimporter, 'caf\xe9')
+               zipimport.zipimporter, self.special_char)
 
     def test_unicode_filename_invalid_zippath(self):
         import zipimport
diff --git a/pypy/objspace/std/test/test_typeobject.py 
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1071,6 +1071,16 @@
         class D(A, B):     # "best base" is A
             __slots__ = ("__weakref__",)
 
+    def test_slot_shadows_class_variable(self):
+        try:
+            class X:
+                __slots__ = ["foo"]
+                foo = None
+        except ValueError as e:
+            assert str(e) == "'foo' in __slots__ conflicts with class variable"
+        else:
+            assert False, "ValueError expected"
+
     def test_metaclass_calc(self):
         """
         # issue1294232: correct metaclass calculation
@@ -1318,15 +1328,6 @@
 
         assert b == 1
 
-    def test_slots_with_method_in_class(self):
-        # this works in cpython...
-        class A(object):
-            __slots__ = ["f"]
-            def f(self, x):
-                return x + 1
-        a = A()
-        assert a.f(1) == 2
-
     def test_eq_returns_notimplemented(self):
         assert type.__eq__(int, 42) is NotImplemented
         assert type.__ne__(dict, 42) is NotImplemented
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
@@ -1041,7 +1041,8 @@
                                 "__weakref__ slot disallowed: we already got 
one")
                 wantweakref = True
             else:
-                index_next_extra_slot = create_slot(w_self, slot_name,
+                index_next_extra_slot = create_slot(w_self, w_slot_name,
+                                                    slot_name,
                                                     index_next_extra_slot)
     wantdict = wantdict or hasoldstylebase
     if wantdict:
@@ -1057,13 +1058,17 @@
         return Layout(base_layout.typedef, index_next_extra_slot,
                       base_layout=base_layout)
 
-def create_slot(w_self, slot_name, index_next_extra_slot):
+def create_slot(w_self, w_slot_name, slot_name, index_next_extra_slot):
     space = w_self.space
     if not valid_slot_name(slot_name):
         raise oefmt(space.w_TypeError, "__slots__ must be identifiers")
     # create member
     slot_name = mangle(slot_name, w_self.name)
-    if slot_name not in w_self.dict_w:
+    if slot_name in w_self.dict_w:
+        raise oefmt(space.w_ValueError,
+                    "%R in __slots__ conflicts with class variable",
+                    w_slot_name)
+    else:
         # Force interning of slot names.
         slot_name = space.str_w(space.new_interned_str(slot_name))
         # in cpython it is ignored less, but we probably don't care
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -1,26 +1,33 @@
 # Edit these appropriately before running this script
 maj=5
 min=1
-rev=1
+rev=2
 branchname=release-$maj.x  # ==OR== release-$maj.$min.x
 tagname=release-$maj.$min.$rev  # ==OR== release-$maj.$min
 
+echo checking hg log -r $branchname
 hg log -r $branchname || exit 1
+echo checking hg log -r $tagname
 hg log -r $tagname || exit 1
 
 # This script will download latest builds from the buildmaster, rename the top
 # level directory, and repackage ready to be uploaded to bitbucket. It will 
also
 # download source, assuming a tag for the release already exists, and 
repackage them.
 # The script should be run in an empty directory, i.e. /tmp/release_xxx
-
 for plat in linux linux64 linux-armhf-raspbian linux-armhf-raring linux-armel 
osx64 s390x
   do
+    echo downloading package for $plat
     wget 
http://buildbot.pypy.org/nightly/$branchname/pypy-c-jit-latest-$plat.tar.bz2
     tar -xf pypy-c-jit-latest-$plat.tar.bz2
     rm pypy-c-jit-latest-$plat.tar.bz2
-    mv pypy-c-jit-*-$plat pypy-$maj.$min.$rev-$plat
-    tar --owner=root --group=root --numeric-owner -cvjf 
pypy-$maj.$min.$rev-$plat.tar.bz2 pypy-$maj.$min.$rev-$plat
-    rm -rf pypy-$maj.$min.$rev-$plat
+    plat_final=$plat
+    if [ $plat = linux ]; then
+        plat_final=linux32
+    fi
+    mv pypy-c-jit-*-$plat pypy-$maj.$min.$rev-$plat_final
+    echo packaging $plat_final
+    tar --owner=root --group=root --numeric-owner -cvjf 
pypy-$maj.$min.$rev-$plat_final.tar.bz2 pypy-$maj.$min.$rev-$plat_final
+    rm -rf pypy-$maj.$min.$rev-$plat_final
   done
 
 plat=win32
diff --git a/pypy/tool/test/test_tab.py b/pypy/tool/test/test_tab.py
--- a/pypy/tool/test/test_tab.py
+++ b/pypy/tool/test/test_tab.py
@@ -7,7 +7,11 @@
 
 ROOT = os.path.abspath(os.path.join(pypydir, '..'))
 RPYTHONDIR = os.path.join(ROOT, "rpython")
-EXCLUDE = {'/virt_test/lib/python2.7/site-packages/setuptools'}
+
+EXCLUDE = {'/virt_test'}
+# ^^^ don't look inside this: it is created by virtualenv on buildslaves.
+# It contains third-party installations that may include tabs in their
+# .py files.
 
 
 def test_no_tabs():
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -27,13 +27,13 @@
     """NOT_RPYTHON: set up rawrefcount with the GC.  This is only used
     for tests; it should not be called at all during translation.
     """
-    global _p_list, _o_list, _adr2pypy, _pypy2ob, _ob_set
+    global _p_list, _o_list, _adr2pypy, _pypy2ob, _pypy2ob_rev
     global _d_list, _dealloc_trigger_callback
     _p_list = []
     _o_list = []
     _adr2pypy = [None]
     _pypy2ob = {}
-    _ob_set = set()
+    _pypy2ob_rev = {}
     _d_list = []
     _dealloc_trigger_callback = dealloc_trigger_callback
 
@@ -41,23 +41,22 @@
     "NOT_RPYTHON: a link where the PyPy object contains some or all the data"
     #print 'create_link_pypy\n\t%s\n\t%s' % (p, ob)
     assert p not in _pypy2ob
-    assert ob._obj not in _ob_set
+    assert ob._obj not in _pypy2ob_rev
     assert not ob.c_ob_pypy_link
     ob.c_ob_pypy_link = _build_pypy_link(p)
     _pypy2ob[p] = ob
+    _pypy2ob_rev[ob._obj] = p
     _p_list.append(ob)
-    _ob_set.add(ob._obj)
 
 def create_link_pyobj(p, ob):
     """NOT_RPYTHON: a link where the PyObject contains all the data.
        from_obj() will not work on this 'p'."""
     #print 'create_link_pyobj\n\t%s\n\t%s' % (p, ob)
     assert p not in _pypy2ob
-    assert ob._obj not in _ob_set
+    assert ob._obj not in _pypy2ob_rev
     assert not ob.c_ob_pypy_link
     ob.c_ob_pypy_link = _build_pypy_link(p)
     _o_list.append(ob)
-    _ob_set.add(ob._obj)
 
 def from_obj(OB_PTR_TYPE, p):
     "NOT_RPYTHON"
@@ -65,6 +64,7 @@
     if ob is None:
         return lltype.nullptr(OB_PTR_TYPE.TO)
     assert lltype.typeOf(ob) == OB_PTR_TYPE
+    assert _pypy2ob_rev[ob._obj] is p
     return ob
 
 def to_obj(Class, ob):
@@ -111,8 +111,10 @@
             new_p_list.append(ob)
         else:
             p = detach(ob, wr_p_list)
-            del _pypy2ob[p]
-            del p
+            ob_test = _pypy2ob.pop(p)
+            p_test = _pypy2ob_rev.pop(ob_test._obj)
+            assert p_test is p
+            del p, p_test
         ob = None
     _p_list = Ellipsis
 
@@ -156,6 +158,10 @@
         p = attach(ob, wr, _p_list)
         if p is not None:
             _pypy2ob[p] = ob
+    _pypy2ob_rev.clear()       # rebuild this dict from scratch
+    for p, ob in _pypy2ob.items():
+        assert ob._obj not in _pypy2ob_rev
+        _pypy2ob_rev[ob._obj] = p
     _o_list = []
     for ob, wr in wr_o_list:
         attach(ob, wr, _o_list)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1045,15 +1045,23 @@
         win32traits = make_win32_traits(traits)
         path1 = traits.as_str0(path1)
         path2 = traits.as_str0(path2)
-        if not win32traits.MoveFile(path1, path2):
+        if not win32traits.MoveFileEx(path1, path2, 0):
             raise rwin32.lastSavedWindowsError()
 
 @specialize.argtype(0, 1)
 def replace(path1, path2):
-    if os.name == 'nt':
-        raise NotImplementedError(
-            'On windows, os.replace() should overwrite the destination')
-    return rename(path1, path2)
+    if _WIN32:
+        traits = _preferred_traits(path1)
+        win32traits = make_win32_traits(traits)
+        path1 = traits.as_str0(path1)
+        path2 = traits.as_str0(path2)
+        ret = win32traits.MoveFileEx(path1, path2,
+                     win32traits.MOVEFILE_REPLACE_EXISTING)
+        if not ret:
+            raise rwin32.lastSavedWindowsError()
+    else:
+        ret = rename(path1, path2)
+    return ret
 
 #___________________________________________________________________
 
diff --git a/rpython/rlib/rwin32file.py b/rpython/rlib/rwin32file.py
--- a/rpython/rlib/rwin32file.py
+++ b/rpython/rlib/rwin32file.py
@@ -45,6 +45,8 @@
             'INVALID_FILE_ATTRIBUTES')
         ERROR_SHARING_VIOLATION = platform.ConstantInteger(
             'ERROR_SHARING_VIOLATION')
+        MOVEFILE_REPLACE_EXISTING = platform.ConstantInteger(
+            'MOVEFILE_REPLACE_EXISTING')
         _S_IFDIR = platform.ConstantInteger('_S_IFDIR')
         _S_IFREG = platform.ConstantInteger('_S_IFREG')
         _S_IFCHR = platform.ConstantInteger('_S_IFCHR')
@@ -103,7 +105,7 @@
                        FILE_WRITE_ATTRIBUTES OPEN_EXISTING 
FILE_FLAG_BACKUP_SEMANTICS
                        VOLUME_NAME_DOS VOLUME_NAME_NT
                        ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES
-                       ERROR_SHARING_VIOLATION
+                       ERROR_SHARING_VIOLATION MOVEFILE_REPLACE_EXISTING
                     '''.split():
             locals()[name] = config[name]
         LPWIN32_FIND_DATA    = lltype.Ptr(WIN32_FIND_DATA)
@@ -199,9 +201,9 @@
             rwin32.BOOL,
             save_err=rffi.RFFI_SAVE_LASTERROR)
 
-        MoveFile = external(
-            'MoveFile' + suffix,
-            [traits.CCHARP, traits.CCHARP],
+        MoveFileEx = external(
+            'MoveFileEx' + suffix,
+            [traits.CCHARP, traits.CCHARP, rwin32.DWORD],
             rwin32.BOOL,
             save_err=rffi.RFFI_SAVE_LASTERROR)
 
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -334,6 +334,11 @@
             self.path  = UnicodeWithEncoding(self.ufilename)
             self.path2 = UnicodeWithEncoding(self.ufilename + ".new")
 
+    def _teardown_method(self, method):
+        for path in [self.ufilename + ".new", self.ufilename]:
+            if os.path.exists(path):
+                os.unlink(path)
+
     def test_open(self):
         def f():
             try:
@@ -390,6 +395,14 @@
         assert not os.path.exists(self.ufilename)
         assert os.path.exists(self.ufilename + '.new')
 
+    def test_replace(self):
+        def f():
+            return rposix.replace(self.path, self.path2)
+
+        interpret(f, [])
+        assert not os.path.exists(self.ufilename)
+        assert os.path.exists(self.ufilename + '.new')
+
     def test_listdir(self):
         udir = UnicodeWithEncoding(os.path.dirname(self.ufilename))
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to