[pypy-commit] pypy default: (alex, fijal) Make char.{lower, upper}() return chars instead of upcasting to strings.

alex_gaynor noreply at buildbot.pypy.org
Thu Oct 4 14:59:37 CEST 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r57780:26fac494c60a
Date: 2012-10-04 05:58 -0700
http://bitbucket.org/pypy/pypy/changeset/26fac494c60a/

Log:	(alex, fijal) Make char.{lower,upper}() return chars instead of
	upcasting to strings.

diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -3859,6 +3859,14 @@
             a = self.RPythonAnnotator()
             py.test.raises(Exception, a.build_types, fn, [])
 
+    def test_lower_char(self):
+        def fn(c):
+            return c.lower()
+        a = self.RPythonAnnotator()
+        s = a.build_types(fn, [annmodel.SomeChar()])
+        assert s == annmodel.SomeChar()
+
+
 def g(n):
     return [0,1,2,n]
 
diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -586,6 +586,12 @@
     def method_isupper(chr):
         return s_Bool
 
+    def method_lower(chr):
+        return chr
+
+    def method_upper(chr):
+        return chr
+
 class __extend__(SomeIterator):
 
     def iter(itr):
diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -405,13 +405,15 @@
         result = mallocstr(s_len)
         #        ^^^^^^^^^ specifically to explode on unicode
         while i < s_len:
-            ch = s_chars[i]
-            if 'a' <= ch <= 'z':
-                ch = chr(ord(ch) - 32)
-            result.chars[i] = ch
+            result.chars[i] = LLHelpers.ll_upper_char(s_chars[i])
             i += 1
         return result
 
+    def ll_upper_char(ch):
+        if 'a' <= ch <= 'z':
+            ch = chr(ord(ch) - 32)
+        return ch
+
     @jit.elidable
     def ll_lower(s):
         s_chars = s.chars
@@ -422,13 +424,15 @@
         result = mallocstr(s_len)
         #        ^^^^^^^^^ specifically to explode on unicode
         while i < s_len:
-            ch = s_chars[i]
-            if 'A' <= ch <= 'Z':
-                ch = chr(ord(ch) + 32)
-            result.chars[i] = ch
+            result.chars[i] = LLHelpers.ll_lower_char(s_chars[i])
             i += 1
         return result
 
+    def ll_lower_char(ch):
+        if 'A' <= ch <= 'Z':
+            ch = chr(ord(ch) + 32)
+        return ch
+
     def ll_join(s, length, items):
         s_chars = s.chars
         s_len = len(s_chars)
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -40,7 +40,18 @@
     
 
 class AbstractCharRepr(AbstractStringRepr):
-    pass
+    def rtype_method_lower(self, hop):
+        char_repr = hop.args_r[0].char_repr
+        v_chr, = hop.inputargs(char_repr)
+        hop.exception_cannot_occur()
+        return hop.gendirectcall(self.ll.ll_lower_char, v_chr)
+
+    def rtype_method_upper(self, hop):
+        char_repr = hop.args_r[0].char_repr
+        v_chr, = hop.inputargs(char_repr)
+        hop.exception_cannot_occur()
+        return hop.gendirectcall(self.ll.ll_upper_char, v_chr)
+
 
 class AbstractUniCharRepr(AbstractStringRepr):
     pass
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -1026,6 +1026,19 @@
     const = str
     constchar = chr
 
+    def test_lower_char(self):
+        def fn(i):
+            return chr(i).lower()
+        for c in ["a", "A", "1"]:
+            assert self.interpret(fn, [ord(c)]) == c.lower()
+
+    def test_upper_char(self):
+        def fn(i):
+            return chr(i).upper()
+        for c in ["a", "A", "1"]:
+            assert self.interpret(fn, [ord(c)]) == c.upper()
+
+
 class TestLLtype(BaseTestRstr, LLRtypeMixin):
 
     def test_ll_find_rfind(self):
@@ -1056,4 +1069,8 @@
 
 
 class TestOOtype(BaseTestRstr, OORtypeMixin):
-    pass
+    def test_lower_char(self):
+        py.test.skip()
+
+    def test_upper_char(self):
+        py.test.skip()


More information about the pypy-commit mailing list