[pypy-svn] pypy default: _io.open translates, and fixed the first set of segfaults.
alex_gaynor
commits-noreply at bitbucket.org
Mon Jan 31 01:00:11 CET 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r41477:74343e919325
Date: 2011-01-30 18:32 -0500
http://bitbucket.org/pypy/pypy/changeset/74343e919325/
Log: _io.open translates, and fixed the first set of segfaults.
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -260,6 +260,7 @@
def __init__(self, space):
W_TextIOBase.__init__(self, space)
self.state = STATE_ZERO
+ self.w_encoder = None
self.w_decoder = None
self.decoded_chars = None # buffer for text returned from decoder
@@ -744,7 +745,7 @@
space.call_method(self.w_decoder, "reset")
self.encoding_start_of_stream = True
else:
- space.call_method(self.w_encoder, "setstate",
+ space.call_method(self.w_decoder, "setstate",
space.newtuple([space.wrap(""),
space.wrap(cookie.dec_flags)]))
diff --git a/pypy/module/_io/interp_io.py b/pypy/module/_io/interp_io.py
--- a/pypy/module/_io/interp_io.py
+++ b/pypy/module/_io/interp_io.py
@@ -1,9 +1,13 @@
from pypy.interpreter.baseobjspace import ObjSpace, W_Root
+from pypy.interpreter.error import operationerrfmt, OperationError
+from pypy.interpreter.gateway import interp2app, Arguments, unwrap_spec
from pypy.interpreter.typedef import (
TypeDef, interp_attrproperty, generic_new_descr)
-from pypy.interpreter.gateway import interp2app, Arguments, unwrap_spec
from pypy.module.exceptions.interp_exceptions import W_IOError
+from pypy.module._io.interp_fileio import W_FileIO
from pypy.module._io.interp_iobase import W_IOBase
+from pypy.module._io.interp_textio import W_TextIOWrapper
+
class W_BlockingIOError(W_IOError):
def __init__(self, space):
@@ -24,11 +28,144 @@
characters_written = interp_attrproperty('written', W_BlockingIOError),
)
- at unwrap_spec(ObjSpace, Arguments)
-def open(space, __args__):
- # XXX cheat!
- w_pyio = space.call_method(space.builtin, '__import__',
- space.wrap("_pyio"))
- w_func = space.getattr(w_pyio, space.wrap("open"))
- return space.call_args(w_func, __args__)
+DEFAULT_BUFFER_SIZE = 8 * 1024
+ at unwrap_spec(ObjSpace, W_Root, str, int, "str_or_None", "str_or_None", "str_or_None", bool)
+def open(space, w_file, mode="r", buffering=-1, encoding=None, errors=None,
+ newline=None, closefd=True):
+ from pypy.module._io.interp_bufferedio import (W_BufferedRandom,
+ W_BufferedWriter, W_BufferedReader)
+
+ if not (space.isinstance_w(w_file, space.w_basestring) or
+ space.isinstance_w(w_file, space.w_int) or
+ space.isinstance_w(w_file, space.w_long)):
+ raise operationerrfmt(space.w_TypeError,
+ "invalid file: %s", space.str_w(space.repr(w_file))
+ )
+
+ reading = writing = appending = updating = text = binary = universal = False
+
+ uniq_mode = {}
+ for flag in mode:
+ uniq_mode[flag] = None
+ if len(uniq_mode) != len(mode):
+ raise operationerrfmt(space.w_ValueError,
+ "invalid mode: %s", mode
+ )
+ for flag in mode:
+ if flag == "r":
+ reading = True
+ elif flag == "w":
+ writing = True
+ elif flag == "a":
+ appending = True
+ elif flag == "+":
+ updating = True
+ elif flag == "t":
+ text = True
+ elif flag == "b":
+ binary = True
+ elif flag == "U":
+ universal = True
+ reading = True
+ else:
+ raise operationerrfmt(space.w_ValueError,
+ "invalid mode: %s", mode
+ )
+
+ rawmode = ""
+ if reading:
+ rawmode += "r"
+ if writing:
+ rawmode += "w"
+ if appending:
+ rawmode += "a"
+ if updating:
+ rawmode += "+"
+
+ if universal and (writing or appending):
+ raise OperationError(space.w_ValueError,
+ space.wrap("can't use U and writing mode at once")
+ )
+ if text and binary:
+ raise OperationError(space.w_ValueError,
+ space.wrap("can't have text and binary mode at once")
+ )
+ if reading + writing + appending > 1:
+ raise OperationError(space.w_ValueError,
+ space.wrap("must have exactly one of read/write/append mode")
+ )
+ if binary and encoding is not None:
+ raise OperationError(space.w_ValueError,
+ space.wrap("binary mode doesn't take an errors argument")
+ )
+ if binary and newline is not None:
+ raise OperationError(space.w_ValueError,
+ space.wrap("binary mode doesn't take a newline argument")
+ )
+ w_raw = space.call_function(
+ space.gettypefor(W_FileIO), w_file, space.wrap(rawmode), space.wrap(closefd)
+ )
+
+ isatty = space.is_true(space.call_method(w_raw, "isatty"))
+ line_buffering = buffering == 1 or (buffering < 0 and isatty)
+ if line_buffering:
+ buffering = -1
+
+ if buffering < 0:
+ buffering = DEFAULT_BUFFER_SIZE
+ """
+ XXX: implement me!
+ #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ {
+ struct stat st;
+ long fileno;
+ PyObject *res = PyObject_CallMethod(raw, "fileno", NULL);
+ if (res == NULL)
+ goto error;
+
+ fileno = PyInt_AsLong(res);
+ Py_DECREF(res);
+ if (fileno == -1 && PyErr_Occurred())
+ goto error;
+
+ if (fstat(fileno, &st) >= 0)
+ buffering = st.st_blksize;
+ }
+ #endif
+ """
+ if buffering < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("invalid buffering size")
+ )
+
+ if buffering == 0:
+ if not binary:
+ raise OperationError(space.w_ValueError,
+ space.wrap("can't have unbuffered text I/O")
+ )
+ return w_raw
+
+ if updating:
+ buffer_cls = W_BufferedRandom
+ elif writing or appending:
+ buffer_cls = W_BufferedWriter
+ elif reading:
+ buffer_cls = W_BufferedReader
+ else:
+ raise operationerrfmt(space.w_ValueError, "unknown mode: '%s'", mode)
+ w_buffer = space.call_function(
+ space.gettypefor(buffer_cls), w_raw, space.wrap(buffering)
+ )
+ if binary:
+ return w_buffer
+
+ w_wrapper = space.call_function(space.gettypefor(W_TextIOWrapper),
+ w_buffer,
+ space.wrap(encoding),
+ space.wrap(errors),
+ space.wrap(newline),
+ space.wrap(line_buffering)
+ )
+ space.setattr(w_wrapper, space.wrap("mode"), space.wrap(mode))
+ return w_wrapper
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
@@ -1,6 +1,9 @@
+from __future__ import with_statement
+
from pypy.conftest import gettestobjspace
from pypy.tool.udir import udir
+
class AppTestIoModule:
def setup_class(cls):
cls.space = gettestobjspace(usemodules=['_io'])
@@ -148,11 +151,21 @@
assert f.mode == 'rb'
f.close()
+ with io.open(self.tmpfile, "rt") as f:
+ assert f.mode == "rt"
+
def test_open_writable(self):
import io
f = io.open(self.tmpfile, "w+b")
f.close()
+ def test_valid_mode(self):
+ import io
+
+ raises(ValueError, io.open, self.tmpfile, "ww")
+ raises(ValueError, io.open, self.tmpfile, "rwa")
+ raises(ValueError, io.open, self.tmpfile, "b", newline="\n")
+
def test_array_write(self):
import _io, array
a = array.array(b'i', range(10))
@@ -160,3 +173,26 @@
with _io.open(self.tmpfile, "wb", 0) as f:
assert f.write(a) == n
+
+ def test_seek_and_tell(self):
+ import _io
+
+ with _io.open(self.tmpfile, "wb") as f:
+ f.write("abcd")
+
+ with _io.open(self.tmpfile) as f:
+ decoded = f.read()
+
+ # seek positions
+ for i in xrange(len(decoded) + 1):
+ # read lenghts
+ for j in [1, 5, len(decoded) - i]:
+ with _io.open(self.tmpfile) as f:
+ res = f.read(i)
+ assert res == decoded[:i]
+ cookie = f.tell()
+ res = f.read(j)
+ assert res == decoded[i:i + j]
+ f.seek(cookie)
+ res = f.read()
+ assert res == decoded[i:]
More information about the Pypy-commit
mailing list