The usual
diff --git a/Lib/dos-8x3/basehttp.py b/Lib/dos-8x3/basehttp.py
index ea5095a..49f8984 100755
--- a/Lib/dos-8x3/basehttp.py
+++ b/Lib/dos-8x3/basehttp.py
@@ -93,19 +93,7 @@
         """Override server_bind to store the server name."""
         SocketServer.TCPServer.server_bind(self)
         host, port = self.socket.getsockname()
-        if not host or host == '0.0.0.0':
-            host = socket.gethostname()
-        try:
-            hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)
-        except socket.error:
-            hostname = host
-        else:
-            if '.' not in hostname:
-                for host in hostnames:
-                    if '.' in host:
-                        hostname = host
-                        break
-        self.server_name = hostname
+        self.server_name = socket.getfqdn(host)
         self.server_port = port
 
 
@@ -418,16 +406,8 @@
 
         """
 
-        (host, port) = self.client_address
-        try:
-            name, names, addresses = socket.gethostbyaddr(host)
-        except socket.error, msg:
-            return host
-        names.insert(0, name)
-        for name in names:
-            if '.' in name: return name
-        return names[0]
-
+        host, port = self.client_address
+        return socket.getfqdn(host)
 
     # Essentially static class variables
 
diff --git a/Lib/dos-8x3/cgihttps.py b/Lib/dos-8x3/cgihttps.py
index fa30cbd..6a259a3 100755
--- a/Lib/dos-8x3/cgihttps.py
+++ b/Lib/dos-8x3/cgihttps.py
@@ -35,6 +35,10 @@
 
     """
 
+    # Make rfile unbuffered -- we need to read one line and then pass
+    # the rest to a subprocess, so we can't use buffered input.
+    rbufsize = 0
+
     def do_POST(self):
         """Serve a POST request.
 
diff --git a/Lib/dos-8x3/configpa.py b/Lib/dos-8x3/configpa.py
index 38a85f4..e7636b9 100644
--- a/Lib/dos-8x3/configpa.py
+++ b/Lib/dos-8x3/configpa.py
@@ -36,6 +36,9 @@
     has_section(section)
         return whether the given section exists
 
+    has_option(section, option)
+        return whether the given option exists in the given section
+
     options(section)
         return list of configuration options for the named section
 
@@ -68,6 +71,18 @@
     getboolean(section, options)
         like get(), but convert value to a boolean (currently defined as 0 or
         1, only)
+
+    remove_section(section)
+	remove the given file section and all its options
+
+    remove_option(section, option)
+	remove the given option from the given section
+
+    set(section, option, value)
+        set the given option
+
+    write(fp)
+	write the configuration state in .ini format
 """
 
 import sys
@@ -286,6 +301,64 @@
     def optionxform(self, optionstr):
         return string.lower(optionstr)
 
+    def has_option(self, section, option):
+        """Check for the existence of a given option in a given section."""
+        if not section or section == "DEFAULT":
+            return self.__defaults.has_key(option)
+        elif not self.has_section(section):
+            return 0
+        else:
+            return self.__sections[section].has_key(option)
+
+    def set(self, section, option, value):
+        """Set an option."""
+        if not section or section == "DEFAULT":
+            sectdict = self.__defaults
+        else:
+            try:
+                sectdict = self.__sections[section]
+            except KeyError:
+                raise NoSectionError(section)
+        sectdict[option] = value
+
+    def write(self, fp):
+        """Write an .ini-format representation of the configuration state."""
+        if self.__defaults:
+            fp.write("[DEFAULT]\n")
+            for (key, value) in self.__defaults.items():
+                fp.write("%s = %s\n" % (key, value))
+            fp.write("\n")
+        for section in self.sections():
+            fp.write("[" + section + "]\n")
+            sectdict = self.__sections[section]
+            for (key, value) in sectdict.items():
+                if key == "__name__":
+                    continue
+                fp.write("%s = %s\n" % (key, value))
+            fp.write("\n")
+
+    def remove_option(self, section, option):
+        """Remove an option."""
+        if not section or section == "DEFAULT":
+            sectdict = self.__defaults
+        else:
+            try:
+                sectdict = self.__sections[section]
+            except KeyError:
+                raise NoSectionError(section)
+        existed = sectdict.has_key(key)
+        if existed:
+            del sectdict[key]
+        return existed
+
+    def remove_section(self, section):
+        """Remove a file section."""
+        if self.__sections.has_key(section):
+            del self.__sections[section]
+            return 1
+        else:
+            return 0
+
     #
     # Regular expressions for parsing section headers and options.  Note a
     # slight semantic change from the previous version, because of the use
@@ -357,7 +430,6 @@
                     mo = self.OPTCRE.match(line)
                     if mo:
                         optname, vi, optval = mo.group('option', 'vi', 'value')
-                        optname = string.lower(optname)
                         if vi in ('=', ':') and ';' in optval:
                             # ';' is a comment delimiter only if it follows
                             # a spacing character
diff --git a/Lib/dos-8x3/multifil.py b/Lib/dos-8x3/multifil.py
index cc8f43c..e43d331 100755
--- a/Lib/dos-8x3/multifil.py
+++ b/Lib/dos-8x3/multifil.py
@@ -30,7 +30,8 @@
 import sys
 import string
 
-Error = 'multifile.Error'
+class Error(Exception):
+	pass
 
 class MultiFile:
 
diff --git a/Lib/dos-8x3/posixfil.py b/Lib/dos-8x3/posixfil.py
index 2db37e0..d358dc4 100755
--- a/Lib/dos-8x3/posixfil.py
+++ b/Lib/dos-8x3/posixfil.py
@@ -176,7 +176,7 @@
         import sys, os
         if sys.platform in ('netbsd1',
                             'openbsd2',
-                            'freebsd2', 'freebsd3',
+                            'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
                             'bsdos2', 'bsdos3', 'bsdos4'):
             flock = struct.pack('lxxxxlxxxxlhh', \
                   l_start, l_len, os.getpid(), l_type, l_whence) 
@@ -192,7 +192,7 @@
         if '?' in how:
             if sys.platform in ('netbsd1',
                                 'openbsd2',
-                                'freebsd2', 'freebsd3',
+                                'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
                                 'bsdos2', 'bsdos3', 'bsdos4'):
                 l_start, l_len, l_pid, l_type, l_whence = \
                     struct.unpack('lxxxxlxxxxlhh', flock)
diff --git a/Lib/dos-8x3/posixpat.py b/Lib/dos-8x3/posixpat.py
index 14b9270..f7e0161 100755
--- a/Lib/dos-8x3/posixpat.py
+++ b/Lib/dos-8x3/posixpat.py
@@ -342,30 +342,25 @@
 
 def normpath(path):
     """Normalize path, eliminating double slashes, etc."""
+    if path == '':
+        return '.'
     import string
-    # Treat initial slashes specially
-    slashes = ''
-    while path[:1] == '/':
-        slashes = slashes + '/'
-        path = path[1:]
-    comps = string.splitfields(path, '/')
-    i = 0
-    while i < len(comps):
-        if comps[i] == '.':
-            del comps[i]
-            while i < len(comps) and comps[i] == '':
-                del comps[i]
-        elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'):
-            del comps[i-1:i+1]
-            i = i-1
-        elif comps[i] == '' and i > 0 and comps[i-1] <> '':
-            del comps[i]
-        else:
-            i = i+1
-    # If the path is now empty, substitute '.'
-    if not comps and not slashes:
-        comps.append('.')
-    return slashes + string.joinfields(comps, '/')
+    initial_slash = (path[0] == '/')
+    comps = string.split(path, '/')
+    new_comps = []
+    for comp in comps:
+        if comp in ('', '.'):
+            continue
+        if (comp != '..' or (not initial_slash and not new_comps) or 
+             (new_comps and new_comps[-1] == '..')):
+            new_comps.append(comp)
+        elif new_comps:
+            new_comps.pop()
+    comps = new_comps
+    path = string.join(comps, '/')
+    if initial_slash:
+        path = '/' + path
+    return path or '.'
 
 
 def abspath(path):
diff --git a/Lib/dos-8x3/simpleht.py b/Lib/dos-8x3/simpleht.py
index 7125413..8a77758 100755
--- a/Lib/dos-8x3/simpleht.py
+++ b/Lib/dos-8x3/simpleht.py
@@ -15,6 +15,7 @@
 import BaseHTTPServer
 import urllib
 import cgi
+import shutil
 from StringIO import StringIO
 
 
@@ -151,12 +152,7 @@
         to copy binary data as well.
 
         """
-
-        BLOCKSIZE = 8192
-        while 1:
-            data = source.read(BLOCKSIZE)
-            if not data: break
-            outputfile.write(data)
+        shutil.copyfileobj(source, outputfile)
 
     def guess_type(self, path):
         """Guess the type of a file.
diff --git a/Lib/dos-8x3/socketse.py b/Lib/dos-8x3/socketse.py
index 5562fb0..a263f8e 100755
--- a/Lib/dos-8x3/socketse.py
+++ b/Lib/dos-8x3/socketse.py
@@ -412,10 +412,20 @@
 
     """Define self.rfile and self.wfile for stream sockets."""
 
+    # Default buffer sizes for rfile, wfile.
+    # We default rfile to buffered because otherwise it could be
+    # really slow for large data (a getc() call per byte); we make
+    # wfile unbuffered because (a) often after a write() we want to
+    # read and we need to flush the line; (b) big writes to unbuffered
+    # files are typically optimized by stdio even when big reads
+    # aren't.
+    rbufsize = -1
+    wbufsize = 0
+
     def setup(self):
         self.connection = self.request
-        self.rfile = self.connection.makefile('rb', 0)
-        self.wfile = self.connection.makefile('wb', 0)
+        self.rfile = self.connection.makefile('rb', self.rbufsize)
+        self.wfile = self.connection.makefile('wb', self.wbufsize)
 
     def finish(self):
         self.wfile.flush()
diff --git a/Lib/dos-8x3/sre_comp.py b/Lib/dos-8x3/sre_comp.py
index fa0cf37..97a57e2 100644
--- a/Lib/dos-8x3/sre_comp.py
+++ b/Lib/dos-8x3/sre_comp.py
@@ -5,22 +5,14 @@
 #
 # Copyright (c) 1997-2000 by Secret Labs AB.  All rights reserved.
 #
-# Portions of this engine have been developed in cooperation with
-# CNRI.  Hewlett-Packard provided funding for 1.6 integration and
-# other compatibility work.
+# See the sre.py file for information on usage and redistribution.
 #
 
-import array
 import _sre
 
 from sre_constants import *
 
-# find an array type code that matches the engine's code size
-for WORDSIZE in "BHil":
-    if len(array.array(WORDSIZE, [0]).tostring()) == _sre.getcodesize():
-        break
-else:
-    raise RuntimeError, "cannot find a usable array type"
+MAXCODE = 65535
 
 def _compile(code, pattern, flags):
     # internal: compile a (sub)pattern
@@ -41,34 +33,16 @@
                 emit(OPCODES[op])
                 fixup = lambda x: x
             skip = len(code); emit(0)
-            for op, av in av:
-                emit(OPCODES[op])
-                if op is NEGATE:
-                    pass
-                elif op is LITERAL:
-                    emit(fixup(av))
-                elif op is RANGE:
-                    emit(fixup(av[0]))
-                    emit(fixup(av[1]))
-                elif op is CATEGORY:
-                    if flags & SRE_FLAG_LOCALE:
-                        emit(CHCODES[CH_LOCALE[av]])
-                    elif flags & SRE_FLAG_UNICODE:
-                        emit(CHCODES[CH_UNICODE[av]])
-                    else:
-                        emit(CHCODES[av])
-                else:
-                    raise error, "internal: unsupported set operator"
-            emit(OPCODES[FAILURE])
+            _compile_charset(av, flags, code, fixup)
             code[skip] = len(code) - skip
         elif op is ANY:
             if flags & SRE_FLAG_DOTALL:
-                emit(OPCODES[op])
+                emit(OPCODES[ANY_ALL])
             else:
-                emit(OPCODES[CATEGORY])
-                emit(CHCODES[CATEGORY_NOT_LINEBREAK])
+                emit(OPCODES[ANY])
         elif op in (REPEAT, MIN_REPEAT, MAX_REPEAT):
             if flags & SRE_FLAG_TEMPLATE:
+                raise error, "internal: unsupported template operator"
                 emit(OPCODES[REPEAT])
                 skip = len(code); emit(0)
                 emit(av[0])
@@ -76,40 +50,50 @@
                 _compile(code, av[2], flags)
                 emit(OPCODES[SUCCESS])
                 code[skip] = len(code) - skip
+            elif _simple(av) and op == MAX_REPEAT:
+                emit(OPCODES[REPEAT_ONE])
+                skip = len(code); emit(0)
+                emit(av[0])
+                emit(av[1])
+                _compile(code, av[2], flags)
+                emit(OPCODES[SUCCESS])
+                code[skip] = len(code) - skip
             else:
-                lo, hi = av[2].getwidth()
-                if lo == 0:
-                    raise error, "nothing to repeat"
-                if 0 and lo == hi == 1 and op is MAX_REPEAT:
-                    # FIXME: <fl> need a better way to figure out when
-                    # it's safe to use this one (in the parser, probably)
-                    emit(OPCODES[MAX_REPEAT_ONE])
-                    skip = len(code); emit(0)
-                    emit(av[0])
-                    emit(av[1])
-                    _compile(code, av[2], flags)
-                    emit(OPCODES[SUCCESS])
-                    code[skip] = len(code) - skip
+                emit(OPCODES[REPEAT])
+                skip = len(code); emit(0)
+                emit(av[0])
+                emit(av[1])
+                _compile(code, av[2], flags)
+                code[skip] = len(code) - skip
+                if op == MAX_REPEAT:
+                    emit(OPCODES[MAX_UNTIL])
                 else:
-                    emit(OPCODES[op])
-                    skip = len(code); emit(0)
-                    emit(av[0])
-                    emit(av[1])
-                    _compile(code, av[2], flags)
-                    emit(OPCODES[SUCCESS])
-                    code[skip] = len(code) - skip
+                    emit(OPCODES[MIN_UNTIL])
         elif op is SUBPATTERN:
-            group = av[0]
-            if group:
+            if av[0]:
                 emit(OPCODES[MARK])
-                emit((group-1)*2)
+                emit((av[0]-1)*2)
+            # _compile_info(code, av[1], flags)
             _compile(code, av[1], flags)
-            if group:
+            if av[0]:
                 emit(OPCODES[MARK])
-                emit((group-1)*2+1)
+                emit((av[0]-1)*2+1)
         elif op in (SUCCESS, FAILURE):
             emit(OPCODES[op])
-        elif op in (ASSERT, ASSERT_NOT, CALL):
+        elif op in (ASSERT, ASSERT_NOT):
+            emit(OPCODES[op])
+            skip = len(code); emit(0)
+            if av[0] >= 0:
+                emit(0) # look ahead
+            else:
+                lo, hi = av[1].getwidth()
+                if lo != hi:
+                    raise error, "look-behind requires fixed-width pattern"
+                emit(lo) # look behind
+            _compile(code, av[1], flags)
+            emit(OPCODES[SUCCESS])
+            code[skip] = len(code) - skip
+        elif op is CALL:
             emit(OPCODES[op])
             skip = len(code); emit(0)
             _compile(code, av, flags)
@@ -126,6 +110,7 @@
             tail = []
             for av in av[1]:
                 skip = len(code); emit(0)
+                # _compile_info(code, av, flags)
                 _compile(code, av, flags)
                 emit(OPCODES[JUMP])
                 tail.append(len(code)); emit(0)
@@ -141,51 +126,196 @@
                 emit(CHCODES[CH_UNICODE[av]])
             else:
                 emit(CHCODES[av])
-        elif op is GROUP:
+        elif op is GROUPREF:
             if flags & SRE_FLAG_IGNORECASE:
                 emit(OPCODES[OP_IGNORE[op]])
             else:
                 emit(OPCODES[op])
             emit(av-1)
-        elif op is MARK:
-            emit(OPCODES[op])
-            emit(av)
         else:
             raise ValueError, ("unsupported operand type", op)
 
+def _compile_charset(charset, flags, code, fixup=None):
+    # compile charset subprogram
+    emit = code.append
+    if not fixup:
+        fixup = lambda x: x
+    for op, av in _optimize_charset(charset, fixup):
+        emit(OPCODES[op])
+        if op is NEGATE:
+            pass
+        elif op is LITERAL:
+            emit(fixup(av))
+        elif op is RANGE:
+            emit(fixup(av[0]))
+            emit(fixup(av[1]))
+        elif op is CHARSET:
+            code.extend(av)
+        elif op is CATEGORY:
+            if flags & SRE_FLAG_LOCALE:
+                emit(CHCODES[CH_LOCALE[av]])
+            elif flags & SRE_FLAG_UNICODE:
+                emit(CHCODES[CH_UNICODE[av]])
+            else:
+                emit(CHCODES[av])
+        else:
+            raise error, "internal: unsupported set operator"
+    emit(OPCODES[FAILURE])
+
+def _optimize_charset(charset, fixup):
+    # internal: optimize character set
+    out = []
+    charmap = [0]*256
+    try:
+        for op, av in charset:
+            if op is NEGATE:
+                out.append((op, av))
+            elif op is LITERAL:
+                charmap[fixup(av)] = 1
+            elif op is RANGE:
+                for i in range(fixup(av[0]), fixup(av[1])+1):
+                    charmap[i] = 1
+            elif op is CATEGORY:
+                # FIXME: could append to charmap tail
+                return charset # cannot compress
+    except IndexError:
+        # character set contains unicode characters
+        return charset
+    # compress character map
+    i = p = n = 0
+    runs = []
+    for c in charmap:
+        if c:
+            if n == 0:
+                p = i
+            n = n + 1
+        elif n:
+            runs.append((p, n))
+            n = 0
+        i = i + 1
+    if n:
+        runs.append((p, n))
+    if len(runs) <= 2:
+        # use literal/range
+        for p, n in runs:
+            if n == 1:
+                out.append((LITERAL, p))
+            else:
+                out.append((RANGE, (p, p+n-1)))
+        if len(out) < len(charset):
+            return out
+    else:
+        # use bitmap
+        data = []
+        m = 1; v = 0
+        for c in charmap:
+            if c:
+                v = v + m
+            m = m << 1
+            if m > MAXCODE:
+                data.append(v)
+                m = 1; v = 0
+        out.append((CHARSET, data))
+        return out
+    return charset
+
+def _simple(av):
+    # check if av is a "simple" operator
+    lo, hi = av[2].getwidth()
+    if lo == 0:
+        raise error, "nothing to repeat"
+    return lo == hi == 1 and av[2][0][0] != SUBPATTERN
+
 def _compile_info(code, pattern, flags):
     # internal: compile an info block.  in the current version,
-    # this contains min/max pattern width and a literal prefix,
-    # if any
+    # this contains min/max pattern width, and an optional literal
+    # prefix or a character map
     lo, hi = pattern.getwidth()
     if lo == 0:
         return # not worth it
     # look for a literal prefix
     prefix = []
+    prefix_skip = 0
+    charset = [] # not used
     if not (flags & SRE_FLAG_IGNORECASE):
+        # look for literal prefix
         for op, av in pattern.data:
             if op is LITERAL:
+                if len(prefix) == prefix_skip:
+                    prefix_skip = prefix_skip + 1
                 prefix.append(av)
+            elif op is SUBPATTERN and len(av[1]) == 1:
+                op, av = av[1][0]
+                if op is LITERAL:
+                    prefix.append(av)
+                else:
+                    break
             else:
                 break
+        # if no prefix, look for charset prefix
+        if not prefix and pattern.data:
+            op, av = pattern.data[0]
+            if op is SUBPATTERN and av[1]:
+                op, av = av[1][0]
+                if op is LITERAL:
+                    charset.append((op, av))
+                elif op is BRANCH:
+                    c = []
+                    for p in av[1]:
+                        if not p:
+                            break
+                        op, av = p[0]
+                        if op is LITERAL:
+                            c.append((op, av))
+                        else:
+                            break
+                    else:
+                        charset = c
+            elif op is BRANCH:
+                c = []
+                for p in av[1]:
+                    if not p:
+                        break
+                    op, av = p[0]
+                    if op is LITERAL:
+                        c.append((op, av))
+                    else:
+                        break
+                else:
+                    charset = c
+            elif op is IN:
+                charset = av
+##     if prefix:
+##         print "*** PREFIX", prefix, prefix_skip
+##     if charset:
+##         print "*** CHARSET", charset
     # add an info block
     emit = code.append
     emit(OPCODES[INFO])
     skip = len(code); emit(0)
     # literal flag
     mask = 0
-    if len(prefix) == len(pattern.data):
-        mask = 1
+    if prefix:
+        mask = SRE_INFO_PREFIX
+        if len(prefix) == prefix_skip == len(pattern.data):
+            mask = mask + SRE_INFO_LITERAL
+    elif charset:
+        mask = mask + SRE_INFO_CHARSET
     emit(mask)
     # pattern length
-    emit(lo)
-    if hi < 32768:
+    if lo < MAXCODE:
+        emit(lo)
+    else:
+        emit(MAXCODE)
+        prefix = prefix[:MAXCODE]
+    if hi < MAXCODE:
         emit(hi)
     else:
         emit(0)
     # add literal prefix
-    emit(len(prefix))
     if prefix:
+        emit(len(prefix)) # length
+        emit(prefix_skip) # skip
         code.extend(prefix)
         # generate overlap table
         table = [-1] + ([0]*len(prefix))
@@ -194,18 +324,18 @@
             while table[i+1] > 0 and prefix[i] != prefix[table[i+1]-1]:
                 table[i+1] = table[table[i+1]-1]+1
         code.extend(table[1:]) # don't store first entry
+    elif charset:
+        _compile_charset(charset, 0, code)
     code[skip] = len(code) - skip
 
-def compile(p, flags=0):
-    # internal: convert pattern list to internal format
+STRING_TYPES = [type("")]
 
-    # compile, as necessary
-    if type(p) in (type(""), type(u"")):
-        import sre_parse
-        pattern = p
-        p = sre_parse.parse(p, flags)
-    else:
-        pattern = None
+try:
+    STRING_TYPES.append(type(unicode("")))
+except NameError:
+    pass
+
+def _code(p, flags):
 
     flags = p.pattern.flags | flags
     code = []
@@ -218,12 +348,34 @@
 
     code.append(OPCODES[SUCCESS])
 
+    return code
+
+def compile(p, flags=0):
+    # internal: convert pattern list to internal format
+
+    if type(p) in STRING_TYPES:
+        import sre_parse
+        pattern = p
+        p = sre_parse.parse(p, flags)
+    else:
+        pattern = None
+
+    code = _code(p, flags)
+
+    # print code
+
     # FIXME: <fl> get rid of this limitation!
     assert p.pattern.groups <= 100,\
            "sorry, but this version only supports 100 named groups"
 
+    # map in either direction
+    groupindex = p.pattern.groupdict
+    indexgroup = [None] * p.pattern.groups
+    for k, i in groupindex.items():
+        indexgroup[i] = k
+
     return _sre.compile(
-        pattern, flags,
-        array.array(WORDSIZE, code).tostring(),
-        p.pattern.groups-1, p.pattern.groupdict
+        pattern, flags, code,
+        p.pattern.groups-1,
+        groupindex, indexgroup
         )
diff --git a/Lib/dos-8x3/sre_cons.py b/Lib/dos-8x3/sre_cons.py
index 45f4f48..5a20930 100644
--- a/Lib/dos-8x3/sre_cons.py
+++ b/Lib/dos-8x3/sre_cons.py
@@ -6,9 +6,7 @@
 #
 # Copyright (c) 1998-2000 by Secret Labs AB.  All rights reserved.
 #
-# Portions of this engine have been developed in cooperation with
-# CNRI.  Hewlett-Packard provided funding for 1.6 integration and
-# other compatibility work.
+# See the sre.py file for information on usage and redistribution.
 #
 
 # should this really be here?
@@ -22,14 +20,16 @@
 SUCCESS = "success"
 
 ANY = "any"
+ANY_ALL = "any_all"
 ASSERT = "assert"
 ASSERT_NOT = "assert_not"
 AT = "at"
 BRANCH = "branch"
 CALL = "call"
 CATEGORY = "category"
-GROUP = "group"
-GROUP_IGNORE = "group_ignore"
+CHARSET = "charset"
+GROUPREF = "groupref"
+GROUPREF_IGNORE = "groupref_ignore"
 IN = "in"
 IN_IGNORE = "in_ignore"
 INFO = "info"
@@ -38,8 +38,9 @@
 LITERAL_IGNORE = "literal_ignore"
 MARK = "mark"
 MAX_REPEAT = "max_repeat"
-MAX_REPEAT_ONE = "max_repeat_one"
+MAX_UNTIL = "max_until"
 MIN_REPEAT = "min_repeat"
+MIN_UNTIL = "min_until"
 NEGATE = "negate"
 NOT_LITERAL = "not_literal"
 NOT_LITERAL_IGNORE = "not_literal_ignore"
@@ -81,25 +82,27 @@
     # failure=0 success=1 (just because it looks better that way :-)
     FAILURE, SUCCESS,
 
-    ANY,
+    ANY, ANY_ALL,
     ASSERT, ASSERT_NOT,
     AT,
     BRANCH,
     CALL,
     CATEGORY,
-    GROUP, GROUP_IGNORE,
+    CHARSET,
+    GROUPREF, GROUPREF_IGNORE,
     IN, IN_IGNORE,
     INFO,
     JUMP,
     LITERAL, LITERAL_IGNORE,
     MARK,
-    MAX_REPEAT,
-    MAX_REPEAT_ONE,
-    MIN_REPEAT,
+    MAX_UNTIL,
+    MIN_UNTIL,
     NOT_LITERAL, NOT_LITERAL_IGNORE,
     NEGATE,
     RANGE,
-    REPEAT
+    REPEAT,
+    REPEAT_ONE,
+    SUBPATTERN
 
 ]
 
@@ -132,7 +135,7 @@
 
 # replacement operations for "ignore case" mode
 OP_IGNORE = {
-    GROUP: GROUP_IGNORE,
+    GROUPREF: GROUPREF_IGNORE,
     IN: IN_IGNORE,
     LITERAL: LITERAL_IGNORE,
     NOT_LITERAL: NOT_LITERAL_IGNORE
@@ -166,13 +169,18 @@
 }
 
 # flags
-SRE_FLAG_TEMPLATE = 1
-SRE_FLAG_IGNORECASE = 2
-SRE_FLAG_LOCALE = 4
-SRE_FLAG_MULTILINE = 8
-SRE_FLAG_DOTALL = 16
-SRE_FLAG_UNICODE = 32
-SRE_FLAG_VERBOSE = 64
+SRE_FLAG_TEMPLATE = 1 # template mode (disable backtracking)
+SRE_FLAG_IGNORECASE = 2 # case insensitive
+SRE_FLAG_LOCALE = 4 # honour system locale
+SRE_FLAG_MULTILINE = 8 # treat target as multiline string
+SRE_FLAG_DOTALL = 16 # treat target as a single string
+SRE_FLAG_UNICODE = 32 # use unicode locale
+SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments
+
+# flags for INFO primitive
+SRE_INFO_PREFIX = 1 # has prefix
+SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix)
+SRE_INFO_CHARSET = 4 # pattern starts with character from given set
 
 if __name__ == "__main__":
     import string
@@ -201,6 +209,7 @@
     dump(f, OPCODES, "SRE_OP")
     dump(f, ATCODES, "SRE")
     dump(f, CHCODES, "SRE")
+
     f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE)
     f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE)
     f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE)
@@ -208,5 +217,10 @@
     f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL)
     f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE)
     f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE)
+
+    f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX)
+    f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL)
+    f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET)
+
     f.close()
     print "done"
diff --git a/Lib/dos-8x3/sre_pars.py b/Lib/dos-8x3/sre_pars.py
index 53616f6..a50191e 100644
--- a/Lib/dos-8x3/sre_pars.py
+++ b/Lib/dos-8x3/sre_pars.py
@@ -5,33 +5,24 @@
 #
 # Copyright (c) 1998-2000 by Secret Labs AB.  All rights reserved.
 #
-# Portions of this engine have been developed in cooperation with
-# CNRI.  Hewlett-Packard provided funding for 1.6 integration and
-# other compatibility work.
+# See the sre.py file for information on usage and redistribution.
 #
 
 import string, sys
 
-import _sre
-
 from sre_constants import *
 
-# FIXME: should be 65535, but the arraymodule is still broken
-MAXREPEAT = 32767
-
-# FIXME: might change in 2.0 final.  but for now, this seems
-# to be the best way to be compatible with 1.5.2
-CHARMASK = 0xff
+MAXREPEAT = 65535
 
 SPECIAL_CHARS = ".\\[{()*+?^$|"
 REPEAT_CHARS  = "*+?{"
 
-DIGITS = tuple(string.digits)
+DIGITS = tuple("012345689")
 
 OCTDIGITS = tuple("01234567")
 HEXDIGITS = tuple("0123456789abcdefABCDEF")
 
-WHITESPACE = tuple(string.whitespace)
+WHITESPACE = tuple(" \t\n\r\v\f")
 
 ESCAPES = {
     r"\a": (LITERAL, 7),
@@ -69,7 +60,8 @@
     "u": SRE_FLAG_UNICODE,
 }
 
-class State:
+class Pattern:
+    # master pattern object.  keeps track of global attributes
     def __init__(self):
         self.flags = 0
         self.groups = 1
@@ -89,6 +81,33 @@
             data = []
         self.data = data
         self.width = None
+    def dump(self, level=0):
+        nl = 1
+        for op, av in self.data:
+            print level*"  " + op,; nl = 0
+            if op == "in":
+                # member sublanguage
+                print; nl = 1
+                for op, a in av:
+                    print (level+1)*"  " + op, a
+            elif op == "branch":
+                print; nl = 1
+                i = 0
+                for a in av[1]:
+                    if i > 0:
+                        print level*"  " + "or"
+                    a.dump(level+1); nl = 1
+                    i = i + 1
+            elif type(av) in (type(()), type([])):
+                for a in av:
+                    if isinstance(a, SubPattern):
+                        if not nl: print
+                        a.dump(level+1); nl = 1
+                    else:
+                        print a, ; nl = 0
+            else:
+                print av, ; nl = 0
+            if not nl: print
     def __repr__(self):
         return repr(self.data)
     def __len__(self):
@@ -112,12 +131,12 @@
         lo = hi = 0L
         for op, av in self.data:
             if op is BRANCH:
-                l = sys.maxint
-                h = 0
+                i = sys.maxint
+                j = 0
                 for av in av[1]:
-                    i, j = av.getwidth()
-                    l = min(l, i)
-                    h = min(h, j)
+                    l, h = av.getwidth()
+                    i = min(i, l)
+                    j = max(j, h)
                 lo = lo + i
                 hi = hi + j
             elif op is CALL:
@@ -142,12 +161,13 @@
 
 class Tokenizer:
     def __init__(self, string):
-        self.index = 0
         self.string = string
-        self.next = self.__next()
+        self.index = 0
+        self.__next()
     def __next(self):
         if self.index >= len(self.string):
-            return None
+            self.next = None
+            return
         char = self.string[self.index]
         if char[0] == "\\":
             try:
@@ -156,21 +176,21 @@
                 raise error, "bogus escape"
             char = char + c
         self.index = self.index + len(char)
-        return char
-    def match(self, char):
+        self.next = char
+    def match(self, char, skip=1):
         if char == self.next:
-            self.next = self.__next()
-            return 1
-        return 0
-    def match_set(self, set):
-        if self.next and self.next in set:
-            self.next = self.__next()
+            if skip:
+                self.__next()
             return 1
         return 0
     def get(self):
         this = self.next
-        self.next = self.__next()
+        self.__next()
         return this
+    def tell(self):
+        return self.index, self.next
+    def seek(self, index):
+        self.index, self.next = index
 
 def isident(char):
     return "a" <= char <= "z" or "A" <= char <= "Z" or char == "_"
@@ -207,15 +227,19 @@
         return code
     try:
         if escape[1:2] == "x":
-            while source.next in HEXDIGITS:
+            # hexadecimal escape (exactly two digits)
+            while source.next in HEXDIGITS and len(escape) < 4:
                 escape = escape + source.get()
             escape = escape[2:]
-            return LITERAL, int(escape[-4:], 16) & CHARMASK
+            if len(escape) != 2:
+                raise error, "bogus escape: %s" % repr("\\" + escape)
+            return LITERAL, int(escape, 16) & 0xff
         elif str(escape[1:2]) in OCTDIGITS:
-            while source.next 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, int(escape[-6:], 8) & CHARMASK
+            return LITERAL, int(escape, 8) & 0xff
         if len(escape) == 2:
             return LITERAL, ord(escape[1])
     except ValueError:
@@ -232,34 +256,57 @@
         return code
     try:
         if escape[1:2] == "x":
-            while source.next in HEXDIGITS:
+            # hexadecimal escape
+            while source.next in HEXDIGITS and len(escape) < 4:
                 escape = escape + source.get()
             escape = escape[2:]
-            return LITERAL, int(escape[-4:], 16) & CHARMASK
+            if len(escape) != 2:
+                raise error, "bogus escape: %s" % repr("\\" + escape)
+            return LITERAL, int(escape, 16) & 0xff
+        elif escape[1:2] == "0":
+            # octal escape
+            while source.next in OCTDIGITS and len(escape) < 5:
+                escape = escape + source.get()
+            return LITERAL, int(escape[1:], 8) & 0xff
         elif escape[1:2] in DIGITS:
-            while 1:
-                group = _group(escape, state.groups)
-                if group:
-                    if (not source.next or
-                        not _group(escape + source.next, state.groups)):
-                        return GROUP, group
+            # octal escape *or* decimal group reference (sigh)
+            here = source.tell()
+            if source.next in DIGITS:
+                escape = escape + source.get()
+                if escape[2] in OCTDIGITS and source.next in OCTDIGITS:
+                    # got three octal digits; this is an octal escape
                     escape = escape + source.get()
-                elif source.next in OCTDIGITS:
-                    escape = escape + source.get()
-                else:
-                    break
-            escape = escape[1:]
-            return LITERAL, int(escape[-6:], 8) & CHARMASK
+                    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:
+                return GROUPREF, group
+            raise error, "bogus escape: %s" % repr(escape)
         if len(escape) == 2:
             return LITERAL, ord(escape[1])
     except ValueError:
         pass
     raise error, "bogus escape: %s" % repr(escape)
 
-def _branch(pattern, items):
-    # form a branch operator from a set of items
+def _parse_sub(source, state, nested=1):
+    # parse an alternation: a|b|c
 
-    subpattern = SubPattern(pattern)
+    items = []
+    while 1:
+        items.append(_parse(source, state))
+        if source.match("|"):
+            continue
+        if not nested:
+            break
+        if not source.next or source.match(")", 0):
+            break
+        else:
+            raise error, "pattern not properly closed"
+
+    if len(items) == 1:
+        return items[0]
+
+    subpattern = SubPattern(state)
 
     # check if all items share a common prefix
     while 1:
@@ -286,7 +333,7 @@
             break
     else:
         # we can store this as a character set instead of a
-        # branch (FIXME: use a range if possible)
+        # branch (the compiler may optimize this even more)
         set = []
         for item in items:
             set.append(item[0])
@@ -297,8 +344,7 @@
     return subpattern
 
 def _parse(source, state):
-
-    # parse regular expression pattern into an operator list.
+    # parse a simple pattern
 
     subpattern = SubPattern(state)
 
@@ -357,7 +403,11 @@
                             code2 = LITERAL, ord(this)
                         if code1[0] != LITERAL or code2[0] != LITERAL:
                             raise error, "illegal range"
-                        set.append((RANGE, (code1[1], code2[1])))
+                        lo = code1[1]
+                        hi = code2[1]
+                        if hi < lo:
+                            raise error, "illegal range"
+                        set.append((RANGE, (lo, hi)))
                 else:
                     if code1[0] is IN:
                         code1 = code1[1][0]
@@ -381,6 +431,7 @@
             elif this == "+":
                 min, max = 1, MAXREPEAT
             elif this == "{":
+                here = source.tell()
                 min, max = 0, MAXREPEAT
                 lo = hi = ""
                 while source.next in DIGITS:
@@ -391,7 +442,9 @@
                 else:
                     hi = lo
                 if not source.match("}"):
-                    raise error, "bogus range"
+                    subpattern.append((LITERAL, ord(this)))
+                    source.seek(here)
+                    continue
                 if lo:
                     min = int(lo)
                 if hi:
@@ -448,7 +501,8 @@
                         gid = state.groupdict.get(name)
                         if gid is None:
                             raise error, "unknown group name"
-                        subpattern.append((GROUP, gid))
+                        subpattern.append((GROUPREF, gid))
+                        continue
                     else:
                         char = source.get()
                         if char is None:
@@ -463,49 +517,41 @@
                         if source.next is None or source.next == ")":
                             break
                         source.get()
-                elif source.next in ("=", "!"):
+                    if not source.match(")"):
+                        raise error, "unbalanced parenthesis"
+                    continue
+                elif source.next in ("=", "!", "<"):
                     # lookahead assertions
                     char = source.get()
-                    b = []
-                    while 1:
-                        p = _parse(source, state)
-                        if source.next == ")":
-                            if b:
-                                b.append(p)
-                                p = _branch(state, b)
-                            if char == "=":
-                                subpattern.append((ASSERT, p))
-                            else:
-                                subpattern.append((ASSERT_NOT, p))
-                            break
-                        elif source.match("|"):
-                            b.append(p)
-                        else:
-                            raise error, "pattern not properly closed"
+                    dir = 1
+                    if char == "<":
+                        if source.next not in ("=", "!"):
+                            raise error, "syntax error"
+                        dir = -1 # lookbehind
+                        char = source.get()
+                    p = _parse_sub(source, state)
+                    if not source.match(")"):
+                        raise error, "unbalanced parenthesis"
+                    if char == "=":
+                        subpattern.append((ASSERT, (dir, p)))
+                    else:
+                        subpattern.append((ASSERT_NOT, (dir, p)))
+                    continue
                 else:
                     # flags
                     while FLAGS.has_key(source.next):
                         state.flags = state.flags | FLAGS[source.get()]
             if group:
                 # parse group contents
-                b = []
                 if group == 2:
                     # anonymous group
                     group = None
                 else:
                     group = state.getgroup(name)
-                while 1:
-                    p = _parse(source, state)
-                    if source.match(")"):
-                        if b:
-                            b.append(p)
-                            p = _branch(state, b)
-                        subpattern.append((SUBPATTERN, (group, p)))
-                        break
-                    elif source.match("|"):
-                        b.append(p)
-                    else:
-                        raise error, "group not properly closed"
+                p = _parse_sub(source, state)
+                if not source.match(")"):
+                    raise error, "unbalanced parenthesis"
+                subpattern.append((SUBPATTERN, (group, p)))
             else:
                 while 1:
                     char = source.get()
@@ -528,26 +574,25 @@
 
     return subpattern
 
-def parse(pattern, flags=0):
+def parse(str, flags=0, pattern=None):
     # parse 're' pattern into list of (opcode, argument) tuples
-    source = Tokenizer(pattern)
-    state = State()
-    state.flags = flags
-    b = []
-    while 1:
-        p = _parse(source, state)
-        tail = source.get()
-        if tail == "|":
-            b.append(p)
-        elif tail == ")":
-            raise error, "unbalanced parenthesis"
-        elif tail is None:
-            if b:
-                b.append(p)
-                p = _branch(state, b)
-            break
-        else:
-            raise error, "bogus characters at end of regular expression"
+
+    source = Tokenizer(str)
+
+    if pattern is None:
+        pattern = Pattern()
+    pattern.flags = flags
+
+    p = _parse_sub(source, pattern, 0)
+
+    tail = source.get()
+    if tail == ")":
+        raise error, "unbalanced parenthesis"
+    elif tail:
+        raise error, "bogus characters at end of regular expression"
+
+    # p.dump()
+
     return p
 
 def parse_template(source, pattern):
@@ -599,7 +644,7 @@
                         break
                 if not code:
                     this = this[1:]
-                    code = LITERAL, int(this[-6:], 8) & CHARMASK
+                    code = LITERAL, int(this[-6:], 8) & 0xff
                 a(code)
             else:
                 try:
@@ -629,4 +674,4 @@
             if s is None:
                 raise error, "empty group"
             a(s)
-    return sep.join(p)
+    return string.join(p, sep)
diff --git a/Lib/dos-8x3/test_arr.py b/Lib/dos-8x3/test_arr.py
index a82ace5..d3fe7e9 100644
--- a/Lib/dos-8x3/test_arr.py
+++ b/Lib/dos-8x3/test_arr.py
@@ -105,6 +105,26 @@
             a[1:-1] = a
             if a != array.array(type, "aabcdee"):
                 raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
+            if a.index("e") != 5:
+            	raise TestFailed, "array(%s) index-test" % `type`
+            if a.count("a") != 2:
+            	raise TestFailed, "array(%s) count-test" % `type`
+            a.remove("e")
+            if a != array.array(type, "aabcde"):
+            	raise TestFailed, "array(%s) remove-test" % `type`
+            if a.pop(0) != "a":
+            	raise TestFailed, "array(%s) pop-test" % `type`
+            if a.pop(1) != "b":
+            	raise TestFailed, "array(%s) pop-test" % `type`
+            a.extend(array.array(type, "xyz"))
+            if a != array.array(type, "acdexyz"):
+                raise TestFailed, "array(%s) extend-test" % `type`
+            a.pop()
+            a.pop()
+            a.pop()
+            a.pop()
+            if a != array.array(type, "acd"):
+            	raise TestFailed, "array(%s) pop-test" % `type`
         else:
             a = array.array(type, [1, 2, 3, 4, 5])
             a[:-1] = a
@@ -118,6 +138,26 @@
             a[1:-1] = a
             if a != array.array(type, [1, 1, 2, 3, 4, 5, 5]):
                 raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
+            if a.index(5) != 5:
+            	raise TestFailed, "array(%s) index-test" % `type`
+            if a.count(1) != 2:
+            	raise TestFailed, "array(%s) count-test" % `type`
+            a.remove(5)
+            if a != array.array(type, [1, 1, 2, 3, 4, 5]):
+            	raise TestFailed, "array(%s) remove-test" % `type`
+            if a.pop(0) != 1:
+            	raise TestFailed, "array(%s) pop-test" % `type`
+            if a.pop(1) != 2:
+            	raise TestFailed, "array(%s) pop-test" % `type`
+            a.extend(array.array(type, [7, 8, 9]))
+            if a != array.array(type, [1, 3, 4, 5, 7, 8, 9]):
+                raise TestFailed, "array(%s) extend-test" % `type`
+            a.pop()
+            a.pop()
+            a.pop()
+            a.pop()
+            if a != array.array(type, [1, 3, 4]):
+            	raise TestFailed, "array(%s) pop-test" % `type`
 
         # test that overflow exceptions are raised as expected for assignment
         # to array of specific integral types
diff --git a/Lib/dos-8x3/test_bin.py b/Lib/dos-8x3/test_bin.py
index 534fa73..52f817b 100644
--- a/Lib/dos-8x3/test_bin.py
+++ b/Lib/dos-8x3/test_bin.py
@@ -1,46 +1,112 @@
-#! /usr/bin/env python
-"""Test script for the binhex C module
+"""Test the binascii C module."""
 
-   Uses the mechanism of the python binhex module
-   Roger E. Masse
-"""
-import binhex
-import tempfile
 from test_support import verbose
+import binascii
 
-def test():
+# Show module doc string
+print binascii.__doc__
 
-    try:
-        fname1 = tempfile.mktemp()
-        fname2 = tempfile.mktemp()
-        f = open(fname1, 'w')
-    except:
-        raise ImportError, "Cannot test binhex without a temp file"
+# Show module exceptions
+print binascii.Error
+print binascii.Incomplete
 
-    start = 'Jack is my hero'
-    f.write(start)
-    f.close()
-    
-    binhex.binhex(fname1, fname2)
-    if verbose:
-        print 'binhex'
+# Check presence and display doc strings of all functions
+funcs = []
+for suffix in "base64", "hqx", "uu":
+    prefixes = ["a2b_", "b2a_"]
+    if suffix == "hqx":
+        prefixes.extend(["crc_", "rlecode_", "rledecode_"])
+    for prefix in prefixes:
+        name = prefix + suffix
+        funcs.append(getattr(binascii, name))
+for func in funcs:
+    print "%-15s: %s" % (func.__name__, func.__doc__)
 
-    binhex.hexbin(fname2, fname1)
-    if verbose:
-        print 'hexbin'
+# Create binary test data
+testdata = "The quick brown fox jumps over the lazy dog.\r\n"
+for i in range(256):
+    # Be slow so we don't depend on other modules
+    testdata = testdata + chr(i)
+testdata = testdata + "\r\nHello world.\n"
 
-    f = open(fname1, 'r')
-    finish = f.readline()
+# Test base64 with valid data
+print "base64 test"
+MAX_BASE64 = 57
+lines = []
+for i in range(0, len(testdata), MAX_BASE64):
+    b = testdata[i:i+MAX_BASE64]
+    a = binascii.b2a_base64(b)
+    lines.append(a)
+    print a,
+res = ""
+for line in lines:
+    b = binascii.a2b_base64(line)
+    res = res + b
+assert res == testdata
 
-    if start <> finish:
-        print 'Error: binhex <> hexbin'
-    elif verbose:
-        print 'binhex == hexbin'
+# Test base64 with random invalid characters sprinkled throughout
+# (This requires a new version of binascii.)
+fillers = ""
+valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
+for i in range(256):
+    c = chr(i)
+    if c not in valid:
+        fillers = fillers + c
+def addnoise(line):
+    noise = fillers
+    ratio = len(line) / len(noise)
+    res = ""
+    while line and noise:
+        if len(line) / len(noise) > ratio:
+            c, line = line[0], line[1:]
+        else:
+            c, noise = noise[0], noise[1:]
+        res = res + c
+    return res + noise + line
+res = ""
+for line in map(addnoise, lines):
+    b = binascii.a2b_base64(line)
+    res = res + b
+assert res == testdata
 
-    try:
-        import os
-        os.unlink(fname1)
-        os.unlink(fname2)
-    except:
-        pass
-test()
+# Test uu
+print "uu test"
+MAX_UU = 45
+lines = []
+for i in range(0, len(testdata), MAX_UU):
+    b = testdata[i:i+MAX_UU]
+    a = binascii.b2a_uu(b)
+    lines.append(a)
+    print a,
+res = ""
+for line in lines:
+    b = binascii.a2b_uu(line)
+    res = res + b
+assert res == testdata
+
+# Test crc32()
+crc = binascii.crc32("Test the CRC-32 of")
+crc = binascii.crc32(" this string.", crc)
+if crc != 1571220330:
+    print "binascii.crc32() failed."
+
+# The hqx test is in test_binhex.py
+
+# test hexlification
+s = '{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
+t = binascii.b2a_hex(s)
+u = binascii.a2b_hex(t)
+if s <> u:
+    print 'binascii hexlification failed'
+try:
+    binascii.a2b_hex(t[:-1])
+except TypeError:
+    pass
+else:
+    print 'expected TypeError not raised'
+try:
+    binascii.a2b_hex(t[:-1] + 'q')
+except TypeError:
+    pass
+else:
+    print 'expected TypeError not raised'
diff --git a/Lib/dos-8x3/test_exc.py b/Lib/dos-8x3/test_exc.py
index 7bc515c..7ee203c 100755
--- a/Lib/dos-8x3/test_exc.py
+++ b/Lib/dos-8x3/test_exc.py
@@ -19,7 +19,7 @@
 
 def r(thing):
     test_raise_catch(thing)
-    if type(thing) == ClassType:
+    if isinstance(thing, ClassType):
         print thing.__name__
     else:
         print thing
@@ -86,6 +86,14 @@
 try: exec '/\n'
 except SyntaxError: pass
 
+r(IndentationError)
+
+r(TabError)
+# can only be tested under -tt, and is the only test for -tt
+#try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n", '<string>', 'exec')
+#except TabError: pass
+#else: raise TestFailed
+
 r(SystemError)
 print '(hard to reproduce)'
 
diff --git a/Lib/dos-8x3/test_ext.py b/Lib/dos-8x3/test_ext.py
index 6cca199..de2312b 100644
--- a/Lib/dos-8x3/test_ext.py
+++ b/Lib/dos-8x3/test_ext.py
@@ -85,10 +85,13 @@
 
 # what about willful misconduct?
 def saboteur(**kw):
-    kw['x'] = locals()
+    kw['x'] = locals() # yields a cyclic kw
+    return kw
 d = {}
-saboteur(a=1, **d)
+kw = saboteur(a=1, **d)
 assert d == {}
+# break the cycle
+del kw['x']
         
 try:
     g(1, 2, 3, **{'x':4, 'y':5})
diff --git a/Lib/dos-8x3/test_fcn.py b/Lib/dos-8x3/test_fcn.py
index b59efda..3c1be88 100644
--- a/Lib/dos-8x3/test_fcn.py
+++ b/Lib/dos-8x3/test_fcn.py
@@ -17,7 +17,7 @@
     print 'Status from fnctl with O_NONBLOCK: ', rv
     
 if sys.platform in ('netbsd1',
-                    'freebsd2', 'freebsd3',
+                    'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
                     'bsdos2', 'bsdos3', 'bsdos4',
                     'openbsd', 'openbsd2'):
     lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
diff --git a/Lib/dos-8x3/test_for.py b/Lib/dos-8x3/test_for.py
index 67e30df..4fd2662 100644
--- a/Lib/dos-8x3/test_for.py
+++ b/Lib/dos-8x3/test_for.py
@@ -6,14 +6,24 @@
 On some systems (e.g. Solaris without posix threads) we find that all
 active threads survive in the child after a fork(); this is an error.
 
+On BeOS, you CANNOT mix threads and fork(), the behaviour is undefined.
+That's OK, fork() is a grotesque hack anyway. ;-) [cjh]
+
 """
 
 import os, sys, time, thread
+from test_support import TestSkipped
+
+try:
+    if os.uname()[0] == "BeOS":
+        raise TestSkipped, "can't mix os.fork with threads on BeOS"
+except AttributeError:
+    pass
 
 try:
     os.fork
 except AttributeError:
-    raise ImportError, "os.fork not defined -- skipping test_fork1"
+    raise TestSkipped, "os.fork not defined -- skipping test_fork1"
 
 LONGSLEEP = 2
 
diff --git a/Lib/dos-8x3/test_gra.py b/Lib/dos-8x3/test_gra.py
index fa09e8c..ef7c09b 100755
--- a/Lib/dos-8x3/test_gra.py
+++ b/Lib/dos-8x3/test_gra.py
@@ -260,6 +260,50 @@
 print 0 or 1, 0 or 1,
 print 0 or 1
 
+print 'extended print_stmt' # 'print' '>>' test ','
+import sys
+print >> sys.stdout, 1, 2, 3
+print >> sys.stdout, 1, 2, 3,
+print >> sys.stdout
+print >> sys.stdout, 0 or 1, 0 or 1,
+print >> sys.stdout, 0 or 1
+
+# test print >> None
+class Gulp:
+	def write(self, msg): pass
+
+def driver():
+	oldstdout = sys.stdout
+	sys.stdout = Gulp()
+	try:
+		tellme(Gulp())
+		tellme()
+	finally:
+		sys.stdout = oldstdout
+
+# we should see this once
+def tellme(file=sys.stdout):
+	print >> file, 'hello world'
+
+driver()
+
+# we should not see this at all
+def tellme(file=None):
+	print >> file, 'goodbye universe'
+
+driver()
+
+# syntax errors
+def check_syntax(statement):
+	try:
+		compile(statement, '<string>', 'exec')
+	except SyntaxError:
+		pass
+	else:
+		print 'Missing SyntaxError: "%s"' % statement
+check_syntax('print ,')
+check_syntax('print >> x,')
+
 print 'del_stmt' # 'del' exprlist
 del abc
 del x, y, (z, xyz)
@@ -542,3 +586,49 @@
 	def meth1(self): pass
 	def meth2(self, arg): pass
 	def meth3(self, a1, a2): pass
+
+# list comprehension tests
+nums = [1, 2, 3, 4, 5]
+strs = ["Apple", "Banana", "Coconut"]
+spcs = ["  Apple", " Banana ", "Coco  nut  "]
+
+print [s.strip() for s in spcs]
+print [3 * x for x in nums]
+print [x for x in nums if x > 2]
+print [(i, s) for i in nums for s in strs]
+print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
+try:
+    eval("[i, s for i in nums for s in strs]")
+    print "FAIL: should have raised a SyntaxError!"
+except SyntaxError:
+    print "good: got a SyntaxError as expected"
+
+try:
+    eval("[x if y]")
+    print "FAIL: should have raised a SyntaxError!"
+except SyntaxError:
+        print "good: got a SyntaxError as expected"
+
+suppliers = [
+  (1, "Boeing"),
+  (2, "Ford"),
+  (3, "Macdonalds")
+]
+
+parts = [
+  (10, "Airliner"),
+  (20, "Engine"),
+  (30, "Cheeseburger")
+]
+
+suppart = [
+  (1, 10), (1, 20), (2, 20), (3, 30)
+]
+
+print [
+  (sname, pname)
+    for (sno, sname) in suppliers
+      for (pno, pname) in parts
+        for (sp_sno, sp_pno) in suppart
+          if sno == sp_sno and pno == sp_pno
+]
diff --git a/Lib/dos-8x3/test_gzi.py b/Lib/dos-8x3/test_gzi.py
index 3ea2ba9..2366d02 100644
--- a/Lib/dos-8x3/test_gzi.py
+++ b/Lib/dos-8x3/test_gzi.py
@@ -16,15 +16,39 @@
 /* See http://www.winimage.com/zLibDll for Windows */
 """
 
-f = gzip.GzipFile(filename, 'wb') ; f.write(data1) ; f.close()
+f = gzip.GzipFile(filename, 'wb') ; f.write(data1 * 50) ; f.close()
 
 f = gzip.GzipFile(filename, 'rb') ; d = f.read() ; f.close()
-assert d == data1
+assert d == data1*50
 
 # Append to the previous file
-f = gzip.GzipFile(filename, 'ab') ; f.write(data2) ; f.close()
+f = gzip.GzipFile(filename, 'ab') ; f.write(data2 * 15) ; f.close()
 
 f = gzip.GzipFile(filename, 'rb') ; d = f.read() ; f.close()
-assert d == data1+data2
+assert d == (data1*50) + (data2*15)
+
+# Try .readline() with varying line lengths
+
+f = gzip.GzipFile(filename, 'rb')
+line_length = 0
+while 1:
+    L = f.readline( line_length )
+    if L == "" and line_length != 0: break
+    assert len(L) <= line_length
+    line_length = (line_length + 1) % 50
+f.close()
+
+# Try .readlines() 
+
+f = gzip.GzipFile(filename, 'rb')
+L = f.readlines()
+f.close()
+
+f = gzip.GzipFile(filename, 'rb')
+while 1:
+    L = f.readlines(150)
+    if L == []: break    
+f.close()
+
 
 os.unlink( filename )
diff --git a/Lib/dos-8x3/test_lin.py b/Lib/dos-8x3/test_lin.py
index 4b612a7..4faaab1 100644
--- a/Lib/dos-8x3/test_lin.py
+++ b/Lib/dos-8x3/test_lin.py
@@ -1,5 +1,6 @@
-from test_support import verbose, findfile, TestFailed
+from test_support import verbose, findfile, TestFailed, TestSkipped
 import linuxaudiodev
+import errno
 import os
 
 def play_sound_file(path):
@@ -9,6 +10,8 @@
     try:
         a = linuxaudiodev.open('w')
     except linuxaudiodev.error, msg:
+        if msg[0] in (errno.EACCES, errno.ENODEV):
+            raise TestSkipped, msg
         raise TestFailed, msg
     else:
         a.write(data)
diff --git a/Lib/dos-8x3/test_mat.py b/Lib/dos-8x3/test_mat.py
index 5c8efc6..6d6bc44 100644
--- a/Lib/dos-8x3/test_mat.py
+++ b/Lib/dos-8x3/test_mat.py
@@ -129,18 +129,6 @@
 testit('pow(2,1)', math.pow(2,1), 2)
 testit('pow(2,-1)', math.pow(2,-1), 0.5)
 
-print 'rint'
-try:
-	math.rint
-except AttributeError:
-	# this platform does not have rint, that is fine, skip the test
-	pass
-else:
-	testit('rint(0.7)', math.rint(0.7), 1)
-	testit('rint(-0.3)', math.rint(-0.3), 0)
-	testit('rint(2.5)', math.rint(2.5), 2)
-	testit('rint(3.5)', math.rint(3.5), 4) 
-
 print 'sin'
 testit('sin(0)', math.sin(0), 0)
 testit('sin(pi/2)', math.sin(math.pi/2), 1)
diff --git a/Lib/dos-8x3/test_mma.py b/Lib/dos-8x3/test_mma.py
index c3cafca..73c1a15 100644
--- a/Lib/dos-8x3/test_mma.py
+++ b/Lib/dos-8x3/test_mma.py
@@ -69,7 +69,7 @@
     m.seek(0,2)
     print '  Seek to last byte'
     assert m.tell() == len(m)
-	
+
     print '  Try to seek to negative position...'
     try:
         m.seek(-1)
@@ -94,6 +94,26 @@
     else:
         assert 0, 'expected a ValueError but did not get it'
 
+    # Try resizing map
+    print '  Attempting resize()'
+    try:
+        m.resize( 512 )
+    except SystemError:
+        # resize() not supported
+        # No messages are printed, since the output of this test suite
+        # would then be different across platforms.
+        pass
+    else:
+        # resize() is supported
+        assert len(m) == 512, "len(m) is %d, but expecting 512" % (len(m),)
+        # Check that we can no longer seek beyond the new size.
+        try:
+            m.seek(513,0)
+        except ValueError:
+            pass
+        else:
+            assert 0, 'Could seek beyond the new size'
+    
     m.close()
     os.unlink("foo")
     print ' Test passed'
diff --git a/Lib/dos-8x3/test_ntp.py b/Lib/dos-8x3/test_ntp.py
index 1f824a5..11f2f44 100644
--- a/Lib/dos-8x3/test_ntp.py
+++ b/Lib/dos-8x3/test_ntp.py
@@ -1,5 +1,6 @@
 import ntpath
 import string
+import os
 
 errors = 0
 
@@ -34,6 +35,15 @@
 tester('ntpath.isabs("\\foo")', 1)
 tester('ntpath.isabs("\\foo\\bar")', 1)
 
+tester('ntpath.abspath("C:\\")', "C:\\")
+
+tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
+       "/home/swen")
+tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
+       "\\home\\swen\\")
+tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
+       "/home/swen/spam")
+
 if errors:
 	print str(errors) + " errors."
 else:
diff --git a/Lib/dos-8x3/test_ope.py b/Lib/dos-8x3/test_ope.py
index 8d3864c..723e57c 100755
--- a/Lib/dos-8x3/test_ope.py
+++ b/Lib/dos-8x3/test_ope.py
@@ -1,77 +1,22 @@
-import operator
-import sys
+# Test to see if openpty works. (But don't worry if it isn't available.)
 
-def test(name, input, output, *args):
-    print 'testing:', name
-    f = getattr(operator, name)
-    params = (input,) + args
-    try:
-        val = apply(f, params)
-    except:
-        val = sys.exc_type
-    if val <> output:
-        print '%s%s = %s: %s expected' % (f.__name__, params, `val`, `output`)
+import os
+from test_support import verbose, TestFailed, TestSkipped
 
-test('abs', -1, 1)
-test('add', 3, 7, 4)
-test('and_', 0xf, 0xa, 0xa)
-test('concat', 'py', 'python', 'thon')
+try:
+    if verbose:
+        print "Calling os.openpty()"
+    master, slave = os.openpty()
+    if verbose:
+        print "(master, slave) = (%d, %d)"%(master, slave)
+except AttributeError:
+    raise TestSkipped, "No openpty() available."
 
-test('countOf', [1, 2, 1, 3, 1, 4], 1, 3)
+if not os.isatty(master):
+    raise TestFailed, "Master-end of pty is not a terminal."
+if not os.isatty(slave):
+    raise TestFailed, "Slave-end of pty is not a terminal."
 
-a = [4, 3, 2, 1]
-test('delitem', a, None, 1)
-if a <> [4, 2, 1]:
-    print 'delitem() failed'
+os.write(slave, 'Ping!')
+print os.read(master, 1024)
 
-a = range(10)
-test('delslice', a, None, 2, 8)
-if a <> [0, 1, 8, 9]:
-    print 'delslice() failed'
-
-a = range(10)
-test('div', 5, 2, 2)
-test('getitem', a, 2, 2)
-test('getslice', a, [4, 5], 4, 6)
-test('indexOf', [4, 3, 2, 1], 1, 3)
-test('inv', 4, -5)
-test('isCallable', 4, 0)
-test('isCallable', operator.isCallable, 1)
-test('isMappingType', operator.isMappingType, 0)
-test('isMappingType', operator.__dict__, 1)
-test('isNumberType', 8.3, 1)
-test('isNumberType', dir(), 0)
-test('isSequenceType', dir(), 1)
-test('isSequenceType', 'yeahbuddy', 1)
-test('isSequenceType', 3, 0)
-test('lshift', 5, 10, 1)
-test('mod', 5, 1, 2)
-test('mul', 5, 10, 2)
-test('neg', 5, -5)
-test('or_', 0xa, 0xf, 0x5)
-test('pos', -5, -5)
-
-a = range(3)
-test('repeat', a, a+a, 2)
-test('rshift', 5, 2, 1)
-
-test('sequenceIncludes', range(4), 1, 2)
-test('sequenceIncludes', range(4), 0, 5)
-
-test('setitem', a, None, 0, 2)
-if a <> [2, 1, 2]:
-    print 'setitem() failed'
-
-a = range(4)
-test('setslice', a, None, 1, 3, [2, 1])
-if a <> [0, 2, 1, 3]:
-    print 'setslice() failed:', a
-
-test('sub', 5, 2, 3)
-test('truth', 5, 1)
-test('truth', [], 0)
-test('xor', 0xb, 0x7, 0xc)
-
-
-# some negative tests
-test('indexOf', [4, 3, 2, 1], ValueError, 9)
diff --git a/Lib/dos-8x3/test_pop.py b/Lib/dos-8x3/test_pop.py
index be79f3c..26ef9d9 100644
--- a/Lib/dos-8x3/test_pop.py
+++ b/Lib/dos-8x3/test_pop.py
@@ -3,15 +3,54 @@
    Christian Tismer
 """
 
+import os
+
 # popen2 contains its own testing routine
 # which is especially useful to see if open files
-# like stdin can be read successfully by a forked 
+# like stdin can be read successfully by a forked
 # subprocess.
 
 def main():
-    from os import fork # skips test through ImportError
+    print "Test popen2 module:"
+    try:
+        from os import popen
+    except ImportError:
+        # if we don't have os.popen, check that
+        # we have os.fork.  if not, skip the test
+        # (by raising an ImportError)
+        from os import fork
     import popen2
     popen2._test()
 
-main()
 
+def _test():
+    # same test as popen2._test(), but using the os.popen*() API
+    print "Testing os module:"
+    import popen2
+    cmd  = "cat"
+    teststr = "abc\n"
+    resultstr = teststr
+    if os.name == "nt":
+        cmd = "more"
+        resultstr = "\n" + resultstr
+    print "testing popen2..."
+    w, r = os.popen2(cmd)
+    w.write(teststr)
+    w.close()
+    assert r.read() == resultstr
+    print "testing popen3..."
+    try:
+        w, r, e = os.popen3([cmd])
+    except:
+        w, r, e = os.popen3(cmd)
+    w.write(teststr)
+    w.close()
+    assert r.read() == resultstr
+    assert e.read() == ""
+    for inst in popen2._active[:]:
+        inst.wait()
+    assert not popen2._active
+    print "All OK"
+
+main()
+_test()
diff --git a/Lib/dos-8x3/test_rgb.py b/Lib/dos-8x3/test_rgb.py
index 38bcdf5..1fa201d 100755
--- a/Lib/dos-8x3/test_rgb.py
+++ b/Lib/dos-8x3/test_rgb.py
@@ -4,7 +4,8 @@
 
 from test_support import verbose, unlink, findfile
 
-error = 'test_rgbimg.error'
+class error(Exception):
+        pass
 
 print 'RGBimg test suite:'
 
diff --git a/Lib/dos-8x3/test_sel.py b/Lib/dos-8x3/test_sel.py
index 60de360..b198cf1 100755
--- a/Lib/dos-8x3/test_sel.py
+++ b/Lib/dos-8x3/test_sel.py
@@ -45,7 +45,6 @@
                 if verbose:
                         print 'timeout =', tout
                 rfd, wfd, xfd = select.select([p], [], [], tout)
-##              print rfd, wfd, xfd
                 if (rfd, wfd, xfd) == ([], [], []):
                         continue
                 if (rfd, wfd, xfd) == ([p], [], []):
@@ -57,7 +56,7 @@
                                         print 'EOF'
                                 break
                         continue
-                print 'Heh?'
+                print 'Unexpected return values from select():', rfd, wfd, xfd
         p.close()
 
 test()
diff --git a/Lib/dos-8x3/test_sig.py b/Lib/dos-8x3/test_sig.py
index 2d33635..02b5dc3 100755
--- a/Lib/dos-8x3/test_sig.py
+++ b/Lib/dos-8x3/test_sig.py
@@ -1,11 +1,11 @@
 # Test the signal module
-from test_support import verbose
+from test_support import verbose, TestSkipped
 import signal
 import os
 import sys
 
 if sys.platform[:3] in ('win', 'os2'):
-    raise ImportError, "Can't test signal on %s" % sys.platform[:3]
+    raise TestSkipped, "Can't test signal on %s" % sys.platform[:3]
 
 if verbose:
 	x = '-x'
diff --git a/Lib/dos-8x3/test_str.py b/Lib/dos-8x3/test_str.py
index ec57c26..c713d05 100644
--- a/Lib/dos-8x3/test_str.py
+++ b/Lib/dos-8x3/test_str.py
@@ -1,185 +1,134 @@
+#! /usr/bin/env python
+
+# Sanity checker for time.strftime
+
+import time, calendar, sys, string, os, re
 from test_support import verbose
-import string, sys
 
-# XXX: kludge... short circuit if strings don't have methods
-try:
-    ''.join
-except AttributeError:
-    raise ImportError
+def main():
+    global verbose
+    now = time.time()
+    strftest(now)
+    verbose = 0
+    # Try a bunch of dates and times,  chosen to vary through time of
+    # day and daylight saving time
+    for j in range(-5, 5):
+        for i in range(25):
+            strftest(now + (i + j*100)*23*3603)
 
-def test(name, input, output, *args):
+def strftest(now):
     if verbose:
-        print 'string.%s%s =? %s... ' % (name, (input,) + args, output),
+        print "strftime test for", time.ctime(now)
+    nowsecs = str(long(now))[:-1]
+    gmt = time.gmtime(now)
+    now = time.localtime(now)
+
+    if now[3] < 12: ampm='AM'
+    else: ampm='PM'
+
+    jan1 = time.localtime(time.mktime((now[0], 1, 1) + (0,)*6))
+
     try:
-        # Prefer string methods over string module functions
+        if now[8]: tz = time.tzname[1]
+        else: tz = time.tzname[0]
+    except AttributeError:
+        tz = ''
+
+    if now[3] > 12: clock12 = now[3] - 12
+    elif now[3] > 0: clock12 = now[3]
+    else: clock12 = 12
+
+    expectations = (
+        ('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'),
+        ('%A', calendar.day_name[now[6]], 'full weekday name'),
+        ('%b', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%B', calendar.month_name[now[1]], 'full month name'),
+        # %c see below
+        ('%d', '%02d' % now[2], 'day of month as number (00-31)'),
+        ('%H', '%02d' % now[3], 'hour (00-23)'),
+        ('%I', '%02d' % clock12, 'hour (01-12)'),
+        ('%j', '%03d' % now[7], 'julian day (001-366)'),
+        ('%m', '%02d' % now[1], 'month as number (01-12)'),
+        ('%M', '%02d' % now[4], 'minute, (00-59)'),
+        ('%p', ampm, 'AM or PM as appropriate'),
+        ('%S', '%02d' % now[5], 'seconds of current time (00-60)'),
+        ('%U', '%02d' % ((now[7] + jan1[6])/7),
+         'week number of the year (Sun 1st)'),
+        ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'),
+        ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)/7),
+         'week number of the year (Mon 1st)'),
+        # %x see below
+        ('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%y', '%02d' % (now[0]%100), 'year without century'),
+        ('%Y', '%d' % now[0], 'year with century'),
+        # %Z see below
+        ('%%', '%', 'single percent sign'),
+        )
+
+    nonstandard_expectations = (
+        # These are standard but don't have predictable output
+        ('%c', fixasctime(time.asctime(now)), 'near-asctime() format'),
+        ('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)),
+         '%m/%d/%y %H:%M:%S'),
+        ('%Z', '%s' % tz, 'time zone name'),
+
+        # These are some platform specific extensions
+        ('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'),
+        ('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'),
+        ('%h', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'),
+        ('%n', '\n', 'newline character'),
+        ('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm),
+         '%I:%M:%S %p'),
+        ('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'),
+        ('%s', nowsecs, 'seconds since the Epoch in UCT'),
+        ('%t', '\t', 'tab character'),
+        ('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%3y', '%03d' % (now[0]%100),
+         'year without century rendered using fieldwidth'),
+        )
+
+    if verbose:
+        print "Strftime test, platform: %s, Python version: %s" % \
+              (sys.platform, string.split(sys.version)[0])
+
+    for e in expectations:
         try:
-            f = getattr(input, name)
-            value = apply(f, args)
-        except AttributeError:
-            f = getattr(string, name)
-            value = apply(f, (input,) + args)
-    except:
-         value = sys.exc_type
-    if value != output:
-        if verbose:
-            print 'no'
-        print f, `input`, `output`, `value`
-    else:
-        if verbose:
-            print 'yes'
+            result = time.strftime(e[0], now)
+        except ValueError, error:
+            print "Standard '%s' format gave error:" % e[0], error
+            continue
+        if re.match(e[1], result): continue
+        if not result or result[0] == '%':
+            print "Does not support standard '%s' format (%s)" % (e[0], e[2])
+        else:
+            print "Conflict for %s (%s):" % (e[0], e[2])
+            print "  Expected %s, but got %s" % (e[1], result)
 
-test('atoi', " 1 ", 1)
-test('atoi', " 1x", ValueError)
-test('atoi', " x1 ", ValueError)
-test('atol', "  1  ", 1L)
-test('atol', "  1x ", ValueError)
-test('atol', "  x1 ", ValueError)
-test('atof', "  1  ", 1.0)
-test('atof', "  1x ", ValueError)
-test('atof', "  x1 ", ValueError)
+    for e in nonstandard_expectations:
+        try:
+            result = time.strftime(e[0], now)
+        except ValueError, result:
+            if verbose:
+                print "Error for nonstandard '%s' format (%s): %s" % \
+                      (e[0], e[2], str(result))
+            continue
+        if re.match(e[1], result):
+            if verbose:
+                print "Supports nonstandard '%s' format (%s)" % (e[0], e[2])
+        elif not result or result[0] == '%':
+            if verbose:
+                print "Does not appear to support '%s' format (%s)" % (e[0],
+                                                                       e[2])
+        else:
+            if verbose:
+                print "Conflict for nonstandard '%s' format (%s):" % (e[0],
+                                                                      e[2])
+                print "  Expected %s, but got %s" % (e[1], result)
 
-test('capitalize', ' hello ', ' hello ')
-test('capitalize', 'hello ', 'Hello ')
-test('find', 'abcdefghiabc', 0, 'abc')
-test('find', 'abcdefghiabc', 9, 'abc', 1)
-test('find', 'abcdefghiabc', -1, 'def', 4)
-test('rfind', 'abcdefghiabc', 9, 'abc')
-test('lower', 'HeLLo', 'hello')
-test('lower', 'hello', 'hello')
-test('upper', 'HeLLo', 'HELLO')
-test('upper', 'HELLO', 'HELLO')
+def fixasctime(s):
+    if s[8] == ' ':
+        s = s[:8] + '0' + s[9:]
+    return s
 
-test('title', ' hello ', ' Hello ')
-test('title', 'hello ', 'Hello ')
-test('title', "fOrMaT thIs aS titLe String", 'Format This As Title String')
-test('title', "fOrMaT,thIs-aS*titLe;String", 'Format,This-As*Title;String')
-test('title', "getInt", 'Getint')
-
-test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab      def\ng       hi')
-test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab      def\ng       hi', 8)
-test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab  def\ng   hi', 4)
-test('expandtabs', 'abc\r\nab\tdef\ng\thi', 'abc\r\nab  def\ng   hi', 4)
-
-test('islower', 'a', 1)
-test('islower', 'A', 0)
-test('islower', '\n', 0)
-test('islower', 'abc', 1)
-test('islower', 'aBc', 0)
-test('islower', 'abc\n', 1)
-
-test('isupper', 'a', 0)
-test('isupper', 'A', 1)
-test('isupper', '\n', 0)
-test('isupper', 'ABC', 1)
-test('isupper', 'AbC', 0)
-test('isupper', 'ABC\n', 1)
-
-test('istitle', 'a', 0)
-test('istitle', 'A', 1)
-test('istitle', '\n', 0)
-test('istitle', 'A Titlecased Line', 1)
-test('istitle', 'A\nTitlecased Line', 1)
-test('istitle', 'A Titlecased, Line', 1)
-test('istitle', 'Not a capitalized String', 0)
-test('istitle', 'Not\ta Titlecase String', 0)
-test('istitle', 'Not--a Titlecase String', 0)
-
-test('splitlines', "abc\ndef\n\rghi", ['abc', 'def', '', 'ghi'])
-test('splitlines', "abc\ndef\n\r\nghi", ['abc', 'def', '', 'ghi'])
-test('splitlines', "abc\ndef\r\nghi", ['abc', 'def', 'ghi'])
-test('splitlines', "abc\ndef\r\nghi\n", ['abc', 'def', 'ghi'])
-test('splitlines', "abc\ndef\r\nghi\n\r", ['abc', 'def', 'ghi', ''])
-test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc', 'def', 'ghi', ''])
-test('splitlines', "\nabc\ndef\r\nghi\n\r", ['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], 1)
-
-transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
-
-test('maketrans', 'abc', transtable, 'xyz')
-test('maketrans', 'abc', ValueError, 'xyzq')
-
-test('split', 'this is the split function',
-     ['this', 'is', 'the', 'split', 'function'])
-test('split', 'a|b|c|d', ['a', 'b', 'c', 'd'], '|')
-test('split', 'a|b|c|d', ['a', 'b', 'c|d'], '|', 2)
-test('split', 'a b c d', ['a', 'b c d'], None, 1)
-test('split', 'a b c d', ['a', 'b', 'c d'], None, 2)
-test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 3)
-test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 4)
-test('split', 'a b c d', ['a b c d'], None, 0)
-test('split', 'a  b  c  d', ['a', 'b', 'c  d'], None, 2)
-test('split', 'a b c d ', ['a', 'b', 'c', 'd'])
-
-# join now works with any sequence type
-class Sequence:
-    def __init__(self): self.seq = 'wxyz'
-    def __len__(self): return len(self.seq)
-    def __getitem__(self, i): return self.seq[i]
-
-test('join', ['a', 'b', 'c', 'd'], 'a b c d')
-test('join', ('a', 'b', 'c', 'd'), 'abcd', '')
-test('join', Sequence(), 'w x y z')
-test('join', 7, TypeError)
-
-class BadSeq(Sequence):
-    def __init__(self): self.seq = [7, 'hello', 123L]
-
-test('join', BadSeq(), TypeError)
-
-# try a few long ones
-print string.join(['x' * 100] * 100, ':')
-print string.join(('x' * 100,) * 100, ':')
-
-test('strip', '   hello   ', 'hello')
-test('lstrip', '   hello   ', 'hello   ')
-test('rstrip', '   hello   ', '   hello')
-test('strip', 'hello', 'hello')
-
-test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS')
-test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def')
-
-table = string.maketrans('a', 'A')
-test('translate', 'abc', 'Abc', table)
-test('translate', 'xyz', 'xyz', table)
-
-test('replace', 'one!two!three!', 'one@two!three!', '!', '@', 1)
-test('replace', 'one!two!three!', 'onetwothree', '!', '')
-test('replace', 'one!two!three!', 'one@two@three!', '!', '@', 2)
-test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 3)
-test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 4)
-test('replace', 'one!two!three!', 'one!two!three!', '!', '@', 0)
-test('replace', 'one!two!three!', 'one@two@three@', '!', '@')
-test('replace', 'one!two!three!', 'one!two!three!', 'x', '@')
-test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2)
-
-test('startswith', 'hello', 1, 'he')
-test('startswith', 'hello', 1, 'hello')
-test('startswith', 'hello', 0, 'hello world')
-test('startswith', 'hello', 1, '')
-test('startswith', 'hello', 0, 'ello')
-test('startswith', 'hello', 1, 'ello', 1)
-test('startswith', 'hello', 1, 'o', 4)
-test('startswith', 'hello', 0, 'o', 5)
-test('startswith', 'hello', 1, '', 5)
-test('startswith', 'hello', 0, 'lo', 6)
-test('startswith', 'helloworld', 1, 'lowo', 3)
-test('startswith', 'helloworld', 1, 'lowo', 3, 7)
-test('startswith', 'helloworld', 0, 'lowo', 3, 6)
-
-test('endswith', 'hello', 1, 'lo')
-test('endswith', 'hello', 0, 'he')
-test('endswith', 'hello', 1, '')
-test('endswith', 'hello', 0, 'hello world')
-test('endswith', 'helloworld', 0, 'worl')
-test('endswith', 'helloworld', 1, 'worl', 3, 9)
-test('endswith', 'helloworld', 1, 'world', 3, 12)
-test('endswith', 'helloworld', 1, 'lowo', 1, 7)
-test('endswith', 'helloworld', 1, 'lowo', 2, 7)
-test('endswith', 'helloworld', 1, 'lowo', 3, 7)
-test('endswith', 'helloworld', 0, 'lowo', 4, 7)
-test('endswith', 'helloworld', 0, 'lowo', 3, 8)
-test('endswith', 'ab', 0, 'ab', 0, 1)
-test('endswith', 'ab', 0, 'ab', 0, 0)
-
-string.whitespace
-string.lowercase
-string.uppercase
+main()
diff --git a/Lib/dos-8x3/test_sup.py b/Lib/dos-8x3/test_sup.py
index 3839c79..99bacda 100755
--- a/Lib/dos-8x3/test_sup.py
+++ b/Lib/dos-8x3/test_sup.py
@@ -1,8 +1,26 @@
-# Python test set -- supporting definitions.
+"""Supporting definitions for the Python regression test."""
 
-TestFailed = 'test_support -- test failed'	# Exception
+
+class Error(Exception):
+        """Base class for regression test exceptions."""
+
+class TestFailed(Error):
+        """Test failed."""
+
+class TestSkipped(Error):
+        """Test skipped.
+
+        This can be raised to indicate that a test was deliberatly
+        skipped, but not because a feature wasn't available.  For
+        example, if some resource can't be used, such as the network
+        appears to be unavailable, this should be raised instead of
+        TestFailed.
+
+        """
+
 
 verbose = 1				# Flag set to 0 by regrtest.py
+use_large_resources = 1 # Flag set to 0 by regrtest.py
 
 def unload(name):
 	import sys
diff --git a/Lib/dos-8x3/test_tim.py b/Lib/dos-8x3/test_tim.py
index 5dbc895..03d081e 100644
--- a/Lib/dos-8x3/test_tim.py
+++ b/Lib/dos-8x3/test_tim.py
@@ -1,21 +1,39 @@
-from test_support import verbose
-import timing
+import time
 
-r = range(100000)
-if verbose:
-    print 'starting...'
-timing.start()
-for i in r:
+time.altzone
+time.clock()
+t = time.time()
+time.asctime(time.gmtime(t))
+if time.ctime(t) <> time.asctime(time.localtime(t)):
+    print 'time.ctime(t) <> time.asctime(time.localtime(t))'
+
+time.daylight
+if long(time.mktime(time.localtime(t))) <> long(t):
+    print 'time.mktime(time.localtime(t)) <> t'
+
+time.sleep(1.2)
+tt = time.gmtime(t)
+for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
+                  'j', 'm', 'M', 'p', 'S',
+                  'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
+    format = ' %' + directive
+    try:
+        time.strftime(format, tt)
+    except ValueError:
+        print 'conversion specifier:', format, ' failed.'
+
+time.timezone
+time.tzname
+
+# expected errors
+try:
+    time.asctime(0)
+except TypeError:
     pass
-timing.finish()
-if verbose:
-    print 'finished'
 
-secs = timing.seconds()
-milli = timing.milli()
-micro = timing.micro()
-
-if verbose:
-    print 'seconds:', secs
-    print 'milli  :', milli
-    print 'micro  :', micro
+try:
+    time.mktime((999999, 999999, 999999, 999999,
+                 999999, 999999, 999999, 999999,
+                 999999))
+except OverflowError:
+    pass
diff --git a/Lib/dos-8x3/test_typ.py b/Lib/dos-8x3/test_typ.py
index e22b0e2..e3a51f0 100755
--- a/Lib/dos-8x3/test_typ.py
+++ b/Lib/dos-8x3/test_typ.py
@@ -253,3 +253,15 @@
 if d.get('c', 3) != 3: raise TestFailed, 'missing dict get, w/ 2nd arg'
 if d.get('a') != 1: raise TestFailed, 'present dict get, no 2nd arg'
 if d.get('a', 3) != 1: raise TestFailed, 'present dict get, w/ 2nd arg'
+# dict.setdefault()
+d = {}
+if d.setdefault('key0') <> None:
+	raise TestFailed, 'missing {} setdefault, no 2nd arg'
+if d.setdefault('key0') <> None:
+	raise TestFailed, 'present {} setdefault, no 2nd arg'
+d.setdefault('key', []).append(3)
+if d['key'][0] <> 3:
+	raise TestFailed, 'missing {} setdefault, w/ 2nd arg'
+d.setdefault('key', []).append(4)
+if len(d['key']) <> 2:
+	raise TestFailed, 'present {} setdefault, w/ 2nd arg'
diff --git a/Lib/dos-8x3/test_uni.py b/Lib/dos-8x3/test_uni.py
index 6ddd077..8479c20 100644
--- a/Lib/dos-8x3/test_uni.py
+++ b/Lib/dos-8x3/test_uni.py
@@ -1,50 +1,517 @@
-""" Test script for the unicodedata module.
+""" Test script for the Unicode implementation.
 
 Written by Marc-Andre Lemburg (mal@lemburg.com).
 
 (c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
 
-"""#"
+"""
 from test_support import verbose
 import sys
 
-# Test Unicode database APIs
-import unicodedata
+def test(method, input, output, *args):
+    if verbose:
+        print '%s.%s%s =? %s... ' % (repr(input), method, args, output),
+    try:
+        f = getattr(input, method)
+        value = apply(f, args)
+    except:
+        value = sys.exc_type
+        exc = sys.exc_info()[:2]
+    else:
+        exc = None
+    if value != output:
+        if verbose:
+            print 'no'
+        print '*',f, `input`, `output`, `value`
+        if exc:
+            print '  value == %s: %s' % (exc)
+    else:
+        if verbose:
+            print 'yes'
 
-print 'Testing unicodedata module...',
+test('capitalize', u' hello ', u' hello ')
+test('capitalize', u'hello ', u'Hello ')
 
-assert unicodedata.digit(u'A',None) is None
-assert unicodedata.digit(u'9') == 9
-assert unicodedata.digit(u'\u215b',None) is None
-assert unicodedata.digit(u'\u2468') == 9
+test('title', u' hello ', u' Hello ')
+test('title', u'hello ', u'Hello ')
+test('title', u"fOrMaT thIs aS titLe String", u'Format This As Title String')
+test('title', u"fOrMaT,thIs-aS*titLe;String", u'Format,This-As*Title;String')
+test('title', u"getInt", u'Getint')
 
-assert unicodedata.numeric(u'A',None) is None
-assert unicodedata.numeric(u'9') == 9
-assert unicodedata.numeric(u'\u215b') == 0.125
-assert unicodedata.numeric(u'\u2468') == 9.0
+test('find', u'abcdefghiabc', 0, u'abc')
+test('find', u'abcdefghiabc', 9, u'abc', 1)
+test('find', u'abcdefghiabc', -1, u'def', 4)
 
-assert unicodedata.decimal(u'A',None) is None
-assert unicodedata.decimal(u'9') == 9
-assert unicodedata.decimal(u'\u215b',None) is None
-assert unicodedata.decimal(u'\u2468',None) is None
+test('rfind', u'abcdefghiabc', 9, u'abc')
 
-assert unicodedata.category(u'\uFFFE') == 'Cn'
-assert unicodedata.category(u'a') == 'Ll'
-assert unicodedata.category(u'A') == 'Lu'
+test('lower', u'HeLLo', u'hello')
+test('lower', u'hello', u'hello')
 
-assert unicodedata.bidirectional(u'\uFFFE') == ''
-assert unicodedata.bidirectional(u' ') == 'WS'
-assert unicodedata.bidirectional(u'A') == 'L'
+test('upper', u'HeLLo', u'HELLO')
+test('upper', u'HELLO', u'HELLO')
 
-assert unicodedata.decomposition(u'\uFFFE') == ''
-assert unicodedata.decomposition(u'\u00bc') == '<fraction> 0031 2044 0034'
+if 0:
+    transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
 
-assert unicodedata.mirrored(u'\uFFFE') == 0
-assert unicodedata.mirrored(u'a') == 0
-assert unicodedata.mirrored(u'\u2201') == 1
+    test('maketrans', u'abc', transtable, u'xyz')
+    test('maketrans', u'abc', ValueError, u'xyzq')
 
-assert unicodedata.combining(u'\uFFFE') == 0
-assert unicodedata.combining(u'a') == 0
-assert unicodedata.combining(u'\u20e1') == 230
+test('split', u'this is the split function',
+     [u'this', u'is', u'the', u'split', u'function'])
+test('split', u'a|b|c|d', [u'a', u'b', u'c', u'd'], u'|')
+test('split', u'a|b|c|d', [u'a', u'b', u'c|d'], u'|', 2)
+test('split', u'a b c d', [u'a', u'b c d'], None, 1)
+test('split', u'a b c d', [u'a', u'b', u'c d'], None, 2)
+test('split', u'a b c d', [u'a', u'b', u'c', u'd'], None, 3)
+test('split', u'a b c d', [u'a', u'b', u'c', u'd'], None, 4)
+test('split', u'a b c d', [u'a b c d'], None, 0)
+test('split', u'a  b  c  d', [u'a', u'b', u'c  d'], None, 2)
+test('split', u'a b c d ', [u'a', u'b', u'c', u'd'])
+
+# join now works with any sequence type
+class Sequence:
+    def __init__(self): self.seq = 'wxyz'
+    def __len__(self): return len(self.seq)
+    def __getitem__(self, i): return self.seq[i]
+
+test('join', u' ', u'a b c d', [u'a', u'b', u'c', u'd'])
+test('join', u'', u'abcd', (u'a', u'b', u'c', u'd'))
+test('join', u' ', u'w x y z', Sequence())
+test('join', u' ', TypeError, 7)
+
+class BadSeq(Sequence):
+    def __init__(self): self.seq = [7, u'hello', 123L]
+
+test('join', u' ', TypeError, BadSeq())
+
+result = u''
+for i in range(10):
+    if i > 0:
+        result = result + u':'
+    result = result + u'x'*10
+test('join', u':', result, [u'x' * 10] * 10)
+test('join', u':', result, (u'x' * 10,) * 10)
+
+test('strip', u'   hello   ', u'hello')
+test('lstrip', u'   hello   ', u'hello   ')
+test('rstrip', u'   hello   ', u'   hello')
+test('strip', u'hello', u'hello')
+
+test('swapcase', u'HeLLo cOmpUteRs', u'hEllO CoMPuTErS')
+
+if 0:
+    test('translate', u'xyzabcdef', u'xyzxyz', transtable, u'def')
+
+    table = string.maketrans('a', u'A')
+    test('translate', u'abc', u'Abc', table)
+    test('translate', u'xyz', u'xyz', table)
+
+test('replace', u'one!two!three!', u'one@two!three!', u'!', u'@', 1)
+test('replace', u'one!two!three!', u'onetwothree', '!', '')
+test('replace', u'one!two!three!', u'one@two@three!', u'!', u'@', 2)
+test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@', 3)
+test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@', 4)
+test('replace', u'one!two!three!', u'one!two!three!', u'!', u'@', 0)
+test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@')
+test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@')
+test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@', 2)
+
+test('startswith', u'hello', 1, u'he')
+test('startswith', u'hello', 1, u'hello')
+test('startswith', u'hello', 0, u'hello world')
+test('startswith', u'hello', 1, u'')
+test('startswith', u'hello', 0, u'ello')
+test('startswith', u'hello', 1, u'ello', 1)
+test('startswith', u'hello', 1, u'o', 4)
+test('startswith', u'hello', 0, u'o', 5)
+test('startswith', u'hello', 1, u'', 5)
+test('startswith', u'hello', 0, u'lo', 6)
+test('startswith', u'helloworld', 1, u'lowo', 3)
+test('startswith', u'helloworld', 1, u'lowo', 3, 7)
+test('startswith', u'helloworld', 0, u'lowo', 3, 6)
+
+test('endswith', u'hello', 1, u'lo')
+test('endswith', u'hello', 0, u'he')
+test('endswith', u'hello', 1, u'')
+test('endswith', u'hello', 0, u'hello world')
+test('endswith', u'helloworld', 0, u'worl')
+test('endswith', u'helloworld', 1, u'worl', 3, 9)
+test('endswith', u'helloworld', 1, u'world', 3, 12)
+test('endswith', u'helloworld', 1, u'lowo', 1, 7)
+test('endswith', u'helloworld', 1, u'lowo', 2, 7)
+test('endswith', u'helloworld', 1, u'lowo', 3, 7)
+test('endswith', u'helloworld', 0, u'lowo', 4, 7)
+test('endswith', u'helloworld', 0, u'lowo', 3, 8)
+test('endswith', u'ab', 0, u'ab', 0, 1)
+test('endswith', u'ab', 0, u'ab', 0, 0)
+
+test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab      def\ng       hi')
+test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab      def\ng       hi', 8)
+test('expandtabs', u'abc\rab\tdef\ng\thi', u'abc\rab  def\ng   hi', 4)
+test('expandtabs', u'abc\r\nab\tdef\ng\thi', u'abc\r\nab  def\ng   hi', 4)
+
+if 0:
+    test('capwords', u'abc def ghi', u'Abc Def Ghi')
+    test('capwords', u'abc\tdef\nghi', u'Abc Def Ghi')
+    test('capwords', u'abc\t   def  \nghi', u'Abc Def Ghi')
+
+# Comparisons:
+print 'Testing Unicode comparisons...',
+assert u'abc' == 'abc'
+assert 'abc' == u'abc'
+assert u'abc' == u'abc'
+assert u'abcd' > 'abc'
+assert 'abcd' > u'abc'
+assert u'abcd' > u'abc'
+assert u'abc' < 'abcd'
+assert 'abc' < u'abcd'
+assert u'abc' < u'abcd'
+print 'done.'
+
+if 0:
+    # Move these tests to a Unicode collation module test...
+
+    print 'Testing UTF-16 code point order comparisons...',
+    #No surrogates, no fixup required.
+    assert u'\u0061' < u'\u20ac'
+    # Non surrogate below surrogate value, no fixup required
+    assert u'\u0061' < u'\ud800\udc02'
+
+    # Non surrogate above surrogate value, fixup required
+    def test_lecmp(s, s2):
+      assert s <  s2 , "comparison failed on %s < %s" % (s, s2)
+
+    def test_fixup(s):
+      s2 = u'\ud800\udc01'
+      test_lecmp(s, s2)
+      s2 = u'\ud900\udc01'
+      test_lecmp(s, s2)
+      s2 = u'\uda00\udc01'
+      test_lecmp(s, s2)
+      s2 = u'\udb00\udc01'
+      test_lecmp(s, s2)
+      s2 = u'\ud800\udd01'
+      test_lecmp(s, s2)
+      s2 = u'\ud900\udd01'
+      test_lecmp(s, s2)
+      s2 = u'\uda00\udd01'
+      test_lecmp(s, s2)
+      s2 = u'\udb00\udd01'
+      test_lecmp(s, s2)
+      s2 = u'\ud800\ude01'
+      test_lecmp(s, s2)
+      s2 = u'\ud900\ude01'
+      test_lecmp(s, s2)
+      s2 = u'\uda00\ude01'
+      test_lecmp(s, s2)
+      s2 = u'\udb00\ude01'
+      test_lecmp(s, s2)
+      s2 = u'\ud800\udfff'
+      test_lecmp(s, s2)
+      s2 = u'\ud900\udfff'
+      test_lecmp(s, s2)
+      s2 = u'\uda00\udfff'
+      test_lecmp(s, s2)
+      s2 = u'\udb00\udfff'
+      test_lecmp(s, s2)
+
+    test_fixup(u'\ue000')
+    test_fixup(u'\uff61')
+
+    # Surrogates on both sides, no fixup required
+    assert u'\ud800\udc02' < u'\ud84d\udc56'
+    print 'done.'
+
+test('ljust', u'abc',  u'abc       ', 10)
+test('rjust', u'abc',  u'       abc', 10)
+test('center', u'abc', u'   abc    ', 10)
+test('ljust', u'abc',  u'abc   ', 6)
+test('rjust', u'abc',  u'   abc', 6)
+test('center', u'abc', u' abc  ', 6)
+test('ljust', u'abc', u'abc', 2)
+test('rjust', u'abc', u'abc', 2)
+test('center', u'abc', u'abc', 2)
+
+test('islower', u'a', 1)
+test('islower', u'A', 0)
+test('islower', u'\n', 0)
+test('islower', u'\u1FFc', 0)
+test('islower', u'abc', 1)
+test('islower', u'aBc', 0)
+test('islower', u'abc\n', 1)
+
+test('isupper', u'a', 0)
+test('isupper', u'A', 1)
+test('isupper', u'\n', 0)
+test('isupper', u'\u1FFc', 0)
+test('isupper', u'ABC', 1)
+test('isupper', u'AbC', 0)
+test('isupper', u'ABC\n', 1)
+
+test('istitle', u'a', 0)
+test('istitle', u'A', 1)
+test('istitle', u'\n', 0)
+test('istitle', u'\u1FFc', 1)
+test('istitle', u'A Titlecased Line', 1)
+test('istitle', u'A\nTitlecased Line', 1)
+test('istitle', u'A Titlecased, Line', 1)
+test('istitle', u'Greek \u1FFcitlecases ...', 1)
+test('istitle', u'Not a capitalized String', 0)
+test('istitle', u'Not\ta Titlecase String', 0)
+test('istitle', u'Not--a Titlecase String', 0)
+
+test('isalpha', u'a', 1)
+test('isalpha', u'A', 1)
+test('isalpha', u'\n', 0)
+test('isalpha', u'\u1FFc', 1)
+test('isalpha', u'abc', 1)
+test('isalpha', u'aBc123', 0)
+test('isalpha', u'abc\n', 0)
+
+test('isalnum', u'a', 1)
+test('isalnum', u'A', 1)
+test('isalnum', u'\n', 0)
+test('isalnum', u'123abc456', 1)
+test('isalnum', u'a1b3c', 1)
+test('isalnum', u'aBc000 ', 0)
+test('isalnum', u'abc\n', 0)
+
+test('splitlines', u"abc\ndef\n\rghi", [u'abc', u'def', u'', u'ghi'])
+test('splitlines', u"abc\ndef\n\r\nghi", [u'abc', u'def', u'', u'ghi'])
+test('splitlines', u"abc\ndef\r\nghi", [u'abc', u'def', u'ghi'])
+test('splitlines', u"abc\ndef\r\nghi\n", [u'abc', u'def', u'ghi'])
+test('splitlines', u"abc\ndef\r\nghi\n\r", [u'abc', u'def', u'ghi', u''])
+test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc', u'def', u'ghi', u''])
+test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'\n', u'abc\n', u'def\r\n', u'ghi\n', u'\r'], 1)
+
+test('translate', u"abababc", u'bbbc', {ord('a'):None})
+test('translate', u"abababc", u'iiic', {ord('a'):None, ord('b'):ord('i')})
+test('translate', u"abababc", u'iiix', {ord('a'):None, ord('b'):ord('i'), ord('c'):u'x'})
+
+# Contains:
+print 'Testing Unicode contains method...',
+assert ('a' in u'abdb') == 1
+assert ('a' in u'bdab') == 1
+assert ('a' in u'bdaba') == 1
+assert ('a' in u'bdba') == 1
+assert ('a' in u'bdba') == 1
+assert (u'a' in u'bdba') == 1
+assert (u'a' in u'bdb') == 0
+assert (u'a' in 'bdb') == 0
+assert (u'a' in 'bdba') == 1
+assert (u'a' in ('a',1,None)) == 1
+assert (u'a' in (1,None,'a')) == 1
+assert (u'a' in (1,None,u'a')) == 1
+assert ('a' in ('a',1,None)) == 1
+assert ('a' in (1,None,'a')) == 1
+assert ('a' in (1,None,u'a')) == 1
+assert ('a' in ('x',1,u'y')) == 0
+assert ('a' in ('x',1,None)) == 0
+print 'done.'
+
+# Formatting:
+print 'Testing Unicode formatting strings...',
+assert u"%s, %s" % (u"abc", "abc") == u'abc, abc'
+assert u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", 1, 2, 3) == u'abc, abc, 1, 2.000000,  3.00'
+assert u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", 1, -2, 3) == u'abc, abc, 1, -2.000000,  3.00'
+assert u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 3.5) == u'abc, abc, -1, -2.000000,  3.50'
+assert u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 3.57) == u'abc, abc, -1, -2.000000,  3.57'
+assert u"%s, %s, %i, %f, %5.2f" % (u"abc", "abc", -1, -2, 1003.57) == u'abc, abc, -1, -2.000000, 1003.57'
+assert u"%c" % (u"a",) == u'a'
+assert u"%c" % ("a",) == u'a'
+assert u"%c" % (34,) == u'"'
+assert u"%c" % (36,) == u'$'
+value = u"%r, %r" % (u"abc", "abc") 
+if value != u"u'abc', 'abc'":
+    print '*** formatting failed for "%s"' % 'u"%r, %r" % (u"abc", "abc")'
+
+assert u"%(x)s, %(y)s" % {'x':u"abc", 'y':"def"} == u'abc, def'
+try:
+    value = u"%(x)s, %(ä)s" % {'x':u"abc", u'ä'.encode('utf-8'):"def"} 
+except KeyError:
+    print '*** formatting failed for "%s"' % "u'abc, def'"
+else:
+    assert value == u'abc, def'
+
+# formatting jobs delegated from the string implementation:
+assert '...%(foo)s...' % {'foo':u"abc"} == u'...abc...'
+assert '...%(foo)s...' % {'foo':"abc"} == '...abc...'
+assert '...%(foo)s...' % {u'foo':"abc"} == '...abc...'
+assert '...%(foo)s...' % {u'foo':u"abc"} == u'...abc...'
+assert '...%(foo)s...' % {u'foo':u"abc",'def':123} ==  u'...abc...'
+assert '...%(foo)s...' % {u'foo':u"abc",u'def':123} == u'...abc...'
+assert '...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...1...2...3...abc...'
+assert '...%s...' % u"abc" == u'...abc...'
+print 'done.'
+
+# Test builtin codecs
+print 'Testing builtin codecs...',
+
+# UTF-8 specific encoding tests:
+assert u'\u20ac'.encode('utf-8') == \
+       ''.join((chr(0xe2), chr(0x82), chr(0xac)))
+assert u'\ud800\udc02'.encode('utf-8') == \
+       ''.join((chr(0xf0), chr(0x90), chr(0x80), chr(0x82)))
+assert u'\ud84d\udc56'.encode('utf-8') == \
+       ''.join((chr(0xf0), chr(0xa3), chr(0x91), chr(0x96)))
+# UTF-8 specific decoding tests
+assert unicode(''.join((chr(0xf0), chr(0xa3), chr(0x91), chr(0x96))),
+               'utf-8') == u'\ud84d\udc56'
+assert unicode(''.join((chr(0xf0), chr(0x90), chr(0x80), chr(0x82))),
+               'utf-8') == u'\ud800\udc02'
+assert unicode(''.join((chr(0xe2), chr(0x82), chr(0xac))),
+               'utf-8') == u'\u20ac'
+
+# Other possible utf-8 test cases:
+# * strict decoding testing for all of the
+#   UTF8_ERROR cases in PyUnicode_DecodeUTF8
+
+
+
+assert unicode('hello','ascii') == u'hello'
+assert unicode('hello','utf-8') == u'hello'
+assert unicode('hello','utf8') == u'hello'
+assert unicode('hello','latin-1') == u'hello'
+
+class String:
+    x = ''
+    def __str__(self):
+        return self.x
+
+o = String()
+
+o.x = 'abc'
+assert unicode(o) == u'abc'
+assert str(o) == 'abc'
+
+o.x = u'abc'
+assert unicode(o) == u'abc'
+assert str(o) == 'abc'
+
+try:
+    u'Andr\202 x'.encode('ascii')
+    u'Andr\202 x'.encode('ascii','strict')
+except ValueError:
+    pass
+else:
+    raise AssertionError, "u'Andr\202'.encode('ascii') failed to raise an exception"
+assert u'Andr\202 x'.encode('ascii','ignore') == "Andr x"
+assert u'Andr\202 x'.encode('ascii','replace') == "Andr? x"
+
+try:
+    unicode('Andr\202 x','ascii')
+    unicode('Andr\202 x','ascii','strict')
+except ValueError:
+    pass
+else:
+    raise AssertionError, "unicode('Andr\202') failed to raise an exception"
+assert unicode('Andr\202 x','ascii','ignore') == u"Andr x"
+assert unicode('Andr\202 x','ascii','replace') == u'Andr\uFFFD x'
+
+assert u'hello'.encode('ascii') == 'hello'
+assert u'hello'.encode('utf-8') == 'hello'
+assert u'hello'.encode('utf8') == 'hello'
+assert u'hello'.encode('utf-16-le') == 'h\000e\000l\000l\000o\000'
+assert u'hello'.encode('utf-16-be') == '\000h\000e\000l\000l\000o'
+assert u'hello'.encode('latin-1') == 'hello'
+
+u = u''.join(map(unichr, range(1024)))
+for encoding in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be',
+                 'raw_unicode_escape', 'unicode_escape', 'unicode_internal'):
+    assert unicode(u.encode(encoding),encoding) == u
+
+u = u''.join(map(unichr, range(256)))
+for encoding in (
+    'latin-1',
+    ):
+    try:
+        assert unicode(u.encode(encoding),encoding) == u
+    except AssertionError:
+        print '*** codec "%s" failed round-trip' % encoding
+    except ValueError,why:
+        print '*** codec for "%s" failed: %s' % (encoding, why)
+
+u = u''.join(map(unichr, range(128)))
+for encoding in (
+    'ascii',
+    ):
+    try:
+        assert unicode(u.encode(encoding),encoding) == u
+    except AssertionError:
+        print '*** codec "%s" failed round-trip' % encoding
+    except ValueError,why:
+        print '*** codec for "%s" failed: %s' % (encoding, why)
 
 print 'done.'
+
+print 'Testing standard mapping codecs...',
+
+print '0-127...',
+s = ''.join(map(chr, range(128)))
+for encoding in (
+    'cp037', 'cp1026',
+    'cp437', 'cp500', 'cp737', 'cp775', 'cp850',
+    'cp852', 'cp855', 'cp860', 'cp861', 'cp862',
+    'cp863', 'cp865', 'cp866', 
+    'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15',
+    'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6',
+    'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1',
+    'mac_cyrillic', 'mac_latin2',
+
+    'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255',
+    'cp1256', 'cp1257', 'cp1258',
+    'cp856', 'cp857', 'cp864', 'cp869', 'cp874',
+
+    'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish',
+    'cp1006', 'cp875', 'iso8859_8',
+    
+    ### These have undefined mappings:
+    #'cp424',
+    
+    ):
+    try:
+        assert unicode(s,encoding).encode(encoding) == s
+    except AssertionError:
+        print '*** codec "%s" failed round-trip' % encoding
+    except ValueError,why:
+        print '*** codec for "%s" failed: %s' % (encoding, why)
+
+print '128-255...',
+s = ''.join(map(chr, range(128,256)))
+for encoding in (
+    'cp037', 'cp1026',
+    'cp437', 'cp500', 'cp737', 'cp775', 'cp850',
+    'cp852', 'cp855', 'cp860', 'cp861', 'cp862',
+    'cp863', 'cp865', 'cp866', 
+    'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15',
+    'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6',
+    'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1',
+    'mac_cyrillic', 'mac_latin2',
+    
+    ### These have undefined mappings:
+    #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255',
+    #'cp1256', 'cp1257', 'cp1258',
+    #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874',
+    #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish',
+    
+    ### These fail the round-trip:
+    #'cp1006', 'cp875', 'iso8859_8',
+    
+    ):
+    try:
+        assert unicode(s,encoding).encode(encoding) == s
+    except AssertionError:
+        print '*** codec "%s" failed round-trip' % encoding
+    except ValueError,why:
+        print '*** codec for "%s" failed: %s' % (encoding, why)
+
+print 'done.'
+
+print 'Testing Unicode string concatenation...',
+assert (u"abc" u"def") == u"abcdef"
+assert ("abc" u"def") == u"abcdef"
+assert (u"abc" "def") == u"abcdef"
+assert (u"abc" u"def" "ghi") == u"abcdefghi"
+assert ("abc" "def" u"ghi") == u"abcdefghi"
+print 'done.'
+
diff --git a/Lib/dos-8x3/test_unp.py b/Lib/dos-8x3/test_unp.py
index 1bfd478..25324c0 100644
--- a/Lib/dos-8x3/test_unp.py
+++ b/Lib/dos-8x3/test_unp.py
@@ -100,7 +100,8 @@
 
 # unpacking a sequence where the test for too long raises a different
 # kind of error
-BozoError = 'BozoError'
+class BozoError(Exception):
+    pass
 
 class BadSeq:
     def __getitem__(self, i):
diff --git a/Lib/dos-8x3/test_use.py b/Lib/dos-8x3/test_use.py
index c12f1e2..63632f7 100644
--- a/Lib/dos-8x3/test_use.py
+++ b/Lib/dos-8x3/test_use.py
@@ -1,227 +1,101 @@
-#!/usr/bin/env python
-import sys, string
-from test_support import verbose
-# UserString is a wrapper around the native builtin string type.
-# UserString instances should behave similar to builtin string objects.
-# The test cases were in part derived from 'test_string.py'.
-from UserString import UserString
+# Check every path through every method of UserDict
 
-if __name__ == "__main__":
-    verbose = 0
+from UserDict import UserDict
 
-tested_methods = {}
+d0 = {}
+d1 = {"one": 1}
+d2 = {"one": 1, "two": 2}
 
-def test(methodname, input, *args):
-    global tested_methods
-    tested_methods[methodname] = 1
-    if verbose:
-        print '%s.%s(%s) ' % (input, methodname, args),
-    u = UserString(input)
-    objects = [input, u, UserString(u)]
-    res = [""] * 3
-    for i in range(3):
-        object = objects[i]
-        try:
-            f = getattr(object, methodname)
-            res[i] = apply(f, args)
-        except:
-            res[i] = sys.exc_type
-    if res[0] != res[1]:
-        if verbose:
-            print 'no'
-        print `input`, f, `res[0]`, "<>", `res[1]`
-    else:
-        if verbose:
-            print 'yes'
-    if res[1] != res[2]:
-        if verbose:
-            print 'no'
-        print `input`, f, `res[1]`, "<>", `res[2]`
-    else:
-        if verbose:
-            print 'yes'
+# Test constructors
 
-test('capitalize', ' hello ')
-test('capitalize', 'hello ')
+u = UserDict()
+u0 = UserDict(d0)
+u1 = UserDict(d1)
+u2 = UserDict(d2)
 
-test('center', 'foo', 0)
-test('center', 'foo', 3)
-test('center', 'foo', 16)
+uu = UserDict(u)
+uu0 = UserDict(u0)
+uu1 = UserDict(u1)
+uu2 = UserDict(u2)
 
-test('ljust', 'foo', 0)
-test('ljust', 'foo', 3)
-test('ljust', 'foo', 16)
+# Test __repr__
 
-test('rjust', 'foo', 0)
-test('rjust', 'foo', 3)
-test('rjust', 'foo', 16)
+assert str(u0) == str(d0)
+assert repr(u1) == repr(d1)
+assert `u2` == `d2`
 
-test('count', 'abcabcabc', 'abc')
-test('count', 'abcabcabc', 'abc', 1)
-test('count', 'abcabcabc', 'abc', -1)
-test('count', 'abcabcabc', 'abc', 7)
-test('count', 'abcabcabc', 'abc', 0, 3)
-test('count', 'abcabcabc', 'abc', 0, 333)
+# Test __cmp__ and __len__
 
-test('find', 'abcdefghiabc', 'abc')
-test('find', 'abcdefghiabc', 'abc', 1)
-test('find', 'abcdefghiabc', 'def', 4)
-test('rfind', 'abcdefghiabc', 'abc')
+all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
+for a in all:
+    for b in all:
+        assert cmp(a, b) == cmp(len(a), len(b))
 
-test('index', 'abcabcabc', 'abc')
-test('index', 'abcabcabc', 'abc', 1)
-test('index', 'abcabcabc', 'abc', -1)
-test('index', 'abcabcabc', 'abc', 7)
-test('index', 'abcabcabc', 'abc', 0, 3)
-test('index', 'abcabcabc', 'abc', 0, 333)
+# Test __getitem__
 
-test('rindex', 'abcabcabc', 'abc')
-test('rindex', 'abcabcabc', 'abc', 1)
-test('rindex', 'abcabcabc', 'abc', -1)
-test('rindex', 'abcabcabc', 'abc', 7)
-test('rindex', 'abcabcabc', 'abc', 0, 3)
-test('rindex', 'abcabcabc', 'abc', 0, 333)
+assert u2["one"] == 1
+try:
+    u1["two"]
+except KeyError:
+    pass
+else:
+    assert 0, "u1['two'] shouldn't exist"
 
+# Test __setitem__
 
-test('lower', 'HeLLo')
-test('lower', 'hello')
-test('upper', 'HeLLo')
-test('upper', 'HELLO')
+u3 = UserDict(u2)
+u3["two"] = 2
+u3["three"] = 3
 
-test('title', ' hello ')
-test('title', 'hello ')
-test('title', "fOrMaT thIs aS titLe String")
-test('title', "fOrMaT,thIs-aS*titLe;String")
-test('title', "getInt")
+# Test __delitem__
 
-test('expandtabs', 'abc\rab\tdef\ng\thi')
-test('expandtabs', 'abc\rab\tdef\ng\thi', 8)
-test('expandtabs', 'abc\rab\tdef\ng\thi', 4)
-test('expandtabs', 'abc\r\nab\tdef\ng\thi', 4)
+del u3["three"]
+try:
+    del u3["three"]
+except KeyError:
+    pass
+else:
+    assert 0, "u3['three'] shouldn't exist"
 
-test('islower', 'a')
-test('islower', 'A')
-test('islower', '\n')
-test('islower', 'abc')
-test('islower', 'aBc')
-test('islower', 'abc\n')
+# Test clear
 
-test('isupper', 'a')
-test('isupper', 'A')
-test('isupper', '\n')
-test('isupper', 'ABC')
-test('isupper', 'AbC')
-test('isupper', 'ABC\n')
+u3.clear()
+assert u3 == {}
 
-test('isdigit', '  0123456789')
-test('isdigit', '56789')
-test('isdigit', '567.89')
-test('isdigit', '0123456789abc')
+# Test copy()
 
-test('isspace', '')
-test('isspace', ' ')
-test('isspace', ' \t')
-test('isspace', ' \t\f\n')
+u2a = u2.copy()
+assert u2a == u2
 
-test('istitle', 'a')
-test('istitle', 'A')
-test('istitle', '\n')
-test('istitle', 'A Titlecased Line')
-test('istitle', 'A\nTitlecased Line')
-test('istitle', 'A Titlecased, Line')
-test('istitle', 'Not a capitalized String')
-test('istitle', 'Not\ta Titlecase String')
-test('istitle', 'Not--a Titlecase String')
+class MyUserDict(UserDict):
+    def display(self): print self
 
-test('splitlines', "abc\ndef\n\rghi")
-test('splitlines', "abc\ndef\n\r\nghi")
-test('splitlines', "abc\ndef\r\nghi")
-test('splitlines', "abc\ndef\r\nghi\n")
-test('splitlines', "abc\ndef\r\nghi\n\r")
-test('splitlines', "\nabc\ndef\r\nghi\n\r")
-test('splitlines', "\nabc\ndef\r\nghi\n\r")
-test('splitlines', "\nabc\ndef\r\nghi\n\r")
+m2 = MyUserDict(u2)
+m2a = m2.copy()
+assert m2a == m2
 
-test('split', 'this is the split function')
-test('split', 'a|b|c|d', '|')
-test('split', 'a|b|c|d', '|', 2)
-test('split', 'a b c d', None, 1)
-test('split', 'a b c d', None, 2)
-test('split', 'a b c d', None, 3)
-test('split', 'a b c d', None, 4)
-test('split', 'a b c d', None, 0)
-test('split', 'a  b  c  d', None, 2)
-test('split', 'a b c d ')
+# Test keys, items, values
 
-# join now works with any sequence type
-class Sequence:
-    def __init__(self): self.seq = 'wxyz'
-    def __len__(self): return len(self.seq)
-    def __getitem__(self, i): return self.seq[i]
+assert u2.keys() == d2.keys()
+assert u2.items() == d2.items()
+assert u2.values() == d2.values()
 
-test('join', '', ('a', 'b', 'c', 'd'))
-test('join', '', Sequence())
-test('join', '', 7)
+# Test has_key
 
-class BadSeq(Sequence):
-    def __init__(self): self.seq = [7, 'hello', 123L]
+for i in u2.keys():
+    assert u2.has_key(i) == 1
+    assert u1.has_key(i) == d1.has_key(i)
+    assert u0.has_key(i) == d0.has_key(i)
 
-test('join', '', BadSeq())
+# Test update
 
-test('strip', '   hello   ')
-test('lstrip', '   hello   ')
-test('rstrip', '   hello   ')
-test('strip', 'hello')
+t = UserDict()
+t.update(u2)
+assert t == u2
 
-test('swapcase', 'HeLLo cOmpUteRs')
-transtable = string.maketrans("abc", "xyz")
-test('translate', 'xyzabcdef', transtable, 'def')
+# Test get
 
-transtable = string.maketrans('a', 'A')
-test('translate', 'abc', transtable)
-test('translate', 'xyz', transtable)
-
-test('replace', 'one!two!three!', '!', '@', 1)
-test('replace', 'one!two!three!', '!', '')
-test('replace', 'one!two!three!', '!', '@', 2)
-test('replace', 'one!two!three!', '!', '@', 3)
-test('replace', 'one!two!three!', '!', '@', 4)
-test('replace', 'one!two!three!', '!', '@', 0)
-test('replace', 'one!two!three!', '!', '@')
-test('replace', 'one!two!three!', 'x', '@')
-test('replace', 'one!two!three!', 'x', '@', 2)
-
-test('startswith', 'hello', 'he')
-test('startswith', 'hello', 'hello')
-test('startswith', 'hello', 'hello world')
-test('startswith', 'hello', '')
-test('startswith', 'hello', 'ello')
-test('startswith', 'hello', 'ello', 1)
-test('startswith', 'hello', 'o', 4)
-test('startswith', 'hello', 'o', 5)
-test('startswith', 'hello', '', 5)
-test('startswith', 'hello', 'lo', 6)
-test('startswith', 'helloworld', 'lowo', 3)
-test('startswith', 'helloworld', 'lowo', 3, 7)
-test('startswith', 'helloworld', 'lowo', 3, 6)
-
-test('endswith', 'hello', 'lo')
-test('endswith', 'hello', 'he')
-test('endswith', 'hello', '')
-test('endswith', 'hello', 'hello world')
-test('endswith', 'helloworld', 'worl')
-test('endswith', 'helloworld', 'worl', 3, 9)
-test('endswith', 'helloworld', 'world', 3, 12)
-test('endswith', 'helloworld', 'lowo', 1, 7)
-test('endswith', 'helloworld', 'lowo', 2, 7)
-test('endswith', 'helloworld', 'lowo', 3, 7)
-test('endswith', 'helloworld', 'lowo', 4, 7)
-test('endswith', 'helloworld', 'lowo', 3, 8)
-test('endswith', 'ab', 'ab', 0, 1)
-test('endswith', 'ab', 'ab', 0, 0)
-
-# TODO: test cases for: int, long, float, complex, +, * and cmp
-s = ""
-for builtin_method in dir(s):
-    if not tested_methods.has_key(builtin_method):
-        print "no regression test case for method '"+builtin_method+"'"
+for i in u2.keys():
+    assert u2.get(i) == u2[i]
+    assert u1.get(i) == d1.get(i)
+    assert u0.get(i) == d0.get(i)
diff --git a/Lib/dos-8x3/threadin.py b/Lib/dos-8x3/threadin.py
index fb2eb21..4921f0e 100644
--- a/Lib/dos-8x3/threadin.py
+++ b/Lib/dos-8x3/threadin.py
@@ -462,11 +462,8 @@
         _active_limbo_lock.acquire()
         _active[_get_ident()] = self
         _active_limbo_lock.release()
-        try:
-            self.__oldexitfunc = _sys.exitfunc
-        except AttributeError:
-            self.__oldexitfunc = None
-        _sys.exitfunc = self.__exitfunc
+        import atexit
+        atexit.register(self.__exitfunc)
 
     def _set_daemon(self):
         return 0
@@ -480,10 +477,6 @@
         while t:
             t.join()
             t = _pickSomeNonDaemonThread()
-        if self.__oldexitfunc:
-            if __debug__:
-                self._note("%s: calling exit handler", self)
-            self.__oldexitfunc()
         if __debug__:
             self._note("%s: exiting", self)
         self._Thread__delete()
diff --git a/Lib/dos-8x3/tracebac.py b/Lib/dos-8x3/tracebac.py
index d219340..b733598 100755
--- a/Lib/dos-8x3/tracebac.py
+++ b/Lib/dos-8x3/tracebac.py
@@ -166,9 +166,15 @@
 						s = s + ' '
 				list.append('%s^\n' % s)
 				value = msg
-		list.append('%s: %s\n' % (str(stype), str(value)))
+		list.append('%s: %s\n' % (str(stype), _some_str(value)))
 	return list
 
+def _some_str(value):
+	try:
+		return str(value)
+	except:
+		return '<unprintable %s object>' % type(value).__name__
+
 
 def print_exc(limit=None, file=None):
 	"""This is a shorthand for 'print_exception(sys.exc_type,
diff --git a/Lib/dos-8x3/userdict.py b/Lib/dos-8x3/userdict.py
index 3c48415..9b6e73b 100755
--- a/Lib/dos-8x3/userdict.py
+++ b/Lib/dos-8x3/userdict.py
@@ -34,3 +34,7 @@
                 self.data[k] = v
     def get(self, key, failobj=None):
         return self.data.get(key, failobj)
+    def setdefault(self, key, failobj=None):
+        if not self.data.has_key(key):
+            self.data[key] = failobj
+        return self.data[key]
diff --git a/Lib/dos-8x3/userlist.py b/Lib/dos-8x3/userlist.py
index d4a8d2f..1146060 100755
--- a/Lib/dos-8x3/userlist.py
+++ b/Lib/dos-8x3/userlist.py
@@ -51,9 +51,20 @@
             return self.__class__(other + self.data)
         else:
             return self.__class__(list(other) + self.data)
+    def __iadd__(self, other):
+        if isinstance(other, UserList):
+            self.data += other.data
+        elif isinstance(other, type(self.data)):
+            self.data += other
+        else:
+            self.data += list(other)
+        return self
     def __mul__(self, n):
         return self.__class__(self.data*n)
     __rmul__ = __mul__
+    def __imul__(self, n):
+        self.data *= n
+        return self
     def append(self, item): self.data.append(item)
     def insert(self, i, item): self.data.insert(i, item)
     def pop(self, i=-1): return self.data.pop(i)
diff --git a/Lib/dos-8x3/userstri.py b/Lib/dos-8x3/userstri.py
index 528065e..ea3d515 100644
--- a/Lib/dos-8x3/userstri.py
+++ b/Lib/dos-8x3/userstri.py
@@ -50,9 +50,20 @@
             return self.__class__(other + self.data)
         else:
             return self.__class__(str(other) + self.data)
+    def __iadd__(self, other):
+        if isinstance(other, UserString):
+            self.data += other.data
+        elif isinstance(other, StringType) or isinstance(other, UnicodeType):
+            self.data += other
+        else:
+            self.data += str(other)
+        return self
     def __mul__(self, n):
         return self.__class__(self.data*n)
     __rmul__ = __mul__
+    def __imull__(self, n):
+        self.data += n
+        return self
 
     # the following methods are defined in alphabetical order:
     def capitalize(self): return self.__class__(self.data.capitalize())
@@ -75,6 +86,8 @@
         return self.data.find(sub, start, end)
     def index(self, sub, start=0, end=sys.maxint): 
         return self.data.index(sub, start, end)
+    def isalpha(self): return self.data.isalpha()
+    def isalnum(self): return self.data.isalnum()
     def isdecimal(self): return self.data.isdecimal()
     def isdigit(self): return self.data.isdigit()
     def islower(self): return self.data.islower()
@@ -102,8 +115,8 @@
     def strip(self): return self.__class__(self.data.strip())
     def swapcase(self): return self.__class__(self.data.swapcase())
     def title(self): return self.__class__(self.data.title())
-    def translate(self, table, deletechars=""): 
-        return self.__class__(self.data.translate(table, deletechars))
+    def translate(self, *args): 
+        return self.__class__(self.data.translate(*args))
     def upper(self): return self.__class__(self.data.upper())
 
 class MutableString(UserString):