[pypy-commit] pypy py3.5: hg merge py3k
rlamy
pypy.commits at gmail.com
Sun Sep 25 12:28:33 EDT 2016
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r87370:991b0bdd50ab
Date: 2016-09-25 17:27 +0100
http://bitbucket.org/pypy/pypy/changeset/991b0bdd50ab/
Log: hg merge py3k
diff --git a/lib-python/3/idlelib/CallTips.py b/lib-python/3/idlelib/CallTips.py
--- a/lib-python/3/idlelib/CallTips.py
+++ b/lib-python/3/idlelib/CallTips.py
@@ -144,7 +144,8 @@
fob = ob_call
else:
fob = ob
- if isinstance(fob, (types.FunctionType, types.MethodType)):
+ if (isinstance(fob, (types.FunctionType, types.MethodType)) and
+ hasattr(fob.__code__, 'co_code')): # PyPy: not on <builtin-code>
argspec = inspect.formatargspec(*inspect.getfullargspec(fob))
if (isinstance(ob, (type, types.MethodType)) or
isinstance(ob_call, types.MethodType)):
diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py
--- a/lib_pypy/_winapi.py
+++ b/lib_pypy/_winapi.py
@@ -22,35 +22,13 @@
code, message = _ffi.getwinerror()
raise WindowsError(code, message)
-_INVALID_HANDLE_VALUE = _ffi.cast("HANDLE", -1)
+def _int2handle(val):
+ return _ffi.cast("HANDLE", val)
-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 _handle2int(handle):
+ return int(_ffi.cast("intptr_t", handle))
- def __int__(self):
- return int(_ffi.cast("intptr_t", self.c_handle))
-
- def __repr__(self):
- return '<_subprocess.handle %d at 0x%x>' % (int(self), id(self))
-
- def Detach(self):
- 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 int(self) != -1:
- c_handle = self.c_handle
- self.c_handle = _INVALID_HANDLE_VALUE
- _ffi.gc(c_handle, None)
- _kernel32.CloseHandle(c_handle)
+_INVALID_HANDLE_VALUE = _int2handle(-1)
def CreatePipe(attributes, size):
handles = _ffi.new("HANDLE[2]")
@@ -60,25 +38,25 @@
if not res:
raise _WinError()
- return _handle(handles[0]), _handle(handles[1])
+ return _handle2int(handles[0]), _handle2int(handles[1])
def GetCurrentProcess():
- return _handle(_kernel32.GetCurrentProcess())
+ return _handle2int(_kernel32.GetCurrentProcess())
def DuplicateHandle(source_process, source, target_process, access, inherit, options=0):
# CPython: the first three arguments are expected to be integers
target = _ffi.new("HANDLE[1]")
res = _kernel32.DuplicateHandle(
- _ffi.cast("HANDLE", source_process),
- _ffi.cast("HANDLE", source),
- _ffi.cast("HANDLE", target_process),
+ _int2handle(source_process),
+ _int2handle(source),
+ _int2handle(target_process),
target, access, inherit, options)
if not res:
raise _WinError()
- return _handle(target[0])
+ return _handle2int(target[0])
def _z(input):
if input is None:
@@ -94,13 +72,14 @@
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
+ # CPython: these three handles are expected to be
+ # subprocess.Handle (int) objects
if startup_info.hStdInput:
- si.hStdInput = startup_info.hStdInput.c_handle
+ si.hStdInput = _int2handle(startup_info.hStdInput)
if startup_info.hStdOutput:
- si.hStdOutput = startup_info.hStdOutput.c_handle
+ si.hStdOutput = _int2handle(startup_info.hStdOutput)
if startup_info.hStdError:
- si.hStdError = startup_info.hStdError.c_handle
+ si.hStdError = _int2handle(startup_info.hStdError)
pi = _ffi.new("PROCESS_INFORMATION *")
flags |= CREATE_UNICODE_ENVIRONMENT
@@ -120,12 +99,14 @@
if not res:
raise _WinError()
- return _handle(pi.hProcess), _handle(pi.hThread), pi.dwProcessId, pi.dwThreadId
+ return (_handle2int(pi.hProcess),
+ _handle2int(pi.hThread),
+ pi.dwProcessId,
+ pi.dwThreadId)
def WaitForSingleObject(handle, milliseconds):
# CPython: the first argument is expected to be an integer.
- res = _kernel32.WaitForSingleObject(_ffi.cast("HANDLE", handle),
- milliseconds)
+ res = _kernel32.WaitForSingleObject(_int2handle(handle), milliseconds)
if res < 0:
raise _WinError()
@@ -135,7 +116,7 @@
# CPython: the first argument is expected to be an integer.
code = _ffi.new("DWORD[1]")
- res = _kernel32.GetExitCodeProcess(_ffi.cast("HANDLE", handle), code)
+ res = _kernel32.GetExitCodeProcess(_int2handle(handle), code)
if not res:
raise _WinError()
@@ -145,7 +126,7 @@
def TerminateProcess(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),
+ res = _kernel32.TerminateProcess(_int2handle(handle),
_ffi.cast("UINT", exitcode))
if not res:
@@ -158,19 +139,17 @@
if not res:
return None
else:
- # note: returns integer, not handle object
- return int(_ffi.cast("intptr_t", res))
+ return _handle2int(res)
def CloseHandle(handle):
- res = _kernel32.CloseHandle(_ffi.cast("HANDLE", handle))
+ res = _kernel32.CloseHandle(_int2handle(handle))
if not res:
raise _WinError()
def GetModuleFileName(module):
buf = _ffi.new("wchar_t[]", _MAX_PATH)
- res = _kernel32.GetModuleFileNameW(_ffi.cast("HANDLE", module),
- buf, _MAX_PATH)
+ res = _kernel32.GetModuleFileNameW(_int2handle(module), buf, _MAX_PATH)
if not res:
raise _WinError()
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -252,6 +252,7 @@
missing_positional = []
missing_kwonly = []
more_filling = (input_argcount < co_argcount + co_kwonlyargcount)
+ def_first = 0
if more_filling:
def_first = co_argcount - (0 if defaults_w is None else len(defaults_w))
j = 0
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -558,16 +558,6 @@
'parser', 'fcntl', '_codecs', 'binascii'
]
- # These modules are treated like CPython treats built-in modules,
- # i.e. they always shadow any xx.py. The other modules are treated
- # like CPython treats extension modules, and are loaded in sys.path
- # order by the fake entry '.../lib_pypy/__extensions__'.
- MODULES_THAT_ALWAYS_SHADOW = dict.fromkeys([
- '__builtin__', '__pypy__', '_ast', '_codecs', '_sre', '_warnings',
- '_weakref', 'errno', '__exceptions__', 'gc', 'imp', 'marshal',
- 'posix', 'nt', 'pwd', 'signal', 'sys', 'thread', 'zipimport',
- ], None)
-
def make_builtins(self):
"NOT_RPYTHON: only for initializing the space."
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -582,3 +582,16 @@
if module:
space.setattr(w_exc, space.wrap("__module__"), space.wrap(module))
return w_exc
+
+def new_import_error(space, w_msg, w_name, w_path):
+ """Create a new instance of ImportError.
+
+ The result corresponds to ImportError(msg, name=name, path=path)
+ """
+ return space.appexec(
+ [w_msg, w_name, w_path], """(msg, name, path):
+ return ImportError(msg, name=name, path=path)""")
+
+def raise_import_error(space, w_msg, w_name, w_path):
+ w_exc = new_import_error(space, w_msg, w_name, w_path)
+ raise OperationError(space.w_ImportError, w_exc)
diff --git a/pypy/interpreter/interactive.py b/pypy/interpreter/interactive.py
--- a/pypy/interpreter/interactive.py
+++ b/pypy/interpreter/interactive.py
@@ -169,7 +169,8 @@
def runsource(self, source, ignored_filename="<input>", symbol="single"):
# the following hacked file name is recognized specially by error.py
- hacked_filename = '<inline>\n' + source
+ hacked_filename = '<inline>\n' + source.encode(
+ 'ascii', 'backslashreplace')
compiler = self.space.getexecutioncontext().compiler
# CPython 2.6 turns console input into unicode
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -107,6 +107,7 @@
self.co_varnames = varnames
self.co_freevars = freevars
self.co_cellvars = cellvars
+ assert isinstance(filename, str)
rstring.check_str0(filename)
self.co_filename = filename
self.co_name = name
diff --git a/pypy/interpreter/test/test_error.py b/pypy/interpreter/test/test_error.py
--- a/pypy/interpreter/test/test_error.py
+++ b/pypy/interpreter/test/test_error.py
@@ -3,7 +3,7 @@
import py, os, errno
from pypy.interpreter.error import (
OperationError, decompose_valuefmt, get_operrcls2, new_exception_class,
- oefmt, wrap_oserror)
+ oefmt, wrap_oserror, new_import_error)
def test_decompose_valuefmt():
@@ -154,3 +154,8 @@
assert operr.match(space, space.w_ValueError)
assert operr.match(space, space.w_TypeError)
+def test_import_error(space):
+ w_exc = new_import_error(
+ space, space.wrap(u'msg'), space.wrap(u'name'), space.wrap(u'path'))
+ assert space.getattr(w_exc, space.wrap(u'name')).unwrap(space) == u'name'
+ assert space.getattr(w_exc, space.wrap(u'path')).unwrap(space) == u'path'
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
@@ -20,7 +20,7 @@
from rpython.tool.udir import udir
from rpython.translator import platform
from pypy.module.cpyext.state import State
-from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import OperationError, oefmt, raise_import_error
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.gateway import unwrap_spec
from pypy.interpreter.nestedscope import Cell
@@ -982,7 +982,7 @@
py_fatalerror = rffi.llexternal('%s_FatalError' % prefix,
[CONST_STRING], lltype.Void,
compilation_info=eci)
- _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [],
+ _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [],
lltype.Void, compilation_info=eci)
def reinit_tls(space):
_reinit_tls()
@@ -1523,9 +1523,10 @@
finally:
lltype.free(ll_libname, flavor='raw')
except rdynload.DLOpenError as e:
- raise oefmt(space.w_ImportError,
- "unable to load extension module '%s': %s",
- path, e.msg)
+ w_name = space.newunicode(name.decode('ascii'))
+ w_path = space.wrap_fsdecoded(path)
+ raise raise_import_error(space,
+ space.wrap_fsdecoded(e.msg), w_name, w_path)
look_for = None
#
if space.config.objspace.usemodules._cffi_backend:
@@ -1555,9 +1556,12 @@
look_for += ' or ' + also_look_for
else:
look_for = also_look_for
- #
- raise oefmt(space.w_ImportError,
- "function %s not found in library %s", look_for, path)
+ msg = u"function %s not found in library %s" % (
+ unicode(look_for), space.unicode_w(space.wrap_fsdecoded(path)))
+ w_name = space.newunicode(name.decode('ascii'))
+ w_path = space.wrap_fsdecoded(path)
+ raise_import_error(space, space.newunicode(msg), w_name, w_path)
+
initfunctype = lltype.Ptr(lltype.FuncType([], PyObject))
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -3,8 +3,10 @@
class AppTestImpModule:
+ # cpyext is required for _imp.create_dynamic()
spaceconfig = {
- 'usemodules': ['binascii', 'imp', 'itertools', 'time', 'struct'],
+ 'usemodules': [
+ 'binascii', 'imp', 'itertools', 'time', 'struct', 'cpyext'],
}
def setup_class(cls):
@@ -55,12 +57,21 @@
del sys.path[0]
def test_create_dynamic(self):
- import imp
+ import _imp
+ PATH = 'this/path/does/not/exist'
class FakeSpec:
- name = 'foo'
- origin = 'this/path/does/not/exist'
- raises(ImportError, imp.create_dynamic, FakeSpec())
- raises(ImportError, imp.create_dynamic, FakeSpec(), "unused")
+ origin = PATH
+ def __init__(self, name):
+ self.name = name
+
+ excinfo = raises(ImportError, _imp.create_dynamic, FakeSpec('foo'))
+ assert excinfo.value.name == 'foo'
+ assert excinfo.value.path == PATH
+ # Note: On CPython, the behavior changes slightly if a 2nd argument is
+ # passed in, whose value is ignored. We don't implement that.
+ #raises(IOError, _imp.create_dynamic, FakeSpec(), "unused")
+
+ raises(ImportError, _imp.create_dynamic, FakeSpec(b'foo'))
def test_suffixes(self):
import imp
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -63,8 +63,6 @@
test_reload = "def test():\n raise ValueError\n",
infinite_reload = "import infinite_reload, imp; imp.reload(infinite_reload)",
del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n",
- _md5 = "hello_world = 42\n",
- _pypyjson = "hello_world = 42\n",
gc = "should_never_be_seen = 42\n",
)
root.ensure("packagenamespace", dir=1) # empty, no __init__.py
@@ -158,7 +156,7 @@
def _setup_path(space, path):
return space.appexec([space.wrap(path)], """
- (dn):
+ (dn):
import sys
path = list(sys.path)
sys.path.insert(0, dn)
@@ -660,52 +658,6 @@
) == 'a/b/c.py'
raises(ValueError, imp.source_from_cache, 'a/b/c.py')
- def test_shadow_builtin(self):
- if self.runappdirect: skip("hard to test: module is already imported")
- # 'import gc' is supposed to always find the built-in module;
- # like CPython, it is a built-in module, so it shadows everything,
- # even though there is a gc.py.
- import sys
- assert 'gc' not in sys.modules
- import gc
- assert not hasattr(gc, 'should_never_be_seen')
- assert '(built-in)' in repr(gc)
- del sys.modules['gc']
-
- def test_shadow_extension_1(self):
- if not self.runappdirect:
- skip("I don't understand why it fails, but it works in -A "
- "on top of a translated PyPy. Good enough...")
- # 'import _pypyjson' is supposed to find _pypyjson.py if there is
- # one in sys.path.
- import sys
- assert '_pypyjson' not in sys.modules
- try:
- import _pypyjson
- assert hasattr(_pypyjson, 'hello_world')
- assert '(built-in)' not in repr(_pypyjson)
- finally:
- sys.modules.pop('_pypyjson', None)
-
- def test_shadow_extension_2(self):
- if self.runappdirect: skip("hard to test: module is already imported")
- # 'import _md5' is supposed to find the built-in module even
- # if there is also one in sys.path as long as it is *after* the
- # special entry '.../lib_pypy/__extensions__'. (Note that for now
- # there is one in lib_pypy/_md5.py, which should not be seen
- # either; hence the (built-in) test below.)
- import sys
- assert '_md5' not in sys.modules
- sys.path.append(sys.path.pop(0))
- try:
- import _md5
- assert not hasattr(_md5, 'hello_world')
- assert hasattr(_md5, 'md5')
- assert '(built-in)' in repr(_md5)
- finally:
- sys.path.insert(0, sys.path.pop())
- sys.modules.pop('_md5', None)
-
def test_invalid_pathname(self):
skip("This test fails on CPython 3.3, but passes on CPython 3.4+")
import imp
@@ -993,11 +945,11 @@
assert s.no_nul
-def test_PYTHONPATH_takes_precedence(space):
+def test_PYTHONPATH_takes_precedence(space):
if sys.platform == "win32":
py.test.skip("unresolved issues with win32 shell quoting rules")
- from pypy.interpreter.test.test_zpy import pypypath
- extrapath = udir.ensure("pythonpath", dir=1)
+ from pypy.interpreter.test.test_zpy import pypypath
+ extrapath = udir.ensure("pythonpath", dir=1)
extrapath.join("sched.py").write("print(42)\n")
old = os.environ.get('PYTHONPATH', None)
oldlang = os.environ.pop('LANG', None)
diff --git a/pypy/objspace/test/test_descriptor.py b/pypy/objspace/test/test_descriptor.py
--- a/pypy/objspace/test/test_descriptor.py
+++ b/pypy/objspace/test/test_descriptor.py
@@ -73,6 +73,10 @@
raises(AttributeError, X.v.__delete__, x)
def test_invalid_unicode_identifier(self):
+ skip("utf-8 encoding before translation accepts lone surrogates, "
+ "because it is Python 2.7, but after translation it does not. "
+ "Moreover, CPython 3.x accepts such unicode attributes anyway. "
+ "This makes this test half-wrong for now.")
class X(object):
pass
x = X()
diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py
--- a/pypy/tool/pytest/apptest.py
+++ b/pypy/tool/pytest/apptest.py
@@ -142,6 +142,9 @@
# They may be extension modules on CPython
name = None
for name in missing.copy():
+ if name == 'cpyext':
+ missing.remove(name)
+ continue
try:
__import__(name)
except ImportError:
More information about the pypy-commit
mailing list