- added lookbehind support (?<=pattern), (?<!pattern).
  the pattern must have a fixed width.

- got rid of array-module dependencies; the match pro-
  gram is now stored inside the pattern object, rather
  than in an extra string buffer.

- cleaned up a various of potential leaks, api abuses,
  and other minors in the engine module.

- use mal's new isalnum macro, rather than my own work-
  around.

- untabified test_sre.py.  seems like I removed a couple
  of trailing spaces in the process...
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index d78737f..07ab782 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -482,9 +482,15 @@
                         if source.next is None or source.next == ")":
                             break
                         source.get()
-                elif source.next in ("=", "!"):
+                elif source.next in ("=", "!", "<"):
                     # lookahead assertions
                     char = source.get()
+                    dir = 1
+                    if char == "<":
+                        if source.next not in ("=", "!"):
+                            raise error, "syntax error"
+                        dir = -1 # lookbehind
+                        char = source.get()
                     b = []
                     while 1:
                         p = _parse(source, state)
@@ -493,9 +499,9 @@
                                 b.append(p)
                                 p = _branch(state, b)
                             if char == "=":
-                                subpattern.append((ASSERT, p))
+                                subpattern.append((ASSERT, (dir, p)))
                             else:
-                                subpattern.append((ASSERT_NOT, p))
+                                subpattern.append((ASSERT_NOT, (dir, p)))
                             break
                         elif source.match("|"):
                             b.append(p)