PEP 292 classes Template and SafeTemplate are added to the string module.
This patch includes test cases and documentation updates, as well as NEWS file
updates.

This patch also updates the sre modules so that they don't import the string
module, breaking direct circular imports.
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index 94d526d..5c4298a 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -12,8 +12,7 @@
 
 # XXX: show string offset and offending character for all errors
 
-# this module works under 1.5.2 and later.  don't use string methods
-import string, sys
+import sys
 
 from sre_constants import *
 
@@ -63,13 +62,6 @@
     "u": SRE_FLAG_UNICODE,
 }
 
-# figure out best way to convert hex/octal numbers to integers
-try:
-    int("10", 8)
-    atoi = int # 2.0 and later
-except TypeError:
-    atoi = string.atoi # 1.5.2
-
 class Pattern:
     # master pattern object.  keeps track of global attributes
     def __init__(self):
@@ -233,7 +225,7 @@
 def _group(escape, groups):
     # check if the escape string represents a valid group
     try:
-        gid = atoi(escape[1:])
+        gid = int(escape[1:])
         if gid and gid < groups:
             return gid
     except ValueError:
@@ -256,13 +248,13 @@
             escape = escape[2:]
             if len(escape) != 2:
                 raise error, "bogus escape: %s" % repr("\\" + escape)
-            return LITERAL, atoi(escape, 16) & 0xff
+            return LITERAL, int(escape, 16) & 0xff
         elif escape[1:2] in OCTDIGITS:
             # octal escape (up to three digits)
             while source.next in OCTDIGITS and len(escape) < 5:
                 escape = escape + source.get()
             escape = escape[1:]
-            return LITERAL, atoi(escape, 8) & 0xff
+            return LITERAL, int(escape, 8) & 0xff
         if len(escape) == 2:
             return LITERAL, ord(escape[1])
     except ValueError:
@@ -284,12 +276,12 @@
                 escape = escape + source.get()
             if len(escape) != 4:
                 raise ValueError
-            return LITERAL, atoi(escape[2:], 16) & 0xff
+            return LITERAL, int(escape[2:], 16) & 0xff
         elif escape[1:2] == "0":
             # octal escape
             while source.next in OCTDIGITS and len(escape) < 4:
                 escape = escape + source.get()
-            return LITERAL, atoi(escape[1:], 8) & 0xff
+            return LITERAL, int(escape[1:], 8) & 0xff
         elif escape[1:2] in DIGITS:
             # octal escape *or* decimal group reference (sigh)
             if source.next in DIGITS:
@@ -298,7 +290,7 @@
                     source.next in OCTDIGITS):
                     # got three octal digits; this is an octal escape
                     escape = escape + source.get()
-                    return LITERAL, atoi(escape[1:], 8) & 0xff
+                    return LITERAL, int(escape[1:], 8) & 0xff
             # got at least one decimal digit; this is a group reference
             group = _group(escape, state.groups)
             if group:
@@ -503,9 +495,9 @@
                     source.seek(here)
                     continue
                 if lo:
-                    min = atoi(lo)
+                    min = int(lo)
                 if hi:
-                    max = atoi(hi)
+                    max = int(hi)
                 if max < min:
                     raise error, "bad repeat interval"
             else:
@@ -617,7 +609,7 @@
                             raise error, "unknown group name"
                     else:
                         try:
-                            condgroup = atoi(condname)
+                            condgroup = int(condname)
                         except ValueError:
                             raise error, "bad character in group name"
                 else:
@@ -730,7 +722,7 @@
                 if not name:
                     raise error, "bad group name"
                 try:
-                    index = atoi(name)
+                    index = int(name)
                 except ValueError:
                     if not isname(name):
                         raise error, "bad character in group name"
@@ -754,7 +746,7 @@
                         break
                 if not code:
                     this = this[1:]
-                    code = LITERAL, makechar(atoi(this[-6:], 8) & 0xff)
+                    code = LITERAL, makechar(int(this[-6:], 8) & 0xff)
                 if code[0] is LITERAL:
                     literal(code[1])
                 else:
@@ -793,4 +785,4 @@
                 raise IndexError
     except IndexError:
         raise error, "empty group"
-    return string.join(literals, sep)
+    return sep.join(literals)