Author: Manuel Jacob <m...@manueljacob.de> Branch: py3.3 Changeset: r79232:54b7b89a7172 Date: 2015-08-26 18:06 +0200 http://bitbucket.org/pypy/pypy/changeset/54b7b89a7172/
Log: Implement preliminary stderr printer and use it in app_main.py. This is needed because during initialization of stderr imports can happen. If the interpreter is run in verbose mode importlib prints to stderr, resulting in an AttributeError. diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -43,9 +43,10 @@ """ try: - from __pypy__ import hidden_applevel + from __pypy__ import hidden_applevel, StdErrPrinter except ImportError: hidden_applevel = lambda f: f + StdErrPrinter = None try: from _ast import PyCF_ACCEPT_NULL_BYTES except ImportError: @@ -266,6 +267,9 @@ if hasattr(sys, 'stdin'): return # already initialized + if StdErrPrinter is not None: + sys.stderr = sys.__stderr__ = StdErrPrinter(2) + if 1: # keep indentation if encoding and ':' in encoding: encoding, errors = encoding.split(':', 1) 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 @@ -87,6 +87,7 @@ 'save_module_content_for_future_reload': 'interp_magic.save_module_content_for_future_reload', 'normalize_exc' : 'interp_magic.normalize_exc', + 'StdErrPrinter' : 'interp_stderrprinter.W_StdErrPrinter', } submodules = { diff --git a/pypy/module/__pypy__/interp_stderrprinter.py b/pypy/module/__pypy__/interp_stderrprinter.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_stderrprinter.py @@ -0,0 +1,70 @@ +import errno, os + +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import wrap_oserror +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.typedef import GetSetProperty, TypeDef + + +class W_StdErrPrinter(W_Root): + @staticmethod + @unwrap_spec(fd='c_int') + def descr_new(space, w_subtype, fd): + return W_StdErrPrinter(fd) + + def __init__(self, fd): + self.fd = fd + + def descr_repr(self, space): + addrstring = unicode(self.getaddrstring(space)) + return space.wrap(u"<StdErrPrinter(fd=%d) object at 0x%s>" % + (self.fd, addrstring)) + + def descr_noop(self, space): + pass + + def descr_fileno(self, space): + return space.wrap(self.fd) + + def descr_isatty(self, space): + try: + res = os.isatty(self.fd) + except OSError, e: + raise wrap_oserror(space, e) + return space.wrap(res) + + def descr_write(self, space, w_data): + # Encode to UTF-8. + data = space.identifier_w(w_data) + + try: + n = os.write(self.fd, data) + except OSError, e: + if e.errno == errno.EAGAIN: + return space.w_None + raise wrap_oserror(space, e) + return space.wrap(n) + + def descr_get_closed(self, space): + return space.wrap(False) + + def descr_get_encoding(self, space): + return space.w_None + + def descr_get_mode(self, space): + return space.wrap(u'w') + + +W_StdErrPrinter.typedef = TypeDef("StdErrPrinter", + __new__ = interp2app(W_StdErrPrinter.descr_new), + __repr__ = interp2app(W_StdErrPrinter.descr_repr), + close = interp2app(W_StdErrPrinter.descr_noop), + flush = interp2app(W_StdErrPrinter.descr_noop), + fileno = interp2app(W_StdErrPrinter.descr_fileno), + isatty = interp2app(W_StdErrPrinter.descr_isatty), + write = interp2app(W_StdErrPrinter.descr_write), + + closed = GetSetProperty(W_StdErrPrinter.descr_get_closed), + encoding = GetSetProperty(W_StdErrPrinter.descr_get_encoding), + mode = GetSetProperty(W_StdErrPrinter.descr_get_mode), +) diff --git a/pypy/module/__pypy__/test/test_stderrprinter.py b/pypy/module/__pypy__/test/test_stderrprinter.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/test/test_stderrprinter.py @@ -0,0 +1,16 @@ +def app_test_stderrprinter(): + from __pypy__ import StdErrPrinter + + p = StdErrPrinter(2) + assert repr(p).startswith("<StdErrPrinter(fd=2) object at") + + p.close() # this should be a no-op + p.flush() # this should be a no-op + assert p.fileno() == 2 + assert p.isatty() + assert p.write('foo') == 3 + raises(TypeError, p.write, b'foo') + + assert not p.closed + assert p.encoding is None + assert p.mode == 'w' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit