Author: Manuel Jacob <m...@manueljacob.de> Branch: py3.3 Changeset: r81986:edefd168b2b3 Date: 2016-01-27 19:52 +0100 http://bitbucket.org/pypy/pypy/changeset/edefd168b2b3/
Log: hg merge 03591a1499c8 This merges marky1991's changes before he merged the problematic merge 88aafcb7c318. diff --git a/lib-python/3/code.py b/lib-python/3/code.py --- a/lib-python/3/code.py +++ b/lib-python/3/code.py @@ -105,10 +105,9 @@ The output is written by self.write(), below. """ - type, value, tb = sys.exc_info() + type, value, sys.last_traceback = sys.exc_info() sys.last_type = type sys.last_value = value - sys.last_traceback = tb if filename and type is SyntaxError: # Work hard to stuff the correct filename in the exception try: @@ -126,7 +125,7 @@ else: # If someone has set sys.excepthook, we let that take precedence # over self.write - sys.excepthook(type, value, tb) + sys.excepthook(type, value, self.last_traceback) def showtraceback(self): """Display the exception that just occurred. @@ -136,25 +135,35 @@ The output is written by self.write(), below. """ + sys.last_type, sys.last_value, last_tb = ei = sys.exc_info() + sys.last_traceback = last_tb try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - lines = traceback.format_list(tblist) - if lines: - lines.insert(0, "Traceback (most recent call last):\n") - lines.extend(traceback.format_exception_only(type, value)) + lines = [] + for value, tb in traceback._iter_chain(*ei[1:]): + if isinstance(value, str): + lines.append(value) + lines.append('\n') + continue + if tb: + tblist = traceback.extract_tb(tb) + if tb is last_tb: + # The last traceback includes the frame we + # exec'd in + del tblist[:1] + tblines = traceback.format_list(tblist) + if tblines: + lines.append("Traceback (most recent call last):\n") + lines.extend(tblines) + lines.extend(traceback.format_exception_only(type(value), + value)) finally: - tblist = tb = None + tblist = last_tb = ei = None if sys.excepthook is sys.__excepthook__: self.write(''.join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write - sys.excepthook(type, value, tb) + sys.excepthook(sys.last_type, sys.last_value, last_tb) def write(self, data): """Write a string. diff --git a/lib-python/3/pickle.py b/lib-python/3/pickle.py --- a/lib-python/3/pickle.py +++ b/lib-python/3/pickle.py @@ -23,7 +23,7 @@ """ -from types import FunctionType, BuiltinFunctionType +from types import FunctionType, BuiltinFunctionType, ModuleType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache import marshal @@ -622,6 +622,9 @@ # else tmp is empty, and we're done def save_dict(self, obj): + modict_saver = self._pickle_maybe_moduledict(obj) + if modict_saver is not None: + return self.save_reduce(*modict_saver) write = self.write if self.bin: @@ -672,6 +675,44 @@ write(SETITEM) # else tmp is empty, and we're done + def _pickle_maybe_moduledict(self, obj): + # save module dictionary as "getattr(module, '__dict__')" + try: + name = obj['__name__'] + if type(name) is not str: + return None + themodule = sys.modules[name] + if type(themodule) is not ModuleType: + return None + if themodule.__dict__ is not obj: + return None + except (AttributeError, KeyError, TypeError): + return None + return getattr, (themodule, '__dict__') + + def save_function(self, obj): + try: + return self.save_global(obj) + except PicklingError: + pass + # Check copy_reg.dispatch_table + reduce = dispatch_table.get(type(obj)) + if reduce: + rv = reduce(obj) + else: + # Check for a __reduce_ex__ method, fall back to __reduce__ + reduce = getattr(obj, "__reduce_ex__", None) + if reduce: + rv = reduce(self.proto) + else: + reduce = getattr(obj, "__reduce__", None) + if reduce: + rv = reduce() + else: + raise e + return self.save_reduce(obj=obj, *rv) + dispatch[FunctionType] = save_function + def save_global(self, obj, name=None, pack=struct.pack): write = self.write memo = self.memo @@ -737,7 +778,7 @@ return self.save_reduce(type, (...,), obj=obj) return self.save_global(obj) - dispatch[FunctionType] = save_global + dispatch[FunctionType] = save_function dispatch[BuiltinFunctionType] = save_global dispatch[type] = save_type diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -1381,7 +1381,7 @@ # ... and store it as __module__ self.name_op("__module__", ast.Store) # store the qualname - w_qualname = self.space.wrap(self.qualname) + w_qualname = self.space.wrap(self.qualname.decode("utf-8")) self.load_const(w_qualname) self.name_op("__qualname__", ast.Store) # compile the body proper diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -306,6 +306,7 @@ tup_base = [] tup_state = [ w(self.name), + w(self.qualname), w_doc, w(self.code), w_func_globals, @@ -319,8 +320,8 @@ def descr_function__setstate__(self, space, w_args): args_w = space.unpackiterable(w_args) try: - (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs, - w_func_dict, w_module) = args_w + (w_name, w_qualname, w_doc, w_code, w_func_globals, w_closure, + w_defs, w_func_dict, w_module) = args_w except ValueError: # wrong args raise OperationError(space.w_ValueError, @@ -328,6 +329,7 @@ self.space = space self.name = space.str_w(w_name) + self.qualname = space.str_w(w_qualname).decode("utf-8") self.code = space.interp_w(Code, w_code) if not space.is_w(w_closure, space.w_None): from pypy.interpreter.nestedscope import Cell diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py --- a/pypy/interpreter/test/test_app_main.py +++ b/pypy/interpreter/test/test_app_main.py @@ -808,31 +808,6 @@ data = self.run('-S -i', expect_prompt=True, expect_banner=True) assert 'copyright' not in data - def test_non_interactive_stdout_fully_buffered(self): - if os.name == 'nt': - try: - import __pypy__ - except: - py.test.skip('app_main cannot run on non-pypy for windows') - path = getscript(r""" - import sys, time - sys.stdout.write('\x00(STDOUT)\n\x00') # stays in buffers - time.sleep(1) - sys.stderr.write('\x00[STDERR]\n\x00') - time.sleep(1) - # stdout flushed automatically here - """) - cmdline = '%s -u "%s" %s' % (python3, app_main, path) - print 'POPEN:', cmdline - child_in, child_out_err = os.popen4(cmdline) - data = child_out_err.read(11) - # Py3 is always at least line buffered - assert data == '\x00(STDOUT)\n\x00' # from stdout - child_in.close() - data = child_out_err.read(11) - assert data == '\x00[STDERR]\n\x00' # from stderr - child_out_err.close() - def test_non_interactive_stdout_unbuffered(self, monkeypatch): monkeypatch.setenv('PYTHONUNBUFFERED', '1') if os.name == 'nt': diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py --- a/pypy/interpreter/test/test_zzpickle_and_slow.py +++ b/pypy/interpreter/test/test_zzpickle_and_slow.py @@ -394,8 +394,10 @@ import pickle tdict = {'2':2, '3':3, '5':5} diter = iter(tdict) - next(diter) - raises(TypeError, pickle.dumps, diter) + seen = next(diter) + pckl = pickle.dumps(diter) + result = pickle.loads(pckl) + assert set(result) == (set('235') - set(seen)) def test_pickle_reversed(self): import pickle diff --git a/pypy/module/__pypy__/test/test_stderrprinter.py b/pypy/module/__pypy__/test/test_stderrprinter.py --- a/pypy/module/__pypy__/test/test_stderrprinter.py +++ b/pypy/module/__pypy__/test/test_stderrprinter.py @@ -7,7 +7,9 @@ p.close() # this should be a no-op p.flush() # this should be a no-op assert p.fileno() == 2 - assert p.isatty() + # It doesn't make sense to assert this. Stderror could be a tty + # (the terminal) or not, depending on how we are running the tests. + # assert p.isatty() assert p.write('foo') == 3 raises(TypeError, p.write, b'foo') diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,6 +1,9 @@ # ____________________________________________________________ import sys +assert __version__ == "1.4.2", ("This test_c.py file is for testing a version" + " of cffi that differs from the one that we" + " get from 'import _cffi_backend'") if sys.version_info < (3,): type_or_class = "type" mandatory_b_prefix = '' @@ -2313,9 +2316,6 @@ f(); f() assert get_errno() == 77 -def test_abi(): - assert isinstance(FFI_DEFAULT_ABI, int) - def test_cast_to_array(): # not valid in C! extension to get a non-owning <cdata 'int[3]'> BInt = new_primitive_type("int") @@ -3393,6 +3393,78 @@ check(4 | 8, "CHB", "GTB") check(4 | 16, "CHB", "ROB") +def test_memmove(): + Short = new_primitive_type("short") + ShortA = new_array_type(new_pointer_type(Short), None) + Char = new_primitive_type("char") + CharA = new_array_type(new_pointer_type(Char), None) + p = newp(ShortA, [-1234, -2345, -3456, -4567, -5678]) + memmove(p, p + 1, 4) + assert list(p) == [-2345, -3456, -3456, -4567, -5678] + p[2] = 999 + memmove(p + 2, p, 6) + assert list(p) == [-2345, -3456, -2345, -3456, 999] + memmove(p + 4, newp(CharA, b"\x71\x72"), 2) + if sys.byteorder == 'little': + assert list(p) == [-2345, -3456, -2345, -3456, 0x7271] + else: + assert list(p) == [-2345, -3456, -2345, -3456, 0x7172] + +def test_memmove_buffer(): + import array + Short = new_primitive_type("short") + ShortA = new_array_type(new_pointer_type(Short), None) + a = array.array('H', [10000, 20000, 30000]) + p = newp(ShortA, 5) + memmove(p, a, 6) + assert list(p) == [10000, 20000, 30000, 0, 0] + memmove(p + 1, a, 6) + assert list(p) == [10000, 10000, 20000, 30000, 0] + b = array.array('h', [-1000, -2000, -3000]) + memmove(b, a, 4) + assert b.tolist() == [10000, 20000, -3000] + assert a.tolist() == [10000, 20000, 30000] + p[0] = 999 + p[1] = 998 + p[2] = 997 + p[3] = 996 + p[4] = 995 + memmove(b, p, 2) + assert b.tolist() == [999, 20000, -3000] + memmove(b, p + 2, 4) + assert b.tolist() == [997, 996, -3000] + p[2] = -p[2] + p[3] = -p[3] + memmove(b, p + 2, 6) + assert b.tolist() == [-997, -996, 995] + +def test_memmove_readonly_readwrite(): + SignedChar = new_primitive_type("signed char") + SignedCharA = new_array_type(new_pointer_type(SignedChar), None) + p = newp(SignedCharA, 5) + memmove(p, b"abcde", 3) + assert list(p) == [ord("a"), ord("b"), ord("c"), 0, 0] + memmove(p, bytearray(b"ABCDE"), 2) + assert list(p) == [ord("A"), ord("B"), ord("c"), 0, 0] + py.test.raises((TypeError, BufferError), memmove, b"abcde", p, 3) + ba = bytearray(b"xxxxx") + memmove(dest=ba, src=p, n=3) + assert ba == bytearray(b"ABcxx") + memmove(ba, b"EFGH", 4) + assert ba == bytearray(b"EFGHx") + +def test_memmove_sign_check(): + SignedChar = new_primitive_type("signed char") + SignedCharA = new_array_type(new_pointer_type(SignedChar), None) + p = newp(SignedCharA, 5) + py.test.raises(ValueError, memmove, p, p + 1, -1) # not segfault + +def test_memmove_bad_cdata(): + BInt = new_primitive_type("int") + p = cast(BInt, 42) + py.test.raises(TypeError, memmove, p, bytearray(b'a'), 1) + py.test.raises(TypeError, memmove, bytearray(b'a'), p, 1) + def test_dereference_null_ptr(): BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) @@ -3425,6 +3497,20 @@ "that you are not e.g. mixing up different ffi " "instances)") -def test_version(): - # this test is here mostly for PyPy - assert __version__ == "1.2.1" +def test_stdcall_function_type(): + assert FFI_CDECL == FFI_DEFAULT_ABI + try: + stdcall = FFI_STDCALL + except NameError: + stdcall = FFI_DEFAULT_ABI + BInt = new_primitive_type("int") + BFunc = new_function_type((BInt, BInt), BInt, False, stdcall) + if stdcall != FFI_DEFAULT_ABI: + assert repr(BFunc) == "<ctype 'int(__stdcall *)(int, int)'>" + else: + assert repr(BFunc) == "<ctype 'int(*)(int, int)'>" + +def test_get_common_types(): + d = {} + _get_common_types(d) + assert d['bool'] == '_Bool' diff --git a/pypy/module/_frozen_importlib/__init__.py b/pypy/module/_frozen_importlib/__init__.py --- a/pypy/module/_frozen_importlib/__init__.py +++ b/pypy/module/_frozen_importlib/__init__.py @@ -30,7 +30,7 @@ space.wrap(space.builtin)) code_w.exec_code(space, self.w_dict, self.w_dict) - self.w_import = space.wrap(interp_import.import_with_frames_removed) + self.w_import = space.wrap(interp_import.__import__) def startup(self, space): """Copy our __import__ to builtins.""" diff --git a/pypy/module/_frozen_importlib/interp_import.py b/pypy/module/_frozen_importlib/interp_import.py --- a/pypy/module/_frozen_importlib/interp_import.py +++ b/pypy/module/_frozen_importlib/interp_import.py @@ -2,7 +2,7 @@ from pypy.interpreter.error import OperationError @interp2app -def import_with_frames_removed(space, __args__): +def __import__(space, __args__): try: return space.call_args( space.getbuiltinmodule('_frozen_importlib').getdictvalue( diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -390,7 +390,7 @@ raises(TypeError, pickle.dumps, f, protocol) def test_mod(self): - import _io + import _io, _frozen_importlib typemods = dict((t, t.__module__) for t in vars(_io).values() if isinstance(t, type)) for t, mod in typemods.items(): @@ -398,6 +398,11 @@ assert mod == 'builtins' elif t is _io.UnsupportedOperation: assert mod == 'io' + #TODO: Make sure this is a reasonable thing to do. Check if there is + #a cleaner way to do these checks or if these checks even make sense + #in general. They seem really brittle. + elif t is _frozen_importlib.BuiltinImporter: + assert mod == "_frozen_importlib" else: assert mod == '_io' diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -1094,27 +1094,13 @@ return space.str(space.getattr(w_exc, space.wrap("args"))) -class W_Error(interp_exceptions.W_OSError): - "An error occurred in the SSL implementation." - - def descr_str(self, space): - if space.isinstance_w(self.w_strerror, space.w_unicode): - return self.w_strerror - else: - return space.str(space.newtuple(self.args_w)) - -W_Error.typedef = TypeDef( - "ssl.SSLError", - interp_exceptions.W_OSError.typedef, - __new__ = interp_exceptions._new(W_Error), - __doc__ = W_Error.__doc__, - __str__ = interp2app(W_Error.descr_str), - ) - - class ErrorCache: def __init__(self, space): - self.w_error = space.gettypefor(W_Error) + w_socketerror = interp_socket.get_error(space, "error") + self.w_error = space.new_exception_class( + "_ssl.SSLError", w_socketerror) + space.setattr(self.w_error, space.wrap('__str__'), + space.wrap(interp2app(SSLError_descr_str))) self.w_ZeroReturnError = space.new_exception_class( "ssl.SSLZeroReturnError", self.w_error) self.w_WantReadError = space.new_exception_class( diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -75,19 +75,25 @@ w_mod = check_sys_modules_w(space, modulename) if w_mod: return w_mod - if modulename in space.builtin_modules: - return space.getbuiltinmodule(modulename) + try: + lock = getimportlock(space) + lock.acquire_lock() - ec = space.getexecutioncontext() - with open(os.path.join(lib_pypy, modulename + '.py')) as fp: - source = fp.read() - pathname = "<frozen %s>" % modulename - code_w = ec.compiler.compile(source, pathname, 'exec', 0) - w_mod = add_module(space, space.wrap(modulename)) - space.setitem(space.sys.get('modules'), w_mod.w_name, w_mod) - space.setitem(w_mod.w_dict, space.wrap('__name__'), w_mod.w_name) - code_w.exec_code(space, w_mod.w_dict, w_mod.w_dict) - assert check_sys_modules_w(space, modulename) + if modulename in space.builtin_modules: + return space.getbuiltinmodule(modulename) + + ec = space.getexecutioncontext() + with open(os.path.join(lib_pypy, modulename + '.py')) as fp: + source = fp.read() + pathname = "<frozen %s>" % modulename + code_w = ec.compiler.compile(source, pathname, 'exec', 0) + w_mod = add_module(space, space.wrap(modulename)) + space.setitem(space.sys.get('modules'), w_mod.w_name, w_mod) + space.setitem(w_mod.w_dict, space.wrap('__name__'), w_mod.w_name) + code_w.exec_code(space, w_mod.w_dict, w_mod.w_dict) + assert check_sys_modules_w(space, modulename) + finally: + lock.release_lock(silent_after_fork=True) return w_mod diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -84,7 +84,9 @@ name = space.str0_w(w_name) if name not in space.builtin_modules: return - return space.getbuiltinmodule(name) + # force_init is needed to make reload actually reload instead of just + # using the already-present module in sys.modules. + return space.getbuiltinmodule(name, force_init=True) def init_frozen(space, w_name): return None 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 @@ -499,7 +499,7 @@ # Check relative fails when __package__ set to a non-string ns = dict(__package__=object()) check_absolute() - raises(ValueError, check_relative) + raises(TypeError, check_relative) def test_import_function(self): # More tests for __import__ @@ -636,7 +636,9 @@ def test_del_from_sys_modules(self): try: import del_sys_module - except ImportError: + #This raises a KeyError in cpython, + #not an import error + except KeyError: pass # ok else: assert False, 'should not work' diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -32,7 +32,8 @@ w_sys.flush_std_files(space) msg = space.bytes_w(space.call_function(w_read)) - assert 'Exception IOError' in msg + # IOError has become an alias for OSError + assert 'Exception OSError' in msg finally: space.setattr(w_sys, space.wrap('stdout'), w_sys.get('__stdout__')) space.setattr(w_sys, space.wrap('stderr'), w_sys.get('__stderr__')) diff --git a/pypy/module/test_lib_pypy/test_code_module.py b/pypy/module/test_lib_pypy/test_code_module.py --- a/pypy/module/test_lib_pypy/test_code_module.py +++ b/pypy/module/test_lib_pypy/test_code_module.py @@ -21,7 +21,9 @@ def test_cause_tb(self): interp = self.get_interp() - interp.runsource('raise IOError from OSError') + # (Arbitrarily) Changing to TypeError as IOError is now an alias of + # OSError, making testing confusing + interp.runsource('raise TypeError from OSError') result = interp.out.getvalue() expected_header = """OSError @@ -30,7 +32,7 @@ Traceback (most recent call last): """ assert expected_header in result - assert result.endswith("IOError\n") + assert result.endswith("TypeError\n") def test_context_tb(self): interp = self.get_interp() diff --git a/pypy/module/thread/test/test_import_lock.py b/pypy/module/thread/test/test_import_lock.py --- a/pypy/module/thread/test/test_import_lock.py +++ b/pypy/module/thread/test/test_import_lock.py @@ -96,14 +96,14 @@ original_acquire() importlock.count = 0 monkeypatch.setattr(importlock, 'acquire_lock', acquire_lock) + # An already imported module - # An already imported module importhook(space, 'sys') assert importlock.count == 0 # A new module - importhook(space, '__future__') + importhook(space, "time") assert importlock.count == 1 # Import it again previous_count = importlock.count - importhook(space, '__future__') + importhook(space, "time") assert importlock.count == previous_count _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit