[pypy-svn] r53755 - in pypy/dist/pypy: doc/config module/cStringIO module/cStringIO/test rlib

arigo at codespeak.net arigo at codespeak.net
Mon Apr 14 15:32:19 CEST 2008


Author: arigo
Date: Mon Apr 14 15:32:17 2008
New Revision: 53755

Added:
   pypy/dist/pypy/doc/config/objspace.usemodules.cStringIO.txt   (contents, props changed)
   pypy/dist/pypy/module/cStringIO/   (props changed)
   pypy/dist/pypy/module/cStringIO/__init__.py   (contents, props changed)
   pypy/dist/pypy/module/cStringIO/interp_stringio.py   (contents, props changed)
   pypy/dist/pypy/module/cStringIO/test/   (props changed)
   pypy/dist/pypy/module/cStringIO/test/__init__.py   (contents, props changed)
   pypy/dist/pypy/module/cStringIO/test/test_interp_stringio.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rlib/rStringIO.py
Log:
Starting an interp-level cStringIO module.

Motivation: the mako benchmark spends about 3 times longer in cStringIO
(which is really StringIO) than it does on CPython.


Added: pypy/dist/pypy/doc/config/objspace.usemodules.cStringIO.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.cStringIO.txt	Mon Apr 14 15:32:17 2008
@@ -0,0 +1,4 @@
+Use the built-in cStringIO module.
+
+If not enabled, importing cStringIO gives you the app-level
+implementation from the standard library StringIO module.

Added: pypy/dist/pypy/module/cStringIO/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/cStringIO/__init__.py	Mon Apr 14 15:32:17 2008
@@ -0,0 +1,13 @@
+
+# Package initialisation
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+    appleveldefs = {
+    }
+
+    interpleveldefs = {
+        'StringIO':    'interp_stringio.StringIO',
+        #'InputType':   'interp_stringio.W_InputType',
+        'OutputType':  'interp_stringio.W_OutputType',
+    }

Added: pypy/dist/pypy/module/cStringIO/interp_stringio.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/cStringIO/interp_stringio.py	Mon Apr 14 15:32:17 2008
@@ -0,0 +1,87 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter.gateway import interp2app
+from pypy.rlib.rStringIO import RStringIO
+
+
+PIECES = 80
+BIGPIECES = 32
+
+
+class W_OutputType(Wrappable, RStringIO):
+    def __init__(self, space):
+        RStringIO.__init__(self)
+        self.space = space
+        self.softspace = 0    # part of the file object API
+
+    def descr_close(self):
+        self.close()
+    descr_close.unwrap_spec = ['self']
+
+    def check_closed(self):
+        if self.is_closed():
+            space = self.space
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("I/O operation on closed file"))
+
+    def descr_getvalue(self):
+        self.check_closed()
+        return self.space.wrap(self.getvalue())
+    descr_getvalue.unwrap_spec = ['self']
+
+    def descr_read(self, n=-1):
+        self.check_closed()
+        return self.space.wrap(self.read(n))
+    descr_read.unwrap_spec = ['self', int]
+
+    def descr_reset(self):
+        self.check_closed()
+        self.seek(0)
+    descr_reset.unwrap_spec = ['self']
+
+    def descr_seek(self, position, mode=0):
+        self.check_closed()
+        self.seek(position, mode)
+    descr_seek.unwrap_spec = ['self', int, int]
+
+    def descr_tell(self):
+        self.check_closed()
+        return self.space.wrap(self.tell())
+    descr_tell.unwrap_spec = ['self']
+
+    def descr_write(self, buffer):
+        self.check_closed()
+        self.write(buffer)
+    descr_write.unwrap_spec = ['self', 'bufferstr']
+
+# ____________________________________________________________
+
+def descr_closed(space, self):
+    return space.wrap(self.strings is None)
+
+def descr_softspace(space, self):
+    return space.wrap(self.softspace)
+
+def descr_setsoftspace(space, self, w_newvalue):
+    self.softspace = space.int_w(w_newvalue)
+
+W_OutputType.typedef = TypeDef(
+    "cStringIO.StringO",
+    close        = interp2app(W_OutputType.descr_close),
+    closed       = GetSetProperty(descr_closed, cls=W_OutputType),
+    getvalue     = interp2app(W_OutputType.descr_getvalue),
+    read         = interp2app(W_OutputType.descr_read),
+    reset        = interp2app(W_OutputType.descr_reset),
+    seek         = interp2app(W_OutputType.descr_seek),
+    softspace    = GetSetProperty(descr_softspace,
+                                  descr_setsoftspace,
+                                  cls=W_OutputType),
+    tell         = interp2app(W_OutputType.descr_tell),
+    write        = interp2app(W_OutputType.descr_write),
+    )
+
+# ____________________________________________________________
+
+def StringIO(space):
+    return space.wrap(W_OutputType(space))

Added: pypy/dist/pypy/module/cStringIO/test/__init__.py
==============================================================================

Added: pypy/dist/pypy/module/cStringIO/test/test_interp_stringio.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/cStringIO/test/test_interp_stringio.py	Mon Apr 14 15:32:17 2008
@@ -0,0 +1,113 @@
+
+from pypy.conftest import gettestobjspace
+
+import os, sys, py
+
+
+class AppTestcStringIO:
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('cStringIO',))
+        cls.space = space
+        cls.w_write_many_expected_result = space.wrap(''.join(
+            [chr(i) for j in range(10) for i in range(253)]))
+        cls.w_StringIO = space.appexec([], """():
+            import cStringIO
+            return cStringIO.StringIO
+        """)
+
+    def test_simple(self):
+        f = self.StringIO()
+        f.write('hello')
+        f.write(' world')
+        assert f.getvalue() == 'hello world'
+
+    def test_write_many(self):
+        f = self.StringIO()
+        for j in range(10):
+            for i in range(253):
+                f.write(chr(i))
+        expected = ''.join([chr(i) for j in range(10) for i in range(253)])
+        assert f.getvalue() == expected
+
+    def test_seek(self):
+        f = self.StringIO()
+        f.write('0123')
+        f.write('456')
+        f.write('789')
+        f.seek(4)
+        f.write('AB')
+        assert f.getvalue() == '0123AB6789'
+        f.seek(-2, 2)
+        f.write('CDE')
+        assert f.getvalue() == '0123AB67CDE'
+        f.seek(2, 0)
+        f.seek(5, 1)
+        f.write('F')
+        assert f.getvalue() == '0123AB6FCDE'
+
+    def test_write_beyond_end(self):
+        f = self.StringIO()
+        f.seek(20, 1)
+        assert f.tell() == 20
+        f.write('X')
+        assert f.getvalue() == '\x00' * 20 + 'X'
+
+    def test_tell(self):
+        f = self.StringIO()
+        f.write('0123')
+        f.write('456')
+        assert f.tell() == 7
+        f.seek(2)
+        for i in range(3, 20):
+            f.write('X')
+            assert f.tell() == i
+        assert f.getvalue() == '01XXXXXXXXXXXXXXXXX'
+
+    def test_read(self):
+        f = self.StringIO()
+        assert f.read() == ''
+        f.write('0123')
+        f.write('456')
+        assert f.read() == ''
+        assert f.read(5) == ''
+        assert f.tell() == 7
+        f.seek(1)
+        assert f.read() == '123456'
+        assert f.tell() == 7
+        f.seek(1)
+        assert f.read(12) == '123456'
+        assert f.tell() == 7
+        f.seek(1)
+        assert f.read(2) == '12'
+        assert f.read(1) == '3'
+        assert f.tell() == 4
+        f.seek(0)
+        assert f.read() == '0123456'
+        assert f.tell() == 7
+        f.seek(0)
+        assert f.read(7) == '0123456'
+        assert f.tell() == 7
+        f.seek(15)
+        assert f.read(2) == ''
+        assert f.tell() == 15
+
+    def test_reset(self):
+        from cStringIO import StringIO
+        f = StringIO()
+        f.write('foobar')
+        f.reset()
+        res = f.read()
+        assert res == 'foobar'
+
+    def test_close(self):
+        from cStringIO import StringIO
+        f = StringIO()
+        assert not f.closed
+        f.close()
+        raises(ValueError, f.write, 'hello')
+        raises(ValueError, f.getvalue)
+        raises(ValueError, f.read, 0)
+        raises(ValueError, f.seek, 0)
+        assert f.closed
+        f.close()
+        assert f.closed

Modified: pypy/dist/pypy/rlib/rStringIO.py
==============================================================================
--- pypy/dist/pypy/rlib/rStringIO.py	(original)
+++ pypy/dist/pypy/rlib/rStringIO.py	Mon Apr 14 15:32:17 2008
@@ -28,6 +28,15 @@
         self.bigbuffer = []
         self.pos = AT_END
 
+    def close(self):
+        self.strings = None
+        self.numstrings = 0
+        self.numbigstrings = 0
+        self.bigbuffer = None
+
+    def is_closed(self):
+        return self.strings is None
+
     def getvalue(self):
         """If self.strings contains more than 1 string, join all the
         strings together.  Return the final single string."""



More information about the Pypy-commit mailing list