[pypy-commit] pypy resource_warning: merge default
cfbolz
pypy.commits at gmail.com
Fri Aug 5 04:00:52 EDT 2016
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
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
- timo at eistee.fritz.box
+ 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\x00\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
+
+ at 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
+ at 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]
More information about the pypy-commit
mailing list