Author: Ronan Lamy <ronan.l...@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: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit