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