bpo-30277: Replace _sre.getlower() with _sre.ascii_tolower() and _sre.unicode_tolower(). (#1468)

diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py
index d7ee4e8..db8b8a2 100644
--- a/Lib/sre_compile.py
+++ b/Lib/sre_compile.py
@@ -69,13 +69,14 @@
     REPEATING_CODES = _REPEATING_CODES
     SUCCESS_CODES = _SUCCESS_CODES
     ASSERT_CODES = _ASSERT_CODES
-    if (flags & SRE_FLAG_IGNORECASE and
-            not (flags & SRE_FLAG_LOCALE) and
-            flags & SRE_FLAG_UNICODE and
-            not (flags & SRE_FLAG_ASCII)):
-        fixes = _ignorecase_fixes
-    else:
-        fixes = None
+    tolower = None
+    fixes = None
+    if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE:
+        if flags & SRE_FLAG_UNICODE and not flags & SRE_FLAG_ASCII:
+            tolower = _sre.unicode_tolower
+            fixes = _ignorecase_fixes
+        else:
+            tolower = _sre.ascii_tolower
     for op, av in pattern:
         if op in LITERAL_CODES:
             if not flags & SRE_FLAG_IGNORECASE:
@@ -85,7 +86,7 @@
                 emit(OP_LOC_IGNORE[op])
                 emit(av)
             else:
-                lo = _sre.getlower(av, flags)
+                lo = tolower(av)
                 if fixes and lo in fixes:
                     emit(IN_IGNORE)
                     skip = _len(code); emit(0)
@@ -102,16 +103,12 @@
         elif op is IN:
             if not flags & SRE_FLAG_IGNORECASE:
                 emit(op)
-                fixup = None
             elif flags & SRE_FLAG_LOCALE:
                 emit(IN_LOC_IGNORE)
-                fixup = None
             else:
                 emit(IN_IGNORE)
-                def fixup(literal, flags=flags):
-                    return _sre.getlower(literal, flags)
             skip = _len(code); emit(0)
-            _compile_charset(av, flags, code, fixup, fixes)
+            _compile_charset(av, flags, code, tolower, fixes)
             code[skip] = _len(code) - skip
         elif op is ANY:
             if flags & SRE_FLAG_DOTALL:
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 7601dc8..b5b7cff 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -883,17 +883,23 @@
     def test_category(self):
         self.assertEqual(re.match(r"(\s)", " ").group(1), " ")
 
-    def test_getlower(self):
+    @cpython_only
+    def test_case_helpers(self):
         import _sre
-        self.assertEqual(_sre.getlower(ord('A'), 0), ord('a'))
-        self.assertEqual(_sre.getlower(ord('A'), re.LOCALE), ord('a'))
-        self.assertEqual(_sre.getlower(ord('A'), re.UNICODE), ord('a'))
-        self.assertEqual(_sre.getlower(ord('A'), re.ASCII), ord('a'))
+        for i in range(128):
+            c = chr(i)
+            lo = ord(c.lower())
+            self.assertEqual(_sre.ascii_tolower(i), lo)
+            self.assertEqual(_sre.unicode_tolower(i), lo)
 
-        self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
-        self.assertEqual(re.match(b"abc", b"ABC", re.I).group(0), b"ABC")
-        self.assertEqual(re.match("abc", "ABC", re.I|re.A).group(0), "ABC")
-        self.assertEqual(re.match(b"abc", b"ABC", re.I|re.L).group(0), b"ABC")
+        for i in list(range(128, 0x1000)) + [0x10400, 0x10428]:
+            c = chr(i)
+            self.assertEqual(_sre.ascii_tolower(i), i)
+            if i != 0x0130:
+                self.assertEqual(_sre.unicode_tolower(i), ord(c.lower()))
+
+        self.assertEqual(_sre.ascii_tolower(0x0130), 0x0130)
+        self.assertEqual(_sre.unicode_tolower(0x0130), ord('i'))
 
     def test_not_literal(self):
         self.assertEqual(re.search(r"\s([^a])", " b").group(1), "b")