Author: Carl Friedrich Bolz <[email protected]> Branch: resource_warning Changeset: r86025:9f2557766bf3 Date: 2016-08-05 10:00 +0200 http://bitbucket.org/pypy/pypy/changeset/9f2557766bf3/
Log: merge default diff too long, truncating to 2000 out of 77823 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -20,3 +20,10 @@ 5f8302b8bf9f53056e40426f10c72151564e5b19 release-4.0.1 246c9cf22037b11dc0e8c29ce3f291d3b8c5935a release-5.0 bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1 +3260adbeba4a8b6659d1cc0d0b41f266769b74da release-5.1 +b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 +80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 +40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 +40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 +c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 +7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -43,17 +43,17 @@ Samuele Pedroni Matti Picus Alex Gaynor + Philip Jenvey Brian Kearns - Philip Jenvey + Ronan Lamy Michael Hudson - Ronan Lamy + Manuel Jacob David Schneider - Manuel Jacob Holger Krekel Christian Tismer Hakan Ardo + Richard Plangger Benjamin Peterson - Richard Plangger Anders Chrigstrom Eric van Riet Paap Wim Lavrijsen @@ -93,9 +93,9 @@ stian Jan de Mooij Tyler Wade + Vincent Legoll Michael Foord Stephan Diehl - Vincent Legoll Stefan Schwarzer Valentino Volonghi Tomek Meka @@ -104,30 +104,34 @@ Bruno Gola David Malcolm Jean-Paul Calderone + Mark Young Timo Paulssen Squeaky + Devin Jeanpierre Marius Gedminas Alexandre Fayolle Simon Burton + Stefano Rivera Martin Matusiak Konstantin Lopuhin Wenzhu Man John Witulski Laurence Tratt + Raffael Tfirst Ivan Sichmann Freitas Greg Price Dario Bertini - Stefano Rivera Mark Pearse Simon Cross + Edd Barrett Andreas Stührk - Edd Barrett + Tobias Pape Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Spenser Bauman Jeremy Thurgood Paweł Piotr Przeradowski - Spenser Bauman Paul deGrandis Ilya Osadchiy marky1991 @@ -139,7 +143,6 @@ Georg Brandl Bert Freudenberg Stian Andreassen - Tobias Pape Wanja Saatkamp Gerald Klix Mike Blume @@ -155,11 +158,13 @@ Dusty Phillips Lukas Renggli Guenter Jantzen + William Leslie Ned Batchelder Tim Felgentreff Anton Gulenko Amit Regmi Ben Young + Sergey Matyunin Nicolas Chauvat Andrew Durdin Andrew Chambers @@ -172,7 +177,7 @@ Gintautas Miliauskas Michael Twomey Lucian Branescu Mihaila - Devin Jeanpierre + anatoly techtonik Gabriel Lavoie Olivier Dormond Jared Grubb @@ -182,7 +187,6 @@ Brian Dorsey Victor Stinner Andrews Medina - anatoly techtonik Stuart Williams Jasper Schulz Christian Hudon @@ -206,18 +210,17 @@ Alex Perry Vaibhav Sood Alan McIntyre - William Leslie Alexander Sedov Attila Gobi Jasper.Schulz Christopher Pope + Florin Papa Christian Tismer Marc Abramowitz Dan Stromberg Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan - Mark Young Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -225,6 +228,7 @@ Pieter Zieschang Gabriel Lukas Vacek + Kunal Grover Andrew Dalke Sylvain Thenault Jakub Stasiak @@ -240,7 +244,6 @@ Kristjan Valur Jonsson David Lievens Neil Blakey-Milner - Sergey Matyunin Lutz Paelike Lucio Torre Lars Wassermann @@ -252,9 +255,11 @@ Artur Lisiecki Sergey Kishchenko Ignas Mikalajunas + Alecsandru Patrascu Christoph Gerum Martin Blais Lene Wagner + Catalin Gabriel Manciu Tomo Cocoa Kim Jin Su Toni Mattis @@ -266,8 +271,9 @@ Yury V. Zaytsev Anna Katrina Dominguez Bobby Impollonia - [email protected] + Vasantha Ganesh K Andrew Thompson + florinpapa Yusei Tahara Aaron Tubbs Ben Darnell @@ -293,6 +299,7 @@ Stephan Busemann Rafał Gałczyński Matt Bogosian + timo Christian Muirhead Berker Peksag James Lan @@ -305,6 +312,7 @@ Boglarka Vezer Chris Pressey Buck Golemon + Diana Popa Konrad Delong Dinu Gherman Chris Lambacher diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py --- a/dotviewer/graphparse.py +++ b/dotviewer/graphparse.py @@ -85,10 +85,11 @@ pass def splitline(line, re_word = re.compile(r'[^\s"]\S*|["]["]|["].*?[^\\]["]')): + import ast result = [] for word in re_word.findall(line): if word.startswith('"'): - word = eval(word) + word = ast.literal_eval(word) result.append(word) return result diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py --- a/dotviewer/graphserver.py +++ b/dotviewer/graphserver.py @@ -143,6 +143,11 @@ if __name__ == '__main__': if len(sys.argv) != 2: + if len(sys.argv) == 1: + # start locally + import sshgraphserver + sshgraphserver.ssh_graph_server(['LOCAL']) + sys.exit(0) print >> sys.stderr, __doc__ sys.exit(2) if sys.argv[1] == '--stdio': diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py --- a/dotviewer/sshgraphserver.py +++ b/dotviewer/sshgraphserver.py @@ -4,11 +4,14 @@ Usage: sshgraphserver.py hostname [more args for ssh...] + sshgraphserver.py LOCAL This logs in to 'hostname' by passing the arguments on the command-line to ssh. No further configuration is required: it works for all programs using the dotviewer library as long as they run on 'hostname' under the same username as the one sshgraphserver logs as. + +If 'hostname' is the string 'LOCAL', then it starts locally without ssh. """ import graphserver, socket, subprocess, random @@ -18,12 +21,19 @@ s1 = socket.socket() s1.bind(('127.0.0.1', socket.INADDR_ANY)) localhost, localport = s1.getsockname() - remoteport = random.randrange(10000, 20000) - # ^^^ and just hope there is no conflict - args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (remoteport, localport)] - args = args + sshargs + ['python -u -c "exec input()"'] - print ' '.join(args[:-1]) + if sshargs[0] != 'LOCAL': + remoteport = random.randrange(10000, 20000) + # ^^^ and just hope there is no conflict + + args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % ( + remoteport, localport)] + args = args + sshargs + ['python -u -c "exec input()"'] + else: + remoteport = localport + args = ['python', '-u', '-c', 'exec input()'] + + print ' '.join(args) p = subprocess.Popen(args, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE) diff --git a/lib-python/2.7/distutils/cmd.py b/lib-python/2.7/distutils/cmd.py --- a/lib-python/2.7/distutils/cmd.py +++ b/lib-python/2.7/distutils/cmd.py @@ -298,8 +298,16 @@ src_cmd_obj.ensure_finalized() for (src_option, dst_option) in option_pairs: if getattr(self, dst_option) is None: - setattr(self, dst_option, - getattr(src_cmd_obj, src_option)) + try: + setattr(self, dst_option, + getattr(src_cmd_obj, src_option)) + except AttributeError: + # This was added after problems with setuptools 18.4. + # It seems that setuptools 20.9 fixes the problem. + # But e.g. on Ubuntu 14.04 with /usr/bin/virtualenv + # if I say "virtualenv -p pypy venv-pypy" then it + # just installs setuptools 18.4 from some cache... + pass def get_finalized_command(self, command, create=1): diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py --- a/lib-python/2.7/subprocess.py +++ b/lib-python/2.7/subprocess.py @@ -834,54 +834,63 @@ c2pread, c2pwrite = None, None errread, errwrite = None, None + ispread = False if stdin is None: p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE) if p2cread is None: p2cread, _ = _subprocess.CreatePipe(None, 0) + ispread = True elif stdin == PIPE: p2cread, p2cwrite = _subprocess.CreatePipe(None, 0) + ispread = True elif isinstance(stdin, int): p2cread = msvcrt.get_osfhandle(stdin) else: # Assuming file-like object p2cread = msvcrt.get_osfhandle(stdin.fileno()) - p2cread = self._make_inheritable(p2cread) + p2cread = self._make_inheritable(p2cread, ispread) # We just duplicated the handle, it has to be closed at the end to_close.add(p2cread) if stdin == PIPE: to_close.add(p2cwrite) + ispwrite = False if stdout is None: c2pwrite = _subprocess.GetStdHandle(_subprocess.STD_OUTPUT_HANDLE) if c2pwrite is None: _, c2pwrite = _subprocess.CreatePipe(None, 0) + ispwrite = True elif stdout == PIPE: c2pread, c2pwrite = _subprocess.CreatePipe(None, 0) + ispwrite = True elif isinstance(stdout, int): c2pwrite = msvcrt.get_osfhandle(stdout) else: # Assuming file-like object c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) - c2pwrite = self._make_inheritable(c2pwrite) + c2pwrite = self._make_inheritable(c2pwrite, ispwrite) # We just duplicated the handle, it has to be closed at the end to_close.add(c2pwrite) if stdout == PIPE: to_close.add(c2pread) + ispwrite = False if stderr is None: errwrite = _subprocess.GetStdHandle(_subprocess.STD_ERROR_HANDLE) if errwrite is None: _, errwrite = _subprocess.CreatePipe(None, 0) + ispwrite = True elif stderr == PIPE: errread, errwrite = _subprocess.CreatePipe(None, 0) + ispwrite = True elif stderr == STDOUT: - errwrite = c2pwrite.handle # pass id to not close it + errwrite = c2pwrite elif isinstance(stderr, int): errwrite = msvcrt.get_osfhandle(stderr) else: # Assuming file-like object errwrite = msvcrt.get_osfhandle(stderr.fileno()) - errwrite = self._make_inheritable(errwrite) + errwrite = self._make_inheritable(errwrite, ispwrite) # We just duplicated the handle, it has to be closed at the end to_close.add(errwrite) if stderr == PIPE: @@ -892,13 +901,14 @@ errread, errwrite), to_close - def _make_inheritable(self, handle): + def _make_inheritable(self, handle, close=False): """Return a duplicate of handle, which is inheritable""" dupl = _subprocess.DuplicateHandle(_subprocess.GetCurrentProcess(), handle, _subprocess.GetCurrentProcess(), 0, 1, _subprocess.DUPLICATE_SAME_ACCESS) - # If the initial handle was obtained with CreatePipe, close it. - if not isinstance(handle, int): + # PyPy: If the initial handle was obtained with CreatePipe, + # close it. + if close: handle.Close() return dupl diff --git a/lib-python/2.7/test/test_descr.py b/lib-python/2.7/test/test_descr.py --- a/lib-python/2.7/test/test_descr.py +++ b/lib-python/2.7/test/test_descr.py @@ -1735,7 +1735,6 @@ ("__reversed__", reversed, empty_seq, set(), {}), ("__length_hint__", list, zero, set(), {"__iter__" : iden, "next" : stop}), - ("__sizeof__", sys.getsizeof, zero, set(), {}), ("__instancecheck__", do_isinstance, return_true, set(), {}), ("__missing__", do_dict_missing, some_number, set(("__class__",)), {}), @@ -1747,6 +1746,8 @@ ("__format__", format, format_impl, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ] + if test_support.check_impl_detail(): + specials.append(("__sizeof__", sys.getsizeof, zero, set(), {})) class Checker(object): def __getattr__(self, attr, test=self): @@ -1768,10 +1769,6 @@ raise MyException for name, runner, meth_impl, ok, env in specials: - if name == '__length_hint__' or name == '__sizeof__': - if not test_support.check_impl_detail(): - continue - class X(Checker): pass for attr, obj in env.iteritems(): diff --git a/lib-python/2.7/test/test_hash.py b/lib-python/2.7/test/test_hash.py --- a/lib-python/2.7/test/test_hash.py +++ b/lib-python/2.7/test/test_hash.py @@ -174,7 +174,7 @@ class StringlikeHashRandomizationTests(HashRandomizationTests): if check_impl_detail(pypy=True): - EMPTY_STRING_HASH = -1 + EMPTY_STRING_HASH = -2 else: EMPTY_STRING_HASH = 0 diff --git a/lib-python/2.7/test/test_sys_settrace.py b/lib-python/2.7/test/test_sys_settrace.py --- a/lib-python/2.7/test/test_sys_settrace.py +++ b/lib-python/2.7/test/test_sys_settrace.py @@ -328,8 +328,8 @@ def test_13_genexp(self): if self.using_gc: + gc.enable() test_support.gc_collect() - gc.enable() try: self.run_test(generator_example) # issue1265: if the trace function contains a generator, diff --git a/lib-python/stdlib-upgrade.txt b/lib-python/stdlib-upgrade.txt --- a/lib-python/stdlib-upgrade.txt +++ b/lib-python/stdlib-upgrade.txt @@ -5,15 +5,23 @@ overly detailed -1. check out the branch vendor/stdlib +0. make sure your working dir is clean +1. check out the branch vendor/stdlib (for 2.7) or vendor/stdlib-3-* (for py3k) + or create branch vendor/stdlib-3-* 2. upgrade the files there + 2a. remove lib-python/2.7/ or lib-python/3/ + 2b. copy the files from the cpython repo + 2c. hg add lib-python/2.7/ or lib-python/3/ + 2d. hg remove --after + 2e. show copied files in cpython repo by running `hg diff --git -r v<old> -r v<new> Lib | grep '^copy \(from\|to\)'` + 2f. fix copies / renames manually by running `hg copy --after <from> <to>` for each copied file 3. update stdlib-version.txt with the output of hg -id from the cpython repo 4. commit -5. update to default/py3k +5. update to default / py3k 6. create a integration branch for the new stdlib (just hg branch stdlib-$version) -7. merge vendor/stdlib +7. merge vendor/stdlib or vendor/stdlib-3-* 8. commit 10. fix issues 11. commit --close-branch -12. merge to default +12. merge to default / py3k diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -320,8 +320,7 @@ def __reduce_ex__(self, proto): return type(self), (list(self), self.maxlen) - def __hash__(self): - raise TypeError("deque objects are unhashable") + __hash__ = None def __copy__(self): return self.__class__(self, self.maxlen) diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py --- a/lib_pypy/_ctypes/basics.py +++ b/lib_pypy/_ctypes/basics.py @@ -199,10 +199,13 @@ return tp._alignmentofinstances() @builtinify -def byref(cdata): +def byref(cdata, offset=0): # "pointer" is imported at the end of this module to avoid circular # imports - return pointer(cdata) + ptr = pointer(cdata) + if offset != 0: + ptr._buffer[0] += offset + return ptr def cdata_from_address(self, address): # fix the address: turn it into as unsigned, in case it's a negative number diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py --- a/lib_pypy/_pypy_interact.py +++ b/lib_pypy/_pypy_interact.py @@ -6,7 +6,7 @@ irc_header = "And now for something completely different" -def interactive_console(mainmodule=None, quiet=False): +def interactive_console(mainmodule=None, quiet=False, future_flags=0): # set sys.{ps1,ps2} just before invoking the interactive interpreter. This # mimics what CPython does in pythonrun.c if not hasattr(sys, 'ps1'): @@ -37,15 +37,17 @@ raise ImportError from pyrepl.simple_interact import run_multiline_interactive_console except ImportError: - run_simple_interactive_console(mainmodule) + run_simple_interactive_console(mainmodule, future_flags=future_flags) else: - run_multiline_interactive_console(mainmodule) + run_multiline_interactive_console(mainmodule, future_flags=future_flags) -def run_simple_interactive_console(mainmodule): +def run_simple_interactive_console(mainmodule, future_flags=0): import code if mainmodule is None: import __main__ as mainmodule console = code.InteractiveConsole(mainmodule.__dict__, filename='<stdin>') + if future_flags: + console.compile.compiler.flags |= future_flags # some parts of code.py are copied here because it seems to be impossible # to start an interactive console without printing at least one line # of banner diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py --- a/lib_pypy/_pypy_irc_topic.py +++ b/lib_pypy/_pypy_irc_topic.py @@ -224,23 +224,9 @@ va ClCl orvat bayl zbqrengryl zntvp vf n tbbq guvat <psobym> """ -from string import ascii_uppercase, ascii_lowercase - def rot13(data): - """ A simple rot-13 encoder since `str.encode('rot13')` was removed from - Python as of version 3.0. It rotates both uppercase and lowercase letters individually. - """ - total = [] - for char in data: - if char in ascii_uppercase: - index = (ascii_uppercase.find(char) + 13) % 26 - total.append(ascii_uppercase[index]) - elif char in ascii_lowercase: - index = (ascii_lowercase.find(char) + 13) % 26 - total.append(ascii_lowercase[index]) - else: - total.append(char) - return "".join(total) + return ''.join(chr(ord(c)+(13 if 'A'<=c.upper()<='M' else + -13 if 'N'<=c.upper()<='Z' else 0)) for c in data) def some_topic(): import time diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py --- a/lib_pypy/_pypy_wait.py +++ b/lib_pypy/_pypy_wait.py @@ -1,51 +1,22 @@ -from resource import _struct_rusage, struct_rusage -from ctypes import CDLL, c_int, POINTER, byref -from ctypes.util import find_library +from resource import ffi, lib, _make_struct_rusage __all__ = ["wait3", "wait4"] -libc = CDLL(find_library("c")) -c_wait3 = libc.wait3 -c_wait3.argtypes = [POINTER(c_int), c_int, POINTER(_struct_rusage)] -c_wait3.restype = c_int - -c_wait4 = libc.wait4 -c_wait4.argtypes = [c_int, POINTER(c_int), c_int, POINTER(_struct_rusage)] -c_wait4.restype = c_int - -def create_struct_rusage(c_struct): - return struct_rusage(( - float(c_struct.ru_utime), - float(c_struct.ru_stime), - c_struct.ru_maxrss, - c_struct.ru_ixrss, - c_struct.ru_idrss, - c_struct.ru_isrss, - c_struct.ru_minflt, - c_struct.ru_majflt, - c_struct.ru_nswap, - c_struct.ru_inblock, - c_struct.ru_oublock, - c_struct.ru_msgsnd, - c_struct.ru_msgrcv, - c_struct.ru_nsignals, - c_struct.ru_nvcsw, - c_struct.ru_nivcsw)) def wait3(options): - status = c_int() - _rusage = _struct_rusage() - pid = c_wait3(byref(status), c_int(options), byref(_rusage)) + status = ffi.new("int *") + ru = ffi.new("struct rusage *") + pid = lib.wait3(status, options, ru) - rusage = create_struct_rusage(_rusage) + rusage = _make_struct_rusage(ru) - return pid, status.value, rusage + return pid, status[0], rusage def wait4(pid, options): - status = c_int() - _rusage = _struct_rusage() - pid = c_wait4(c_int(pid), byref(status), c_int(options), byref(_rusage)) + status = ffi.new("int *") + ru = ffi.new("struct rusage *") + pid = lib.wait4(pid, status, options, ru) - rusage = create_struct_rusage(_rusage) + rusage = _make_struct_rusage(ru) - return pid, status.value, rusage + return pid, status[0], rusage diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_pypy_winbase_build.py @@ -0,0 +1,91 @@ +# Note: uses the CFFI out-of-line ABI mode. We can't use the API +# mode because ffi.compile() needs to run the compiler, which +# needs 'subprocess', which needs 'msvcrt' and '_subprocess', +# which depend on '_pypy_winbase_cffi' already. +# +# Note that if you need to regenerate _pypy_winbase_cffi and +# can't use a preexisting PyPy to do that, then running this +# file should work as long as 'subprocess' is not imported +# by cffi. I had to hack in 'cffi._pycparser' to move an +#'import subprocess' to the inside of a function. (Also, +# CPython+CFFI should work as well.) +# +# This module supports both msvcrt.py and _subprocess.py. + +from cffi import FFI + +ffi = FFI() + +ffi.set_source("_pypy_winbase_cffi", None) + +# ---------- MSVCRT ---------- + +ffi.cdef(""" +typedef unsigned short wint_t; + +int _open_osfhandle(intptr_t osfhandle, int flags); +intptr_t _get_osfhandle(int fd); +int _setmode(int fd, int mode); +int _locking(int fd, int mode, long nbytes); + +int _kbhit(void); +int _getch(void); +wint_t _getwch(void); +int _getche(void); +wint_t _getwche(void); +int _putch(int); +wint_t _putwch(wchar_t); +int _ungetch(int); +wint_t _ungetwch(wint_t); +""") + +# ---------- SUBPROCESS ---------- + +ffi.cdef(""" +typedef struct { + DWORD cb; + char * lpReserved; + char * lpDesktop; + char * lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} STARTUPINFO, *LPSTARTUPINFO; + +typedef struct { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; +} PROCESS_INFORMATION, *LPPROCESS_INFORMATION; + +DWORD WINAPI GetVersion(void); +BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD); +BOOL WINAPI CloseHandle(HANDLE); +HANDLE WINAPI GetCurrentProcess(void); +BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE, + DWORD, BOOL, DWORD); +BOOL WINAPI CreateProcessA(char *, char *, void *, + void *, BOOL, DWORD, char *, + char *, LPSTARTUPINFO, LPPROCESS_INFORMATION); +DWORD WINAPI WaitForSingleObject(HANDLE, DWORD); +BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD); +BOOL WINAPI TerminateProcess(HANDLE, UINT); +HANDLE WINAPI GetStdHandle(DWORD); +""") + +# -------------------- + +if __name__ == "__main__": + ffi.compile() diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -0,0 +1,10 @@ +# auto-generated file +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\x50\x03\x00\x00\x13\x11\x00\x00\x53\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\x4F\x03\x00\x00\x4E\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\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x18\x03\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\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x 00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x42\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x01\x00\x00\x52\x03\x00\x00\x04\x01\x00\x00\x00\x01', + _globals = (b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x2F\x23DuplicateHandle',0,b'\x00\x00\x4C\x23GetCurrentProcess',0,b'\x00\x00\x2B\x23GetExitCodeProcess',0,b'\x00\x00\x49\x23GetStdHandle',0,b'\x00\x00\x3F\x23GetVersion',0,b'\x00\x00\x27\x23TerminateProcess',0,b'\x00\x00\x3B\x23WaitForSingleObject',0,b'\x00\x00\x38\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x44\x23_getwch',0,b'\x00\x00\x44\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\x46\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x41\x23_ungetwch',0), + _struct_unions = ((b'\x00\x00\x00\x4E\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\x4F\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\x42\x11wShowWindow',b'\x00\x00\x42\x11cbReserved2',b'\x00\x00\x51\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError')), + _typenames = (b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\x4EPROCESS_INFORMATION',b'\x00\x00\x00\x4FSTARTUPINFO',b'\x00\x00\x00\x42wint_t'), +) diff --git a/lib_pypy/_resource_build.py b/lib_pypy/_resource_build.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_resource_build.py @@ -0,0 +1,118 @@ +from cffi import FFI + +ffi = FFI() + +# Note: we don't directly expose 'struct timeval' or 'struct rlimit' + + +rlimit_consts = ''' +RLIMIT_CPU +RLIMIT_FSIZE +RLIMIT_DATA +RLIMIT_STACK +RLIMIT_CORE +RLIMIT_NOFILE +RLIMIT_OFILE +RLIMIT_VMEM +RLIMIT_AS +RLIMIT_RSS +RLIMIT_NPROC +RLIMIT_MEMLOCK +RLIMIT_SBSIZE +RLIM_INFINITY +RUSAGE_SELF +RUSAGE_CHILDREN +RUSAGE_BOTH +'''.split() + +rlimit_consts = ['#ifdef %s\n\t{"%s", %s},\n#endif\n' % (s, s, s) + for s in rlimit_consts] + + +ffi.set_source("_resource_cffi", """ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> + +static const struct my_rlimit_def { + const char *name; + long long value; +} my_rlimit_consts[] = { +$RLIMIT_CONSTS + { NULL, 0 } +}; + +#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) + +static double my_utime(struct rusage *input) +{ + return doubletime(input->ru_utime); +} + +static double my_stime(struct rusage *input) +{ + return doubletime(input->ru_stime); +} + +static int my_getrlimit(int resource, long long result[2]) +{ + struct rlimit rl; + if (getrlimit(resource, &rl) == -1) + return -1; + result[0] = rl.rlim_cur; + result[1] = rl.rlim_max; + return 0; +} + +static int my_setrlimit(int resource, long long cur, long long max) +{ + struct rlimit rl; + rl.rlim_cur = cur & RLIM_INFINITY; + rl.rlim_max = max & RLIM_INFINITY; + return setrlimit(resource, &rl); +} + +""".replace('$RLIMIT_CONSTS', ''.join(rlimit_consts))) + + +ffi.cdef(""" + +#define RLIM_NLIMITS ... + +const struct my_rlimit_def { + const char *name; + long long value; +} my_rlimit_consts[]; + +struct rusage { + long ru_maxrss; + long ru_ixrss; + long ru_idrss; + long ru_isrss; + long ru_minflt; + long ru_majflt; + long ru_nswap; + long ru_inblock; + long ru_oublock; + long ru_msgsnd; + long ru_msgrcv; + long ru_nsignals; + long ru_nvcsw; + long ru_nivcsw; + ...; +}; + +static double my_utime(struct rusage *); +static double my_stime(struct rusage *); +void getrusage(int who, struct rusage *result); +int my_getrlimit(int resource, long long result[2]); +int my_setrlimit(int resource, long long cur, long long max); + +int wait3(int *status, int options, struct rusage *rusage); +int wait4(int pid, int *status, int options, struct rusage *rusage); +""") + + +if __name__ == "__main__": + ffi.compile() diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py --- a/lib_pypy/_subprocess.py +++ b/lib_pypy/_subprocess.py @@ -4,151 +4,105 @@ subprocess module on Windows. """ +import sys +if sys.platform != 'win32': + raise ImportError("The '_subprocess' module is only available on Windows") # Declare external Win32 functions -import ctypes - -_kernel32 = ctypes.WinDLL('kernel32') - -_CloseHandle = _kernel32.CloseHandle -_CloseHandle.argtypes = [ctypes.c_int] -_CloseHandle.restype = ctypes.c_int - -_CreatePipe = _kernel32.CreatePipe -_CreatePipe.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), - ctypes.c_void_p, ctypes.c_int] -_CreatePipe.restype = ctypes.c_int - -_GetCurrentProcess = _kernel32.GetCurrentProcess -_GetCurrentProcess.argtypes = [] -_GetCurrentProcess.restype = ctypes.c_int +from _pypy_winbase_cffi import ffi as _ffi +_kernel32 = _ffi.dlopen('kernel32') GetVersion = _kernel32.GetVersion -GetVersion.argtypes = [] -GetVersion.restype = ctypes.c_int -_DuplicateHandle = _kernel32.DuplicateHandle -_DuplicateHandle.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int, - ctypes.POINTER(ctypes.c_int), - ctypes.c_int, ctypes.c_int, ctypes.c_int] -_DuplicateHandle.restype = ctypes.c_int - -_WaitForSingleObject = _kernel32.WaitForSingleObject -_WaitForSingleObject.argtypes = [ctypes.c_int, ctypes.c_uint] -_WaitForSingleObject.restype = ctypes.c_int - -_GetExitCodeProcess = _kernel32.GetExitCodeProcess -_GetExitCodeProcess.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int)] -_GetExitCodeProcess.restype = ctypes.c_int - -_TerminateProcess = _kernel32.TerminateProcess -_TerminateProcess.argtypes = [ctypes.c_int, ctypes.c_int] -_TerminateProcess.restype = ctypes.c_int - -_GetStdHandle = _kernel32.GetStdHandle -_GetStdHandle.argtypes = [ctypes.c_int] -_GetStdHandle.restype = ctypes.c_int - -class _STARTUPINFO(ctypes.Structure): - _fields_ = [('cb', ctypes.c_int), - ('lpReserved', ctypes.c_void_p), - ('lpDesktop', ctypes.c_char_p), - ('lpTitle', ctypes.c_char_p), - ('dwX', ctypes.c_int), - ('dwY', ctypes.c_int), - ('dwXSize', ctypes.c_int), - ('dwYSize', ctypes.c_int), - ('dwXCountChars', ctypes.c_int), - ('dwYCountChars', ctypes.c_int), - ("dwFillAttribute", ctypes.c_int), - ("dwFlags", ctypes.c_int), - ("wShowWindow", ctypes.c_short), - ("cbReserved2", ctypes.c_short), - ("lpReserved2", ctypes.c_void_p), - ("hStdInput", ctypes.c_int), - ("hStdOutput", ctypes.c_int), - ("hStdError", ctypes.c_int) - ] - -class _PROCESS_INFORMATION(ctypes.Structure): - _fields_ = [("hProcess", ctypes.c_int), - ("hThread", ctypes.c_int), - ("dwProcessID", ctypes.c_int), - ("dwThreadID", ctypes.c_int)] - -_CreateProcess = _kernel32.CreateProcessA -_CreateProcess.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_void_p, - ctypes.c_int, ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p, - ctypes.POINTER(_STARTUPINFO), ctypes.POINTER(_PROCESS_INFORMATION)] -_CreateProcess.restype = ctypes.c_int - -del ctypes # Now the _subprocess module implementation -from ctypes import c_int as _c_int, byref as _byref, WinError as _WinError +def _WinError(): + code, message = _ffi.getwinerror() + raise WindowsError(code, message) -class _handle: - def __init__(self, handle): - self.handle = handle +_INVALID_HANDLE_VALUE = _ffi.cast("HANDLE", -1) + +class _handle(object): + def __init__(self, c_handle): + # 'c_handle' is a cffi cdata of type HANDLE, which is basically 'void *' + self.c_handle = c_handle + if int(self) != -1: + self.c_handle = _ffi.gc(self.c_handle, _kernel32.CloseHandle) def __int__(self): - return self.handle + return int(_ffi.cast("intptr_t", self.c_handle)) - def __del__(self): - if self.handle is not None: - _CloseHandle(self.handle) + def __repr__(self): + return '<_subprocess.handle %d at 0x%x>' % (int(self), id(self)) def Detach(self): - handle, self.handle = self.handle, None - return handle + h = int(self) + if h != -1: + c_handle = self.c_handle + self.c_handle = _INVALID_HANDLE_VALUE + _ffi.gc(c_handle, None) + return h def Close(self): - if self.handle not in (-1, None): - _CloseHandle(self.handle) - self.handle = None + if int(self) != -1: + c_handle = self.c_handle + self.c_handle = _INVALID_HANDLE_VALUE + _ffi.gc(c_handle, None) + _kernel32.CloseHandle(c_handle) def CreatePipe(attributes, size): - read = _c_int() - write = _c_int() + handles = _ffi.new("HANDLE[2]") - res = _CreatePipe(_byref(read), _byref(write), None, size) + res = _kernel32.CreatePipe(handles, handles + 1, _ffi.NULL, size) if not res: raise _WinError() - return _handle(read.value), _handle(write.value) + return _handle(handles[0]), _handle(handles[1]) def GetCurrentProcess(): - return _handle(_GetCurrentProcess()) + return _handle(_kernel32.GetCurrentProcess()) def DuplicateHandle(source_process, source, target_process, access, inherit, options=0): - target = _c_int() + # CPython: the first three arguments are expected to be integers + target = _ffi.new("HANDLE[1]") - res = _DuplicateHandle(int(source_process), int(source), int(target_process), - _byref(target), - access, inherit, options) + res = _kernel32.DuplicateHandle( + _ffi.cast("HANDLE", source_process), + _ffi.cast("HANDLE", source), + _ffi.cast("HANDLE", target_process), + target, access, inherit, options) if not res: raise _WinError() - return _handle(target.value) + return _handle(target[0]) + +def _z(input): + if input is None: + return _ffi.NULL + if isinstance(input, basestring): + return str(input) + raise TypeError("string/unicode/None expected, got %r" % ( + type(input).__name__,)) def CreateProcess(name, command_line, process_attr, thread_attr, inherit, flags, env, start_dir, startup_info): - si = _STARTUPINFO() + si = _ffi.new("STARTUPINFO *") if startup_info is not None: si.dwFlags = startup_info.dwFlags si.wShowWindow = startup_info.wShowWindow + # CPython: these three handles are expected to be _handle objects if startup_info.hStdInput: - si.hStdInput = int(startup_info.hStdInput) + si.hStdInput = startup_info.hStdInput.c_handle if startup_info.hStdOutput: - si.hStdOutput = int(startup_info.hStdOutput) + si.hStdOutput = startup_info.hStdOutput.c_handle if startup_info.hStdError: - si.hStdError = int(startup_info.hStdError) + si.hStdError = startup_info.hStdError.c_handle - pi = _PROCESS_INFORMATION() + pi = _ffi.new("PROCESS_INFORMATION *") if env is not None: envbuf = "" @@ -156,47 +110,55 @@ envbuf += "%s=%s\0" % (k, v) envbuf += '\0' else: - envbuf = None + envbuf = _ffi.NULL - res = _CreateProcess(name, command_line, None, None, inherit, flags, envbuf, - start_dir, _byref(si), _byref(pi)) + res = _kernel32.CreateProcessA(_z(name), _z(command_line), _ffi.NULL, + _ffi.NULL, inherit, flags, envbuf, + _z(start_dir), si, pi) if not res: raise _WinError() - return _handle(pi.hProcess), _handle(pi.hThread), pi.dwProcessID, pi.dwThreadID + return _handle(pi.hProcess), _handle(pi.hThread), pi.dwProcessId, pi.dwThreadId def WaitForSingleObject(handle, milliseconds): - res = _WaitForSingleObject(int(handle), milliseconds) - + # CPython: the first argument is expected to be an integer. + res = _kernel32.WaitForSingleObject(_ffi.cast("HANDLE", handle), + milliseconds) if res < 0: raise _WinError() return res def GetExitCodeProcess(handle): - code = _c_int() + # CPython: the first argument is expected to be an integer. + code = _ffi.new("DWORD[1]") - res = _GetExitCodeProcess(int(handle), _byref(code)) + res = _kernel32.GetExitCodeProcess(_ffi.cast("HANDLE", handle), code) if not res: raise _WinError() - return code.value + return code[0] def TerminateProcess(handle, exitcode): - res = _TerminateProcess(int(handle), exitcode) + # CPython: the first argument is expected to be an integer. + # The second argument is silently wrapped in a UINT. + res = _kernel32.TerminateProcess(_ffi.cast("HANDLE", handle), + _ffi.cast("UINT", exitcode)) if not res: raise _WinError() def GetStdHandle(stdhandle): - res = _GetStdHandle(stdhandle) + stdhandle = _ffi.cast("DWORD", stdhandle) + res = _kernel32.GetStdHandle(stdhandle) if not res: return None else: - return res + # note: returns integer, not handle object + return int(_ffi.cast("intptr_t", res)) STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- 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.5.2 +Version: 1.7.0 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 --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,8 +4,8 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.5.2" -__version_info__ = (1, 5, 2) +__version__ = "1.7.0" +__version_info__ = (1, 7, 0) # 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/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h --- a/lib_pypy/cffi/_cffi_include.h +++ b/lib_pypy/cffi/_cffi_include.h @@ -57,6 +57,12 @@ # define _CFFI_UNUSED_FN /* nothing */ #endif +#ifdef __cplusplus +# ifndef _Bool +# define _Bool bool /* semi-hackish: C++ has no _Bool; bool is builtin */ +# endif +#endif + /********** CPython-specific section **********/ #ifndef PYPY_VERSION diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.5.2" + "\ncompiled with cffi version: 1.7.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/_pycparser/__init__.py b/lib_pypy/cffi/_pycparser/__init__.py --- a/lib_pypy/cffi/_pycparser/__init__.py +++ b/lib_pypy/cffi/_pycparser/__init__.py @@ -10,7 +10,6 @@ __all__ = ['c_lexer', 'c_parser', 'c_ast'] __version__ = '2.14' -from subprocess import Popen, PIPE from .c_parser import CParser @@ -28,6 +27,7 @@ When successful, returns the preprocessed file's contents. Errors from cpp will be printed out. """ + from subprocess import Popen, PIPE path_list = [cpp_path] if isinstance(cpp_args, list): path_list += cpp_args diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -299,6 +299,23 @@ """ return self._backend.string(cdata, maxlen) + def unpack(self, cdata, length): + """Unpack an array of C data of the given length, + returning a Python string/unicode/list. + + If 'cdata' is a pointer to 'char', returns a byte string. + It does not stop at the first null. This is equivalent to: + ffi.buffer(cdata, length)[:] + + If 'cdata' is a pointer to 'wchar_t', returns a unicode string. + 'length' is measured in wchar_t's; it is not the size in bytes. + + If 'cdata' is a pointer to anything else, returns a list of + 'length' items. This is a faster equivalent to: + [cdata[i] for i in range(length)] + """ + return self._backend.unpack(cdata, length) + def buffer(self, cdata, size=-1): """Return a read-write buffer object that references the raw C data pointed to by the given 'cdata'. The 'cdata' must be a pointer or @@ -315,8 +332,8 @@ def from_buffer(self, python_buffer): """Return a <cdata 'char[]'> that points to the data of the given Python object, which must support the buffer interface. - Note that this is not meant to be used on the built-in types str, - unicode, or bytearray (you can build 'char[]' arrays explicitly) + Note that this is not meant to be used on the built-in types + str or unicode (you can build 'char[]' arrays explicitly) but only on objects containing large quantities of raw data in some other format, like 'array.array' or numpy arrays. """ @@ -380,20 +397,7 @@ data. Later, when this new cdata object is garbage-collected, 'destructor(old_cdata_object)' will be called. """ - try: - gcp = self._backend.gcp - except AttributeError: - pass - else: - return gcp(cdata, destructor) - # - with self._lock: - try: - gc_weakrefs = self.gc_weakrefs - except AttributeError: - from .gc_weakref import GcWeakrefs - gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self) - return gc_weakrefs.build(cdata, destructor) + return self._backend.gcp(cdata, destructor) def _get_cached_btype(self, type): assert self._lock.acquire(False) is False @@ -721,6 +725,26 @@ raise ValueError("ffi.def_extern() is only available on API-mode FFI " "objects") + def list_types(self): + """Returns the user type names known to this FFI instance. + This returns a tuple containing three lists of names: + (typedef_names, names_of_structs, names_of_unions) + """ + typedefs = [] + structs = [] + unions = [] + for key in self._parser._declarations: + if key.startswith('typedef '): + typedefs.append(key[8:]) + elif key.startswith('struct '): + structs.append(key[7:]) + elif key.startswith('union '): + unions.append(key[6:]) + typedefs.sort() + structs.sort() + unions.sort() + return (typedefs, structs, unions) + def _load_backend_lib(backend, name, flags): if name is None: diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py --- a/lib_pypy/cffi/backend_ctypes.py +++ b/lib_pypy/cffi/backend_ctypes.py @@ -205,9 +205,7 @@ def __nonzero__(self): return bool(self._address) - - def __bool__(self): - return bool(self._address) + __bool__ = __nonzero__ @classmethod def _to_ctypes(cls, value): @@ -460,6 +458,12 @@ return x._value raise TypeError("character expected, got %s" % type(x).__name__) + def __nonzero__(self): + return ord(self._value) != 0 + else: + def __nonzero__(self): + return self._value != 0 + __bool__ = __nonzero__ if kind == 'float': @staticmethod @@ -993,6 +997,31 @@ assert onerror is None # XXX not implemented return BType(source, error) + def gcp(self, cdata, destructor): + BType = self.typeof(cdata) + + if destructor is None: + if not (hasattr(BType, '_gcp_type') and + BType._gcp_type is BType): + raise TypeError("Can remove destructor only on a object " + "previously returned by ffi.gc()") + cdata._destructor = None + return None + + try: + gcp_type = BType._gcp_type + except AttributeError: + class CTypesDataGcp(BType): + __slots__ = ['_orig', '_destructor'] + def __del__(self): + if self._destructor is not None: + self._destructor(self._orig) + gcp_type = BType._gcp_type = CTypesDataGcp + new_cdata = self.cast(gcp_type, cdata) + new_cdata._orig = cdata + new_cdata._destructor = destructor + return new_cdata + typeof = type def getcname(self, BType, replace_with): diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py --- a/lib_pypy/cffi/commontypes.py +++ b/lib_pypy/cffi/commontypes.py @@ -35,8 +35,11 @@ "you call ffi.set_unicode()" % (commontype,)) else: if commontype == cdecl: - raise api.FFIError("Unsupported type: %r. Please file a bug " - "if you think it should be." % (commontype,)) + raise api.FFIError( + "Unsupported type: %r. Please look at " + "http://cffi.readthedocs.io/en/latest/cdef.html#ffi-cdef-limitations " + "and file an issue if you think this type should really " + "be supported." % (commontype,)) result, quals = parser.parse_type_and_quals(cdecl) # recursive assert isinstance(result, model.BaseTypeByIdentity) diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -29,7 +29,8 @@ _r_stdcall1 = re.compile(r"\b(__stdcall|WINAPI)\b") _r_stdcall2 = re.compile(r"[(]\s*(__stdcall|WINAPI)\b") _r_cdecl = re.compile(r"\b__cdecl\b") -_r_extern_python = re.compile(r'\bextern\s*"Python"\s*.') +_r_extern_python = re.compile(r'\bextern\s*"' + r'(Python|Python\s*\+\s*C|C\s*\+\s*Python)"\s*.') _r_star_const_space = re.compile( # matches "* const " r"[*]\s*((const|volatile|restrict)\b\s*)+") @@ -88,6 +89,12 @@ # void __cffi_extern_python_start; # int foo(int); # void __cffi_extern_python_stop; + # + # input: `extern "Python+C" int foo(int);` + # output: + # void __cffi_extern_python_plus_c_start; + # int foo(int); + # void __cffi_extern_python_stop; parts = [] while True: match = _r_extern_python.search(csource) @@ -98,7 +105,10 @@ #print ''.join(parts)+csource #print '=>' parts.append(csource[:match.start()]) - parts.append('void __cffi_extern_python_start; ') + if 'C' in match.group(1): + parts.append('void __cffi_extern_python_plus_c_start; ') + else: + parts.append('void __cffi_extern_python_start; ') if csource[endpos] == '{': # grouping variant closing = csource.find('}', endpos) @@ -302,7 +312,7 @@ break # try: - self._inside_extern_python = False + self._inside_extern_python = '__cffi_extern_python_stop' for decl in iterator: if isinstance(decl, pycparser.c_ast.Decl): self._parse_decl(decl) @@ -376,8 +386,10 @@ tp = self._get_type_pointer(tp, quals) if self._options.get('dllexport'): tag = 'dllexport_python ' - elif self._inside_extern_python: + elif self._inside_extern_python == '__cffi_extern_python_start': tag = 'extern_python ' + elif self._inside_extern_python == '__cffi_extern_python_plus_c_start': + tag = 'extern_python_plus_c ' else: tag = 'function ' self._declare(tag + decl.name, tp) @@ -421,11 +433,9 @@ # hack: `extern "Python"` in the C source is replaced # with "void __cffi_extern_python_start;" and # "void __cffi_extern_python_stop;" - self._inside_extern_python = not self._inside_extern_python - assert self._inside_extern_python == ( - decl.name == '__cffi_extern_python_start') + self._inside_extern_python = decl.name else: - if self._inside_extern_python: + if self._inside_extern_python !='__cffi_extern_python_stop': raise api.CDefError( "cannot declare constants or " "variables with 'extern \"Python\"'") diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -814,7 +814,7 @@ try: if ftype.is_integer_type() or fbitsize >= 0: # accept all integers, but complain on float or double - prnt(" (void)((p->%s) << 1); /* check that '%s.%s' is " + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " "an integer */" % (fname, cname, fname)) continue # only accept exactly the type declared, except that '[]' @@ -991,7 +991,7 @@ prnt('static int %s(unsigned long long *o)' % funcname) prnt('{') prnt(' int n = (%s) <= 0;' % (name,)) - prnt(' *o = (unsigned long long)((%s) << 0);' + prnt(' *o = (unsigned long long)((%s) | 0);' ' /* check that %s is an integer */' % (name, name)) if check_value is not None: if check_value > 0: @@ -1145,11 +1145,11 @@ def _generate_cpy_extern_python_collecttype(self, tp, name): assert isinstance(tp, model.FunctionPtrType) self._do_collect_type(tp) + _generate_cpy_dllexport_python_collecttype = \ + _generate_cpy_extern_python_plus_c_collecttype = \ + _generate_cpy_extern_python_collecttype - def _generate_cpy_dllexport_python_collecttype(self, tp, name): - self._generate_cpy_extern_python_collecttype(tp, name) - - def _generate_cpy_extern_python_decl(self, tp, name, dllexport=False): + def _extern_python_decl(self, tp, name, tag_and_space): prnt = self._prnt if isinstance(tp.result, model.VoidType): size_of_result = '0' @@ -1184,11 +1184,7 @@ size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % ( tp.result.get_c_name(''), size_of_a, tp.result.get_c_name(''), size_of_a) - if dllexport: - tag = 'CFFI_DLLEXPORT' - else: - tag = 'static' - prnt('%s %s' % (tag, tp.result.get_c_name(name_and_arguments))) + prnt('%s%s' % (tag_and_space, tp.result.get_c_name(name_and_arguments))) prnt('{') prnt(' char a[%s];' % size_of_a) prnt(' char *p = a;') @@ -1206,8 +1202,14 @@ prnt() self._num_externpy += 1 + def _generate_cpy_extern_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'static ') + def _generate_cpy_dllexport_python_decl(self, tp, name): - self._generate_cpy_extern_python_decl(tp, name, dllexport=True) + self._extern_python_decl(tp, name, 'CFFI_DLLEXPORT ') + + def _generate_cpy_extern_python_plus_c_decl(self, tp, name): + self._extern_python_decl(tp, name, '') def _generate_cpy_extern_python_ctx(self, tp, name): if self.target_is_python: @@ -1220,8 +1222,9 @@ self._lsts["global"].append( GlobalExpr(name, '&_cffi_externpy__%s' % name, type_op, name)) - def _generate_cpy_dllexport_python_ctx(self, tp, name): - self._generate_cpy_extern_python_ctx(tp, name) + _generate_cpy_dllexport_python_ctx = \ + _generate_cpy_extern_python_plus_c_ctx = \ + _generate_cpy_extern_python_ctx def _string_literal(self, s): def _char_repr(c): @@ -1231,7 +1234,7 @@ if c == '\n': return '\\n' return '\\%03o' % ord(c) lines = [] - for line in s.splitlines(True): + for line in s.splitlines(True) or ['']: lines.append('"%s"' % ''.join([_char_repr(c) for c in line])) return ' \\\n'.join(lines) @@ -1247,7 +1250,7 @@ def _emit_bytecode_UnknownIntegerType(self, tp, index): s = ('_cffi_prim_int(sizeof(%s), (\n' - ' ((%s)-1) << 0 /* check that %s is an integer type */\n' + ' ((%s)-1) | 0 /* check that %s is an integer type */\n' ' ) <= 0)' % (tp.name, tp.name, tp.name)) self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) @@ -1319,7 +1322,9 @@ s = s.encode('ascii') super(NativeIO, self).write(s) -def _make_c_or_py_source(ffi, module_name, preamble, target_file): +def _make_c_or_py_source(ffi, module_name, preamble, target_file, verbose): + if verbose: + print("generating %s" % (target_file,)) recompiler = Recompiler(ffi, module_name, target_is_python=(preamble is None)) recompiler.collect_type_table() @@ -1331,6 +1336,8 @@ with open(target_file, 'r') as f1: if f1.read(len(output) + 1) != output: raise IOError + if verbose: + print("(already up-to-date)") return False # already up-to-date except IOError: tmp_file = '%s.~%d' % (target_file, os.getpid()) @@ -1343,12 +1350,14 @@ os.rename(tmp_file, target_file) return True -def make_c_source(ffi, module_name, preamble, target_c_file): +def make_c_source(ffi, module_name, preamble, target_c_file, verbose=False): assert preamble is not None - return _make_c_or_py_source(ffi, module_name, preamble, target_c_file) + return _make_c_or_py_source(ffi, module_name, preamble, target_c_file, + verbose) -def make_py_source(ffi, module_name, target_py_file): - return _make_c_or_py_source(ffi, module_name, None, target_py_file) +def make_py_source(ffi, module_name, target_py_file, verbose=False): + return _make_c_or_py_source(ffi, module_name, None, target_py_file, + verbose) def _modname_to_file(outputdir, modname, extension): parts = modname.split('.') @@ -1438,7 +1447,8 @@ target = '*' # ext = ffiplatform.get_extension(ext_c_file, module_name, **kwds) - updated = make_c_source(ffi, module_name, preamble, c_file) + updated = make_c_source(ffi, module_name, preamble, c_file, + verbose=compiler_verbose) if call_c_compiler: patchlist = [] cwd = os.getcwd() @@ -1458,7 +1468,8 @@ else: if c_file is None: c_file, _ = _modname_to_file(tmpdir, module_name, '.py') - updated = make_py_source(ffi, module_name, c_file) + updated = make_py_source(ffi, module_name, c_file, + verbose=compiler_verbose) if call_c_compiler: return c_file else: @@ -1484,4 +1495,7 @@ def typeof_disabled(*args, **kwds): raise NotImplementedError ffi._typeof = typeof_disabled + for name in dir(ffi): + if not name.startswith('_') and not hasattr(module.ffi, name): + setattr(ffi, name, NotImplemented) return module.lib diff --git a/lib_pypy/ctypes_config_cache/.empty b/lib_pypy/ctypes_config_cache/.empty new file mode 100644 --- /dev/null +++ b/lib_pypy/ctypes_config_cache/.empty @@ -0,0 +1,1 @@ +dummy file to allow old buildbot configuration to run diff --git a/lib_pypy/ctypes_config_cache/__init__.py b/lib_pypy/ctypes_config_cache/__init__.py deleted file mode 100644 diff --git a/lib_pypy/ctypes_config_cache/dumpcache.py b/lib_pypy/ctypes_config_cache/dumpcache.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/dumpcache.py +++ /dev/null @@ -1,21 +0,0 @@ -import sys, os -from ctypes_configure import dumpcache - -def dumpcache2(basename, config): - size = 32 if sys.maxint <= 2**32 else 64 - filename = '_%s_%s_.py' % (basename, size) - dumpcache.dumpcache(__file__, filename, config) - # - filename = os.path.join(os.path.dirname(__file__), - '_%s_cache.py' % (basename,)) - g = open(filename, 'w') - print >> g, '''\ -import sys -_size = 32 if sys.maxint <= 2**32 else 64 -# XXX relative import, should be removed together with -# XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib -_mod = __import__("_%s_%%s_" %% (_size,), - globals(), locals(), ["*"]) -globals().update(_mod.__dict__)\ -''' % (basename,) - g.close() diff --git a/lib_pypy/ctypes_config_cache/locale.ctc.py b/lib_pypy/ctypes_config_cache/locale.ctc.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/locale.ctc.py +++ /dev/null @@ -1,73 +0,0 @@ -""" -'ctypes_configure' source for _locale.py. -Run this to rebuild _locale_cache.py. -""" - -from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType, check_eci) -import dumpcache - -# ____________________________________________________________ - -_CONSTANTS = [ - 'LC_CTYPE', - 'LC_TIME', - 'LC_COLLATE', - 'LC_MONETARY', - 'LC_MESSAGES', - 'LC_NUMERIC', - 'LC_ALL', - 'CHAR_MAX', -] - -class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['limits.h', - 'locale.h']) -for key in _CONSTANTS: - setattr(LocaleConfigure, key, DefinedConstantInteger(key)) - -config = configure(LocaleConfigure, noerr=True) -for key, value in config.items(): - if value is None: - del config[key] - _CONSTANTS.remove(key) - -# ____________________________________________________________ - -eci = ExternalCompilationInfo(includes=['locale.h', 'langinfo.h']) -HAS_LANGINFO = check_eci(eci) - -if HAS_LANGINFO: - # list of all possible names - langinfo_names = [ - "RADIXCHAR", "THOUSEP", "CRNCYSTR", - "D_T_FMT", "D_FMT", "T_FMT", "AM_STR", "PM_STR", - "CODESET", "T_FMT_AMPM", "ERA", "ERA_D_FMT", "ERA_D_T_FMT", - "ERA_T_FMT", "ALT_DIGITS", "YESEXPR", "NOEXPR", "_DATE_FMT", - ] - for i in range(1, 8): - langinfo_names.append("DAY_%d" % i) - langinfo_names.append("ABDAY_%d" % i) - for i in range(1, 13): - langinfo_names.append("MON_%d" % i) - langinfo_names.append("ABMON_%d" % i) - - class LanginfoConfigure: - _compilation_info_ = eci - nl_item = SimpleType('nl_item') - for key in langinfo_names: - setattr(LanginfoConfigure, key, DefinedConstantInteger(key)) - - langinfo_config = configure(LanginfoConfigure) - for key, value in langinfo_config.items(): - if value is None: - del langinfo_config[key] - langinfo_names.remove(key) - config.update(langinfo_config) - _CONSTANTS += langinfo_names - -# ____________________________________________________________ - -config['ALL_CONSTANTS'] = tuple(_CONSTANTS) -config['HAS_LANGINFO'] = HAS_LANGINFO -dumpcache.dumpcache2('locale', config) diff --git a/lib_pypy/ctypes_config_cache/rebuild.py b/lib_pypy/ctypes_config_cache/rebuild.py deleted file mode 100755 --- a/lib_pypy/ctypes_config_cache/rebuild.py +++ /dev/null @@ -1,56 +0,0 @@ -#! /usr/bin/env python -# Run this script to rebuild all caches from the *.ctc.py files. - -import os, sys - -sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) - -import py - -_dirpath = os.path.dirname(__file__) or os.curdir - -from rpython.tool.ansi_print import AnsiLogger -log = AnsiLogger("ctypes_config_cache") - - -def rebuild_one(name): - filename = os.path.join(_dirpath, name) - d = {'__file__': filename} - path = sys.path[:] - try: - sys.path.insert(0, _dirpath) - execfile(filename, d) - finally: - sys.path[:] = path - -def try_rebuild(): - size = 32 if sys.maxint <= 2**32 else 64 - # remove the files '_*_size_.py' - left = {} - for p in os.listdir(_dirpath): - if p.startswith('_') and (p.endswith('_%s_.py' % size) or - p.endswith('_%s_.pyc' % size)): - os.unlink(os.path.join(_dirpath, p)) - elif p.startswith('_') and (p.endswith('_.py') or - p.endswith('_.pyc')): - for i in range(2, len(p)-4): - left[p[:i]] = True - # remove the files '_*_cache.py' if there is no '_*_*_.py' left around - for p in os.listdir(_dirpath): - if p.startswith('_') and (p.endswith('_cache.py') or - p.endswith('_cache.pyc')): - if p[:-9] not in left: - os.unlink(os.path.join(_dirpath, p)) - # - for p in os.listdir(_dirpath): - if p.endswith('.ctc.py'): - try: - rebuild_one(p) - except Exception, e: - log.ERROR("Running %s:\n %s: %s" % ( - os.path.join(_dirpath, p), - e.__class__.__name__, e)) - - -if __name__ == '__main__': - try_rebuild() diff --git a/lib_pypy/ctypes_config_cache/resource.ctc.py b/lib_pypy/ctypes_config_cache/resource.ctc.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/resource.ctc.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -'ctypes_configure' source for resource.py. -Run this to rebuild _resource_cache.py. -""" - - -from ctypes import sizeof -import dumpcache -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, - SimpleType) - - -_CONSTANTS = ( - 'RLIM_INFINITY', - 'RLIM_NLIMITS', -) -_OPTIONAL_CONSTANTS = ( - 'RLIMIT_CPU', - 'RLIMIT_FSIZE', - 'RLIMIT_DATA', - 'RLIMIT_STACK', - 'RLIMIT_CORE', - 'RLIMIT_RSS', - 'RLIMIT_NPROC', - 'RLIMIT_NOFILE', - 'RLIMIT_OFILE', - 'RLIMIT_MEMLOCK', - 'RLIMIT_AS', - 'RLIMIT_LOCKS', - 'RLIMIT_SIGPENDING', - 'RLIMIT_MSGQUEUE', - 'RLIMIT_NICE', - 'RLIMIT_RTPRIO', - 'RLIMIT_VMEM', - - 'RUSAGE_BOTH', - 'RUSAGE_SELF', - 'RUSAGE_CHILDREN', -) - -# Setup our configure -class ResourceConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) - rlim_t = SimpleType('rlim_t') -for key in _CONSTANTS: - setattr(ResourceConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(ResourceConfigure, key, DefinedConstantInteger(key)) - -# Configure constants and types -config = configure(ResourceConfigure) -config['rlim_t_max'] = (1<<(sizeof(config['rlim_t']) * 8)) - 1 -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - optional_constants.append(key) - else: - del config[key] - -config['ALL_CONSTANTS'] = _CONSTANTS + tuple(optional_constants) -dumpcache.dumpcache2('resource', config) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -839,7 +839,7 @@ month = self._month if day is None: day = self._day - return date(year, month, day) + return date.__new__(type(self), year, month, day) # Comparisons of date objects with other. @@ -1356,7 +1356,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - return time(hour, minute, second, microsecond, tzinfo) + return time.__new__(type(self), + hour, minute, second, microsecond, tzinfo) def __nonzero__(self): if self.second or self.microsecond: @@ -1566,8 +1567,9 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - return datetime(year, month, day, hour, minute, second, microsecond, - tzinfo) + return datetime.__new__(type(self), + year, month, day, hour, minute, second, + microsecond, tzinfo) def astimezone(self, tz): if not isinstance(tz, tzinfo): diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info --- a/lib_pypy/greenlet.egg-info +++ b/lib_pypy/greenlet.egg-info @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: greenlet -Version: 0.4.9 +Version: 0.4.10 Summary: Lightweight in-process concurrent programming Home-page: https://github.com/python-greenlet/greenlet Author: Ralf Schmitt (for CPython), PyPy team diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,7 +1,7 @@ import sys import _continuation -__version__ = "0.4.9" +__version__ = "0.4.10" # ____________________________________________________________ # Exceptions diff --git a/lib_pypy/msvcrt.py b/lib_pypy/msvcrt.py --- a/lib_pypy/msvcrt.py +++ b/lib_pypy/msvcrt.py @@ -7,26 +7,39 @@ # XXX incomplete: implemented only functions needed by subprocess.py # PAC: 2010/08 added MS locking for Whoosh -import ctypes +# 07/2016: rewrote in CFFI + +import sys +if sys.platform != 'win32': + raise ImportError("The 'msvcrt' module is only available on Windows") + +import _rawffi +from _pypy_winbase_cffi import ffi as _ffi +_lib = _ffi.dlopen(_rawffi.get_libc().name) + import errno -from ctypes_support import standard_c_lib as _c -from ctypes_support import get_errno - -try: - open_osfhandle = _c._open_osfhandle -except AttributeError: # we are not on windows - raise ImportError try: from __pypy__ import builtinify, validate_fd except ImportError: builtinify = validate_fd = lambda f: f -open_osfhandle.argtypes = [ctypes.c_int, ctypes.c_int] -open_osfhandle.restype = ctypes.c_int +def _ioerr(): + e = _ffi.errno + raise IOError(e, errno.errorcode[e]) -_get_osfhandle = _c._get_osfhandle -_get_osfhandle.argtypes = [ctypes.c_int] -_get_osfhandle.restype = ctypes.c_int + +@builtinify +def open_osfhandle(fd, flags): + """"open_osfhandle(handle, flags) -> file descriptor + + Create a C runtime file descriptor from the file handle handle. The + flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY, + and os.O_TEXT. The returned file descriptor may be used as a parameter + to os.fdopen() to create a file object.""" + fd = _lib._open_osfhandle(fd, flags) + if fd == -1: + _ioerr() + return fd @builtinify def get_osfhandle(fd): @@ -38,62 +51,74 @@ validate_fd(fd) except OSError as e: raise IOError(*e.args) - return _get_osfhandle(fd) + result = _lib._get_osfhandle(fd) + if result == -1: + _ioerr() + return result -setmode = _c._setmode -setmode.argtypes = [ctypes.c_int, ctypes.c_int] -setmode.restype = ctypes.c_int +@builtinify +def setmode(fd, flags): + """setmode(fd, mode) -> Previous mode + + Set the line-end translation mode for the file descriptor fd. To set + it to text mode, flags should be os.O_TEXT; for binary, it should be + os.O_BINARY.""" + flags = _lib._setmode(fd, flags) + if flags == -1: + _ioerr() + return flags LK_UNLCK, LK_LOCK, LK_NBLCK, LK_RLCK, LK_NBRLCK = range(5) -_locking = _c._locking -_locking.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int] _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
