[pypy-commit] pypy default: Implement the app-level interface.

arigo noreply at buildbot.pypy.org
Tue May 10 22:58:30 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r44057:7166ff963e21
Date: 2011-05-10 22:08 +0200
http://bitbucket.org/pypy/pypy/changeset/7166ff963e21/

Log:	Implement the app-level interface.

diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py
--- a/pypy/module/_multibytecodec/c_codecs.py
+++ b/pypy/module/_multibytecodec/c_codecs.py
@@ -12,7 +12,7 @@
         self.start = start
         self.end = end
         self.reason = reason
-    def __str__(self):
+    def __repr__(self):
         return 'EncodeDecodeError(%r, %r, %r)' % (self.start, self.end,
                                                   self.reason)
 
@@ -74,12 +74,8 @@
 assert len(_codecs_getters) == len(codecs)
 
 def getcodec(name):
-    try:
-        getter = _codecs_getters[name]
-    except KeyError:
-        return lltype.nullptr(MULTIBYTECODEC_P.TO)
-    else:
-        return getter()
+    getter = _codecs_getters[name]
+    return getter()
 
 # ____________________________________________________________
 
diff --git a/pypy/module/_multibytecodec/interp_multibytecodec.py b/pypy/module/_multibytecodec/interp_multibytecodec.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_multibytecodec/interp_multibytecodec.py
@@ -0,0 +1,58 @@
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.gateway import ObjSpace, interp2app
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.error import OperationError
+from pypy.module._multibytecodec import c_codecs
+
+
+class MultibyteCodec(Wrappable):
+
+    def __init__(self, name, codec):
+        self.name = name
+        self.codec = codec
+
+    def decode(self, space, input, errors=None):
+        if errors is not None and errors != 'strict':
+            raise OperationError(space.w_NotImplementedError,    # XXX
+                                 space.wrap("errors='%s' in _multibytecodec"
+                                            % errors))
+        #
+        try:
+            output = c_codecs.decode(self.codec, input)
+        except c_codecs.EncodeDecodeError, e:
+            raise OperationError(
+                space.w_UnicodeDecodeError,
+                space.newtuple([
+                    space.wrap(self.name),
+                    space.wrap(input),
+                    space.wrap(e.start),
+                    space.wrap(e.end),
+                    space.wrap(e.reason)]))
+        except RuntimeError:
+            raise OperationError(space.w_RuntimeError,
+                                 space.wrap("internal codec error"))
+        return space.newtuple([space.wrap(output),
+                               space.wrap(len(input))])
+    decode.unwrap_spec = ['self', ObjSpace, str, 'str_or_None']
+
+    def encode(self):
+        xxx
+
+
+MultibyteCodec.typedef = TypeDef(
+    'MultibyteCodec',
+    __module__ = '_multibytecodec',
+    decode = interp2app(MultibyteCodec.decode),
+    encode = interp2app(MultibyteCodec.encode),
+    )
+MultibyteCodec.typedef.acceptable_as_base_class = False
+
+
+def getcodec(space, name):
+    try:
+        codec = c_codecs.getcodec(name)
+    except KeyError:
+        raise OperationError(space.w_LookupError,
+                             space.wrap("no such codec is supported."))
+    return space.wrap(MultibyteCodec(name, codec))
+getcodec.unwrap_spec = [ObjSpace, str]
diff --git a/pypy/module/_multibytecodec/test/test_app_codecs.py b/pypy/module/_multibytecodec/test/test_app_codecs.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_multibytecodec/test/test_app_codecs.py
@@ -0,0 +1,36 @@
+from pypy.conftest import gettestobjspace
+
+
+class AppTestCodecs:
+    def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=['_multibytecodec'])
+
+    def test_missing_codec(self):
+        import _codecs_cn
+        raises(LookupError, _codecs_cn.getcodec, "foobar")
+
+    def test_decode_hz(self):
+        import _codecs_cn
+        codec = _codecs_cn.getcodec("hz")
+        r = codec.decode("~{abc}")
+        assert r == (u'\u5f95\u6cef', 6)
+
+    def test_strict_error(self):
+        import _codecs_cn
+        codec = _codecs_cn.getcodec("hz")
+        r = codec.decode("~{abc}", "strict")
+        assert r == (u'\u5f95\u6cef', 6)
+
+    def test_decode_hz_error(self):
+        import _codecs_cn
+        codec = _codecs_cn.getcodec("hz")
+        e = raises(UnicodeDecodeError, codec.decode, "~{}").value
+        assert e.args == ('hz', '~{}', 2, 3, 'incomplete multibyte sequence')
+        assert e.encoding == 'hz'
+        assert e.object == '~{}'
+        assert e.start == 2
+        assert e.end == 3
+        assert e.reason == "incomplete multibyte sequence"
+        #
+        e = raises(UnicodeDecodeError, codec.decode, "~{xyz}").value
+        assert e.args == ('hz', '~{xyz}', 2, 4, 'illegal multibyte sequence')
diff --git a/pypy/module/_multibytecodec/test/test_c_codecs.py b/pypy/module/_multibytecodec/test/test_c_codecs.py
--- a/pypy/module/_multibytecodec/test/test_c_codecs.py
+++ b/pypy/module/_multibytecodec/test/test_c_codecs.py
@@ -7,8 +7,7 @@
     for name in codecs:
         c = getcodec(name)
         assert c
-    c = getcodec("foobar")
-    assert not c
+    py.test.raises(KeyError, getcodec, "foobar")
 
 def test_decode_gbk():
     c = getcodec("gbk")


More information about the pypy-commit mailing list