[pypy-svn] pypy default: Implemented StringIO.__{get, set}setate__.
alex_gaynor
commits-noreply at bitbucket.org
Fri Feb 4 18:57:23 CET 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r41614:5a4e944400d5
Date: 2011-02-04 12:41 -0500
http://bitbucket.org/pypy/pypy/changeset/5a4e944400d5/
Log: Implemented StringIO.__{get,set}setate__.
diff --git a/pypy/module/_io/test/test_stringio.py b/pypy/module/_io/test/test_stringio.py
--- a/pypy/module/_io/test/test_stringio.py
+++ b/pypy/module/_io/test/test_stringio.py
@@ -264,3 +264,33 @@
sio = io.StringIO(s * 2)
sio.close()
raises(ValueError, next, sio)
+
+ def test_getstate(self):
+ import io
+
+ sio = io.StringIO()
+ state = sio.__getstate__()
+ assert len(state) == 4
+ assert isinstance(state[0], unicode)
+ assert isinstance(state[1], str)
+ assert isinstance(state[2], int)
+ assert isinstance(state[3], dict)
+ sio.close()
+ raises(ValueError, sio.__getstate__)
+
+ def test_setstate(self):
+ import io
+
+ sio = io.StringIO()
+ sio.__setstate__((u"no error", u"\n", 0, None))
+ sio.__setstate__((u"no error", u"", 0, {"spam": 3}))
+ raises(ValueError, sio.__setstate__, (u"", u"f", 0, None))
+ raises(ValueError, sio.__setstate__, (u"", u"", -1, None))
+ raises(TypeError, sio.__setstate__, ("", u"", 0, None))
+ raises(TypeError, sio.__setstate__, (u"", u"", 0.0, None))
+ raises(TypeError, sio.__setstate__, (u"", u"", 0, 0))
+ raises(TypeError, sio.__setstate__, (u"len-test", 0))
+ raises(TypeError, sio.__setstate__)
+ raises(TypeError, sio.__setstate__, 0)
+ sio.close()
+ raises(ValueError, sio.__setstate__, (u"closed", u"", 0, None))
diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py
--- a/pypy/module/_io/interp_stringio.py
+++ b/pypy/module/_io/interp_stringio.py
@@ -53,6 +53,61 @@
self.write_w(space, w_initvalue)
self.pos = 0
+ @unwrap_spec('self', ObjSpace)
+ def descr_getstate(self, space):
+ w_initialval = self.getvalue_w(space)
+ w_dict = space.call_method(self.w_dict, "copy")
+ if self.readnl is None:
+ w_readnl = space.w_None
+ else:
+ w_readnl = space.str(space.wrap(self.readnl))
+ return space.newtuple([
+ w_initialval, w_readnl, space.wrap(self.pos), w_dict
+ ])
+
+ @unwrap_spec('self', ObjSpace, W_Root)
+ def descr_setstate(self, space, w_state):
+ self._check_closed(space)
+
+ # We allow the state tuple to be longer than 4, because we may need
+ # someday to extend the object's state without breaking
+ # backwards-compatibility
+ if not space.isinstance_w(w_state, space.w_tuple) or space.int_w(space.len(w_state)) < 4:
+ raise operationerrfmt(space.w_TypeError,
+ "%s.__setstate__ argument should be a 4-tuple, got %s",
+ space.type(self).getname(space),
+ space.type(w_state).getname(space)
+ )
+ w_initval, w_readnl, w_pos, w_dict = space.unpackiterable(w_state, 4)
+ # Initialize state
+ self.descr_init(space, w_initval, w_readnl)
+
+ # Restore the buffer state. Even if __init__ did initialize the buffer,
+ # we have to initialize it again since __init__ may translates the
+ # newlines in the inital_value string. We clearly do not want that
+ # because the string value in the state tuple has already been
+ # translated once by __init__. So we do not take any chance and replace
+ # object's buffer completely
+ initval = space.unicode_w(w_initval)
+ size = len(initval)
+ self.resize_buffer(size)
+ self.buf = list(initval)
+ pos = space.getindex_w(w_pos, space.w_TypeError)
+ if pos < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("position value cannot be negative")
+ )
+ self.pos = pos
+ if not space.is_w(w_dict, space.w_None):
+ if not space.isinstance_w(w_dict, space.w_dict):
+ raise operationerrfmt(space.w_TypeError,
+ "fourth item of state should be a dict, got a %s",
+ space.type(w_dict).getname(space)
+ )
+ # Alternatively, we could replace the internal dictionary
+ # completely. However, it seems more practical to just update it.
+ space.call_method(self.w_dict, "update", w_dict)
+
def _check_closed(self, space, message=None):
if self.buf is None:
if message is None:
@@ -230,6 +285,8 @@
__module__ = "_io",
__new__ = generic_new_descr(W_StringIO),
__init__ = interp2app(W_StringIO.descr_init),
+ __getstate__ = interp2app(W_StringIO.descr_getstate),
+ __setstate__ = interp2app(W_StringIO.descr_setstate),
write = interp2app(W_StringIO.write_w),
read = interp2app(W_StringIO.read_w),
readline = interp2app(W_StringIO.readline_w),
More information about the Pypy-commit
mailing list