Issue #17381: Fixed ranges handling in case-insensitive regular expressions.
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 7921c4a..7a25dbe 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -474,6 +474,43 @@
         self.assertEqual(re.match(r"((a)\s(abc|a))", "a a", re.I).group(1), "a a")
         self.assertEqual(re.match(r"((a)\s(abc|a)*)", "a aa", re.I).group(1), "a aa")
 
+    def test_ignore_case_range(self):
+        # Issues #3511, #17381.
+        self.assertTrue(re.match(r'[9-a]', '_', re.I))
+        self.assertIsNone(re.match(r'[9-A]', '_', re.I))
+        self.assertTrue(re.match(r'[\xc0-\xde]', '\xd7', re.I))
+        self.assertIsNone(re.match(r'[\xc0-\xde]', '\xf7', re.I))
+        self.assertTrue(re.match(r'[\xe0-\xfe]', '\xf7',re.I))
+        self.assertIsNone(re.match(r'[\xe0-\xfe]', '\xd7', re.I))
+        if have_unicode:
+            self.assertTrue(re.match(u(r'[9-a]'), u(r'_'), re.U | re.I))
+            self.assertIsNone(re.match(u(r'[9-A]'), u(r'_'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\xc0-\xde]'),
+                                     u(r'\xd7'), re.U | re.I))
+            self.assertIsNone(re.match(u(r'[\xc0-\xde]'),
+                                       u(r'\xf7'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\xe0-\xfe]'),
+                                     u(r'\xf7'), re.U | re.I))
+            self.assertIsNone(re.match(u(r'[\xe0-\xfe]'),
+                                       u(r'\xd7'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\u0430-\u045f]'),
+                                     u(r'\u0450'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\u0430-\u045f]'),
+                                     u(r'\u0400'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\u0400-\u042f]'),
+                                     u(r'\u0450'), re.U | re.I))
+            self.assertTrue(re.match(u(r'[\u0400-\u042f]'),
+                                     u(r'\u0400'), re.U | re.I))
+            if sys.maxunicode > 0xffff:
+                self.assertTrue(re.match(u(r'[\U00010428-\U0001044f]'),
+                                         u(r'\U00010428'), re.U | re.I))
+                self.assertTrue(re.match(u(r'[\U00010428-\U0001044f]'),
+                                         u(r'\U00010400'), re.U | re.I))
+                self.assertTrue(re.match(u(r'[\U00010400-\U00010427]'),
+                                         u(r'\U00010428'), re.U | re.I))
+                self.assertTrue(re.match(u(r'[\U00010400-\U00010427]'),
+                                         u(r'\U00010400'), re.U | re.I))
+
     def test_category(self):
         self.assertEqual(re.match(r"(\s)", " ").group(1), " ")