[pypy-commit] pypy py3.3: Implement preliminary stderr printer and use it in app_main.py.
mjacob
noreply at buildbot.pypy.org
Wed Aug 26 18:06:52 CEST 2015
Author: Manuel Jacob <me at 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'
More information about the pypy-commit
mailing list