Author: Carl Friedrich Bolz <[email protected]>
Branch: 
Changeset: r73944:890bbf260864
Date: 2014-10-14 11:47 +0200
http://bitbucket.org/pypy/pypy/changeset/890bbf260864/

Log:    add a way to check that something is a list of chars

        this is useful, because often it turns into a list of strings sort
        of by accident, which is very inefficient

diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -4,6 +4,7 @@
     import_from_mixin, newlist_hint, resizelist_hint, specialize)
 from rpython.rlib.buffer import Buffer
 from rpython.rlib.rstring import StringBuilder, ByteListBuilder
+from rpython.rlib.debug import check_list_of_chars
 
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
@@ -22,6 +23,7 @@
     import_from_mixin(StringMethods)
 
     def __init__(self, data):
+        check_list_of_chars(data)
         self.data = data
 
     def __repr__(self):
diff --git a/rpython/rlib/debug.py b/rpython/rlib/debug.py
--- a/rpython/rlib/debug.py
+++ b/rpython/rlib/debug.py
@@ -383,3 +383,32 @@
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
         return hop.inputarg(hop.args_r[0], arg=0)
+
+def check_list_of_chars(l):
+    if not we_are_translated():
+        assert isinstance(l, list)
+        for x in l:
+            assert isinstance(x, (unicode, str)) and len(x) == 1
+    return l
+
+class NotAListOfChars(Exception):
+    pass
+
+class Entry(ExtRegistryEntry):
+    _about_ = check_list_of_chars
+
+    def compute_result_annotation(self, s_arg):
+        from rpython.annotator.model import SomeList, s_None
+        from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint
+        if s_None.contains(s_arg):
+            return s_arg    # only None: just return
+        assert isinstance(s_arg, SomeList)
+        if not isinstance(s_arg.listdef.listitem.s_value, (SomeChar, 
SomeUnicodeCodePoint)):
+            raise NotAListOfChars
+        return s_arg
+
+    def specialize_call(self, hop):
+        hop.exception_cannot_occur()
+        return hop.inputarg(hop.args_r[0], arg=0)
+
+
diff --git a/rpython/rlib/test/test_debug.py b/rpython/rlib/test/test_debug.py
--- a/rpython/rlib/test/test_debug.py
+++ b/rpython/rlib/test/test_debug.py
@@ -4,7 +4,9 @@
                              debug_print, debug_start, debug_stop,
                              have_debug_prints, debug_offset, debug_flush,
                              check_nonneg, IntegerCanBeNegative,
-                             mark_dict_non_null)
+                             mark_dict_non_null,
+                             check_list_of_chars,
+                             NotAListOfChars)
 from rpython.rlib import debug
 from rpython.rtyper.test.test_llinterp import interpret, gengraph
 
@@ -72,6 +74,24 @@
     assert 
sorted(graph.returnblock.inputargs[0].concretetype.TO.entries.TO.OF._flds.keys())
 == ['key', 'value']
 
 
+def test_check_list_of_chars():
+    def f(x):
+        result = [chr(x), 'a']
+        check_list_of_chars(result)
+        result = [unichr(x)]
+        check_list_of_chars(result)
+        return result
+
+    interpret(f, [3])
+
+    def g(x):
+        result = ['a', 'b', 'c', '']
+        check_list_of_chars(result)
+        return x
+
+    py.test.raises(NotAListOfChars, "interpret(g, [3])")
+
+
 class DebugTests(object):
 
     def test_debug_print_start_stop(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to