[pypy-commit] pypy py3.6: merge py3.5 into branch
mattip
pypy.commits at gmail.com
Sun Nov 18 03:57:39 EST 2018
Author: Matti Picus <matti.picus at gmail.com>
Branch: py3.6
Changeset: r95329:18106031c176
Date: 2018-11-17 23:33 -0800
http://bitbucket.org/pypy/pypy/changeset/18106031c176/
Log: merge py3.5 into branch
diff too long, truncating to 2000 out of 2161 lines
diff --git a/lib-python/3/distutils/sysconfig_pypy.py b/lib-python/3/distutils/sysconfig_pypy.py
--- a/lib-python/3/distutils/sysconfig_pypy.py
+++ b/lib-python/3/distutils/sysconfig_pypy.py
@@ -8,11 +8,9 @@
available.
"""
-__revision__ = "$Id: sysconfig.py 85358 2010-10-10 09:54:59Z antoine.pitrou $"
-
import sys
import os
-import imp
+import imp, _imp
from distutils.errors import DistutilsPlatformError
@@ -71,9 +69,17 @@
def _init_nt():
"""Initialize the module as appropriate for NT"""
g = {}
+ # set basic install directories
+ g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
+ g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
+
+ # XXX hmmm.. a normal install puts include files here
+ g['INCLUDEPY'] = get_python_inc(plat_specific=0)
+
+ g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
g['EXE'] = ".exe"
- g['SO'] = ".pyd"
- g['SOABI'] = g['SO'].rsplit('.')[0] # xxx?
+ g['VERSION'] = get_python_version().replace(".", "")
+ g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
global _config_vars
_config_vars = g
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -190,7 +190,7 @@
# Prefer poll, if available, since you can poll() any fd
# which can't be done with select().
if HAVE_POLL:
- p.register(sock.fileno(), POLLOUT | POLLIN)
+ p.register(sock.fileno(), POLLOUT if writing else POLLIN)
rc = len(p.poll(timeout * 1000.0))
else:
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -27,6 +27,12 @@
from .console import Console, Event
from .unix_eventqueue import EventQueue
from .trace import trace
+try:
+ from __pypy__ import pyos_inputhook
+except ImportError:
+ def pyos_inputhook():
+ pass
+
class InvalidTerminal(RuntimeError):
pass
@@ -76,8 +82,8 @@
pass
def register(self, fd, flag):
self.fd = fd
- def poll(self, timeout=None):
- r,w,e = select.select([self.fd],[],[],timeout)
+ def poll(self): # note: a 'timeout' argument would be *milliseconds*
+ r,w,e = select.select([self.fd],[],[])
return r
POLLIN = getattr(select, "POLLIN", None)
@@ -407,6 +413,7 @@
def get_event(self, block=1):
while self.event_queue.empty():
while 1: # All hail Unix!
+ pyos_inputhook()
try:
self.push_char(os.read(self.input_fd, 1))
except (IOError, OSError) as err:
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -42,3 +42,16 @@
.. branch: py3.6-wordcode
implement new wordcode instruction encoding on the 3.6 branch
+
+.. branch: socket_default_timeout_blockingness
+
+Backport CPython fix for possible shell injection issue in `distutils.spawn`,
+https://bugs.python.org/issue34540
+
+.. branch: cffi_dlopen_unicode
+
+Enable use of unicode file names in `dlopen`
+
+.. branch: rlock-in-rpython
+
+Backport CPython fix for `thread.RLock`
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -110,6 +110,7 @@
'stack_almost_full' : 'interp_magic.stack_almost_full',
'fsencode' : 'interp_magic.fsencode',
'fsdecode' : 'interp_magic.fsdecode',
+ 'pyos_inputhook' : 'interp_magic.pyos_inputhook',
}
submodules = {
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -209,3 +209,13 @@
def revdb_stop(space):
from pypy.interpreter.reverse_debugging import stop_point
stop_point()
+
+def pyos_inputhook(space):
+ """Call PyOS_InputHook() from the CPython C API."""
+ if not space.config.objspace.usemodules.cpyext:
+ return
+ w_modules = space.sys.get('modules')
+ if space.finditem_str(w_modules, 'cpyext') is None:
+ return # cpyext not imported yet, ignore
+ from pypy.module.cpyext.api import invoke_pyos_inputhook
+ invoke_pyos_inputhook(space)
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -79,13 +79,6 @@
w_result = self.ctype.cast_to_int(ptr)
return w_result
- def long(self, space):
- w_result = self.int(space)
- space = self.space
- if space.is_w(space.type(w_result), space.w_int):
- w_result = space.newlong(space.int_w(w_result))
- return w_result
-
def float(self):
with self as ptr:
w_result = self.ctype.float(ptr)
@@ -664,7 +657,6 @@
__repr__ = interp2app(W_CData.repr),
__bool__ = interp2app(W_CData.bool),
__int__ = interp2app(W_CData.int),
- __long__ = interp2app(W_CData.long),
__float__ = interp2app(W_CData.float),
__complex__ = interp2app(W_CData.complex),
__len__ = interp2app(W_CData.len),
diff --git a/pypy/module/_cffi_backend/cdlopen.py b/pypy/module/_cffi_backend/cdlopen.py
--- a/pypy/module/_cffi_backend/cdlopen.py
+++ b/pypy/module/_cffi_backend/cdlopen.py
@@ -1,31 +1,24 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rlib.objectmodel import specialize, we_are_translated
-from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError
+from rpython.rlib.rdynload import DLLHANDLE, dlsym, dlclose
from pypy.interpreter.error import oefmt
-from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
from pypy.module._cffi_backend.parse_c_type import (
_CFFI_OPCODE_T, GLOBAL_S, CDL_INTCONST_S, STRUCT_UNION_S, FIELD_S,
ENUM_S, TYPENAME_S, ll_set_cdl_realize_global_int)
from pypy.module._cffi_backend.realize_c_type import getop
from pypy.module._cffi_backend.lib_obj import W_LibObject
-from pypy.module._cffi_backend import cffi_opcode, cffi1_module
-
+from pypy.module._cffi_backend import cffi_opcode, cffi1_module, misc
class W_DlOpenLibObject(W_LibObject):
- def __init__(self, ffi, filename, flags):
- with rffi.scoped_str2charp(filename) as ll_libname:
- if filename is None:
- filename = "<None>"
- try:
- handle = dlopen(ll_libname, flags)
- except DLOpenError as e:
- raise wrap_dlopenerror(ffi.space, e, filename)
- W_LibObject.__init__(self, ffi, filename)
+ def __init__(self, ffi, w_filename, flags):
+ space = ffi.space
+ fname, handle = misc.dlopen_w(space, w_filename, flags)
+ W_LibObject.__init__(self, ffi, fname)
self.libhandle = handle
- self.register_finalizer(ffi.space)
+ self.register_finalizer(space)
def _finalize_(self):
h = self.libhandle
diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py
--- a/pypy/module/_cffi_backend/embedding.py
+++ b/pypy/module/_cffi_backend/embedding.py
@@ -95,7 +95,9 @@
if os.name == 'nt':
do_includes = r"""
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
+#endif
#include <windows.h>
static void _cffi_init(void);
diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -572,8 +572,8 @@
return self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CDATA)
- @unwrap_spec(filename="fsencode_or_none", flags=int)
- def descr_dlopen(self, filename, flags=0):
+ @unwrap_spec(flags=int)
+ def descr_dlopen(self, w_filename, flags=0):
"""\
Load and return a dynamic library identified by 'name'. The standard
C library can be loaded by passing None.
@@ -584,7 +584,7 @@
first access."""
#
from pypy.module._cffi_backend import cdlopen
- return cdlopen.W_DlOpenLibObject(self, filename, flags)
+ return cdlopen.W_DlOpenLibObject(self, w_filename, flags)
def descr_dlclose(self, w_lib):
diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py
--- a/pypy/module/_cffi_backend/libraryobj.py
+++ b/pypy/module/_cffi_backend/libraryobj.py
@@ -4,28 +4,21 @@
from pypy.interpreter.error import oefmt
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
-from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
from rpython.rtyper.lltypesystem import rffi
-from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError
+from rpython.rlib.rdynload import DLLHANDLE, dlsym, dlclose
from pypy.module._cffi_backend.cdataobj import W_CData
from pypy.module._cffi_backend.ctypeobj import W_CType
+from pypy.module._cffi_backend import misc
class W_Library(W_Root):
_immutable_ = True
- def __init__(self, space, filename, flags):
+ def __init__(self, space, w_filename, flags):
self.space = space
- with rffi.scoped_str2charp(filename) as ll_libname:
- if filename is None:
- filename = "<None>"
- try:
- self.handle = dlopen(ll_libname, flags)
- except DLOpenError as e:
- raise wrap_dlopenerror(space, e, filename)
- self.name = filename
+ self.name, self.handle = misc.dlopen_w(space, w_filename, flags)
self.register_finalizer(space)
def _finalize_(self):
@@ -104,7 +97,7 @@
W_Library.typedef.acceptable_as_base_class = False
- at unwrap_spec(filename="fsencode_or_none", flags=int)
-def load_library(space, filename, flags=0):
- lib = W_Library(space, filename, flags)
+ at unwrap_spec(flags=int)
+def load_library(space, w_filename, flags=0):
+ lib = W_Library(space, w_filename, flags)
return lib
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -1,14 +1,24 @@
from __future__ import with_statement
+import sys
from pypy.interpreter.error import OperationError, oefmt
+from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
from rpython.rlib import jit
from rpython.rlib.objectmodel import specialize, we_are_translated
from rpython.rlib.rarithmetic import r_uint, r_ulonglong
from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rdynload import dlopen, DLOpenError
+from rpython.rlib.nonconst import NonConstant
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.translator.tool.cbuild import ExternalCompilationInfo
+if sys.platform == 'win32':
+ from rpython.rlib.rdynload import dlopenU
+ WIN32 = True
+else:
+ WIN32 = False
+
# ____________________________________________________________
@@ -202,6 +212,9 @@
else:
if strict and value < 0:
raise OperationError(space.w_OverflowError, space.newtext(neg_msg))
+ if not we_are_translated():
+ if isinstance(value, NonConstant): # hack for test_ztranslation
+ return r_uint(0)
return r_uint(value)
# note that if not 'strict', then space.int() will round down floats
bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
@@ -389,3 +402,28 @@
ptr = rffi.cast(rffi.FLOATP, source)
for i in range(len(float_list)):
float_list[i] = rffi.cast(lltype.Float, ptr[i])
+
+# ____________________________________________________________
+
+def dlopen_w(space, w_filename, flags):
+ if WIN32 and space.isinstance_w(w_filename, space.w_unicode):
+ fname = space.text_w(space.repr(w_filename))
+ unicode_name = space.unicode_w(w_filename)
+ with rffi.scoped_unicode2wcharp(unicode_name) as ll_libname:
+ try:
+ handle = dlopenU(ll_libname, flags)
+ except DLOpenError as e:
+ raise wrap_dlopenerror(space, e, fname)
+ else:
+ if space.is_none(w_filename):
+ fname = None
+ else:
+ fname = space.fsencode_w(w_filename)
+ with rffi.scoped_str2charp(fname) as ll_libname:
+ if fname is None:
+ fname = "<None>"
+ try:
+ handle = dlopen(ll_libname, flags)
+ except DLOpenError as e:
+ raise wrap_dlopenerror(space, e, fname)
+ return fname, handle
diff --git a/pypy/module/_cffi_backend/test/test_re_python.py b/pypy/module/_cffi_backend/test/test_re_python.py
--- a/pypy/module/_cffi_backend/test/test_re_python.py
+++ b/pypy/module/_cffi_backend/test/test_re_python.py
@@ -1,8 +1,13 @@
import py
+import sys, shutil, os
from rpython.tool.udir import udir
from pypy.interpreter.gateway import interp2app
from pypy.module._cffi_backend.newtype import _clean_cache
+if sys.platform == 'win32':
+ WIN32 = True
+else:
+ WIN32 = False
class AppTestRecompilerPython:
spaceconfig = dict(usemodules=['_cffi_backend'])
@@ -40,6 +45,18 @@
'globalconst42', 'globalconsthello'])
outputfilename = ffiplatform.compile(str(tmpdir), ext)
cls.w_extmod = space.wrap(outputfilename)
+ if WIN32:
+ unicode_name = u'load\u03betest.dll'
+ else:
+ unicode_name = u'load_caf\xe9' + os.path.splitext(outputfilename)[1]
+ try:
+ unicode_name.encode(sys.getfilesystemencoding())
+ except UnicodeEncodeError:
+ unicode_name = None # skip test_dlopen_unicode
+ if unicode_name is not None:
+ outputfileUname = os.path.join(unicode(udir), unicode_name)
+ shutil.copyfile(outputfilename, outputfileUname)
+ cls.w_extmodU = space.wrap(outputfileUname)
#mod.tmpdir = tmpdir
#
ffi = FFI()
@@ -108,6 +125,16 @@
assert lib.add42(-10) == 32
assert type(lib.add42) is _cffi_backend.FFI.CData
+ def test_dlopen_unicode(self):
+ if not getattr(self, 'extmodU', None):
+ skip("no unicode file name")
+ import _cffi_backend, sys
+ sys.pypy_initfsencoding() # initialize space.sys.filesystemencoding
+ self.fix_path()
+ from re_python_pysrc import ffi
+ lib = ffi.dlopen(self.extmodU)
+ assert lib.add42(-10) == 32
+
def test_dlclose(self):
import _cffi_backend
self.fix_path()
diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -761,6 +761,26 @@
assert b"\\u3042\u3xxx".decode("unicode-escape", "test.handler1") == \
u"\u3042[<92><117><51>]xxx"
+ def test_unicode_internal_error_handler_infinite_loop(self):
+ import codecs
+ class MyException(Exception):
+ pass
+ seen = [0]
+ def handler_unicodeinternal(exc):
+ if not isinstance(exc, UnicodeDecodeError):
+ raise TypeError("don't know how to handle %r" % exc)
+ seen[0] += 1
+ if seen[0] == 20: # stop the 20th time this is called
+ raise MyException
+ return (u"\x01", 4) # 4 < len(input), so will try and fail again
+ codecs.register_error("test.inf", handler_unicodeinternal)
+ try:
+ b"\x00\x00\x00\x00\x00".decode("unicode-internal", "test.inf")
+ except MyException:
+ pass
+ else:
+ raise AssertionError("should have gone into infinite loop")
+
def test_encode_error_bad_handler(self):
import codecs
codecs.register_error("test.bad_handler", lambda e: (repl, 1))
diff --git a/pypy/module/_cppyy/capi/loadable_capi.py b/pypy/module/_cppyy/capi/loadable_capi.py
--- a/pypy/module/_cppyy/capi/loadable_capi.py
+++ b/pypy/module/_cppyy/capi/loadable_capi.py
@@ -308,10 +308,10 @@
dldflags = rdynload.RTLD_LOCAL | rdynload.RTLD_LAZY
if os.environ.get('CPPYY_BACKEND_LIBRARY'):
libname = os.environ['CPPYY_BACKEND_LIBRARY']
- state.backend = W_Library(space, libname, dldflags)
+ state.backend = W_Library(space, space.newtext(libname), dldflags)
else:
# try usual lookups
- state.backend = W_Library(space, backend_library, dldflags)
+ state.backend = W_Library(space, space.newtext(backend_library), dldflags)
if state.backend:
# fix constants
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -197,12 +197,11 @@
wrap_oserror2(space, e, w_name,
exception_name='w_IOError',
eintr_retry=True)
- if not rposix._WIN32:
- try:
- _open_inhcache.set_non_inheritable(self.fd)
- except OSError as e:
- raise wrap_oserror2(space, e, w_name,
- eintr_retry=False)
+ try:
+ _open_inhcache.set_non_inheritable(self.fd)
+ except OSError as e:
+ raise wrap_oserror2(space, e, w_name,
+ eintr_retry=False)
else:
w_fd = space.call_function(w_opener, w_name,
space.newint(flags))
@@ -226,6 +225,7 @@
raise wrap_oserror2(space, e, w_name,
eintr_retry=False)
+
try:
st = os.fstat(self.fd)
except OSError as e:
diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -169,12 +169,12 @@
#
exc = raises(TypeError, readinto, u"hello")
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not str")
#
exc = raises(TypeError, readinto, memoryview(b"hello"))
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not memoryview")
#
f.close()
diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py
--- a/pypy/module/_io/test/test_bytesio.py
+++ b/pypy/module/_io/test/test_bytesio.py
@@ -111,12 +111,12 @@
#
exc = raises(TypeError, readinto, u"hello")
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not str")
#
exc = raises(TypeError, readinto, memoryview(b"hello"))
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not memoryview")
#
b.close()
diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py
--- a/pypy/module/_io/test/test_fileio.py
+++ b/pypy/module/_io/test/test_fileio.py
@@ -173,12 +173,12 @@
#
exc = raises(TypeError, f.readinto, u"hello")
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not str")
#
exc = raises(TypeError, f.readinto, memoryview(b"hello"))
msg = str(exc.value)
- print(msg)
+ # print(msg)
assert " read-write b" in msg and msg.endswith(", not memoryview")
#
f.close()
@@ -288,31 +288,34 @@
raises(FileExistsError, _io.FileIO, filename, 'x')
def test_non_inheritable(self):
- import _io, posix
+ import _io
+ os = self.posix
f = _io.FileIO(self.tmpfile, 'r')
- assert posix.get_inheritable(f.fileno()) == False
+ assert os.get_inheritable(f.fileno()) == False
f.close()
def test_FileIO_fd_does_not_change_inheritable(self):
- import _io, posix
- fd1, fd2 = posix.pipe()
- posix.set_inheritable(fd1, True)
- posix.set_inheritable(fd2, False)
+ import _io
+ os = self.posix
+ fd1, fd2 = os.pipe()
+ os.set_inheritable(fd1, True)
+ os.set_inheritable(fd2, False)
f1 = _io.FileIO(fd1, 'r')
f2 = _io.FileIO(fd2, 'w')
- assert posix.get_inheritable(fd1) == True
- assert posix.get_inheritable(fd2) == False
+ assert os.get_inheritable(fd1) == True
+ assert os.get_inheritable(fd2) == False
f1.close()
f2.close()
def test_close_upon_reinit(self):
- import _io, posix
+ import _io
+ os = self.posix
f = _io.FileIO(self.tmpfile, 'r')
fd1 = f.fileno()
f.__init__(self.tmpfile, 'w')
fd2 = f.fileno()
if fd1 != fd2:
- raises(OSError, posix.close, fd1)
+ raises(OSError, os.close, fd1)
def test_opener_negative(self):
import _io
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -179,6 +179,10 @@
lltype.free(self._buffer, flavor='raw')
def setlen(self, size, zero=False, overallocate=True):
+ if self._buffer:
+ delta_memory_pressure = -self.allocated * self.itemsize
+ else:
+ delta_memory_pressure = 0
if size > 0:
if size > self.allocated or size < self.allocated / 2:
if overallocate:
@@ -191,14 +195,13 @@
some = 0
self.allocated = size + some
byte_size = self.allocated * self.itemsize
+ delta_memory_pressure += byte_size
if zero:
new_buffer = lltype.malloc(
- rffi.CCHARP.TO, byte_size, flavor='raw',
- add_memory_pressure=True, zero=True)
+ rffi.CCHARP.TO, byte_size, flavor='raw', zero=True)
else:
new_buffer = lltype.malloc(
- rffi.CCHARP.TO, byte_size, flavor='raw',
- add_memory_pressure=True)
+ rffi.CCHARP.TO, byte_size, flavor='raw')
copy_bytes = min(size, self.len) * self.itemsize
rffi.c_memcpy(rffi.cast(rffi.VOIDP, new_buffer),
rffi.cast(rffi.VOIDP, self._buffer),
@@ -215,6 +218,11 @@
lltype.free(self._buffer, flavor='raw')
self._buffer = new_buffer
self.len = size
+ # adds the difference between the old and the new raw-malloced
+ # size. If setlen() is called a lot on the same array object,
+ # it is important to take into account the fact that we also do
+ # lltype.free() above.
+ rgc.add_memory_pressure(delta_memory_pressure)
def _fromiterable(self, w_seq):
# used by fromsequence().
@@ -259,8 +267,10 @@
return None
oldbuffer = self._buffer
self._buffer = lltype.malloc(rffi.CCHARP.TO,
- (self.len - (j - i)) * self.itemsize, flavor='raw',
- add_memory_pressure=True)
+ (self.len - (j - i)) * self.itemsize, flavor='raw')
+ # Issue #2913: don't pass add_memory_pressure here, otherwise
+ # memory pressure grows but actual raw memory usage doesn't---we
+ # are freeing the old buffer at the end of this function.
if i:
rffi.c_memcpy(
rffi.cast(rffi.VOIDP, self._buffer),
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -93,8 +93,11 @@
if sys.platform == 'win32':
dash = '_'
+ WIN32 = True
else:
dash = ''
+ WIN32 = False
+
def fclose(fp):
try:
@@ -610,13 +613,9 @@
'PyObject_CallMethod', 'PyObject_CallFunctionObjArgs', 'PyObject_CallMethodObjArgs',
'_PyObject_CallFunction_SizeT', '_PyObject_CallMethod_SizeT',
- 'PyObject_GetBuffer', 'PyBuffer_Release',
+ 'PyObject_DelItemString', 'PyObject_GetBuffer', 'PyBuffer_Release',
'_Py_setfilesystemdefaultencoding',
- 'PyCObject_FromVoidPtr', 'PyCObject_FromVoidPtrAndDesc', 'PyCObject_AsVoidPtr',
- 'PyCObject_GetDesc', 'PyCObject_Import', 'PyCObject_SetVoidPtr',
- 'PyCObject_Type', '_Py_get_cobject_type',
-
'PyCapsule_New', 'PyCapsule_IsValid', 'PyCapsule_GetPointer',
'PyCapsule_GetName', 'PyCapsule_GetDestructor', 'PyCapsule_GetContext',
'PyCapsule_SetPointer', 'PyCapsule_SetName', 'PyCapsule_SetDestructor',
@@ -648,6 +647,7 @@
'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag',
'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory',
'_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext',
+ 'PyOS_InputHook',
'PyMem_RawMalloc', 'PyMem_RawCalloc', 'PyMem_RawRealloc', 'PyMem_RawFree',
'PyMem_Malloc', 'PyMem_Calloc', 'PyMem_Realloc', 'PyMem_Free',
@@ -672,7 +672,7 @@
'PyObject*', 'space.w_None', header=pypy_decl)
register_global('_Py_TrueStruct',
'PyObject*', 'space.w_True', header=pypy_decl)
-register_global('_Py_ZeroStruct',
+register_global('_Py_FalseStruct',
'PyObject*', 'space.w_False', header=pypy_decl)
register_global('_Py_NotImplementedStruct',
'PyObject*', 'space.w_NotImplemented', header=pypy_decl)
@@ -716,8 +716,8 @@
"PyByteArray_Type": "space.w_bytearray",
"PyMemoryView_Type": "space.w_memoryview",
"PyBaseObject_Type": "space.w_object",
- 'PyNone_Type': 'space.type(space.w_None)',
- 'PyNotImplemented_Type': 'space.type(space.w_NotImplemented)',
+ '_PyNone_Type': 'space.type(space.w_None)',
+ '_PyNotImplemented_Type': 'space.type(space.w_NotImplemented)',
'PyCell_Type': 'space.gettypeobject(Cell.typedef)',
'PyModule_Type': 'space.gettypeobject(Module.typedef)',
'PyProperty_Type': 'space.gettypeobject(W_Property.typedef)',
@@ -1121,9 +1121,6 @@
# of the cpyext module. The C functions are called with no wrapper,
# but must not do anything like calling back PyType_Ready(). We
# use them just to get a pointer to the PyTypeObjects defined in C.
- get_cobject_type = rffi.llexternal('_%s_get_cobject_type' % prefix,
- [], PyTypeObjectPtr,
- compilation_info=eci, _nowrapper=True)
get_capsule_type = rffi.llexternal('_%s_get_capsule_type' % prefix,
[], PyTypeObjectPtr,
compilation_info=eci, _nowrapper=True)
@@ -1134,7 +1131,6 @@
def init_types(space):
from pypy.module.cpyext.typeobject import py_type_ready
from pypy.module.sys.interp_encoding import getfilesystemencoding
- py_type_ready(space, get_cobject_type())
py_type_ready(space, get_capsule_type())
s = space.text_w(getfilesystemencoding(space))
setdefenc(rffi.str2charp(s, track_allocation=False)) # "leaks"
@@ -1188,6 +1184,10 @@
state.C._PyPy_object_dealloc = rffi.llexternal(
'_PyPy_object_dealloc', [PyObject], lltype.Void,
compilation_info=eci, _nowrapper=True)
+ FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT))
+ state.C.get_pyos_inputhook = rffi.llexternal(
+ '_PyPy_get_PyOS_InputHook', [], FUNCPTR,
+ compilation_info=eci, _nowrapper=True)
def init_function(func):
@@ -1495,7 +1495,6 @@
source_dir / "pythonrun.c",
source_dir / "sysmodule.c",
source_dir / "complexobject.c",
- source_dir / "cobject.c",
source_dir / "structseq.c",
source_dir / "capsule.c",
source_dir / "pysignals.c",
@@ -1549,7 +1548,6 @@
if sys.platform == 'win32':
get_pythonapi_source = '''
- #include <windows.h>
RPY_EXTERN
HANDLE pypy_get_pythonapi_handle() {
MEMORY_BASIC_INFORMATION mi;
@@ -1563,6 +1561,9 @@
}
'''
separate_module_sources.append(get_pythonapi_source)
+ kwds['post_include_bits'] = ['#include <windows.h>',
+ 'RPY_EXTERN HANDLE pypy_get_pythonapi_handle();',
+ ]
eci = ExternalCompilationInfo(
include_dirs=include_dirs,
@@ -1673,7 +1674,11 @@
try:
ll_libname = rffi.str2charp(path)
try:
- dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags)
+ if WIN32:
+ # Allow other DLLs in the same directory with "path"
+ dll = rdynload.dlopenex(ll_libname)
+ else:
+ dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags)
finally:
lltype.free(ll_libname, flavor='raw')
except rdynload.DLOpenError as e:
@@ -1789,6 +1794,12 @@
return
return exec_def(space, w_mod, mod_as_pyobj)
+def invoke_pyos_inputhook(space):
+ state = space.fromcache(State)
+ c_inputhook = state.C.get_pyos_inputhook()
+ if c_inputhook:
+ generic_cpy_call(space, c_inputhook)
+
@specialize.ll()
def generic_cpy_call(space, func, *args):
FT = lltype.typeOf(func).TO
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -9,6 +9,7 @@
from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
from pypy.module.cpyext.funcobject import PyCodeObject
+from pypy.module.cpyext.frameobject import PyFrameObject
from pypy.module.__builtin__ import compiling
PyCompilerFlags = cpython_struct(
@@ -58,6 +59,11 @@
return None
return caller.get_w_globals() # borrowed ref
+ at cpython_api([], PyFrameObject, error=CANNOT_FAIL, result_borrowed=True)
+def PyEval_GetFrame(space):
+ caller = space.getexecutioncontext().gettopframe_nohidden()
+ return caller # borrowed ref, may be null
+
@cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
def PyEval_EvalCode(space, w_code, w_globals, w_locals):
"""This is a simplified interface to PyEval_EvalCodeEx(), with just
diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -123,7 +123,6 @@
#include "memoryobject.h"
#include "eval.h"
#include "pymem.h"
-#include "pycobject.h"
#include "pycapsule.h"
#include "bytesobject.h"
#include "sliceobject.h"
diff --git a/pypy/module/cpyext/include/abstract.h b/pypy/module/cpyext/include/abstract.h
--- a/pypy/module/cpyext/include/abstract.h
+++ b/pypy/module/cpyext/include/abstract.h
@@ -4,6 +4,15 @@
extern "C" {
#endif
+ PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key);
+
+ /*
+ Remove the mapping for object, key, from the object *o.
+ Returns -1 on failure. This is equivalent to
+ the Python statement: del o[key].
+ */
+
+
/* new buffer API */
#define PyObject_CheckBuffer(obj) \
@@ -27,6 +36,27 @@
/* Releases a Py_buffer obtained from getbuffer ParseTuple's s*.
*/
+/* Mapping protocol:*/
+
+ /* implemented as a macro:
+
+ int PyMapping_DelItemString(PyObject *o, char *key);
+
+ Remove the mapping for object, key, from the object *o.
+ Returns -1 on failure. This is equivalent to
+ the Python statement: del o[key].
+ */
+#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K))
+
+ /* implemented as a macro:
+
+ int PyMapping_DelItem(PyObject *o, PyObject *key);
+
+ Remove the mapping for object, key, from the object *o.
+ Returns -1 on failure. This is equivalent to
+ the Python statement: del o[key].
+ */
+#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K))
#ifdef __cplusplus
}
diff --git a/pypy/module/cpyext/include/boolobject.h b/pypy/module/cpyext/include/boolobject.h
--- a/pypy/module/cpyext/include/boolobject.h
+++ b/pypy/module/cpyext/include/boolobject.h
@@ -1,5 +1,4 @@
-
-/* Bool object interface */
+/* Boolean object interface */
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
@@ -7,15 +6,19 @@
extern "C" {
#endif
-#define Py_False ((PyObject *) &_Py_ZeroStruct)
+#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type)
+
+/* Py_False and Py_True are the only two bools in existence.
+Don't forget to apply Py_INCREF() when returning either!!! */
+
+/* Use these macros */
+#define Py_False ((PyObject *) &_Py_FalseStruct)
#define Py_True ((PyObject *) &_Py_TrueStruct)
/* Macros for returning Py_True or Py_False, respectively */
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
-#define PyBool_Check(op) ((op)->ob_type == &PyBool_Type)
-
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/include/pycobject.h b/pypy/module/cpyext/include/pycobject.h
deleted file mode 100644
--- a/pypy/module/cpyext/include/pycobject.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef Py_COBJECT_H
-#define Py_COBJECT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PyAPI_DATA(PyTypeObject) PyCObject_Type;
-
-#define PyCObject_Check(op) ((op)->ob_type == &PyCObject_Type)
-
-/* Create a PyCObject from a pointer to a C object and an optional
- destructor function. If the second argument is non-null, then it
- will be called with the first argument if and when the PyCObject is
- destroyed.
-
-*/
-PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(
- void *cobj, void (*destruct)(void*));
-
-
-/* Create a PyCObject from a pointer to a C object, a description object,
- and an optional destructor function. If the third argument is non-null,
- then it will be called with the first and second arguments if and when
- the PyCObject is destroyed.
-*/
-PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc(
- void *cobj, void *desc, void (*destruct)(void*,void*));
-
-/* Retrieve a pointer to a C object from a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *);
-
-/* Retrieve a pointer to a description object from a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
-
-/* Import a pointer to a C object from a module using a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_Import(const char *module_name, const char *cobject_name);
-
-/* Modify a C object. Fails (==0) if object has a destructor. */
-PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
-
-
-#if (PY_VERSION_HEX >= 0x02060000 || defined(Py_BUILD_CORE))
-typedef struct {
- PyObject_HEAD
- void *cobject;
- void *desc;
- void (*destructor)(void *);
-} PyCObject;
-#endif
-
-PyAPI_FUNC(PyTypeObject *) _Py_get_cobject_type(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_COBJECT_H */
diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -41,6 +41,11 @@
#define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL)
+/* Stuff with no proper home (yet) */
+PyAPI_DATA(int) (*PyOS_InputHook)(void);
+typedef int (*_pypy_pyos_inputhook)(void);
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -41,19 +41,6 @@
w_mode = space.newtext(rffi.charp2str(mode))
return space.call_method(space.builtin, 'open', w_filename, w_mode)
- at cpython_api([FILEP, CONST_STRING, CONST_STRING, rffi.VOIDP], PyObject)
-def PyFile_FromFile(space, fp, name, mode, close):
- """Create a new PyFileObject from the already-open standard C file
- pointer, fp. The function close will be called when the file should be
- closed. Return NULL on failure."""
- raise NotImplementedError
-
- at cpython_api([PyObject, rffi.INT_real], lltype.Void)
-def PyFile_SetBufSize(space, w_file, n):
- """Available on systems with setvbuf() only. This should only be called
- immediately after file object creation."""
- raise NotImplementedError
-
@cpython_api([CONST_STRING, PyObject], rffi.INT_real, error=-1)
def PyFile_WriteString(space, s, w_p):
"""Write string s to file object p. Return 0 on success or -1 on
@@ -75,9 +62,3 @@
w_str = space.repr(w_obj)
space.call_method(w_p, "write", w_str)
return 0
-
- at cpython_api([PyObject], PyObject)
-def PyFile_Name(space, w_p):
- """Return the name of the file specified by p as a string object."""
- w_name = space.getattr(w_p, space.newtext("name"))
- return w_name # borrowed ref, should be a W_StringObject from the file
diff --git a/pypy/module/cpyext/src/abstract.c b/pypy/module/cpyext/src/abstract.c
--- a/pypy/module/cpyext/src/abstract.c
+++ b/pypy/module/cpyext/src/abstract.c
@@ -23,6 +23,23 @@
/* Operations on any object */
int
+PyObject_DelItemString(PyObject *o, char *key)
+{
+ PyObject *okey;
+ int ret;
+
+ if (o == NULL || key == NULL) {
+ null_error();
+ return -1;
+ }
+ okey = PyUnicode_FromString(key);
+ if (okey == NULL)
+ return -1;
+ ret = PyObject_DelItem(o, okey);
+ Py_DECREF(okey);
+ return ret;
+}
+int
PyObject_CheckReadBuffer(PyObject *obj)
{
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
@@ -96,6 +113,20 @@
return 0;
}
+/* Buffer C-API for Python 3.0 */
+
+int
+PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
+{
+ if (!PyObject_CheckBuffer(obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "'%100s' does not have the buffer interface",
+ Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+ return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+}
+
void*
PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
{
@@ -111,6 +142,7 @@
return (void*)pointer;
}
+
void
_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
@@ -253,19 +285,6 @@
-/* Buffer C-API for Python 3.0 */
-
-int
-PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
-{
- if (!PyObject_CheckBuffer(obj)) {
- PyErr_Format(PyExc_TypeError,
- "'%100s' does not have the buffer interface",
- Py_TYPE(obj)->tp_name);
- return -1;
- }
- return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
-}
void
PyBuffer_Release(Py_buffer *view)
@@ -427,6 +446,7 @@
return retval;
}
+
static PyObject *
objargs_mktuple(va_list va)
{
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
deleted file mode 100644
--- a/pypy/module/cpyext/src/cobject.c
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/* Wrap void* pointers to be passed between C modules */
-
-#include "Python.h"
-
-
-/* Declarations for objects of type PyCObject */
-
-typedef void (*destructor1)(void *);
-typedef void (*destructor2)(void *, void*);
-
-PyObject *
-PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
-{
- PyCObject *self;
-
- self = PyObject_NEW(PyCObject, &PyCObject_Type);
- if (self == NULL)
- return NULL;
- self->cobject=cobj;
- self->destructor=destr;
- self->desc=NULL;
-
- return (PyObject *)self;
-}
-
-PyObject *
-PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
- void (*destr)(void *, void *))
-{
- PyCObject *self;
-
- if (!desc) {
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_FromVoidPtrAndDesc called with null"
- " description");
- return NULL;
- }
- self = PyObject_NEW(PyCObject, &PyCObject_Type);
- if (self == NULL)
- return NULL;
- self->cobject = cobj;
- self->destructor = (destructor1)destr;
- self->desc = desc;
-
- return (PyObject *)self;
-}
-
-void *
-PyCObject_AsVoidPtr(PyObject *self)
-{
- if (self) {
- if (PyCapsule_CheckExact(self)) {
- const char *name = PyCapsule_GetName(self);
- return (void *)PyCapsule_GetPointer(self, name);
- }
- if (self->ob_type == &PyCObject_Type)
- return ((PyCObject *)self)->cobject;
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_AsVoidPtr with non-C-object");
- }
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_AsVoidPtr called with null pointer");
- return NULL;
-}
-
-void *
-PyCObject_GetDesc(PyObject *self)
-{
- if (self) {
- if (self->ob_type == &PyCObject_Type)
- return ((PyCObject *)self)->desc;
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_GetDesc with non-C-object");
- }
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_GetDesc called with null pointer");
- return NULL;
-}
-
-void *
-PyCObject_Import(const char *module_name, const char *name)
-{
- PyObject *m, *c;
- void *r = NULL;
-
- if ((m = PyImport_ImportModule(module_name))) {
- if ((c = PyObject_GetAttrString(m,name))) {
- r = PyCObject_AsVoidPtr(c);
- Py_DECREF(c);
- }
- Py_DECREF(m);
- }
- return r;
-}
-
-int
-PyCObject_SetVoidPtr(PyObject *self, void *cobj)
-{
- PyCObject* cself = (PyCObject*)self;
- if (cself == NULL || !PyCObject_Check(cself) ||
- cself->destructor != NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Invalid call to PyCObject_SetVoidPtr");
- return 0;
- }
- cself->cobject = cobj;
- return 1;
-}
-
-static void
-PyCObject_dealloc(PyCObject *self)
-{
- if (self->destructor) {
- if(self->desc)
- ((destructor2)(self->destructor))(self->cobject, self->desc);
- else
- (self->destructor)(self->cobject);
- }
- PyObject_DEL(self);
-}
-
-
-PyDoc_STRVAR(PyCObject_Type__doc__,
-"C objects to be exported from one extension module to another\n\
-\n\
-C objects are used for communication between extension modules. They\n\
-provide a way for an extension module to export a C interface to other\n\
-extension modules, so that extension modules can use the Python import\n\
-mechanism to link to one another.");
-
-PyTypeObject PyCObject_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "PyCObject", /*tp_name*/
- sizeof(PyCObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)PyCObject_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- 0, /*tp_flags*/
- PyCObject_Type__doc__ /*tp_doc*/
-};
-
-PyTypeObject *_Py_get_cobject_type(void)
-{
- return &PyCObject_Type;
-}
diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c
--- a/pypy/module/cpyext/src/missing.c
+++ b/pypy/module/cpyext/src/missing.c
@@ -31,3 +31,7 @@
void _Py_setfilesystemdefaultencoding(const char *enc) {
Py_FileSystemDefaultEncoding = enc;
}
+int (*PyOS_InputHook)(void) = 0; /* only ever filled in by C extensions */
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void) {
+ return PyOS_InputHook;
+}
diff --git a/pypy/module/cpyext/stubs-find-implemented.py b/pypy/module/cpyext/stubs-find-implemented.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/stubs-find-implemented.py
@@ -0,0 +1,21 @@
+import re
+import os
+
+
+for line in open('stubs.py'):
+ if not line.strip():
+ continue
+ if line.startswith(' '):
+ continue
+ if line.startswith('#'):
+ continue
+ if line.startswith('@cpython_api'):
+ continue
+ if line.endswith(' = rffi.VOIDP\n'):
+ continue
+
+ #print line.rstrip()
+ m = re.match(r"def ([\w\d_]+)[(]", line)
+ assert m, line
+ funcname = m.group(1)
+ os.system('grep -w %s [a-r]*.py s[a-s]*.py str*.py stubsa*.py sy*.py [t-z]*.py' % funcname)
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1,29 +1,10 @@
-from pypy.module.cpyext.api import (
- cpython_api, PyObject, PyObjectP, CANNOT_FAIL
- )
-from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
-from rpython.rtyper.lltypesystem import rffi, lltype
+#----this file is not imported, only here for reference----
-CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True}))
-
-# we don't really care
-PyTypeObjectPtr = rffi.VOIDP
-Py_ssize_t = rffi.SSIZE_T
-PyModuleDef = rffi.VOIDP
-PyMethodDef = rffi.VOIDP
-PyGetSetDef = rffi.VOIDP
-PyMemberDef = rffi.VOIDP
-va_list = rffi.VOIDP
-wrapperbase = rffi.VOIDP
-FILE = rffi.VOIDP
-PyFrameObject = rffi.VOIDP
-_inittab = rffi.VOIDP
-PyThreadState = rffi.VOIDP
-PyInterpreterState = rffi.VOIDP
-Py_UNICODE = lltype.UniChar
-PyCompilerFlags = rffi.VOIDP
-struct_node = rffi.VOIDP
-Py_tracefunc = rffi.VOIDP
+#from pypy.module.cpyext.api import (
+# cpython_api, PyObject, PyObjectP, CANNOT_FAIL
+# )
+#from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
+#from rpython.rtyper.lltypesystem import rffi, lltype
@cpython_api([rffi.CCHARP], Py_ssize_t, error=-1)
@@ -228,39 +209,6 @@
this method returns zero and sets errno to EDOM."""
raise NotImplementedError
- at cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, rffi.INTP], rffi.CCHARP)
-def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
- """Convert a double val to a string using supplied
- format_code, precision, and flags.
-
- format_code must be one of 'e', 'E', 'f', 'F',
- 'g', 'G' or 'r'. For 'r', the supplied precision
- must be 0 and is ignored. The 'r' format code specifies the
- standard repr() format.
-
- flags can be zero or more of the values Py_DTSF_SIGN,
- Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:
-
- Py_DTSF_SIGN means to always precede the returned string with a sign
- character, even if val is non-negative.
-
- Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
- like an integer.
-
- Py_DTSF_ALT means to apply "alternate" formatting rules. See the
- documentation for the PyOS_snprintf() '#' specifier for
- details.
-
- If ptype is non-NULL, then the value it points to will be set to one of
- Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
- val is a finite number, an infinite number, or not a number, respectively.
-
- The return value is a pointer to buffer with the converted string or
- NULL if the conversion failed. The caller is responsible for freeing the
- returned string by calling PyMem_Free().
- """
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP, rffi.CCHARP], rffi.CCHARP)
def PyOS_stricmp(space, s1, s2):
"""Case insensitive comparison of strings. The function works almost
@@ -275,24 +223,6 @@
"""
raise NotImplementedError
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyTZInfo_Check(space, ob):
- """Return true if ob is of type PyDateTime_TZInfoType or a subtype of
- PyDateTime_TZInfoType. ob must not be NULL.
- """
- raise NotImplementedError
-
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyTZInfo_CheckExact(space, ob):
- """Return true if ob is of type PyDateTime_TZInfoType. ob must not be
- NULL.
- """
- raise NotImplementedError
-
- at cpython_api([PyTypeObjectPtr, PyGetSetDef], PyObject)
-def PyDescr_NewGetSet(space, type, getset):
- raise NotImplementedError
-
@cpython_api([PyTypeObjectPtr, PyMemberDef], PyObject)
def PyDescr_NewMember(space, type, meth):
raise NotImplementedError
@@ -483,31 +413,6 @@
0 on success, -1 on failure."""
raise NotImplementedError
- at cpython_api([PyObject], rffi.INT_real, error=-1)
-def Py_ReprEnter(space, object):
- """Called at the beginning of the tp_repr implementation to
- detect cycles.
-
- If the object has already been processed, the function returns a
- positive integer. In that case the tp_repr implementation
- should return a string object indicating a cycle. As examples,
- dict objects return {...} and list objects
- return [...].
-
- The function will return a negative integer if the recursion limit
- is reached. In that case the tp_repr implementation should
- typically return NULL.
-
- Otherwise, the function returns zero and the tp_repr
- implementation can continue normally."""
- raise NotImplementedError
-
- at cpython_api([PyObject], lltype.Void)
-def Py_ReprLeave(space, object):
- """Ends a Py_ReprEnter(). Must be called once for each
- invocation of Py_ReprEnter() that returns zero."""
- raise NotImplementedError
-
@cpython_api([rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject)
def PyFile_FromFd(space, fd, name, mode, buffering, encoding, errors, newline, closefd):
"""Create a Python file object from the file descriptor of an already
@@ -1295,39 +1200,6 @@
"""
raise NotImplementedError
- at cpython_api([PyObject], rffi.VOIDP)
-def PyModule_GetState(space, module):
- """Return the "state" of the module, that is, a pointer to the block of memory
- allocated at module creation time, or NULL. See
- PyModuleDef.m_size."""
- raise NotImplementedError
-
- at cpython_api([PyObject], PyModuleDef)
-def PyModule_GetDef(space, module):
- """Return a pointer to the PyModuleDef struct from which the module was
- created, or NULL if the module wasn't created with
- PyModule_Create()."""
- raise NotImplementedError
-
-
- at cpython_api([PyModuleDef], PyObject)
-def PyModule_Create(space, module):
- """Create a new module object, given the definition in module. This behaves
- like PyModule_Create2() with module_api_version set to
- PYTHON_API_VERSION."""
- raise NotImplementedError
-
-
- at cpython_api([PyModuleDef, rffi.INT_real], PyObject)
-def PyModule_Create2(space, module, module_api_version):
- """Create a new module object, given the definition in module, assuming the
- API version module_api_version. If that version does not match the version
- of the running interpreter, a RuntimeWarning is emitted.
-
- Most uses of this function should be using PyModule_Create()
- instead; only use this if you are sure you need it."""
- raise NotImplementedError
-
@cpython_api([PyObject, rffi.INT_real], PyObject)
def PyNumber_ToBase(space, n, base):
"""Returns the integer n converted to base base as a string. The base
@@ -1337,23 +1209,6 @@
PyNumber_Index() first."""
raise NotImplementedError
- at cpython_api([PyObject], PyObject)
-def PyObject_Bytes(space, o):
- """
- Compute a bytes representation of object o. NULL is returned on
- failure and a bytes object on success. This is equivalent to the Python
- expression bytes(o), when o is not an integer. Unlike bytes(o),
- a TypeError is raised when o is an integer instead of a zero-initialized
- bytes object."""
- raise NotImplementedError
-
- at cpython_api([], PyFrameObject)
-def PyEval_GetFrame(space):
- """Return the current thread state's frame, which is NULL if no frame is
- currently executing."""
- raise NotImplementedError
- borrow_from()
-
@cpython_api([PyFrameObject], rffi.INT_real, error=-1)
def PyFrame_GetLineNumber(space, frame):
"""Return the line number that frame is currently executing."""
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -510,3 +510,15 @@
assert run_async(list1()) == ([], [0, 1, 2])
assert run_async(list2()) == ([], [0, 1, 2])
"""
+
+ def test_getframe(self):
+ import sys
+ module = self.import_extension('foo', [
+ ("getframe1", "METH_NOARGS",
+ """
+ PyFrameObject *x = PyEval_GetFrame();
+ Py_INCREF(x);
+ return (PyObject *)x;
+ """),], prologue="#include <frameobject.h>\n")
+ res = module.getframe1()
+ assert res is sys._getframe(0)
diff --git a/pypy/module/cpyext/test/test_misc.py b/pypy/module/cpyext/test/test_misc.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_misc.py
@@ -0,0 +1,35 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+
+class AppTestMisc(AppTestCpythonExtensionBase):
+
+ def test_pyos_inputhook(self):
+ module = self.import_extension('foo', [
+ ("set_pyos_inputhook", "METH_NOARGS",
+ '''
+ PyOS_InputHook = &my_callback;
+ Py_RETURN_NONE;
+ '''),
+ ("fetch_value", "METH_NOARGS",
+ '''
+ return PyLong_FromLong(my_flag);
+ '''),
+ ], prologue='''
+ static long my_flag = 0;
+ static int my_callback(void) { return ++my_flag; }
+ ''')
+
+ try:
+ import __pypy__
+ except ImportError:
+ skip("only runs on top of pypy")
+ assert module.fetch_value() == 0
+ __pypy__.pyos_inputhook()
+ assert module.fetch_value() == 0
+ module.set_pyos_inputhook() # <= set
+ assert module.fetch_value() == 0
+ __pypy__.pyos_inputhook()
+ assert module.fetch_value() == 1
+ __pypy__.pyos_inputhook()
+ assert module.fetch_value() == 2
+ assert module.fetch_value() == 2
diff --git a/pypy/module/cpyext/test/test_pycobject.py b/pypy/module/cpyext/test/test_pycobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/test/test_pycobject.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import py
-from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-
-class AppTestStringObject(AppTestCpythonExtensionBase):
- def test_pycobject_import(self):
- module = self.import_extension('foo', [
- ("set_ptr", "METH_O",
- """
- PyObject *pointer, *module;
- void *ptr = PyLong_AsVoidPtr(args);
- if (PyErr_Occurred()) return NULL;
- pointer = PyCObject_FromVoidPtr(ptr, NULL);
- if (PyErr_Occurred()) return NULL;
- module = PyImport_ImportModule("foo");
- PyModule_AddObject(module, "_ptr", pointer);
- Py_DECREF(module);
- if (PyErr_Occurred()) return NULL;
- Py_RETURN_NONE;
- """),
- ("get_ptr", "METH_NOARGS",
- """
- void *ptr = PyCObject_Import("foo", "_ptr");
- if (PyErr_Occurred()) return NULL;
- return PyLong_FromVoidPtr(ptr);
- """)])
- module.set_ptr(1234)
- assert "PyCObject object" in str(module._ptr)
- import gc; gc.collect()
- assert module.get_ptr() == 1234
- del module._ptr
diff --git a/pypy/module/cpyext/test/test_pyfile.py b/pypy/module/cpyext/test/test_pyfile.py
--- a/pypy/module/cpyext/test/test_pyfile.py
+++ b/pypy/module/cpyext/test/test_pyfile.py
@@ -48,17 +48,6 @@
space.call_method(w_file, "close")
- def test_file_name(self, space, api):
- name = str(udir / "_test_file")
- with rffi.scoped_str2charp(name) as filename:
- with rffi.scoped_str2charp("wb") as mode:
- w_file = api.PyFile_FromString(filename, mode)
- assert space.str_w(api.PyFile_Name(w_file)) == name
-
- @pytest.mark.xfail
- def test_file_setbufsize(self, space, api):
- api.PyFile_SetBufSize()
-
def test_file_writestring(self, space, api, capfd):
w_stdout = space.sys.get("stdout")
with rffi.scoped_str2charp("test\n") as s:
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -677,13 +677,15 @@
def test_decode_null_encoding(self, space):
null_charp = lltype.nullptr(rffi.CCHARP.TO)
u_text = u'abcdefg'
- s_text = space.str_w(PyUnicode_AsEncodedString(space, space.wrap(u_text), null_charp, null_charp))
+ s_text = space.bytes_w(PyUnicode_AsEncodedString(space, space.wrap(u_text), null_charp, null_charp))
b_text = rffi.str2charp(s_text)
assert space.unicode_w(PyUnicode_Decode(
space, b_text, len(s_text), null_charp, null_charp)) == u_text
with raises_w(space, TypeError):
PyUnicode_FromEncodedObject(
space, space.wrap(u_text), null_charp, None)
+ assert space.unicode_w(PyUnicode_FromEncodedObject(
+ space, space.newbytes(s_text), null_charp, None)) == u_text
rffi.free_charp(b_text)
def test_mbcs(self, space):
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -486,11 +486,16 @@
in the unicode() built-in function. The codec to be used is looked up
using the Python codec registry. Return NULL if an exception was raised by
the codec."""
- if not encoding:
- # This tracks CPython 2.7, in CPython 3.4 'utf-8' is hardcoded instead
- encoding = PyUnicode_GetDefaultEncoding(space)
- w_str = space.newbytes(rffi.charpsize2str(s, size))
- w_encoding = space.newtext(rffi.charp2str(encoding))
+ return _pyunicode_decode(space, rffi.charpsize2str(s, size),
+ encoding, errors)
+
+def _pyunicode_decode(space, s, encoding, errors):
+ if encoding:
+ w_encoding = space.newtext(rffi.charp2str(encoding))
+ else:
+ # python 3.4 changed to this from defaultencoding
+ w_encoding = space.newtext('utf-8')
+ w_str = space.newbytes(s)
if errors:
w_errors = space.newtext(rffi.charp2str(errors))
else:
@@ -525,28 +530,12 @@
All other objects, including Unicode objects, cause a TypeError to be
set."""
- if not encoding:
- raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
- w_encoding = space.newtext(rffi.charp2str(encoding))
- if errors:
- w_errors = space.newtext(rffi.charp2str(errors))
- else:
- w_errors = None
-
- # - unicode is disallowed
- # - raise TypeError for non-string types
if space.isinstance_w(w_obj, space.w_unicode):
- w_meth = None
- else:
- try:
- w_meth = space.getattr(w_obj, space.newtext('decode'))
- except OperationError as e:
- if not e.match(space, space.w_AttributeError):
- raise
- w_meth = None
- if w_meth is None:
- raise oefmt(space.w_TypeError, "decoding Unicode is not supported")
- return space.call_function(w_meth, w_encoding, w_errors)
+ raise oefmt(space.w_TypeError, "decoding str is not supported")
+ if space.isinstance_w(w_obj, space.w_bytearray): # Python 2.x specific
+ raise oefmt(space.w_TypeError, "decoding bytearray is not supported")
+ s = space.charbuf_w(w_obj)
+ return _pyunicode_decode(space, s, encoding, errors)
@cpython_api([PyObject, PyObjectP], rffi.INT_real, error=0)
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -232,9 +232,9 @@
def test_pickle(self):
import pickle, os
st = self.posix.stat(os.curdir)
- print(type(st).__module__)
+ # print(type(st).__module__)
s = pickle.dumps(st)
- print(repr(s))
+ # print(repr(s))
new = pickle.loads(s)
assert new == st
assert type(new) is type(st)
@@ -578,6 +578,12 @@
res = fp.read()
assert res == '1\n'
+ if sys.platform == "win32":
+ # using startfile in app_startfile creates global state
+ test_popen.dont_track_allocations = True
+ test_popen_with.dont_track_allocations = True
+ test_popen_child_fds.dont_track_allocations = True
+
if hasattr(__import__(os.name), '_getfullpathname'):
def test__getfullpathname(self):
# nt specific
diff --git a/pypy/module/pwd/interp_pwd.py b/pypy/module/pwd/interp_pwd.py
--- a/pypy/module/pwd/interp_pwd.py
+++ b/pypy/module/pwd/interp_pwd.py
@@ -37,7 +37,8 @@
passwd_p = lltype.Ptr(config['passwd'])
def external(name, args, result, **kwargs):
- return rffi.llexternal(name, args, result, compilation_info=eci, **kwargs)
+ return rffi.llexternal(name, args, result, compilation_info=eci,
+ releasegil=False, **kwargs)
c_getpwuid = external("getpwuid", [uid_t], passwd_p)
c_getpwnam = external("getpwnam", [rffi.CCHARP], passwd_p)
diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py
--- a/pypy/module/sys/initpath.py
+++ b/pypy/module/sys/initpath.py
@@ -231,11 +231,13 @@
if os.name == 'nt':
_source_code = r"""
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
+#endif
#include <windows.h>
#include <stdio.h>
+#include <stdlib.h>
-RPY_EXPORTED
char *_pypy_init_home(void)
{
HMODULE hModule = 0;
@@ -271,7 +273,6 @@
#include <stdio.h>
#include <stdlib.h>
-RPY_EXPORTED
char *_pypy_init_home(void)
{
Dl_info info;
@@ -289,11 +290,27 @@
}
"""
+_source_code += """
+inline
+void _pypy_init_free(char *p)
+{
+ free(p);
+}
+"""
+
+if we_are_translated():
+ post_include_bits = []
+else:
+ # for tests
+ post_include_bits=['RPY_EXPORTED char *_pypy_init_home(void);',
+ 'RPY_EXPORTED void _pypy_init_free(char*);',
+ ]
+
_eci = ExternalCompilationInfo(separate_module_sources=[_source_code],
- post_include_bits=['RPY_EXPORTED char *_pypy_init_home(void);'])
+ post_include_bits=post_include_bits)
_eci = _eci.merge(rdynload.eci)
pypy_init_home = rffi.llexternal("_pypy_init_home", [], rffi.CCHARP,
_nowrapper=True, compilation_info=_eci)
-pypy_init_free = rffi.llexternal("free", [rffi.CCHARP], lltype.Void,
+pypy_init_free = rffi.llexternal("_pypy_init_free", [rffi.CCHARP], lltype.Void,
_nowrapper=True, compilation_info=_eci)
diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py
--- a/pypy/module/thread/os_lock.py
+++ b/pypy/module/thread/os_lock.py
@@ -49,7 +49,8 @@
# Run signal handlers if we were interrupted
space.getexecutioncontext().checksignals()
if microseconds >= 0:
- microseconds = r_longlong(endtime - (time.time() * 1e6))
+ microseconds = r_longlong((endtime - (time.time() * 1e6))
+ + 0.999)
# Check for negative values, since those mean block
# forever
if microseconds <= 0:
@@ -247,7 +248,7 @@
"cannot release un-acquired lock")
self.rlock_count -= 1
if self.rlock_count == 0:
- self.rlock_owner == 0
+ self.rlock_owner = 0
self.lock.release()
def is_owned_w(self, space):
diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py
--- a/pypy/module/thread/test/test_lock.py
+++ b/pypy/module/thread/test/test_lock.py
@@ -306,6 +306,9 @@
finally:
signal.signal(signal.SIGALRM, oldalrm)
+
+class AppTestLockRepr(GenericTestThread):
+
def test_lock_repr(self):
import _thread
lock = _thread.allocate_lock()
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -151,7 +151,7 @@
if getattr(func, '_elidable_function_', False):
raise TypeError("it does not make sense for %s to be both elidable and unroll_safe" % func)
if not getattr(func, '_jit_look_inside_', True):
- raise TypeError("it does not make sense for %s to be both elidable and dont_look_inside" % func)
+ raise TypeError("it does not make sense for %s to be both unroll_safe and dont_look_inside" % func)
func._jit_unroll_safe_ = True
return func
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -233,6 +233,25 @@
raise DLOpenError(ustr.encode('utf-8'))
return res
+ def dlopenex(name):
+ res = rwin32.LoadLibraryExA(name)
+ if not res:
+ err = rwin32.GetLastError_saved()
+ ustr = rwin32.FormatErrorW(err)
+ # DLOpenError unicode msg breaks translation of cpyext create_extension_module
+ raise DLOpenError(ustr.encode('utf-8'))
+ return res
+
+ def dlopenU(name, mode=-1):
+ # mode is unused on windows, but a consistant signature
+ res = rwin32.LoadLibraryW(name)
+ if not res:
+ err = rwin32.GetLastError_saved()
+ ustr = rwin32.FormatErrorW(err)
+ # DLOpenError unicode msg breaks translation of cpyext create_extension_module
+ raise DLOpenError(ustr.encode('utf-8'))
+ return res
+
def dlclose(handle):
res = rwin32.FreeLibrary(handle)
if res:
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -835,7 +835,7 @@
# assume -1 and 0 both mean invalid file descriptor
# to 'anonymously' map memory.
if fileno != -1 and fileno != 0:
- fh = rwin32.get_osfhandle(fileno)
+ fh = rffi.cast(HANDLE, rwin32.get_osfhandle(fileno))
# Win9x appears to need us seeked to zero
# SEEK_SET = 0
# libc._lseek(fileno, 0, SEEK_SET)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -137,7 +137,10 @@
RPY_EXTERN void exit_suppress_iph(void* handle) {};
#endif
''',]
- post_include_bits=['RPY_EXTERN int _PyVerify_fd(int);']
+ post_include_bits=['RPY_EXTERN int _PyVerify_fd(int);',
+ 'RPY_EXTERN void* enter_suppress_iph();',
+ 'RPY_EXTERN void exit_suppress_iph(void* handle);',
+ ]
else:
separate_module_sources = []
post_include_bits = []
@@ -235,7 +238,8 @@
rthread.tlfield_rpy_errno.setraw(_get_errno())
# ^^^ keep fork() up-to-date too, below
if _WIN32:
- includes = ['io.h', 'sys/utime.h', 'sys/types.h', 'process.h', 'time.h']
+ includes = ['io.h', 'sys/utime.h', 'sys/types.h', 'process.h', 'time.h',
+ 'direct.h']
libraries = []
else:
if sys.platform.startswith(('darwin', 'netbsd', 'openbsd')):
@@ -730,16 +734,21 @@
length = rwin32.MAX_PATH + 1
traits = _preferred_traits(path)
win32traits = make_win32_traits(traits)
- with traits.scoped_alloc_buffer(length) as buf:
- res = win32traits.GetFullPathName(
- traits.as_str0(path), rffi.cast(rwin32.DWORD, length),
- buf.raw, lltype.nullptr(win32traits.LPSTRP.TO))
- if res == 0:
- raise rwin32.lastSavedWindowsError("_getfullpathname failed")
- result = buf.str(intmask(res))
- assert result is not None
- result = rstring.assert_str0(result)
- return result
+ while True: # should run the loop body maximum twice
+ with traits.scoped_alloc_buffer(length) as buf:
+ res = win32traits.GetFullPathName(
+ traits.as_str0(path), rffi.cast(rwin32.DWORD, length),
+ buf.raw, lltype.nullptr(win32traits.LPSTRP.TO))
+ res = intmask(res)
+ if res == 0:
+ raise rwin32.lastSavedWindowsError("_getfullpathname failed")
+ if res >= length:
+ length = res + 1
+ continue
+ result = buf.str(res)
+ assert result is not None
+ result = rstring.assert_str0(result)
+ return result
c_getcwd = external(UNDERSCORE_ON_WIN32 + 'getcwd',
[rffi.CCHARP, rffi.SIZE_T], rffi.CCHARP,
diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py
--- a/rpython/rlib/runicode.py
+++ b/rpython/rlib/runicode.py
@@ -1775,8 +1775,6 @@
"truncated input",
s, pos, size)
result.append(res)
- if pos > size - unicode_bytes:
- break
continue
t = r_uint(0)
h = 0
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -20,7 +20,7 @@
if WIN32:
eci = ExternalCompilationInfo(
- includes = ['windows.h', 'stdio.h', 'stdlib.h'],
+ includes = ['windows.h', 'stdio.h', 'stdlib.h', 'io.h'],
libraries = ['kernel32'],
)
else:
@@ -113,6 +113,7 @@
MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION
WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE
STD_ERROR_HANDLE HANDLE_FLAG_INHERIT FILE_TYPE_CHAR
+ LOAD_WITH_ALTERED_SEARCH_PATH
"""
from rpython.translator.platform import host_factory
static_platform = host_factory()
@@ -195,12 +196,28 @@
GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE)
LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE,
save_err=rffi.RFFI_SAVE_LASTERROR)
+ def wrap_loadlibraryex(func):
+ def loadlibrary(name, flags=LOAD_WITH_ALTERED_SEARCH_PATH):
+ # Requires a full path name with '/' -> '\\'
+ return func(name, NULL_HANDLE, flags)
+ return loadlibrary
+
+ _LoadLibraryExA = winexternal('LoadLibraryExA',
+ [rffi.CCHARP, HANDLE, DWORD], HMODULE,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
+ LoadLibraryExA = wrap_loadlibraryex(_LoadLibraryExA)
+ LoadLibraryW = winexternal('LoadLibraryW', [rffi.CWCHARP], HMODULE,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
+ _LoadLibraryExW = winexternal('LoadLibraryExW',
+ [rffi.CWCHARP, HANDLE, DWORD], HMODULE,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
+ LoadLibraryExW = wrap_loadlibraryex(_LoadLibraryExW)
GetProcAddress = winexternal('GetProcAddress',
[HMODULE, rffi.CCHARP],
rffi.VOIDP)
FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL, releasegil=False)
- LocalFree = winexternal('LocalFree', [HLOCAL], DWORD)
+ LocalFree = winexternal('LocalFree', [HLOCAL], HLOCAL)
CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL, releasegil=False,
save_err=rffi.RFFI_SAVE_LASTERROR)
CloseHandle_no_err = winexternal('CloseHandle', [HANDLE], BOOL,
@@ -215,12 +232,12 @@
[DWORD, rffi.VOIDP, DWORD, DWORD, rffi.CWCHARP, DWORD, rffi.VOIDP],
DWORD)
- _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], HANDLE)
+ _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], rffi.INTP)
def get_osfhandle(fd):
from rpython.rlib.rposix import FdValidator
with FdValidator(fd):
- handle = _get_osfhandle(fd)
+ handle = rffi.cast(HANDLE, _get_osfhandle(fd))
if handle == INVALID_HANDLE_VALUE:
raise WindowsError(ERROR_INVALID_HANDLE, "Invalid file handle")
return handle
diff --git a/rpython/rlib/test/loadtest/loadtest0.dll b/rpython/rlib/test/loadtest/loadtest0.dll
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9bdcc33a1902f8e989d349c49c2cc08e633aa32b
GIT binary patch
[cut]
More information about the pypy-commit
mailing list