aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2019-04-14 13:17:25 +0300
committerMatti Picus <matti.picus@gmail.com>2019-04-14 13:17:25 +0300
commitad4624feefdfa2583efe6fcc07d6a62c53a64274 (patch)
tree90219d386df65a62327bd7eddd4534e1c344070c
parentupdate version to 7.1.1 (diff)
parentMerged heads. (diff)
downloadpypy-ad4624feefdfa2583efe6fcc07d6a62c53a64274.tar.gz
pypy-ad4624feefdfa2583efe6fcc07d6a62c53a64274.tar.bz2
pypy-ad4624feefdfa2583efe6fcc07d6a62c53a64274.zip
merge py3.6 into releaserelease-pypy3.6-v7.1.1
-rw-r--r--lib_pypy/_overlapped.py612
-rw-r--r--lib_pypy/_pypy_winbase_build.py162
-rw-r--r--lib_pypy/_pypy_winbase_cffi.py8
-rw-r--r--lib_pypy/_winapi.py80
-rw-r--r--lib_pypy/cffi.egg-info/PKG-INFO2
-rw-r--r--lib_pypy/cffi/__init__.py4
-rw-r--r--lib_pypy/cffi/_embedding.h2
-rw-r--r--pypy/doc/release-v7.1.1.rst96
-rw-r--r--pypy/doc/whatsnew-pypy3-head.rst5
-rw-r--r--pypy/interpreter/baseobjspace.py7
-rw-r--r--pypy/module/__pypy__/test/test_special.py2
-rw-r--r--pypy/module/_cffi_backend/__init__.py2
-rw-r--r--pypy/module/_cffi_backend/test/_backend_test_c.py2
-rw-r--r--pypy/module/array/interp_array.py12
-rw-r--r--pypy/module/array/test/test_array.py8
-rw-r--r--pypy/objspace/std/dictmultiobject.py7
-rw-r--r--pypy/objspace/std/listobject.py26
-rw-r--r--pypy/objspace/std/objspace.py14
-rw-r--r--pypy/objspace/std/setobject.py22
-rw-r--r--pypy/objspace/std/test/test_dictmultiobject.py2
-rw-r--r--pypy/objspace/std/test/test_listobject.py4
-rw-r--r--pypy/objspace/std/test/test_liststrategies.py36
-rw-r--r--pypy/objspace/std/test/test_setobject.py10
-rw-r--r--pypy/objspace/std/test/test_setstrategies.py8
-rw-r--r--pypy/objspace/std/test/test_stdobjspace.py11
-rw-r--r--pypy/objspace/std/test/test_unicodeobject.py10
-rw-r--r--pypy/objspace/std/typeobject.py8
-rw-r--r--pypy/objspace/std/unicodeobject.py27
28 files changed, 1058 insertions, 131 deletions
diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py
new file mode 100644
index 0000000000..61d4cc5f89
--- /dev/null
+++ b/lib_pypy/_overlapped.py
@@ -0,0 +1,612 @@
+"""
+Support routines for overlapping io.
+Currently, this extension module is only required when using the
+modules on Windows.
+"""
+
+import sys
+if sys.platform != 'win32':
+ raise ImportError("The '_overlapped' module is only available on Windows")
+
+# Declare external Win32 functions
+
+from _pypy_winbase_cffi import ffi as _ffi
+_kernel32 = _ffi.dlopen('kernel32')
+
+_winsock2 = _ffi.dlopen('Ws2_32')
+
+_mswsock = _ffi.dlopen('Mswsock')
+
+GetVersion = _kernel32.GetVersion
+NULL = _ffi.NULL
+
+from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr
+import _winapi
+
+#
+# Error Codes
+#
+ERROR_IO_PENDING = 997
+ERROR_PIPE_BUSY = 231
+ERROR_NETNAME_DELETED = 64
+
+SOCKET_ERROR = -1
+
+AF_INET = 2
+AF_INET6 = 23
+
+SOCK_STREAM = 1
+IPPROTO_TCP = 6
+
+INVALID_SOCKET = -1
+
+IOC_OUT = 0x40000000
+IOC_IN = 0x80000000
+IOC_INOUT = IOC_IN | IOC_OUT
+IOC_WS2 = 0x08000000
+
+def _WSAIORW(x, y):
+ return IOC_INOUT | x | y
+
+WSAID_ACCEPTEX = _ffi.new("GUID[1]")
+WSAID_ACCEPTEX[0].Data1 = 0xb5367df1
+WSAID_ACCEPTEX[0].Data2 = 0xcbac
+WSAID_ACCEPTEX[0].Data3 = 0x11cf
+WSAID_ACCEPTEX[0].Data4 = [0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92]
+
+
+WSAID_CONNECTEX = _ffi.new("GUID[1]")
+WSAID_CONNECTEX[0].Data1 = 0x25a207b9
+WSAID_CONNECTEX[0].Data2 = 0xddf3
+WSAID_CONNECTEX[0].Data3 = 0x4660
+WSAID_CONNECTEX[0].Data4 = [0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e]
+
+WSAID_DISCONNECTEX = _ffi.new("GUID[1]")
+WSAID_DISCONNECTEX[0].Data1 = 0x7fda2e11
+WSAID_DISCONNECTEX[0].Data2 = 0x8630
+WSAID_DISCONNECTEX[0].Data3 = 0x436f
+WSAID_DISCONNECTEX[0].Data4 = [0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57]
+
+SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6)
+
+SO_UPDATE_ACCEPT_CONTEXT = 0x700B
+SO_UPDATE_CONNECT_CONTEXT = 0x7010
+INADDR_ANY = 0x00000000
+in6addr_any = _ffi.new("struct in6_addr[1]")
+
+# Status Codes
+STATUS_PENDING = 0x00000103
+
+
+def _int2intptr(int2cast):
+ return _ffi.cast("ULONG_PTR", int2cast)
+
+def _int2dword(int2cast):
+ return _ffi.cast("DWORD", int2cast)
+
+def _int2handle(val):
+ return _ffi.cast("HANDLE", val)
+
+def _int2overlappedptr(val):
+ return _ffi.cast("OVERLAPPED*", val)
+
+def _handle2int(handle):
+ return int(_ffi.cast("intptr_t", handle))
+
+from enum import Enum
+class OverlappedType(Enum):
+ TYPE_NONE = 0
+ TYPE_NOT_STARTED = 1
+ TYPE_READ = 2
+ TYPE_READINTO = 3
+ TYPE_WRITE = 4
+ TYPE_ACCEPT = 5
+ TYPE_CONNECT = 6
+ TYPE_DISCONNECT = 7
+ TYPE_CONNECT_NAMED_PIPE = 8
+ TYPE_WAIT_NAMED_PIPE_AND_CONNECT = 9
+ TYPE_TRANSMIT_FILE = 10
+
+_accept_ex = _ffi.new("AcceptExPtr*")
+_connect_ex = _ffi.new("ConnectExPtr*")
+_disconnect_ex = _ffi.new("DisconnectExPtr*")
+
+
+def initiailize_function_ptrs():
+ ## importing socket ensures that WSAStartup() is called
+ import _socket
+ s = _winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
+ dwBytes = _ffi.new("DWORD[1]", [0])
+ if s == INVALID_SOCKET:
+ raise _winapi._WinError()
+
+ result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \
+ WSAID_ACCEPTEX, _ffi.sizeof(WSAID_ACCEPTEX[0]), _accept_ex, \
+ _ffi.sizeof(_accept_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL)
+ if result == INVALID_SOCKET:
+ _winsock2.closesocket(s)
+ raise _winapi._WinError()
+
+ result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \
+ WSAID_CONNECTEX, _ffi.sizeof(WSAID_CONNECTEX[0]), _connect_ex, \
+ _ffi.sizeof(_connect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL)
+ if result == INVALID_SOCKET:
+ _winsock2.closesocket(s)
+ raise _winapi._WinError()
+
+ result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \
+ WSAID_DISCONNECTEX, _ffi.sizeof(WSAID_DISCONNECTEX[0]), _disconnect_ex, \
+ _ffi.sizeof(_disconnect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL)
+
+ _winsock2.closesocket(s)
+ if result == INVALID_SOCKET:
+ raise _winapi._WinError()
+
+
+initiailize_function_ptrs()
+
+
+class Overlapped(object):
+ def __init__(self, event=_ffi.NULL):
+ self.overlapped = _ffi.new('OVERLAPPED[1]')
+ self.handle = _ffi.NULL
+ self.read_buffer = None
+ self.write_buffer = None
+ self.error = 0
+
+ self.type = OverlappedType.TYPE_NONE
+ if event == _int2handle(INVALID_HANDLE_VALUE) or not event:
+ event = _kernel32.CreateEventW(NULL, True, False, NULL)
+ if event == _winapi.NULL:
+ raise _winapi._WinError()
+
+ if event:
+ self.overlapped[0].hEvent = event
+ else:
+ raise _winapi._WinError()
+
+ if self.overlapped[0].hEvent == _ffi.NULL:
+ raise _winapi._WinError()
+
+ def __del__(self):
+ bytes = _ffi.new("DWORD[1]",[0])
+ olderr = _kernel32.GetLastError()
+ hascompletedio = HasOverlappedIoCompleted(self.overlapped[0])
+ if not hascompletedio and self.type != OverlappedType.TYPE_NOT_STARTED:
+
+ wait = _kernel32.CancelIoEx(self.handle, self.overlapped)
+ ret = self.GetOverlappedResult(wait)
+ err = _winapi.ERROR_SUCCESS
+ if not ret:
+ err = _kernel32.GetLastError()
+ self.error = err
+ if err != _winapi.ERROR_SUCCESS and \
+ err != _winapi.ERROR_NOT_FOUND and \
+ err != _winapi.ERROR_OPERATION_ABORTED:
+ SetFromWindowsErr(err)
+ if self.overlapped[0].hEvent != 0:
+ _winapi.CloseHandle(self.overlapped[0].hEvent)
+
+ @property
+ def event(self):
+ return self.overlapped[0].hEvent
+
+ def GetOverlappedResult(self, wait):
+ transferred = _ffi.new('DWORD[1]', [0])
+
+ if self.type == OverlappedType.TYPE_NONE:
+ return _ffi.NULL
+
+ if self.type == OverlappedType.TYPE_NOT_STARTED:
+ return _ffi.NULL
+
+ res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0)
+ if res:
+ err = _winapi.ERROR_SUCCESS
+ else:
+ err = _kernel32.GetLastError()
+ self.error = err
+
+ if err != _winapi.ERROR_SUCCESS and err != _winapi.ERROR_MORE_DATA:
+ if not (err == _winapi.ERROR_BROKEN_PIPE and (self.type in [OverlappedType.TYPE_READ, OverlappedType.TYPE_READINTO])):
+ SetFromWindowsErr(err)
+
+ if self.type == OverlappedType.TYPE_READ:
+ return _ffi.unpack(self.read_buffer, transferred[0])
+ else:
+ return transferred[0]
+
+ def getbuffer(self):
+ xxx
+ return None
+
+ def cancel(self):
+ result = True
+ if self.type == OverlappedType.TYPE_NOT_STARTED or self.type == OverlappedType.TYPE_WAIT_NAMED_PIPE_AND_CONNECT:
+ return None
+ if not HasOverlappedIoCompleted(self.overlapped[0]):
+ ### If we are to support xp we will need to dynamically load the below method
+ result = _kernel32.CancelIoEx(self.handle, self.overlapped)
+ if (not result and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND):
+ SetFromWindowsErr(0)
+
+ def WSARecv(self ,handle, size, flags):
+ handle = _int2handle(handle)
+ flags = _int2dword(flags)
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+
+ self.type = OverlappedType.TYPE_READ
+ self.handle = _int2handle(handle)
+ self.read_buffer = _ffi.new("CHAR[]", max(1,size))
+ return self.do_WSARecv(handle, self.read_buffer, size, flags)
+
+ def do_WSARecv(self, handle, allocatedbuffer, size, flags):
+ nread = _ffi.new("LPDWORD")
+ wsabuff = _ffi.new("WSABUF[1]")
+ buffercount = _ffi.new("DWORD[1]", [1])
+ pflags = _ffi.new("LPDWORD")
+ pflags[0] = flags
+
+ wsabuff[0].len = size
+ wsabuff[0].buf = allocatedbuffer
+
+ result = _winsock2.WSARecv(handle, wsabuff, _int2dword(1), nread, pflags, self.overlapped, _ffi.NULL)
+ if result == SOCKET_ERROR:
+ self.error = _kernel32.GetLastError()
+ else:
+ self.error = _winapi.ERROR_SUCCESS
+
+ if self.error == _winapi.ERROR_BROKEN_PIPE:
+ mark_as_completed(self.overlapped)
+ SetFromWindowsErr(self.error)
+ elif self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING] :
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(self.error)
+
+ def WSASend(self ,handle, bufobj, flags):
+ handle = _int2handle(handle)
+
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+ self.write_buffer = bufobj
+ self.type = OverlappedType.TYPE_WRITE
+ self.handle = handle
+
+ wsabuff = _ffi.new("WSABUF[1]")
+ wsabuff[0].len = len(bufobj)
+ wsabuff[0].buf = _ffi.new("CHAR[]", bufobj)
+ nwritten = _ffi.new("LPDWORD")
+
+ result = _winsock2.WSASend(handle, wsabuff, _int2dword(1), nwritten, flags, self.overlapped, _ffi.NULL)
+
+ if result == SOCKET_ERROR:
+ self.error = _kernel32.GetLastError()
+ else:
+ self.error = _winapi.ERROR_SUCCESS
+
+ if self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_IO_PENDING]:
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(self.error)
+
+ def getresult(self, wait=False):
+ return self.GetOverlappedResult(wait)
+
+ def ConnectNamedPipe(self, handle):
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+ self.type = OverlappedType.TYPE_CONNECT_NAMED_PIPE
+ self.handle = _int2handle(handle)
+ success = _kernel32.ConnectNamedPipe(self.handle, self.overlapped)
+
+ if success:
+ err = _winapi.ERROR_SUCCESS
+ else:
+ err = _kernel32.GetLastError()
+ self.error = err
+
+ if err == _winapi.ERROR_IO_PENDING | _winapi.ERROR_SUCCESS:
+ return False
+ elif err == _winapi.ERROR_PIPE_CONNECTED:
+ mark_as_completed(self.overlapped)
+ return True
+ else:
+ SetFromWindowsErr(err)
+
+ def ReadFile(self, handle, size):
+ self.type = OverlappedType.TYPE_READ
+ self.handle = _int2handle(handle)
+ self.read_buffer = _ffi.new("CHAR[]", max(1,size))
+ return self.do_ReadFile(self.handle, self.read_buffer, size)
+
+ def do_ReadFile(self, handle, buf, size):
+ nread = _ffi.new('DWORD[1]', [0])
+ ret = _kernel32.ReadFile(handle, buf, size, nread, self.overlapped)
+ if ret:
+ err = _winapi.ERROR_SUCCESS
+ else:
+ err = _kernel32.GetLastError()
+
+ self.error = err
+
+ if err == _winapi.ERROR_BROKEN_PIPE:
+ mark_as_completed(self.overlapped)
+ SetFromWindowsErr(err)
+ elif err in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING]:
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(err)
+
+ def WriteFile(self, handle, buffer):
+ self.handle = _int2handle(handle)
+ self.write_buffer = buffer
+ written = _ffi.new('DWORD[1]', [0])
+
+ # Check if we have already performed some IO
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+
+ self.type = OverlappedType.TYPE_WRITE
+
+ ret = _kernel32.WriteFile(self.handle, self.write_buffer, len(self.write_buffer), written, self.overlapped)
+
+ if ret:
+ self.error = _winapi.ERROR_SUCCESS
+ else:
+ self.error = _kernel32.GetLastError()
+
+ if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING:
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(self.error)
+
+ def AcceptEx(self, listensocket, acceptsocket):
+ listensocket = _int2handle(listensocket)
+ acceptsocket = _int2handle(acceptsocket)
+ bytesreceived = _ffi.new("DWORD[1]")
+
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+
+ size = _ffi.sizeof("struct sockaddr_in6") + 16
+ buf = _ffi.new("CHAR[]", size*2)
+ if not buf:
+ return None
+
+ self.type = OverlappedType.TYPE_ACCEPT
+ self.handle = listensocket
+ self.read_buffer = buf
+
+ res = _accept_ex[0](listensocket, acceptsocket, buf, \
+ 0, size, size, bytesreceived, self.overlapped)
+
+ if res:
+ self.error = _winapi.ERROR_SUCCESS
+ else:
+ self.error = _kernel32.GetLastError()
+
+ if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING:
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(0)
+
+ def DisconnectEx(self, socket, flags):
+ xxx
+ return None
+
+ def ConnectEx(self, socket, addressobj):
+ socket = _int2handle(socket)
+
+ if self.type != OverlappedType.TYPE_NONE:
+ raise _winapi._WinError()
+
+ address = _ffi.new("struct sockaddr_in6*")
+ length = _ffi.sizeof("struct sockaddr_in6")
+
+ address, length = parse_address(addressobj, _ffi.cast("SOCKADDR*",address), length)
+
+ if length < 0:
+ return None
+
+ self.type = OverlappedType.TYPE_CONNECT
+ self.handle = socket
+
+ res = _connect_ex[0](socket, address, length, \
+ _ffi.NULL, 0, _ffi.NULL, self.overlapped)
+
+ if res:
+ self.error = _winapi.ERROR_SUCCESS
+ else:
+ self.error = _kernel32.GetLastError()
+
+ if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING:
+ return None
+ else:
+ self.type = OverlappedType.TYPE_NOT_STARTED
+ SetFromWindowsErr(0)
+
+ @property
+ def pending(self):
+ return (not HasOverlappedIoCompleted(self.overlapped[0]) and
+ self.type != OverlappedType.TYPE_NOT_STARTED)
+
+ @property
+ def address(self):
+ return _handle2int(self.overlapped)
+
+def SetEvent(handle):
+ ret = _kernel32.SetEvent(_int2handle(handle))
+ if not ret:
+ raise _winapi._WinError()
+
+def mark_as_completed(overlapped):
+ overlapped[0].Internal = 0
+ if overlapped[0].hEvent != _ffi.NULL:
+ SetEvent(overlapped[0].hEvent)
+
+def CreateEvent(eventattributes, manualreset, initialstate, name):
+ event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name))
+ event = _handle2int(event)
+ if not event:
+ raise _winapi._WinError()
+ return event
+
+def CreateIoCompletionPort(handle, existingcompletionport, completionkey, numberofconcurrentthreads):
+ completionkey = _int2intptr(completionkey)
+ existingcompletionport = _int2handle(existingcompletionport)
+ numberofconcurrentthreads = _int2dword(numberofconcurrentthreads)
+ handle = _int2handle(handle)
+ result = _kernel32.CreateIoCompletionPort(handle,
+ existingcompletionport,
+ completionkey,
+ numberofconcurrentthreads)
+ if result == _ffi.NULL:
+ raise SetFromWindowsErr(0)
+ return _handle2int(result)
+
+def PostQueuedCompletionStatus(completionport, ms):
+ raise _winapi._WinError()
+
+def GetQueuedCompletionStatus(completionport, milliseconds):
+ numberofbytes = _ffi.new('DWORD[1]', [0])
+ completionkey = _ffi.new('ULONG**')
+ completionport = _int2handle(completionport)
+
+ if completionport is None:
+ raise _winapi._WinError()
+ overlapped = _ffi.new("OVERLAPPED**")
+ overlapped[0] = _ffi.NULL
+ result = _kernel32.GetQueuedCompletionStatus(completionport,
+ numberofbytes,
+ completionkey,
+ overlapped,
+ milliseconds)
+ if result:
+ err = _winapi.ERROR_SUCCESS
+ else:
+ err = _kernel32.GetLastError()
+
+ if overlapped[0] == _ffi.NULL:
+ if err == _winapi.WAIT_TIMEOUT:
+ return None
+ return SetFromWindowsErr(err)
+
+ return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0])))
+
+@_ffi.callback("void(void*, int)")
+def post_to_queue_callback(lpparameter, timerorwaitfired):
+ pdata = _ffi.cast("PostCallbackData*", lpparameter)
+ ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped)
+ result = False
+ _winapi.free(pdata)
+
+
+def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds):
+ data = _ffi.cast('PostCallbackData*', _winapi.malloc( _ffi.sizeof("PostCallbackData")))
+ newwaitobject = _ffi.new("HANDLE*")
+ data[0].hCompletionPort = _int2handle(completionport)
+ data[0].Overlapped = _int2overlappedptr(ovaddress)
+ ret = _kernel32.RegisterWaitForSingleObject(newwaitobject,
+ _int2handle(object),
+ _ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback),
+ data,
+ miliseconds,
+ _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE)
+ if not ret:
+ SetFromWindowsErr(0)
+
+ return _handle2int(newwaitobject[0])
+
+def ConnectPipe(address):
+ err = _winapi.ERROR_PIPE_BUSY
+ waddress = _ffi.new("wchar_t[]", address)
+ handle = _kernel32.CreateFileW(waddress,
+ _winapi.GENERIC_READ | _winapi.GENERIC_WRITE,
+ 0,
+ _ffi.NULL,
+ _winapi.OPEN_EXISTING,
+ _winapi.FILE_FLAG_OVERLAPPED,
+ _ffi.NULL)
+ err = _kernel32.GetLastError()
+
+ if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY:
+ SetFromWindowsErr(err)
+
+ return _handle2int(handle)
+
+def UnregisterWaitEx(handle, event):
+ waithandle = _int2handle(handle)
+ waitevent = _int2handle(event)
+
+ ret = _kernel32.UnregisterWaitEx(waithandle, waitevent)
+
+ if not ret:
+ SetFromWindowsErr(0)
+
+def UnregisterWait(handle):
+ handle = _int2handle(handle)
+
+ ret = _kernel32.UnregisterWait(handle)
+
+ if not ret:
+ SetFromWindowsErr(0)
+
+def BindLocal(socket, family):
+ socket = _int2handle(socket)
+ if family == AF_INET:
+ addr = _ffi.new("struct sockaddr_in*")
+ addr[0].sin_family = AF_INET
+ addr[0].sin_port = 0
+ addr[0].sin_addr.S_un.S_addr = INADDR_ANY
+ paddr = _ffi.cast("PSOCKADDR", addr)
+ result = _winsock2.bind(socket, paddr, _ffi.sizeof("struct sockaddr_in"))
+ elif family == AF_INET6:
+ addr = _ffi.new("struct sockaddr_in6*")
+ addr.sin6_family = AF_INET6
+ addr.sin6_port = 0
+ addr.sin6_addr = in6addr_any[0]
+ result = _winsock2.bind(socket, _ffi.cast("PSOCKADDR", addr), _ffi.sizeof("struct sockaddr_in"))
+ else:
+ raise ValueError()
+
+ if result == SOCKET_ERROR:
+ SetFromWindowsErr(0)
+
+def HasOverlappedIoCompleted(overlapped):
+ return (overlapped.Internal != STATUS_PENDING)
+
+def parse_address(addressobj, address, length):
+ lengthptr = _ffi.new("INT*")
+ lengthptr[0] = length
+ if len(addressobj) == 2:
+ host,port = addressobj
+ address[0].sa_family = AF_INET
+ result = _winsock2.WSAStringToAddressW(host, AF_INET, _ffi.NULL, address, lengthptr)
+ if result < 0:
+ raise _winapi.WinError()
+ _ffi.cast("SOCKADDR_IN*",address)[0].sin_port = _winsock2.htons(port)
+ return address, lengthptr[0]
+ elif len(addressobj) == 4:
+ host, port, flowinfo, scopeid = addressobj
+ address.sa_family = AF_INET6
+ result = _winsock2.WSAStringToAddressW(host, AF_INET6, _ffi.NULL, address, lengthptr)
+ address.sin6_port = _winsock2.htons(port)
+ address.sin6_flowinfo = flowinfo
+ address.sin6_scopeid = scopeid
+ return address, lengthptr[0]
+ else:
+ return -1
+
+
+
+
+
+
+
diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py
index e6022632fc..3391585157 100644
--- a/lib_pypy/_pypy_winbase_build.py
+++ b/lib_pypy/_pypy_winbase_build.py
@@ -90,7 +90,6 @@ typedef struct _OVERLAPPED {
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
-
DWORD WINAPI GetVersion(void);
BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD);
HANDLE WINAPI CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD,
@@ -101,16 +100,17 @@ HANDLE WINAPI CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
DWORD, DWORD, HANDLE);
HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
DWORD, DWORD, HANDLE);
+BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD);
BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED);
HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR);
HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR);
-VOID WINAPI SetEvent(HANDLE);
+BOOL WINAPI SetEvent(HANDLE);
+BOOL WINAPI CancelIo(HANDLE);
BOOL WINAPI CancelIoEx(HANDLE, LPOVERLAPPED);
BOOL WINAPI CloseHandle(HANDLE);
DWORD WINAPI GetLastError(VOID);
BOOL WINAPI GetOverlappedResult(HANDLE, LPOVERLAPPED, LPDWORD, BOOL);
-
HANDLE WINAPI GetCurrentProcess(void);
BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE,
DWORD, BOOL, DWORD);
@@ -121,19 +121,171 @@ BOOL WINAPI CreateProcessW(wchar_t *, wchar_t *, void *,
void *, BOOL, DWORD, wchar_t *,
wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION);
DWORD WINAPI WaitForSingleObject(HANDLE, DWORD);
+DWORD WaitForMultipleObjects(DWORD, HANDLE*, BOOL, DWORD);
BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD);
BOOL WINAPI TerminateProcess(HANDLE, UINT);
HANDLE WINAPI GetStdHandle(DWORD);
DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD);
-
UINT WINAPI SetErrorMode(UINT);
#define SEM_FAILCRITICALERRORS 0x0001
#define SEM_NOGPFAULTERRORBOX 0x0002
#define SEM_NOALIGNMENTFAULTEXCEPT 0x0004
#define SEM_NOOPENFILEERRORBOX 0x8000
+
+typedef struct _PostCallbackData {
+ HANDLE hCompletionPort;
+ LPOVERLAPPED Overlapped;
+} PostCallbackData, *LPPostCallbackData;
+
+typedef VOID (WINAPI *WAITORTIMERCALLBACK) (PVOID, BOOL);
+BOOL WINAPI RegisterWaitForSingleObject(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG);
+
+BOOL WINAPI PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED);
+BOOL WINAPI UnregisterWaitEx(HANDLE, HANDLE);
+BOOL WINAPI UnregisterWait(HANDLE);
+
+BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, DWORD);
+HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD);
+
+BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
+
+#define WT_EXECUTEINWAITTHREAD 0x00000004
+#define WT_EXECUTEONLYONCE 0x00000008
+
+HANDLE GetProcessHeap();
+LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T);
+BOOL HeapFree(HANDLE, DWORD, LPVOID);
+
""")
-# --------------------
+# -------------------- Win Sock 2 ----------------------
+
+ffi.cdef("""
+typedef struct _WSABUF {
+ ULONG len;
+ CHAR *buf;
+} WSABUF, *LPWSABUF;
+
+typedef HANDLE SOCKET;
+SOCKET __stdcall socket(int, int, int);
+int closesocket(SOCKET);
+
+
+typedef BOOL (__stdcall * LPFN_DISCONNECTEX) (SOCKET, LPOVERLAPPED, DWORD, DWORD);
+typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPVOID);
+
+int __stdcall WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
+int __stdcall WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
+int __stdcall WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
+
+
+typedef struct _GUID {
+ DWORD Data1;
+ WORD Data2;
+ WORD Data3;
+ BYTE Data4[8];
+} GUID;
+
+typedef USHORT ADDRESS_FAMILY;
+
+typedef struct in6_addr {
+ union {
+ UCHAR Byte[16];
+ USHORT Word[8];
+ } u;
+} IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR;
+
+typedef struct {
+ union {
+ struct {
+ ULONG Zone : 28;
+ ULONG Level : 4;
+ };
+ ULONG Value;
+ };
+} SCOPE_ID, *PSCOPE_ID;
+
+typedef struct sockaddr_in6 {
+ ADDRESS_FAMILY sin6_family;
+ USHORT sin6_port;
+ ULONG sin6_flowinfo;
+ IN6_ADDR sin6_addr;
+ union {
+ ULONG sin6_scope_id;
+ SCOPE_ID sin6_scope_struct;
+ };
+} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH;
+
+typedef struct in_addr {
+ union {
+ struct {
+ UCHAR s_b1;
+ UCHAR s_b2;
+ UCHAR s_b3;
+ UCHAR s_b4;
+ } S_un_b;
+ struct {
+ USHORT s_w1;
+ USHORT s_w2;
+ } S_un_w;
+ ULONG S_addr;
+ } S_un;
+} INADDR, *PINADDR;
+
+typedef struct sockaddr_in {
+ SHORT sin_family;
+ USHORT sin_port;
+ INADDR sin_addr;
+ CHAR sin_zero[8];
+} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN;
+
+typedef struct sockaddr {
+ USHORT sa_family;
+ CHAR sa_data[14];
+} SOCKADDR, *PSOCKADDR, *LPSOCKADDR;
+
+int bind(SOCKET, const PSOCKADDR, int);
+
+#define MAX_PROTOCOL_CHAIN 7
+
+typedef struct _WSAPROTOCOLCHAIN {
+ int ChainLen;
+ DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
+} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN;
+
+#define WSAPROTOCOL_LEN 255
+
+typedef struct _WSAPROTOCOL_INFOW {
+ DWORD dwServiceFlags1;
+ DWORD dwServiceFlags2;
+ DWORD dwServiceFlags3;
+ DWORD dwServiceFlags4;
+ DWORD dwProviderFlags;
+ GUID ProviderId;
+ DWORD dwCatalogEntryId;
+ WSAPROTOCOLCHAIN ProtocolChain;
+ int iVersion;
+ int iAddressFamily;
+ int iMaxSockAddr;
+ int iMinSockAddr;
+ int iSocketType;
+ int iProtocol;
+ int iProtocolMaxOffset;
+ int iNetworkByteOrder;
+ int iSecurityScheme;
+ DWORD dwMessageSize;
+ DWORD dwProviderReserved;
+ WCHAR szProtocol[WSAPROTOCOL_LEN + 1];
+} WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW;
+
+int __stdcall WSAStringToAddressW(LPWSTR, int, LPWSAPROTOCOL_INFOW, LPSOCKADDR, int* );
+
+typedef BOOL (WINAPI* AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED);
+typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const PSOCKADDR, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED);
+typedef BOOL (WINAPI *DisconnectExPtr)(SOCKET, LPOVERLAPPED, DWORD, DWORD);
+
+USHORT htons(USHORT);
+""")
if __name__ == "__main__":
ffi.compile()
diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py
index 2e7f083c02..fe348304f6 100644
--- a/lib_pypy/_pypy_winbase_cffi.py
+++ b/lib_pypy/_pypy_winbase_cffi.py
@@ -3,8 +3,8 @@ import _cffi_backend
ffi = _cffi_backend.FFI('_pypy_winbase_cffi',
_version = 0x2601,
- _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xAB\x03\x00\x00\x13\x11\x00\x00\xB0\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\xAA\x03\x00\x00\xA8\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\xA7\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x29\x11\x00\x00\x18\x03\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x6B\x03\x00\x00\x49\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x33\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x66\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\xA9\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xAB\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x6E\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6B\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x77\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\xB0\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x04\x09\x00\x00\x02\x09\x00\x00\x05\x09\x00\x00\x03\x09\x00\x00\x02\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\xAF\x03\x00\x00\x04\x01\x00\x00\x00\x01',
- _globals = (b'\x00\x00\x27\x23CancelIoEx',0,b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x27\x23ConnectNamedPipe',0,b'\x00\x00\x6D\x23CreateEventA',0,b'\x00\x00\x73\x23CreateEventW',0,b'\x00\x00\x79\x23CreateFileA',0,b'\x00\x00\x9B\x23CreateFileW',0,b'\x00\x00\x82\x23CreateNamedPipeA',0,b'\x00\x00\x91\x23CreateNamedPipeW',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x48\x23CreateProcessW',0,b'\x00\x00\x3F\x23DuplicateHandle',0,b'\x00\x00\x8F\x23GetCurrentProcess',0,b'\x00\x00\x35\x23GetExitCodeProcess',0,b'\x00\x00\x63\x23GetLastError',0,b'\x00\x00\x5E\x23GetModuleFileNameW',0,b'\x00\x00\x2B\x23GetOverlappedResult',0,b'\x00\x00\x8C\x23GetStdHandle',0,b'\x00\x00\x63\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x57\x23SetErrorMode',0,b'\x00\x00\xA4\x23SetEvent',0,b'\x00\x00\x39\x23SetNamedPipeHandleState',0,b'\x00\x00\x31\x23TerminateProcess',0,b'\x00\x00\x5A\x23WaitForSingleObject',0,b'\x00\x00\x54\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x68\x23_getwch',0,b'\x00\x00\x68\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x6A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x65\x23_ungetwch',0),
- _struct_unions = ((b'\x00\x00\x00\xAD\x00\x00\x00\x03$1',b'\x00\x00\xAC\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x00\xAC\x00\x00\x00\x02$2',b'\x00\x00\x18\x11Offset',b'\x00\x00\x18\x11OffsetHigh'),(b'\x00\x00\x00\xA8\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\xAA\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x66\x11wShowWindow',b'\x00\x00\x66\x11cbReserved2',b'\x00\x00\xAE\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x00\xA7\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x18\x11Internal',b'\x00\x00\x18\x11InternalHigh',b'\x00\x00\xAD\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x00\xA9\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x18\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle')),
- _typenames = (b'\x00\x00\x00\x29LPOVERLAPPED',b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x6ELPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\xA7OVERLAPPED',b'\x00\x00\x00\xA8PROCESS_INFORMATION',b'\x00\x00\x00\x6EPSECURITY_ATTRIBUTES',b'\x00\x00\x00\xA9SECURITY_ATTRIBUTES',b'\x00\x00\x00\xAASTARTUPINFO',b'\x00\x00\x00\x66wint_t'),
+ _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00',
+ _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0),
+ _struct_unions = ((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')),
+ _typenames = (b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'),
)
diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py
index ba9dbe5239..c61d8071da 100644
--- a/lib_pypy/_winapi.py
+++ b/lib_pypy/_winapi.py
@@ -17,10 +17,25 @@ GetVersion = _kernel32.GetVersion
NULL = _ffi.NULL
# Now the _subprocess module implementation
-
-def _WinError():
+def _WinError(type=WindowsError):
code, message = _ffi.getwinerror()
- raise WindowsError(code, message)
+ excep = type(None, message, None ,code)
+ raise excep
+
+# In CPython this function converts a windows error into a python object
+# Not sure what we should do here.
+def SetFromWindowsErr(err):
+ if err == 0:
+ err = _kernel32.GetLastError()
+
+ if err == ERROR_CONNECTION_REFUSED:
+ type = ConnectionRefusedError
+ elif err == ERROR_CONNECTION_ABORTED:
+ type = ConnectionAbortedError
+ else:
+ type = WindowsError
+
+ return _WinError(type)
def _int2handle(val):
return _ffi.cast("HANDLE", val)
@@ -32,25 +47,25 @@ _INVALID_HANDLE_VALUE = _int2handle(-1)
def CreatePipe(attributes, size):
handles = _ffi.new("HANDLE[2]")
-
+
res = _kernel32.CreatePipe(handles, handles + 1, NULL, size)
if not res:
- raise _WinError()
+ SetFromWindowsErr(0)
return _handle2int(handles[0]), _handle2int(handles[1])
def CreateNamedPipe(*args):
handle = _kernel32.CreateNamedPipeW(*args)
if handle == INVALID_HANDLE_VALUE:
- raise _WinError()
- return handle
+ SetFromWindowsErr(0)
+ return _handle2int(handle)
def CreateFile(*args):
handle = _kernel32.CreateFileW(*args)
if handle == INVALID_HANDLE_VALUE:
- raise _WinError()
- return handle
+ SetFromWindowsErr(0)
+ return _handle2int(handle)
def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, collect_data_timeout):
d0 = _ffi.new('DWORD[1]', [mode])
@@ -79,20 +94,20 @@ class Overlapped(object):
def __del__(self):
# do this somehow else
- xxx
err = _kernel32.GetLastError()
bytes = _ffi.new('DWORD[1]')
- o = overlapped[0]
- if overlapped[0].pending:
+ o = self.overlapped[0]
+ if self.pending:
if _kernel32.CancelIoEx(o.handle, o.overlapped) & \
self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True):
# The operation is no longer pending, nothing to do
pass
else:
- raise RuntimeError('deleting an overlapped strucwith a pending operation not supported')
+ raise RuntimeError('deleting an overlapped struct with a pending operation not supported')
@property
def event(self):
+ xxx
return None
def GetOverlappedResult(self, wait):
@@ -110,8 +125,8 @@ class Overlapped(object):
else:
self.pending = 0
raise _WinError()
- if self.completed and self.read_buffer:
- if transferred != len(self.read_buffer):
+ if self.completed and self.readbuffer:
+ if transferred != len(self.readbuffer):
raise _WinError()
return transferred[0], err
@@ -125,6 +140,7 @@ class Overlapped(object):
def ConnectNamedPipe(handle, overlapped=False):
+ handle = _int2handle(handle)
if overlapped:
ov = Overlapped(handle)
else:
@@ -140,10 +156,10 @@ def ConnectNamedPipe(handle, overlapped=False):
_kernel32.SetEvent(ov.overlapped[0].hEvent)
else:
del ov
- raise _WinError()
+ SetFromWindowsErr(err)
return ov
elif not success:
- raise _WinError()
+ SetFromWindowsErr(0)
def GetCurrentProcess():
return _handle2int(_kernel32.GetCurrentProcess())
@@ -217,6 +233,18 @@ def WaitForSingleObject(handle, milliseconds):
return res
+def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds):
+ if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS:
+ return None
+
+ # CPython makes the wait interruptible by ctrl-c. We need to add this in at some point
+ res = _kernel32.WaitForMultipleObjects(len(handle_sequence), handle_sequence, waitflag, milliseconds)
+
+ if res == WAIT_FAILED:
+ raise _WinError()
+ return int(res)
+
+
def GetExitCodeProcess(handle):
# CPython: the first argument is expected to be an integer.
code = _ffi.new("DWORD[1]")
@@ -260,6 +288,14 @@ def GetModuleFileName(module):
raise _WinError()
return _ffi.string(buf)
+ZERO_MEMORY = 0x00000008
+
+def malloc(size):
+ return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size)
+
+def free(voidptr):
+ _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr)
+
# #define macros from WinBase.h and elsewhere
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
@@ -272,6 +308,7 @@ INFINITE = 0xffffffff
WAIT_OBJECT_0 = 0
WAIT_ABANDONED_0 = 0x80
WAIT_TIMEOUT = 0x102
+WAIT_FAILED = 0xFFFFFFFF
CREATE_NEW_CONSOLE = 0x010
CREATE_NEW_PROCESS_GROUP = 0x200
CREATE_UNICODE_ENVIRONMENT = 0x400
@@ -281,11 +318,14 @@ _MAX_PATH = 260
ERROR_SUCCESS = 0
ERROR_NETNAME_DELETED = 64
ERROR_BROKEN_PIPE = 109
+ERROR_PIPE_BUSY = 231
ERROR_MORE_DATA = 234
ERROR_PIPE_CONNECTED = 535
ERROR_OPERATION_ABORTED = 995
ERROR_IO_INCOMPLETE = 996
ERROR_IO_PENDING = 997
+ERROR_CONNECTION_REFUSED = 1225
+ERROR_CONNECTION_ABORTED = 1236
PIPE_ACCESS_INBOUND = 0x00000001
PIPE_ACCESS_OUTBOUND = 0x00000002
@@ -299,11 +339,13 @@ PIPE_TYPE_MESSAGE = 0x00000004
PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000
PIPE_REJECT_REMOTE_CLIENTS = 0x00000008
+PIPE_UNLIMITED_INSTANCES = 255
+
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
GENERIC_EXECUTE= 0x20000000
GENERIC_ALL = 0x10000000
-INVALID_HANDLE_VALUE = -1
+INVALID_HANDLE_VALUE = _int2handle(-1)
FILE_FLAG_WRITE_THROUGH = 0x80000000
FILE_FLAG_OVERLAPPED = 0x40000000
FILE_FLAG_NO_BUFFERING = 0x20000000
@@ -326,3 +368,5 @@ OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5
+MAXIMUM_WAIT_OBJECTS = 64
+
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
index a2c12a1fc9..c223f85359 100644
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cffi
-Version: 1.12.2
+Version: 1.12.3
Summary: Foreign Function Interface for Python calling C code.
Home-page: http://cffi.readthedocs.org
Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
index 5ebb64b072..0224a15a7d 100644
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -5,8 +5,8 @@ from .api import FFI
from .error import CDefError, FFIError, VerificationError, VerificationMissing
from .error import PkgConfigError
-__version__ = "1.12.2"
-__version_info__ = (1, 12, 2)
+__version__ = "1.12.3"
+__version_info__ = (1, 12, 3)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h
index 09a784875c..fb851bbd9e 100644
--- a/lib_pypy/cffi/_embedding.h
+++ b/lib_pypy/cffi/_embedding.h
@@ -223,7 +223,7 @@ static int _cffi_initialize_python(void)
if (f != NULL && f != Py_None) {
PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
- "\ncompiled with cffi version: 1.12.2"
+ "\ncompiled with cffi version: 1.12.3"
"\n_cffi_backend module: ", f);
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, "_cffi_backend");
diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst
new file mode 100644
index 0000000000..716a393d1e
--- /dev/null
+++ b/pypy/doc/release-v7.1.1.rst
@@ -0,0 +1,96 @@
+=========================================
+PyPy v7.1.1: release of 2.7, and 3.6-beta
+=========================================
+
+The PyPy team is proud to release a bug-fix release version 7.1.1 of PyPy, which
+includes two different interpreters:
+
+ - PyPy2.7, which is an interpreter supporting the syntax and the features of
+ Python 2.7
+
+ - PyPy3.6-beta: this is the second official release of PyPy to support 3.6
+ features, although it is still considered beta quality.
+
+The interpreters are based on much the same codebase, thus the double
+release.
+
+As always, this release is 100% compatible with the previous one and fixed
+several issues and bugs raised by the growing community of PyPy users.
+We strongly recommend updating.
+
+The PyPy3.6 release is still not production quality so your mileage may vary.
+There are open issues with incomplete compatibility and c-extension support.
+
+You can download the v7.1.1 releases here:
+
+ http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project. If PyPy is not quite good enough for your needs, we are available for
+direct consulting work.
+
+We would also like to thank our contributors and encourage new people to join
+the project. PyPy has many layers and we need help with all of them: `PyPy`_
+and `RPython`_ documentation improvements, tweaking popular modules to run
+on pypy, or general `help`_ with making RPython's JIT even better.
+
+.. _`PyPy`: index.html
+.. _`RPython`: https://rpython.readthedocs.org
+.. _`help`: project-ideas.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7, 3.6. It's fast (`PyPy and CPython 2.7.x`_ performance
+comparison) due to its integrated tracing JIT compiler.
+
+We also welcome developers of other `dynamic languages`_ to see what RPython
+can do for them.
+
+This PyPy release supports:
+
+ * **x86** machines on most common operating systems
+ (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD)
+
+ * big- and little-endian variants of **PPC64** running Linux,
+
+ * **s390x** running Linux
+
+Unfortunately at the moment of writing our ARM buildbots are out of service,
+so for now we are **not** releasing any binary for the ARM architecture,
+although PyPy does support ARM 32 bit processors.
+
+.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html
+
+
+Changelog
+=========
+
+Changes shared across versions
+* improve performance of ``u''.append``
+* Prevent a crash in ``zlib`` when flushing a closed stream
+* Fix a few corener cases when encountering unicode values above 0x110000
+* Teach the JIT how to handle very large constant lists, sets, or dicts
+* Fix building on ARM32 (issue 2984_)
+* Fix a bug in register assignment in ARM32
+* Package windows DLLs needed by cffi modules next to the cffi c-extensions
+ (issue 2988_)
+* Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem``
+* Fix memoryviews of ctype structures with padding, (cpython issue 32780_)
+
+Python 3.6 only
+
+* On win32, override some ``errno.E*`` values that were added to MSVC in v2010
+ so that ``errno.E* == errno.WSAE*`` as in CPython
+* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the
+ AST level)
+* ``str.maketrans`` was broken (issue 2991_)
+* Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)``
+ and ``'a' < buffer``
+
+.. _2984: https://bitbucket.org/pypy/pypy/issues/2984
+.. _2991: https://bitbucket.org/pypy/pypy/issues/2991
+.. _2988: https://bitbucket.org/pypy/pypy/issues/2988
+.. _32780: https://bugs.python.org/issue32780
diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst
index 9cce421e53..8a42bfafdd 100644
--- a/pypy/doc/whatsnew-pypy3-head.rst
+++ b/pypy/doc/whatsnew-pypy3-head.rst
@@ -8,3 +8,8 @@ What's new in PyPy3 7.1+
.. branch: zlib-make-py3-go-boom
Complain if you try to copy a flushed zlib decompress on py3
+
+.. branch: winoverlapped
+
+Add support for async (overlapped) IO on Windows.
+
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
index 8f402fdb69..2ca1bbd809 100644
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1067,9 +1067,10 @@ class ObjSpace(object):
"""
return None
- def listview_utf8(self, w_list):
- """ Return a list of unwrapped unicode out of a list of unicode. If the
- argument is not a list or does not contain only unicode, return None.
+ def listview_ascii(self, w_list):
+ """ Return a list of unwrapped **ASCII** strings out of a list of
+ unicode. If the argument is not a list, does not contain only unicode,
+ or contains a unicode with non-ascii characters, return None.
May return None anyway.
"""
return None
diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py
index b06a509884..e55615c82a 100644
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -82,7 +82,7 @@ class AppTest(object):
l = [b"a", b"b", b"c"]
assert strategy(l) == "BytesListStrategy"
l = [u"a", u"b", u"c"]
- assert strategy(l) == "UnicodeListStrategy"
+ assert strategy(l) == "AsciiListStrategy"
l = [1.1, 2.2, 3.3]
assert strategy(l) == "FloatListStrategy"
l = [1, "b", 3]
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
index 1a508b8751..4cb2fefd28 100644
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -3,7 +3,7 @@ from pypy.interpreter.mixedmodule import MixedModule
from rpython.rlib import rdynload, clibffi
from rpython.rtyper.lltypesystem import rffi
-VERSION = "1.12.2"
+VERSION = "1.12.3"
FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI
try:
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
index 0b82017ade..5b5eea4021 100644
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1,7 +1,7 @@
# ____________________________________________________________
import sys
-assert __version__ == "1.12.2", ("This test_c.py file is for testing a version"
+assert __version__ == "1.12.3", ("This test_c.py file is for testing a version"
" of cffi that differs from the one that we"
" get from 'import _cffi_backend'")
if sys.version_info < (3,):
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
index 3ada0162d0..f84d60765d 100644
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -1156,11 +1156,15 @@ def make_array(mytype):
elif mytype.typecode == 'c':
return space.newbytes(item)
elif mytype.typecode == 'u':
- if ord(item) >= 0x110000:
+ code = r_uint(ord(item))
+ try:
+ item = rutf8.unichr_as_utf8(code)
+ except rutf8.OutOfRange:
raise oefmt(space.w_ValueError,
- "array contains a unicode character out of "
- "range(0x110000)")
- return space.newtext(rutf8.unichr_as_utf8(ord(item)), 1)
+ "cannot operate on this array('u') because it contains"
+ " character %s not in range [U+0000; U+10ffff]"
+ " at index %d", 'U+%x' % code, idx)
+ return space.newtext(item, 1)
assert 0, "unreachable"
# interface
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
index b44c871fb6..d59717a27c 100644
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -897,7 +897,13 @@ class AppTestArray(object):
a = self.array('u', input_unicode)
b = self.array('u', input_unicode)
b.byteswap()
- raises(ValueError, "a != b")
+ assert b[2] == u'\u0000'
+ raises(ValueError, "b[1]") # doesn't work
+ e = raises(ValueError, "a != b") # doesn't work
+ assert str(e.value) == (
+ "cannot operate on this array('u') because it contains"
+ " character U+1000000 not in range [U+0000; U+10ffff]"
+ " at index 0")
assert str(a) == "array('u', %r)" % (input_unicode,)
assert str(b) == ("array('u', <character U+1000000 is not in"
" range [U+0000; U+10ffff]>)")
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
index de224c971c..43535457e3 100644
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -344,7 +344,7 @@ def _add_indirections():
popitem delitem clear copy \
length w_keys values items \
iterkeys itervalues iteritems \
- listview_bytes listview_utf8 listview_int \
+ listview_bytes listview_ascii listview_int \
view_as_kwargs".split()
def make_method(method):
@@ -491,7 +491,7 @@ class DictStrategy(object):
def listview_bytes(self, w_dict):
return None
- def listview_utf8(self, w_dict):
+ def listview_ascii(self, w_dict):
return None
def listview_int(self, w_dict):
@@ -1202,7 +1202,8 @@ class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy):
assert key is not None
return self.getitem(w_dict, self.space.newtext(key))
- ## def listview_utf8(self, w_dict):
+ ## def listview_ascii(self, w_dict):
+ ## XXX reimplement. Also warning: must return a list of _ascii_
## return self.unerase(w_dict.dstorage).keys()
def wrapkey(space, key):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
index ef7791cf48..b765deb2d8 100644
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -97,13 +97,13 @@ def get_strategy_from_list_objects(space, list_w, sizehint):
return space.fromcache(BytesListStrategy)
elif type(w_firstobj) is W_UnicodeObject and w_firstobj.is_ascii():
- # check for all-unicodes
+ # check for all-unicodes containing only ascii
for i in range(1, len(list_w)):
item = list_w[i]
if type(item) is not W_UnicodeObject or not item.is_ascii():
break
else:
- return space.fromcache(UnicodeListStrategy)
+ return space.fromcache(AsciiListStrategy)
elif type(w_firstobj) is W_FloatObject:
# check for all-floats
@@ -197,8 +197,8 @@ class W_ListObject(W_Root):
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
@staticmethod
- def newlist_utf8(space, list_u):
- strategy = space.fromcache(UnicodeListStrategy)
+ def newlist_ascii(space, list_u):
+ strategy = space.fromcache(AsciiListStrategy)
storage = strategy.erase(list_u)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
@@ -336,10 +336,10 @@ class W_ListObject(W_Root):
not use the list strategy, return None."""
return self.strategy.getitems_bytes(self)
- def getitems_utf8(self):
+ def getitems_ascii(self):
"""Return the items in the list as unwrapped unicodes. If the list does
not use the list strategy, return None."""
- return self.strategy.getitems_utf8(self)
+ return self.strategy.getitems_ascii(self)
def getitems_int(self):
"""Return the items in the list as unwrapped ints. If the list does not
@@ -778,7 +778,7 @@ class ListStrategy(object):
def getitems_bytes(self, w_list):
return None
- def getitems_utf8(self, w_list):
+ def getitems_ascii(self, w_list):
return None
def getitems_int(self, w_list):
@@ -925,7 +925,7 @@ class EmptyListStrategy(ListStrategy):
elif type(w_item) is W_BytesObject:
strategy = self.space.fromcache(BytesListStrategy)
elif type(w_item) is W_UnicodeObject and w_item.is_ascii():
- strategy = self.space.fromcache(UnicodeListStrategy)
+ strategy = self.space.fromcache(AsciiListStrategy)
elif type(w_item) is W_FloatObject:
strategy = self.space.fromcache(FloatListStrategy)
else:
@@ -1003,9 +1003,9 @@ class EmptyListStrategy(ListStrategy):
w_list.lstorage = strategy.erase(byteslist[:])
return
- unilist = space.listview_utf8(w_iterable)
+ unilist = space.listview_ascii(w_iterable)
if unilist is not None:
- w_list.strategy = strategy = space.fromcache(UnicodeListStrategy)
+ w_list.strategy = strategy = space.fromcache(AsciiListStrategy)
# need to copy because intlist can share with w_iterable
w_list.lstorage = strategy.erase(unilist[:])
return
@@ -1967,7 +1967,7 @@ class BytesListStrategy(ListStrategy):
return self.unerase(w_list.lstorage)
-class UnicodeListStrategy(ListStrategy):
+class AsciiListStrategy(ListStrategy):
import_from_mixin(AbstractUnwrappedStrategy)
_none_value = ""
@@ -1987,7 +1987,7 @@ class UnicodeListStrategy(ListStrategy):
return type(w_obj) is W_UnicodeObject and w_obj.is_ascii()
def list_is_correct_type(self, w_list):
- return w_list.strategy is self.space.fromcache(UnicodeListStrategy)
+ return w_list.strategy is self.space.fromcache(AsciiListStrategy)
def sort(self, w_list, reverse):
l = self.unerase(w_list.lstorage)
@@ -1996,7 +1996,7 @@ class UnicodeListStrategy(ListStrategy):
if reverse:
l.reverse()
- def getitems_utf8(self, w_list):
+ def getitems_ascii(self, w_list):
return self.unerase(w_list.lstorage)
# _______________________________________________________
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
index e92dc0cc44..ab2990fe11 100644
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -333,7 +333,7 @@ class StdObjSpace(ObjSpace):
def newlist_utf8(self, list_u, is_ascii):
if is_ascii:
- return W_ListObject.newlist_utf8(self, list_u)
+ return W_ListObject.newlist_ascii(self, list_u)
return ObjSpace.newlist_utf8(self, list_u, False)
@@ -542,19 +542,19 @@ class StdObjSpace(ObjSpace):
return w_obj.getitems_bytes()
return None
- def listview_utf8(self, w_obj):
+ def listview_ascii(self, w_obj):
# note: uses exact type checking for objects with strategies,
# and isinstance() for others. See test_listobject.test_uses_custom...
if type(w_obj) is W_ListObject:
- return w_obj.getitems_utf8()
+ return w_obj.getitems_ascii()
if type(w_obj) is W_DictObject:
- return w_obj.listview_utf8()
+ return w_obj.listview_ascii()
if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
- return w_obj.listview_utf8()
+ return w_obj.listview_ascii()
if isinstance(w_obj, W_UnicodeObject) and self._uses_unicode_iter(w_obj):
- return w_obj.listview_utf8()
+ return w_obj.listview_ascii()
if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
- return w_obj.getitems_utf8()
+ return w_obj.getitems_ascii()
return None
def listview_int(self, w_obj):
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
index db2c0d6bed..6845c7907f 100644
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -86,9 +86,9 @@ class W_BaseSetObject(W_Root):
""" If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """
return self.strategy.listview_bytes(self)
- def listview_utf8(self):
+ def listview_ascii(self):
""" If this is a unicode set return its contents as a list of uwnrapped unicodes. Otherwise return None. """
- return self.strategy.listview_utf8(self)
+ return self.strategy.listview_ascii(self)
def listview_int(self):
""" If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """
@@ -671,7 +671,7 @@ class SetStrategy(object):
def listview_bytes(self, w_set):
return None
- def listview_utf8(self, w_set):
+ def listview_ascii(self, w_set):
return None
def listview_int(self, w_set):
@@ -777,7 +777,7 @@ class EmptySetStrategy(SetStrategy):
elif type(w_key) is W_BytesObject:
strategy = self.space.fromcache(BytesSetStrategy)
elif type(w_key) is W_UnicodeObject and w_key.is_ascii():
- strategy = self.space.fromcache(UnicodeSetStrategy)
+ strategy = self.space.fromcache(AsciiSetStrategy)
elif self.space.type(w_key).compares_by_identity():
strategy = self.space.fromcache(IdentitySetStrategy)
else:
@@ -1239,7 +1239,7 @@ class BytesSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
return BytesIteratorImplementation(self.space, self, w_set)
-class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
+class AsciiSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
erase, unerase = rerased.new_erasing_pair("unicode")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
@@ -1253,7 +1253,7 @@ class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
def get_empty_dict(self):
return {}
- def listview_utf8(self, w_set):
+ def listview_ascii(self, w_set):
return self.unerase(w_set.sstorage).keys()
def is_correct_type(self, w_key):
@@ -1301,7 +1301,7 @@ class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
def may_contain_equal_elements(self, strategy):
if strategy is self.space.fromcache(BytesSetStrategy):
return False
- elif strategy is self.space.fromcache(UnicodeSetStrategy):
+ elif strategy is self.space.fromcache(AsciiSetStrategy):
return False
elif strategy is self.space.fromcache(EmptySetStrategy):
return False
@@ -1392,7 +1392,7 @@ class IdentitySetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
return False
if strategy is self.space.fromcache(BytesSetStrategy):
return False
- if strategy is self.space.fromcache(UnicodeSetStrategy):
+ if strategy is self.space.fromcache(AsciiSetStrategy):
return False
return True
@@ -1585,9 +1585,9 @@ def set_strategy_and_setdata(space, w_set, w_iterable):
w_set.sstorage = strategy.get_storage_from_unwrapped_list(byteslist)
return
- unicodelist = space.listview_utf8(w_iterable)
+ unicodelist = space.listview_ascii(w_iterable)
if unicodelist is not None:
- strategy = space.fromcache(UnicodeSetStrategy)
+ strategy = space.fromcache(AsciiSetStrategy)
w_set.strategy = strategy
w_set.sstorage = strategy.get_storage_from_unwrapped_list(unicodelist)
return
@@ -1634,7 +1634,7 @@ def _pick_correct_strategy_unroll(space, w_set, w_iterable):
if type(w_item) is not W_UnicodeObject or not w_item.is_ascii():
break
else:
- w_set.strategy = space.fromcache(UnicodeSetStrategy)
+ w_set.strategy = space.fromcache(AsciiSetStrategy)
w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
return
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
index bc469b7e0b..99d84c823b 100644
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -148,7 +148,7 @@ class TestW_DictObject(object):
w = self.space.wrap
w_d = self.space.newdict()
w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(2))])
- assert self.space.listview_utf8(w_d) == ["a", "b"]
+ assert self.space.listview_ascii(w_d) == ["a", "b"]
def test_listview_int_dict(self):
w = self.space.wrap
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
index 5ac6672f3e..66f8d9e947 100644
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -1403,6 +1403,10 @@ class AppTestListObject(object):
l1 = list(s)
assert len(l1) == 1
+ def test_unicode_bug_in_listview_utf8(self):
+ l1 = list(u'\u1234\u2345')
+ assert l1 == [u'\u1234', '\u2345']
+
def test_list_from_set(self):
l = ['a']
l.__init__(set('b'))
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
index 8bc276b7ac..7cde753570 100644
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -3,7 +3,7 @@ import py
from pypy.objspace.std.listobject import (
W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy,
FloatListStrategy, BytesListStrategy, RangeListStrategy,
- SimpleRangeListStrategy, make_range_list, UnicodeListStrategy,
+ SimpleRangeListStrategy, make_range_list, AsciiListStrategy,
IntOrFloatListStrategy)
from pypy.objspace.std import listobject
from pypy.objspace.std.test.test_listobject import TestW_ListObject
@@ -21,7 +21,7 @@ class TestW_ListStrategies(TestW_ListObject):
assert isinstance(W_ListObject(space, [wb('a'), wb('b')]).strategy,
BytesListStrategy)
assert isinstance(W_ListObject(space, [w(u'a'), w(u'b')]).strategy,
- UnicodeListStrategy)
+ AsciiListStrategy)
assert isinstance(W_ListObject(space, [w(u'a'), wb('b')]).strategy,
ObjectListStrategy) # mixed unicode and bytes
@@ -47,7 +47,7 @@ class TestW_ListStrategies(TestW_ListObject):
l = W_ListObject(space, [])
assert isinstance(l.strategy, EmptyListStrategy)
l.append(w(u'a'))
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
l = W_ListObject(space, [])
assert isinstance(l.strategy, EmptyListStrategy)
@@ -76,9 +76,9 @@ class TestW_ListStrategies(TestW_ListObject):
def test_unicode_to_any(self):
space = self.space
l = W_ListObject(space, [space.wrap(u'a'), space.wrap(u'b'), space.wrap(u'c')])
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
l.append(space.wrap(u'd'))
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
l.append(space.wrap(3))
assert isinstance(l.strategy, ObjectListStrategy)
@@ -101,7 +101,7 @@ class TestW_ListStrategies(TestW_ListObject):
l.setitem(0, w('d'))
assert space.eq_w(l.getitem(0), w('d'))
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
# IntStrategy to ObjectStrategy
l = W_ListObject(space, [w(1),w(2),w(3)])
@@ -139,7 +139,7 @@ class TestW_ListStrategies(TestW_ListObject):
# UnicodeStrategy
l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')])
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
l.insert(3, w(2))
assert isinstance(l.strategy, ObjectListStrategy)
@@ -219,7 +219,7 @@ class TestW_ListStrategies(TestW_ListObject):
# UnicodeStrategy to ObjectStrategy
l = W_ListObject(space, [w(u'a'), w(u'b'), w(u'c')])
- assert isinstance(l.strategy, UnicodeListStrategy)
+ assert isinstance(l.strategy, AsciiListStrategy)
l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
assert isinstance(l.strategy, ObjectListStrategy)
@@ -270,7 +270,7 @@ class TestW_ListStrategies(TestW_ListObject):
l = W_ListObject(space, wrapitems([u"a",u"b",u"c",u"d",u"e"]))
other = W_ListObject(space, wrapitems([u"a", u"b", u"c"]))
keep_other_strategy(l, 0, 2, other.length(), other)
- assert l.strategy is space.fromcache(UnicodeListStrategy)
+ assert l.strategy is space.fromcache(AsciiListStrategy)
l = W_ListObject(space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5]))
other = W_ListObject(space, [])
@@ -340,7 +340,7 @@ class TestW_ListStrategies(TestW_ListObject):
empty = W_ListObject(space, [])
assert isinstance(empty.strategy, EmptyListStrategy)
empty.extend(W_ListObject(space, [w(u"a"), w(u"b"), w(u"c")]))
- assert isinstance(empty.strategy, UnicodeListStrategy)
+ assert isinstance(empty.strategy, AsciiListStrategy)
empty = W_ListObject(space, [])
assert isinstance(empty.strategy, EmptyListStrategy)
@@ -596,7 +596,7 @@ class TestW_ListStrategies(TestW_ListObject):
l1 = W_ListObject(self.space, [self.space.newbytes("eins"), self.space.newbytes("zwei")])
assert isinstance(l1.strategy, BytesListStrategy)
l2 = W_ListObject(self.space, [self.space.newutf8("eins", 4), self.space.newutf8("zwei", 4)])
- assert isinstance(l2.strategy, UnicodeListStrategy)
+ assert isinstance(l2.strategy, AsciiListStrategy)
l3 = W_ListObject(self.space, [self.space.newbytes("eins"), self.space.newutf8("zwei", 4)])
assert isinstance(l3.strategy, ObjectListStrategy)
@@ -608,9 +608,9 @@ class TestW_ListStrategies(TestW_ListObject):
def test_listview_unicode(self):
space = self.space
- assert space.listview_utf8(space.wrap(1)) == None
+ assert space.listview_ascii(space.wrap(1)) == None
w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')])
- assert space.listview_utf8(w_l) == ["a", "b"]
+ assert space.listview_ascii(w_l) == ["a", "b"]
def test_string_join_uses_listview_bytes(self):
space = self.space
@@ -670,10 +670,10 @@ class TestW_ListStrategies(TestW_ListObject):
w_l4 = space.call_method(w_u, "rsplit", space.wrap(" "))
finally:
del space.newlist
- assert space.listview_utf8(w_l) == [u"a", u"b", u"c"]
- assert space.listview_utf8(w_l2) == [u"a", u"b", u"c"]
- assert space.listview_utf8(w_l3) == [u"a", u"b", u"c"]
- assert space.listview_utf8(w_l4) == [u"a", u"b", u"c"]
+ assert space.listview_ascii(w_l) == [u"a", u"b", u"c"]
+ assert space.listview_ascii(w_l2) == [u"a", u"b", u"c"]
+ assert space.listview_ascii(w_l3) == [u"a", u"b", u"c"]
+ assert space.listview_ascii(w_l4) == [u"a", u"b", u"c"]
def test_pop_without_argument_is_fast(self):
space = self.space
@@ -717,7 +717,7 @@ class TestW_ListStrategies(TestW_ListObject):
def test_listview_unicode_list(self):
space = self.space
w_l = W_ListObject(space, [space.wrap(u"a"), space.wrap(u"b")])
- assert self.space.listview_utf8(w_l) == [u"a", u"b"]
+ assert self.space.listview_ascii(w_l) == [u"a", u"b"]
def test_listview_int_list(self):
space = self.space
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
index fc866fe1d6..cc776bd457 100644
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -83,7 +83,7 @@ class TestW_SetObject:
def test_create_set_from_list(self):
from pypy.interpreter.baseobjspace import W_Root
- from pypy.objspace.std.setobject import BytesSetStrategy, ObjectSetStrategy, UnicodeSetStrategy
+ from pypy.objspace.std.setobject import BytesSetStrategy, ObjectSetStrategy, AsciiSetStrategy
from pypy.objspace.std.floatobject import W_FloatObject
w = self.space.wrap
@@ -108,8 +108,8 @@ class TestW_SetObject:
w_list = self.space.iter(W_ListObject(self.space, [w(u"1"), w(u"2"), w(u"3")]))
w_set = W_SetObject(self.space)
_initialize_set(self.space, w_set, w_list)
- #assert w_set.strategy is self.space.fromcache(UnicodeSetStrategy)
- #assert w_set.strategy.unerase(w_set.sstorage) == {u"1":None, u"2":None, u"3":None}
+ assert w_set.strategy is self.space.fromcache(AsciiSetStrategy)
+ assert w_set.strategy.unerase(w_set.sstorage) == {u"1":None, u"2":None, u"3":None}
w_list = W_ListObject(self.space, [w("1"), w(2), w("3")])
w_set = W_SetObject(self.space)
@@ -1114,3 +1114,7 @@ class AppTestAppSetTest:
assert len(items) == 2
items.add(first)
assert items == set(d)
+
+ def test_unicode_bug_in_listview_utf8(self):
+ l1 = set(u'\u1234\u2345')
+ assert l1 == set([u'\u1234', '\u2345'])
diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py
index de479cf4eb..57ad8b8738 100644
--- a/pypy/objspace/std/test/test_setstrategies.py
+++ b/pypy/objspace/std/test/test_setstrategies.py
@@ -3,7 +3,7 @@ from pypy.objspace.std.setobject import W_SetObject
from pypy.objspace.std.setobject import (
BytesIteratorImplementation, BytesSetStrategy, EmptySetStrategy,
IntegerIteratorImplementation, IntegerSetStrategy, ObjectSetStrategy,
- UnicodeIteratorImplementation, UnicodeSetStrategy)
+ UnicodeIteratorImplementation, AsciiSetStrategy)
from pypy.objspace.std.listobject import W_ListObject
class TestW_SetStrategies:
@@ -31,8 +31,8 @@ class TestW_SetStrategies:
s = W_SetObject(self.space, self.wrapped(["a", "b"], bytes=True))
assert s.strategy is self.space.fromcache(BytesSetStrategy)
- #s = W_SetObject(self.space, self.wrapped([u"a", u"b"]))
- #assert s.strategy is self.space.fromcache(UnicodeSetStrategy)
+ s = W_SetObject(self.space, self.wrapped([u"a", u"b"]))
+ assert s.strategy is self.space.fromcache(AsciiSetStrategy)
def test_switch_to_object(self):
s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
@@ -47,7 +47,7 @@ class TestW_SetStrategies:
def test_switch_to_unicode(self):
s = W_SetObject(self.space, self.wrapped([]))
s.add(self.space.wrap(u"six"))
- assert s.strategy is self.space.fromcache(UnicodeSetStrategy)
+ assert s.strategy is self.space.fromcache(AsciiSetStrategy)
def test_symmetric_difference(self):
s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py
index 8836be4485..3fc64c6a28 100644
--- a/pypy/objspace/std/test/test_stdobjspace.py
+++ b/pypy/objspace/std/test/test_stdobjspace.py
@@ -86,11 +86,6 @@ class TestW_StdObjSpace:
assert isinstance(w_x, W_UnicodeObject)
assert w_x._utf8 == 'foo'
#
- # calling space.wrap() on a byte string which is not ASCII should
- # never happen. Howeven it might happen while the py3k port is not
- # 100% complete. In the meantime, try to return something more or less
- # sensible instead of crashing with an RPython UnicodeError.
- from pypy.objspace.std.unicodeobject import W_UnicodeObject
- w_x = self.space.wrap('foo\xF0')
- assert isinstance(w_x, W_UnicodeObject)
- assert w_x._utf8 == 'foo\xF0'
+ # calling space.wrap() on a byte string which is not utf-8 should
+ # never happen.
+ py.test.raises(UnicodeDecodeError, self.space.wrap, 'foo\xF0')
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
index c4f83c206c..34c1e189c8 100644
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -28,7 +28,7 @@ class TestUnicodeObject:
def test_listview_unicode(self):
w_str = self.space.newutf8('abcd', 4)
- assert self.space.listview_utf8(w_str) == list("abcd")
+ assert self.space.listview_ascii(w_str) == list("abcd")
def test_new_shortcut(self):
space = self.space
@@ -225,6 +225,14 @@ class AppTestUnicodeString:
raises(TypeError, ','.join, [b'a'])
exc = raises(TypeError, ''.join, ['a', 2, 3])
assert 'sequence item 1' in str(exc.value)
+ # unicode lists
+ check(''.join(['\u1234']), '\u1234')
+ check(''.join(['\u1234', '\u2345']), '\u1234\u2345')
+ check('\u1234'.join(['\u2345', '\u3456']), '\u2345\u1234\u3456')
+ # also checking passing a single unicode instead of a list
+ check(''.join('\u1234'), '\u1234')
+ check(''.join('\u1234\u2345'), '\u1234\u2345')
+ check('\u1234'.join('\u2345\u3456'), '\u2345\u1234\u3456')
def test_contains(self):
assert '' in 'abc'
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
index 7b2f0ba0a0..a7d0cc4bb6 100644
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -821,8 +821,8 @@ def _create_new_type(space, w_typetype, w_name, w_bases, w_dict, __args__):
raise oefmt(space.w_ValueError, "type name must not contain null characters")
pos = surrogate_in_utf8(name)
if pos >= 0:
- raise oefmt(space.w_ValueError, "can't encode character %s in position "
- "%d, surrogates not allowed", name[pos], pos)
+ raise oefmt(space.w_ValueError, "can't encode character in position "
+ "%d, surrogates not allowed", pos)
dict_w = {}
dictkeys_w = space.listview(w_dict)
for w_key in dictkeys_w:
@@ -927,8 +927,8 @@ def descr_set__name__(space, w_type, w_value):
raise oefmt(space.w_ValueError, "type name must not contain null characters")
pos = surrogate_in_utf8(name)
if pos >= 0:
- raise oefmt(space.w_ValueError, "can't encode character %s in position "
- "%d, surrogates not allowed", name[pos], pos)
+ raise oefmt(space.w_ValueError, "can't encode character in position "
+ "%d, surrogates not allowed", pos)
w_type.name = name
def descr_get__qualname__(space, w_type):
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
index 096d53d6ea..6828a62d8f 100644
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -39,13 +39,10 @@ class W_UnicodeObject(W_Root):
self._length = length
self._index_storage = rutf8.null_storage()
if not we_are_translated():
- try:
- # best effort, too expensive to handle surrogates
- ulength = rutf8.codepoints_in_utf(utf8str)
- except:
- ulength = length
- assert ulength == length
-
+ # utf8str must always be a valid utf8 string, except maybe with
+ # explicit surrogate characters---which .decode('utf-8') doesn't
+ # special-case in Python 2, which is exactly what we want here
+ assert length == len(utf8str.decode('utf-8'))
@staticmethod
@@ -99,8 +96,12 @@ class W_UnicodeObject(W_Root):
def utf8_w(self, space):
return self._utf8
- def listview_utf8(self):
- return _create_list_from_unicode(self._utf8)
+ def listview_ascii(self):
+ if self.is_ascii():
+ return [c for c in self._utf8]
+ # rpython note: can't use list() to return a list of strings
+ # (only a list of chars is supported)
+ return None
def descr_iter(self, space):
from pypy.objspace.std.iterobject import W_FastUnicodeIterObject
@@ -572,7 +573,7 @@ class W_UnicodeObject(W_Root):
_StringMethods_descr_join = descr_join
def descr_join(self, space, w_list):
- l = space.listview_utf8(w_list)
+ l = space.listview_ascii(w_list)
if l is not None and self.is_ascii():
if len(l) == 1:
return space.newutf8(l[0], len(l[0]))
@@ -1851,12 +1852,6 @@ W_UnicodeObject.typedef = TypeDef(
W_UnicodeObject.typedef.flag_sequence_bug_compat = True
-def _create_list_from_unicode(value):
- # need this helper function to allow the jit to look inside and inline
- # listview_unicode
- return [rutf8.unichr_as_utf8(r_uint(s), True) for s in rutf8.Utf8StringIterator(value)]
-
-
W_UnicodeObject.EMPTY = W_UnicodeObject('', 0)
# Helper for converting int/long this is called only from