Commits

Armin Rigo committed 3c8fd2f

Work a bit harder to get valid RPython code for some functions.

Comments (0)

Files changed (3)

rpython/rlib/rsre/rsre_re.py

 """
-Testing code.  This is not used in a PyPy translation.
-It exports the same interface as the Python 're' module.
+This is not used in a PyPy translation, but it can be used
+in RPython code (at least the functions at the start of the
+module, except the ones with NOT_RPYTHON).  It exports the
+same interface as the Python 're' module.
 """
 import re, sys
 from rpython.rlib.rsre import rsre_core, rsre_char
 from rpython.rlib.rsre.rpy import get_code as _get_code
 from rpython.rlib.unicodedata import unicodedb
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, we_are_translated
 rsre_char.set_unicode_db(unicodedb)
 
 
 X = VERBOSE    = re.X   # ignore whitespace and comments
 
 
+@specialize.call_location()
 def match(pattern, string, flags=0):
     return compile(pattern, flags).match(string)
 
+@specialize.call_location()
 def search(pattern, string, flags=0):
     return compile(pattern, flags).search(string)
 
+@specialize.call_location()
 def findall(pattern, string, flags=0):
     return compile(pattern, flags).findall(string)
 
+@specialize.call_location()
 def finditer(pattern, string, flags=0):
     return compile(pattern, flags).finditer(string)
 
 def sub(pattern, repl, string, count=0):
+    "NOT_RPYTHON"
     return compile(pattern).sub(repl, string, count)
 
 def subn(pattern, repl, string, count=0):
+    "NOT_RPYTHON"
     return compile(pattern).subn(repl, string, count)
 
+@specialize.call_location()
 def split(pattern, string, maxsplit=0):
     return compile(pattern).split(string, maxsplit)
 
             if self.groups == 0 or self.groups == 1:
                 item = match.group(self.groups)
             else:
+                assert False, ("findall() not supported if there is more "
+                               "than one group: not valid RPython")
                 item = match.groups("")
             matchlist.append(item)
         return matchlist
             yield match
 
     def subn(self, repl, string, count=0):
+        "NOT_RPYTHON"
         filter = repl
         if not callable(repl) and "\\" in repl:
             # handle non-literal strings; hand it over to the template compiler
         return item, n
 
     def sub(self, repl, string, count=0):
+        "NOT_RPYTHON"
         item, n = self.subn(repl, string, count)
         return item
 
             grp = self.group(i)
             if grp is None: grp = default
             grps.append(grp)
-        return tuple(grps)
+        if not we_are_translated():
+            grps = tuple(grps)    # xxx mostly to make tests happy
+        return grps
 
     def groupdict(self, default=None):
         d = {}

rpython/rlib/rsre/test/test_re.py

         assert re.findall(":+", "abc") == []
         assert re.findall(":+", "a:b::c:::d") == [":", "::", ":::"]
         assert re.findall("(:+)", "a:b::c:::d") == [":", "::", ":::"]
+
+    def test_re_findall_2(self):
+        py.test.skip("findall() returning groups is not RPython")
         assert re.findall("(:)(:*)", "a:b::c:::d") == [(":", ""),
                                                                (":", ":"),
                                                                (":", "::")]
 
     def test_bug_117612(self):
+        py.test.skip("findall() returning groups is not RPython")
         assert re.findall(r"(a|(b))", "aba") == (
                          [("a", ""),("b", "b"),("a", "")])
 

rpython/rlib/rsre/test/test_zinterp.py

         return int("aaaaaa" == g.group(0))
     assert interpret(f, [3]) == 1
     assert interpret(f, [0]) == 3
+
+def test_translates():
+    from rpython.rlib.rsre import rsre_re
+    def f(i):
+        if i:
+            s = "aaaaaa"
+        else:
+            s = "caaaaa"
+        print rsre_re.match("(a|b)aa", s)
+        print rsre_re.match("a{4}", s)
+        print rsre_re.search("(a|b)aa", s)
+        print rsre_re.search("a{4}", s)
+        for x in rsre_re.findall("(a|b)a", s):  print x
+        for x in rsre_re.findall("a{2}", s):    print x
+        for x in rsre_re.finditer("(a|b)a", s): print x
+        for x in rsre_re.finditer("a{2}", s):   print x
+        for x in rsre_re.split("(a|b)a", s):    print x
+        for x in rsre_re.split("a{2}", s):      print x
+        return 0
+    interpret(f, [3])  # assert does not crash