diff options
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 |