[Python-checkins] CVS: python/dist/src/Lib/dos-8x3 mimepars.py,NONE,1.1 rfc822-n.py,NONE,1.1 robotpar.py,NONE,1.1 sre_comp.py,NONE,1.1 sre_cons.py,NONE,1.1 sre_pars.py,NONE,1.1 stringol.py,NONE,1.1 test_con.py,NONE,1.1 test_ext.py,NONE,1.1 test_for.py,NONE,1.1 test_mma.py,NONE,1.1 test_pye.py,NONE,1.1 test_uni.py,NONE,1.1 test_win.py,NONE,1.1 test_zip.py,NONE,1.1 threadst.py,NONE,1.1 userstri.py,NONE,1.1 basehttp.py,1.4,1.5 cgihttps.py,1.6,1.7 configpa.py,1.5,1.6 exceptio.py,1.7,1.8 fileinpu.py,1.3,1.4 formatte.py,1.8,1.9 gopherli.py,1.2,1.3 htmlenti.py,1.1,1.2 linecach.py,1.1,1.2 macurl2p.py,1.5,1.6 mimetool.py,1.6,1.7 mimetype.py,1.5,1.6 multifil.py,1.3,1.4 nturl2pa.py,1.3,1.4 posixfil.py,1.7,1.8 posixpat.py,1.9,1.10 py_compi.py,1.8,1.9 queue.py,1.6,1.7 regex_sy.py,1.2,1.3 rlcomple.py,1.4,1.5 simpleht.py,1.4,1.5 socketse.py,1.8,1.9 statcach.py,1.1,1.2 stringio.py,1.3,1.4 telnetli.py,1.3,1.4 test_bin.py,1.2,1.3 test_cpi.py,1.1,1.2 test_fcn.py,1.5,1.6 test_gdb.py,1.1,1.2 test_gra.py,! 1.2,1.3 test_lon.py,1.1,1.2 test_rfc.py,1.1,1.2 test_soc.py,1.5,1.6 test_typ.py,1.6,1.7 test_zli.py,1.4,1.5 threadin.py,1.1,1.2 tracebac.py,1.6,1.7 userdict.py,1.5,1.6 userlist.py,1.5,1.6

Guido van Rossum python-dev@python.org
Mon, 8 May 2000 13:31:13 -0400 (EDT)


Update of /projects/cvsroot/python/dist/src/Lib/dos-8x3
In directory eric:/projects/python/develop/guido/src/Lib/dos-8x3

Modified Files:
	basehttp.py cgihttps.py configpa.py exceptio.py fileinpu.py 
	formatte.py gopherli.py htmlenti.py linecach.py macurl2p.py 
	mimetool.py mimetype.py multifil.py nturl2pa.py posixfil.py 
	posixpat.py py_compi.py queue.py regex_sy.py rlcomple.py 
	simpleht.py socketse.py statcach.py stringio.py telnetli.py 
	test_bin.py test_cpi.py test_fcn.py test_gdb.py test_gra.py 
	test_lon.py test_rfc.py test_soc.py test_typ.py test_zli.py 
	threadin.py tracebac.py userdict.py userlist.py 
Added Files:
	mimepars.py rfc822-n.py robotpar.py sre_comp.py sre_cons.py 
	sre_pars.py stringol.py test_con.py test_ext.py test_for.py 
	test_mma.py test_pye.py test_uni.py test_win.py test_zip.py 
	threadst.py userstri.py 
Log Message:
The usual...


















Index: basehttp.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/basehttp.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** basehttp.py	1999/04/08 20:27:39	1.4
--- basehttp.py	2000/05/08 17:30:59	1.5
***************
*** 69,73 ****
  import socket # For gethostbyaddr()
  import string
- import rfc822
  import mimetools
  import SocketServer
--- 69,72 ----
***************
*** 95,104 ****
          if not host or host == '0.0.0.0':
              host = socket.gethostname()
!         hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)
!         if '.' not in hostname:
!             for host in hostnames:
!                 if '.' in host:
!                     hostname = host
!                     break
          self.server_name = hostname
          self.server_port = port
--- 94,107 ----
          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_port = port
***************
*** 170,174 ****
      This server parses the request and the headers, and then calls a
      function specific to the request type (<command>).  Specifically,
!     a request SPAM will be handled by a method handle_SPAM().  If no
      such method exists the server sends an error response to the
      client.  If it exists, it is called with no arguments:
--- 173,177 ----
      This server parses the request and the headers, and then calls a
      function specific to the request type (<command>).  Specifically,
!     a request SPAM will be handled by a method do_SPAM().  If no
      such method exists the server sends an error response to the
      client.  If it exists, it is called with no arguments:
***************
*** 217,230 ****
      server_version = "BaseHTTP/" + __version__
  
!     def handle(self):
!         """Handle a single HTTP request.
  
!         You normally don't need to override this method; see the class
!         __doc__ string for information on how to handle specific HTTP
!         commands such as GET and POST.
  
!         """
  
!         self.raw_requestline = self.rfile.readline()
          self.request_version = version = "HTTP/0.9" # Default
          requestline = self.raw_requestline
--- 220,234 ----
      server_version = "BaseHTTP/" + __version__
  
!     def parse_request(self):
!         """Parse a request (internal).
  
!         The request should be stored in self.raw_request; the results
!         are in self.command, self.path, self.request_version and
!         self.headers.
  
!         Return value is 1 for success, 0 for failure; on failure, an
!         error is sent back.
  
!         """
          self.request_version = version = "HTTP/0.9" # Default
          requestline = self.raw_requestline
***************
*** 239,243 ****
              if version[:5] != 'HTTP/':
                  self.send_error(400, "Bad request version (%s)" % `version`)
!                 return
          elif len(words) == 2:
              [command, path] = words
--- 243,247 ----
              if version[:5] != 'HTTP/':
                  self.send_error(400, "Bad request version (%s)" % `version`)
!                 return 0
          elif len(words) == 2:
              [command, path] = words
***************
*** 245,257 ****
                  self.send_error(400,
                                  "Bad HTTP/0.9 request type (%s)" % `command`)
!                 return
          else:
              self.send_error(400, "Bad request syntax (%s)" % `requestline`)
!             return
          self.command, self.path, self.request_version = command, path, version
          self.headers = self.MessageClass(self.rfile, 0)
!         mname = 'do_' + command
          if not hasattr(self, mname):
!             self.send_error(501, "Unsupported method (%s)" % `command`)
              return
          method = getattr(self, mname)
--- 249,275 ----
                  self.send_error(400,
                                  "Bad HTTP/0.9 request type (%s)" % `command`)
!                 return 0
          else:
              self.send_error(400, "Bad request syntax (%s)" % `requestline`)
!             return 0
          self.command, self.path, self.request_version = command, path, version
          self.headers = self.MessageClass(self.rfile, 0)
!         return 1
! 
!     def handle(self):
!         """Handle a single HTTP request.
! 
!         You normally don't need to override this method; see the class
!         __doc__ string for information on how to handle specific HTTP
!         commands such as GET and POST.
! 
!         """
! 
!         self.raw_requestline = self.rfile.readline()
!         if not self.parse_request(): # An error code has been sent, just exit
!             return
!         mname = 'do_' + self.command
          if not hasattr(self, mname):
!             self.send_error(501, "Unsupported method (%s)" % `self.command`)
              return
          method = getattr(self, mname)

Index: cgihttps.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/cgihttps.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** cgihttps.py	1998/12/22 13:50:29	1.6
--- cgihttps.py	2000/05/08 17:30:59	1.7
***************
*** 4,7 ****
--- 4,10 ----
  requests to cgi-bin scripts.
  
+ If the os.fork() function is not present, this module will not work;
+ SystemError will be raised instead.
+ 
  """
  
***************
*** 11,17 ****
  
  import os
- import sys
- import time
- import socket
  import string
  import urllib
--- 14,17 ----
***************
*** 20,23 ****
--- 20,29 ----
  
  
+ try:
+     os.fork
+ except AttributeError:
+     raise SystemError, __name__ + " requires os.fork()"
+ 
+ 
  class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  
***************
*** 151,154 ****
--- 157,163 ----
              if ua:
                  env['HTTP_USER_AGENT'] = ua
+             co = filter(None, self.headers.getheaders('cookie'))
+             if co:
+                 env['HTTP_COOKIE'] = string.join(co, ', ')
              # XXX Other HTTP_* headers
              decoded_query = string.replace(query, '+', ' ')
***************
*** 178,182 ****
      try:
          nobody = pwd.getpwnam('nobody')[2]
!     except pwd.error:
          nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
      return nobody
--- 187,191 ----
      try:
          nobody = pwd.getpwnam('nobody')[2]
!     except KeyError:
          nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
      return nobody

Index: configpa.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/configpa.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** configpa.py	1999/02/16 20:05:33	1.5
--- configpa.py	2000/05/08 17:30:59	1.6
***************
*** 34,42 ****
          return all the configuration section names, sans DEFAULT
  
      options(section)
          return list of configuration options for the named section
  
      read(filenames)
!         read and parse the list of named configuration files
  
      get(section, option, raw=0, vars=None)
--- 34,55 ----
          return all the configuration section names, sans DEFAULT
  
+     has_section(section)
+         return whether the given section exists
+ 
      options(section)
          return list of configuration options for the named section
  
+     has_option(section, option)
+         return whether the given section has the given option
+ 
      read(filenames)
!         read and parse the list of named configuration files, given by
!         name.  A single filename is also allowed.  Non-existing files
!         are ignored.
! 
!     readfp(fp, filename=None)
!         read and parse one configuration file, given as a file object.
!         The filename defaults to fp.name; it is only used in error
!         messages (if fp has no `name' attribute, the string `<???>' is used).
  
      get(section, option, raw=0, vars=None)
***************
*** 159,162 ****
--- 172,176 ----
  
      def options(self, section):
+         """Return a list of option names for the given section name."""
          try:
              opts = self.__sections[section].copy()
***************
*** 166,180 ****
          return opts.keys()
  
      def read(self, filenames):
!         """Read and parse a list of filenames."""
          if type(filenames) is type(''):
              filenames = [filenames]
!         for file in filenames:
              try:
!                 fp = open(file, 'r')
!                 self.__read(fp)
              except IOError:
!                 pass
  
      def get(self, section, option, raw=0, vars=None):
          """Get an option value for a given section.
--- 180,227 ----
          return opts.keys()
  
+     def has_option(self, section, option):
+         """Return whether the given section has the given option."""
+         try:
+             opts = self.__sections[section]
+         except KeyError:
+             raise NoSectionError(section)
+         return opts.has_key(option)
+ 
      def read(self, filenames):
!         """Read and parse a filename or a list of filenames.
!         
!         Files that cannot be opened are silently ignored; this is
!         designed so that you can specify a list of potential
!         configuration file locations (e.g. current directory, user's
!         home directory, systemwide directory), and all existing
!         configuration files in the list will be read.  A single
!         filename may also be given.
!         """
          if type(filenames) is type(''):
              filenames = [filenames]
!         for filename in filenames:
              try:
!                 fp = open(filename)
              except IOError:
!                 continue
!             self.__read(fp, filename)
!             fp.close()
! 
!     def readfp(self, fp, filename=None):
!         """Like read() but the argument must be a file-like object.
  
+         The `fp' argument must have a `readline' method.  Optional
+         second argument is the `filename', which if not given, is
+         taken from fp.name.  If fp has no `name' attribute, `<???>' is
+         used.
+ 
+         """
+         if filename is None:
+             try:
+                 filename = fp.name
+             except AttributeError:
+                 filename = '<???>'
+         self.__read(fp, filename)
+ 
      def get(self, section, option, raw=0, vars=None):
          """Get an option value for a given section.
***************
*** 200,204 ****
          if vars:
              d.update(vars)
!         option = string.lower(option)
          try:
              rawval = d[option]
--- 247,251 ----
          if vars:
              d.update(vars)
!         option = self.optionxform(option)
          try:
              rawval = d[option]
***************
*** 213,217 ****
          while depth < 10:               # Loop through this until it's done
              depth = depth + 1
!             if not string.find(value, "%("):
                  try:
                      value = value % d
--- 260,264 ----
          while depth < 10:               # Loop through this until it's done
              depth = depth + 1
!             if string.find(value, "%(") >= 0:
                  try:
                      value = value % d
***************
*** 237,252 ****
          return val
  
      #
      # Regular expressions for parsing section headers and options.  Note a
      # slight semantic change from the previous version, because of the use
      # of \w, _ is allowed in section header names.
!     __SECTCRE = re.compile(
          r'\['                                 # [
!         r'(?P<header>[-\w]+)'                 # `-', `_' or any alphanum
          r'\]'                                 # ]
          )
!     __OPTCRE = re.compile(
!         r'(?P<option>[-.\w]+)'                # - . _ alphanum
!         r'[ \t]*[:=][ \t]*'                   # any number of space/tab,
                                                # followed by separator
                                                # (either : or =), followed
--- 284,302 ----
          return val
  
+     def optionxform(self, optionstr):
+         return string.lower(optionstr)
+ 
      #
      # Regular expressions for parsing section headers and options.  Note a
      # slight semantic change from the previous version, because of the use
      # of \w, _ is allowed in section header names.
!     SECTCRE = re.compile(
          r'\['                                 # [
!         r'(?P<header>[-\w_.*,(){}]+)'         # a lot of stuff found by IvL
          r'\]'                                 # ]
          )
!     OPTCRE = re.compile(
!         r'(?P<option>[-\w_.*,(){}]+)'         # a lot of stuff found by IvL
!         r'[ \t]*(?P<vi>[:=])[ \t]*'           # any number of space/tab,
                                                # followed by separator
                                                # (either : or =), followed
***************
*** 255,259 ****
          )
  
!     def __read(self, fp):
          """Parse a sectioned setup file.
  
--- 305,309 ----
          )
  
!     def __read(self, fp, fpname):
          """Parse a sectioned setup file.
  
***************
*** 278,282 ****
                  continue
              if string.lower(string.split(line)[0]) == 'rem' \
!                and line[0] == "r":      # no leading whitespace
                  continue
              # continuation line?
--- 328,332 ----
                  continue
              if string.lower(string.split(line)[0]) == 'rem' \
!                and line[0] in "rR":      # no leading whitespace
                  continue
              # continuation line?
***************
*** 288,292 ****
              else:
                  # is it a section header?
!                 mo = self.__SECTCRE.match(line)
                  if mo:
                      sectname = mo.group('header')
--- 338,342 ----
              else:
                  # is it a section header?
!                 mo = self.SECTCRE.match(line)
                  if mo:
                      sectname = mo.group('header')
***************
*** 302,312 ****
                  # no section header in the file?
                  elif cursect is None:
!                     raise MissingSectionHeaderError(fp.name, lineno, `line`)
                  # an option line?
                  else:
!                     mo = self.__OPTCRE.match(line)
                      if mo:
!                         optname, optval = mo.group('option', 'value')
                          optname = string.lower(optname)
                          optval = string.strip(optval)
                          # allow empty values
--- 352,368 ----
                  # no section header in the file?
                  elif cursect is None:
!                     raise MissingSectionHeaderError(fpname, lineno, `line`)
                  # an option line?
                  else:
!                     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
+                             pos = string.find(optval, ';')
+                             if pos and optval[pos-1] in string.whitespace:
+                                 optval = optval[:pos]
                          optval = string.strip(optval)
                          # allow empty values
***************
*** 320,324 ****
                          # list of all bogus lines
                          if not e:
!                             e = ParsingError(fp.name)
                          e.append(lineno, `line`)
          # if any parsing errors occurred, raise an exception
--- 376,380 ----
                          # list of all bogus lines
                          if not e:
!                             e = ParsingError(fpname)
                          e.append(lineno, `line`)
          # if any parsing errors occurred, raise an exception

Index: exceptio.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/exceptio.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** exceptio.py	1999/04/08 20:27:40	1.7
--- exceptio.py	2000/05/08 17:30:59	1.8
***************
*** 34,37 ****
--- 34,39 ----
        |    +-- IOError
        |    +-- OSError(*)
+       |         |
+       |         +-- WindowsError(*)
        |
        +-- EOFError
***************
*** 41,44 ****
--- 43,49 ----
        |
        +-- NameError
+       |    |
+       |    +-- UnboundLocalError(*)
+       |
        +-- AttributeError
        +-- SyntaxError
***************
*** 57,60 ****
--- 62,68 ----
        |
        +-- ValueError
+       |    |
+       |    +-- UnicodeError(*)
+       |
        +-- SystemError
        +-- MemoryError
***************
*** 137,140 ****
--- 145,152 ----
      pass
  
+ class WindowsError(OSError):
+     """MS-Windows OS system call failed."""
+     pass
+ 
  class RuntimeError(StandardError):
      """Unspecified run-time error."""
***************
*** 209,213 ****
  
  class NameError(StandardError):
!     """Name not found locally or globally."""
      pass
  
--- 221,233 ----
  
  class NameError(StandardError):
!     """Name not found globally."""
!     pass
! 
! class UnboundLocalError(NameError):
!     """Local name referenced but not bound to a value."""
!     pass
! 
! class UnicodeError(ValueError):
!     """Unicode related error."""
      pass
  

Index: fileinpu.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/fileinpu.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** fileinpu.py	1998/08/12 02:37:54	1.3
--- fileinpu.py	2000/05/08 17:31:00	1.4
***************
*** 74,82 ****
  """
  
! import sys, os
  
  _state = None
  
! def input(files=(), inplace=0, backup=""):
      global _state
      if _state and _state._file:
--- 74,82 ----
  """
  
! import sys, os, stat
  
  _state = None
  
! def input(files=None, inplace=0, backup=""):
      global _state
      if _state and _state._file:
***************
*** 124,136 ****
  class FileInput:
  
!     def __init__(self, files=(), inplace=0, backup=""):
          if type(files) == type(''):
              files = (files,)
          else:
!             files = tuple(files)
              if not files:
!                 files = tuple(sys.argv[1:])
!                 if not files:
!                     files = ('-',)
          self._files = files
          self._inplace = inplace
--- 124,137 ----
  class FileInput:
  
!     def __init__(self, files=None, inplace=0, backup=""):
          if type(files) == type(''):
              files = (files,)
          else:
!             if files is None:
!                 files = sys.argv[1:]
              if not files:
!                 files = ('-',)
!             else:
!                 files = tuple(files)
          self._files = files
          self._inplace = inplace
***************
*** 204,211 ****
                      try: os.unlink(self._backupfilename)
                      except os.error: pass
!                     # The next three lines may raise IOError
                      os.rename(self._filename, self._backupfilename)
                      self._file = open(self._backupfilename, "r")
!                     self._output = open(self._filename, "w")
                      self._savestdout = sys.stdout
                      sys.stdout = self._output
--- 205,224 ----
                      try: os.unlink(self._backupfilename)
                      except os.error: pass
!                     # The next few lines may raise IOError
                      os.rename(self._filename, self._backupfilename)
                      self._file = open(self._backupfilename, "r")
!                     try:
!                         perm = os.fstat(self._file.fileno())[stat.ST_MODE]
!                     except:
!                         self._output = open(self._filename, "w")
!                     else:
!                         fd = os.open(self._filename,
!                                      os.O_CREAT | os.O_WRONLY | os.O_TRUNC,
!                                      perm)
!                         self._output = os.fdopen(fd, "w")
!                         try:
!                             os.chmod(self._filename, perm)
!                         except:
!                             pass
                      self._savestdout = sys.stdout
                      sys.stdout = self._output

Index: formatte.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/formatte.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** formatte.py	1999/01/25 21:57:26	1.8
--- formatte.py	2000/05/08 17:31:00	1.9
***************
*** 1,2 ****
--- 1,22 ----
+ """Generic output formatting.
+ 
+ Formatter objects transform an abstract flow of formatting events into
+ specific output events on writer objects. Formatters manage several stack
+ structures to allow various properties of a writer object to be changed and
+ restored; writers need not be able to handle relative changes nor any sort
+ of ``change back'' operation. Specific writer properties which may be
+ controlled via formatter objects are horizontal alignment, font, and left
+ margin indentations. A mechanism is provided which supports providing
+ arbitrary, non-exclusive style settings to a writer as well. Additional
+ interfaces facilitate formatting events which are not reversible, such as
+ paragraph separation. 
+ 
+ Writer objects encapsulate device interfaces. Abstract devices, such as
+ file formats, are supported as well as physical devices. The provided
+ implementations all work with abstract devices. The interface makes
+ available mechanisms for setting the properties which formatter objects
+ manage and inserting data into the output. 
+ """
+ 
  import string
  import sys

Index: gopherli.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/gopherli.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** gopherli.py	1998/03/26 22:13:11	1.2
--- gopherli.py	2000/05/08 17:31:00	1.3
***************
*** 1,3 ****
! # Gopher protocol client interface
  
  import string
--- 1,3 ----
! """Gopher protocol client interface."""
  
  import string
***************
*** 30,35 ****
  A_QUERY      = 'q'
  A_GIF        = 'g'
! A_HTML       = 'h'			# HTML file
! A_WWW        = 'w'			# WWW address
  A_PLUS_IMAGE = ':'
  A_PLUS_MOVIE = ';'
--- 30,35 ----
  A_QUERY      = 'q'
  A_GIF        = 'g'
! A_HTML       = 'h'          # HTML file
! A_WWW        = 'w'          # WWW address
  A_PLUS_IMAGE = ':'
  A_PLUS_MOVIE = ';'
***************
*** 37,52 ****
  
  
- # Function mapping all file types to strings; unknown types become TYPE='x'
  _names = dir()
  _type_to_name_map = {}
  def type_to_name(gtype):
! 	global _type_to_name_map
! 	if _type_to_name_map=={}:
! 		for name in _names:
! 			if name[:2] == 'A_':
! 				_type_to_name_map[eval(name)] = name[2:]
! 	if _type_to_name_map.has_key(gtype):
! 		return _type_to_name_map[gtype]
! 	return 'TYPE=' + `gtype`
  
  # Names for characters and strings
--- 37,52 ----
  
  
  _names = dir()
  _type_to_name_map = {}
  def type_to_name(gtype):
!     """Map all file types to strings; unknown types become TYPE='x'."""
!     global _type_to_name_map
!     if _type_to_name_map=={}:
!         for name in _names:
!             if name[:2] == 'A_':
!                 _type_to_name_map[eval(name)] = name[2:]
!     if _type_to_name_map.has_key(gtype):
!         return _type_to_name_map[gtype]
!     return 'TYPE=' + `gtype`
  
  # Names for characters and strings
***************
*** 54,208 ****
  TAB = '\t'
  
- # Send a selector to a given host and port, return a file with the reply
  def send_selector(selector, host, port = 0):
! 	import socket
! 	import string
! 	if not port:
! 		i = string.find(host, ':')
! 		if i >= 0:
! 			host, port = host[:i], string.atoi(host[i+1:])
! 	if not port:
! 		port = DEF_PORT
! 	elif type(port) == type(''):
! 		port = string.atoi(port)
! 	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
! 	s.connect(host, port)
! 	s.send(selector + CRLF)
! 	s.shutdown(1)
! 	return s.makefile('rb')
  
- # Send a selector and a query string
  def send_query(selector, query, host, port = 0):
! 	return send_selector(selector + '\t' + query, host, port)
  
- # Takes a path as returned by urlparse and returns the appropriate selector
  def path_to_selector(path):
! 	if path=="/":
! 		return "/"
! 	else:
! 		return path[2:] # Cuts initial slash and data type identifier
  
- # Takes a path as returned by urlparse and maps it to a string
- # See section 3.4 of RFC 1738 for details
  def path_to_datatype_name(path):
! 	if path=="/":
! 		# No way to tell, although "INDEX" is likely
! 		return "TYPE='unknown'"
! 	else:
! 		return type_to_name(path[1])
  
  # The following functions interpret the data returned by the gopher
  # server according to the expected type, e.g. textfile or directory
  
- # Get a directory in the form of a list of entries
  def get_directory(f):
! 	import string
! 	list = []
! 	while 1:
! 		line = f.readline()
! 		if not line:
! 			print '(Unexpected EOF from server)'
! 			break
! 		if line[-2:] == CRLF:
! 			line = line[:-2]
! 		elif line[-1:] in CRLF:
! 			line = line[:-1]
! 		if line == '.':
! 			break
! 		if not line:
! 			print '(Empty line from server)'
! 			continue
! 		gtype = line[0]
! 		parts = string.splitfields(line[1:], TAB)
! 		if len(parts) < 4:
! 			print '(Bad line from server:', `line`, ')'
! 			continue
! 		if len(parts) > 4:
! 			if parts[4:] != ['+']:
! 				print '(Extra info from server:',
! 				print parts[4:], ')'
! 		else:
! 			parts.append('')
! 		parts.insert(0, gtype)
! 		list.append(parts)
! 	return list
  
- # Get a text file as a list of lines, with trailing CRLF stripped
  def get_textfile(f):
! 	list = []
! 	get_alt_textfile(f, list.append)
! 	return list
  
- # Get a text file and pass each line to a function, with trailing CRLF stripped
  def get_alt_textfile(f, func):
! 	while 1:
! 		line = f.readline()
! 		if not line:
! 			print '(Unexpected EOF from server)'
! 			break
! 		if line[-2:] == CRLF:
! 			line = line[:-2]
! 		elif line[-1:] in CRLF:
! 			line = line[:-1]
! 		if line == '.':
! 			break
! 		if line[:2] == '..':
! 			line = line[1:]
! 		func(line)
  
- # Get a binary file as one solid data block
  def get_binary(f):
! 	data = f.read()
! 	return data
  
- # Get a binary file and pass each block to a function
  def get_alt_binary(f, func, blocksize):
! 	while 1:
! 		data = f.read(blocksize)
! 		if not data:
! 			break
! 		func(data)
  
- # Trivial test program
  def test():
! 	import sys
! 	import getopt
! 	opts, args = getopt.getopt(sys.argv[1:], '')
! 	selector = DEF_SELECTOR
! 	type = selector[0]
! 	host = DEF_HOST
! 	port = DEF_PORT
! 	if args:
! 		host = args[0]
! 		args = args[1:]
! 	if args:
! 		type = args[0]
! 		args = args[1:]
! 		if len(type) > 1:
! 			type, selector = type[0], type
! 		else:
! 			selector = ''
! 			if args:
! 				selector = args[0]
! 				args = args[1:]
! 		query = ''
! 		if args:
! 			query = args[0]
! 			args = args[1:]
! 	if type == A_INDEX:
! 		f = send_query(selector, query, host)
! 	else:
! 		f = send_selector(selector, host)
! 	if type == A_TEXT:
! 		list = get_textfile(f)
! 		for item in list: print item
! 	elif type in (A_MENU, A_INDEX):
! 		list = get_directory(f)
! 		for item in list: print item
! 	else:
! 		data = get_binary(f)
! 		print 'binary data:', len(data), 'bytes:', `data[:100]`[:40]
  
  # Run the test when run as script
  if __name__ == '__main__':
! 	test()
--- 54,208 ----
  TAB = '\t'
  
  def send_selector(selector, host, port = 0):
!     """Send a selector to a given host and port, return a file with the reply."""
!     import socket
!     import string
!     if not port:
!         i = string.find(host, ':')
!         if i >= 0:
!             host, port = host[:i], string.atoi(host[i+1:])
!     if not port:
!         port = DEF_PORT
!     elif type(port) == type(''):
!         port = string.atoi(port)
!     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
!     s.connect((host, port))
!     s.send(selector + CRLF)
!     s.shutdown(1)
!     return s.makefile('rb')
  
  def send_query(selector, query, host, port = 0):
!     """Send a selector and a query string."""
!     return send_selector(selector + '\t' + query, host, port)
  
  def path_to_selector(path):
!     """Takes a path as returned by urlparse and returns the appropriate selector."""
!     if path=="/":
!         return "/"
!     else:
!         return path[2:] # Cuts initial slash and data type identifier
  
  def path_to_datatype_name(path):
!     """Takes a path as returned by urlparse and maps it to a string.
!     See section 3.4 of RFC 1738 for details."""
!     if path=="/":
!         # No way to tell, although "INDEX" is likely
!         return "TYPE='unknown'"
!     else:
!         return type_to_name(path[1])
  
  # The following functions interpret the data returned by the gopher
  # server according to the expected type, e.g. textfile or directory
  
  def get_directory(f):
!     """Get a directory in the form of a list of entries."""
!     import string
!     list = []
!     while 1:
!         line = f.readline()
!         if not line:
!             print '(Unexpected EOF from server)'
!             break
!         if line[-2:] == CRLF:
!             line = line[:-2]
!         elif line[-1:] in CRLF:
!             line = line[:-1]
!         if line == '.':
!             break
!         if not line:
!             print '(Empty line from server)'
!             continue
!         gtype = line[0]
!         parts = string.splitfields(line[1:], TAB)
!         if len(parts) < 4:
!             print '(Bad line from server:', `line`, ')'
!             continue
!         if len(parts) > 4:
!             if parts[4:] != ['+']:
!                 print '(Extra info from server:',
!                 print parts[4:], ')'
!         else:
!             parts.append('')
!         parts.insert(0, gtype)
!         list.append(parts)
!     return list
  
  def get_textfile(f):
!     """Get a text file as a list of lines, with trailing CRLF stripped."""
!     list = []
!     get_alt_textfile(f, list.append)
!     return list
  
  def get_alt_textfile(f, func):
!     """Get a text file and pass each line to a function, with trailing CRLF stripped."""
!     while 1:
!         line = f.readline()
!         if not line:
!             print '(Unexpected EOF from server)'
!             break
!         if line[-2:] == CRLF:
!             line = line[:-2]
!         elif line[-1:] in CRLF:
!             line = line[:-1]
!         if line == '.':
!             break
!         if line[:2] == '..':
!             line = line[1:]
!         func(line)
  
  def get_binary(f):
!     """Get a binary file as one solid data block."""
!     data = f.read()
!     return data
  
  def get_alt_binary(f, func, blocksize):
!     """Get a binary file and pass each block to a function."""
!     while 1:
!         data = f.read(blocksize)
!         if not data:
!             break
!         func(data)
  
  def test():
!     """Trivial test program."""
!     import sys
!     import getopt
!     opts, args = getopt.getopt(sys.argv[1:], '')
!     selector = DEF_SELECTOR
!     type = selector[0]
!     host = DEF_HOST
!     port = DEF_PORT
!     if args:
!         host = args[0]
!         args = args[1:]
!     if args:
!         type = args[0]
!         args = args[1:]
!         if len(type) > 1:
!             type, selector = type[0], type
!         else:
!             selector = ''
!             if args:
!                 selector = args[0]
!                 args = args[1:]
!         query = ''
!         if args:
!             query = args[0]
!             args = args[1:]
!     if type == A_INDEX:
!         f = send_query(selector, query, host)
!     else:
!         f = send_selector(selector, host)
!     if type == A_TEXT:
!         list = get_textfile(f)
!         for item in list: print item
!     elif type in (A_MENU, A_INDEX):
!         list = get_directory(f)
!         for item in list: print item
!     else:
!         data = get_binary(f)
!         print 'binary data:', len(data), 'bytes:', `data[:100]`[:40]
  
  # Run the test when run as script
  if __name__ == '__main__':
!     test()

Index: htmlenti.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/htmlenti.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** htmlenti.py	1996/07/22 15:21:53	1.1
--- htmlenti.py	2000/05/08 17:31:00	1.2
***************
*** 1,105 ****
! # Proposed entity definitions for HTML, taken from
! # http://www.w3.org/hypertext/WWW/MarkUp/html-spec/html-spec_14.html
  
  entitydefs = {
!     'lt':       '<',
!     'gt':       '>',
!     'amp':      '&',
!     'quot':	'"',
!     'nbsp':	chr(160),	# no-break space
!     'iexcl':	chr(161),	# inverted exclamation mark
!     'cent':	chr(162),	# cent sign
!     'pound':	chr(163),	# pound sterling sign
!     'curren':	chr(164),	# general currency sign
!     'yen':	chr(165),	# yen sign
!     'brvbar':	chr(166),	# broken (vertical) bar
!     'sect':	chr(167),	# section sign
!     'uml':	chr(168),	# umlaut (dieresis)
!     'copy':	chr(169),	# copyright sign
!     'ordf':	chr(170),	# ordinal indicator, feminine
!     'laquo':	chr(171),	# angle quotation mark, left
!     'not':	chr(172),	# not sign
!     'shy':	chr(173),	# soft hyphen
!     'reg':	chr(174),	# registered sign
!     'macr':	chr(175),	# macron
!     'deg':	chr(176),	# degree sign
!     'plusmn':	chr(177),	# plus-or-minus sign
!     'sup2':	chr(178),	# superscript two
!     'sup3':	chr(179),	# superscript three
!     'acute':	chr(180),	# acute accent
!     'micro':	chr(181),	# micro sign
!     'para':	chr(182),	# pilcrow (paragraph sign)
!     'middot':	chr(183),	# middle dot
!     'cedil':	chr(184),	# cedilla
!     'sup1':	chr(185),	# superscript one
!     'ordm':	chr(186),	# ordinal indicator, masculine
!     'raquo':	chr(187),	# angle quotation mark, right
!     'frac14':	chr(188),	# fraction one-quarter
!     'frac12':	chr(189),	# fraction one-half
!     'frac34':	chr(190),	# fraction three-quarters
!     'iquest':	chr(191),	# inverted question mark
!     'Agrave':	chr(192),	# capital A, grave accent
!     'Aacute':	chr(193),	# capital A, acute accent
!     'Acirc':	chr(194),	# capital A, circumflex accent
!     'Atilde':	chr(195),	# capital A, tilde
!     'Auml':	chr(196),	# capital A, dieresis or umlaut mark
!     'Aring':	chr(197),	# capital A, ring
!     'AElig':	chr(198),	# capital AE diphthong (ligature)
!     'Ccedil':	chr(199),	# capital C, cedilla
!     'Egrave':	chr(200),	# capital E, grave accent
!     'Eacute':	chr(201),	# capital E, acute accent
!     'Ecirc':	chr(202),	# capital E, circumflex accent
!     'Euml':	chr(203),	# capital E, dieresis or umlaut mark
!     'Igrave':	chr(204),	# capital I, grave accent
!     'Iacute':	chr(205),	# capital I, acute accent
!     'Icirc':	chr(206),	# capital I, circumflex accent
!     'Iuml':	chr(207),	# capital I, dieresis or umlaut mark
!     'ETH':	chr(208),	# capital Eth, Icelandic
!     'Ntilde':	chr(209),	# capital N, tilde
!     'Ograve':	chr(210),	# capital O, grave accent
!     'Oacute':	chr(211),	# capital O, acute accent
!     'Ocirc':	chr(212),	# capital O, circumflex accent
!     'Otilde':	chr(213),	# capital O, tilde
!     'Ouml':	chr(214),	# capital O, dieresis or umlaut mark
!     'times':	chr(215),	# multiply sign
!     'Oslash':	chr(216),	# capital O, slash
!     'Ugrave':	chr(217),	# capital U, grave accent
!     'Uacute':	chr(218),	# capital U, acute accent
!     'Ucirc':	chr(219),	# capital U, circumflex accent
!     'Uuml':	chr(220),	# capital U, dieresis or umlaut mark
!     'Yacute':	chr(221),	# capital Y, acute accent
!     'THORN':	chr(222),	# capital THORN, Icelandic
!     'szlig':	chr(223),	# small sharp s, German (sz ligature)
!     'agrave':	chr(224),	# small a, grave accent
!     'aacute':	chr(225),	# small a, acute accent
!     'acirc':	chr(226),	# small a, circumflex accent
!     'atilde':	chr(227),	# small a, tilde
!     'auml':	chr(228),	# small a, dieresis or umlaut mark
!     'aring':	chr(229),	# small a, ring
!     'aelig':	chr(230),	# small ae diphthong (ligature)
!     'ccedil':	chr(231),	# small c, cedilla
!     'egrave':	chr(232),	# small e, grave accent
!     'eacute':	chr(233),	# small e, acute accent
!     'ecirc':	chr(234),	# small e, circumflex accent
!     'euml':	chr(235),	# small e, dieresis or umlaut mark
!     'igrave':	chr(236),	# small i, grave accent
!     'iacute':	chr(237),	# small i, acute accent
!     'icirc':	chr(238),	# small i, circumflex accent
!     'iuml':	chr(239),	# small i, dieresis or umlaut mark
!     'eth':	chr(240),	# small eth, Icelandic
!     'ntilde':	chr(241),	# small n, tilde
!     'ograve':	chr(242),	# small o, grave accent
!     'oacute':	chr(243),	# small o, acute accent
!     'ocirc':	chr(244),	# small o, circumflex accent
!     'otilde':	chr(245),	# small o, tilde
!     'ouml':	chr(246),	# small o, dieresis or umlaut mark
!     'divide':	chr(247),	# divide sign
!     'oslash':	chr(248),	# small o, slash
!     'ugrave':	chr(249),	# small u, grave accent
!     'uacute':	chr(250),	# small u, acute accent
!     'ucirc':	chr(251),	# small u, circumflex accent
!     'uuml':	chr(252),	# small u, dieresis or umlaut mark
!     'yacute':	chr(253),	# small y, acute accent
!     'thorn':	chr(254),	# small thorn, Icelandic
!     'yuml':	chr(255),	# small y, dieresis or umlaut mark
  }
--- 1,257 ----
! """HTML character entity references."""
  
  entitydefs = {
!     'AElig':	'\306',  	# latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1
!     'Aacute':	'\301',  	# latin capital letter A with acute, U+00C1 ISOlat1
!     'Acirc':	'\302',  	# latin capital letter A with circumflex, U+00C2 ISOlat1
!     'Agrave':	'\300',  	# latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1
!     'Alpha':	'&#913;',  	# greek capital letter alpha, U+0391
!     'Aring':	'\305',  	# latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1
!     'Atilde':	'\303',  	# latin capital letter A with tilde, U+00C3 ISOlat1
!     'Auml':	'\304',  	# latin capital letter A with diaeresis, U+00C4 ISOlat1
!     'Beta':	'&#914;',  	# greek capital letter beta, U+0392
!     'Ccedil':	'\307',  	# latin capital letter C with cedilla, U+00C7 ISOlat1
!     'Chi':	'&#935;',  	# greek capital letter chi, U+03A7
!     'Dagger':	'&#8225;',  	# double dagger, U+2021 ISOpub
!     'Delta':	'&#916;',  	# greek capital letter delta, U+0394 ISOgrk3
!     'ETH':	'\320',  	# latin capital letter ETH, U+00D0 ISOlat1
!     'Eacute':	'\311',  	# latin capital letter E with acute, U+00C9 ISOlat1
!     'Ecirc':	'\312',  	# latin capital letter E with circumflex, U+00CA ISOlat1
!     'Egrave':	'\310',  	# latin capital letter E with grave, U+00C8 ISOlat1
!     'Epsilon':	'&#917;',  	# greek capital letter epsilon, U+0395
!     'Eta':	'&#919;',  	# greek capital letter eta, U+0397
!     'Euml':	'\313',  	# latin capital letter E with diaeresis, U+00CB ISOlat1
!     'Gamma':	'&#915;',  	# greek capital letter gamma, U+0393 ISOgrk3
!     'Iacute':	'\315',  	# latin capital letter I with acute, U+00CD ISOlat1
!     'Icirc':	'\316',  	# latin capital letter I with circumflex, U+00CE ISOlat1
!     'Igrave':	'\314',  	# latin capital letter I with grave, U+00CC ISOlat1
!     'Iota':	'&#921;',  	# greek capital letter iota, U+0399
!     'Iuml':	'\317',  	# latin capital letter I with diaeresis, U+00CF ISOlat1
!     'Kappa':	'&#922;',  	# greek capital letter kappa, U+039A
!     'Lambda':	'&#923;',  	# greek capital letter lambda, U+039B ISOgrk3
!     'Mu':	'&#924;',  	# greek capital letter mu, U+039C
!     'Ntilde':	'\321',  	# latin capital letter N with tilde, U+00D1 ISOlat1
!     'Nu':	'&#925;',  	# greek capital letter nu, U+039D
!     'OElig':	'&#338;',  	# latin capital ligature OE, U+0152 ISOlat2
!     'Oacute':	'\323',  	# latin capital letter O with acute, U+00D3 ISOlat1
!     'Ocirc':	'\324',  	# latin capital letter O with circumflex, U+00D4 ISOlat1
!     'Ograve':	'\322',  	# latin capital letter O with grave, U+00D2 ISOlat1
!     'Omega':	'&#937;',  	# greek capital letter omega, U+03A9 ISOgrk3
!     'Omicron':	'&#927;',  	# greek capital letter omicron, U+039F
!     'Oslash':	'\330',  	# latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1
!     'Otilde':	'\325',  	# latin capital letter O with tilde, U+00D5 ISOlat1
!     'Ouml':	'\326',  	# latin capital letter O with diaeresis, U+00D6 ISOlat1
!     'Phi':	'&#934;',  	# greek capital letter phi, U+03A6 ISOgrk3
!     'Pi':	'&#928;',  	# greek capital letter pi, U+03A0 ISOgrk3
!     'Prime':	'&#8243;',  	# double prime = seconds = inches, U+2033 ISOtech
!     'Psi':	'&#936;',  	# greek capital letter psi, U+03A8 ISOgrk3
!     'Rho':	'&#929;',  	# greek capital letter rho, U+03A1
!     'Scaron':	'&#352;',  	# latin capital letter S with caron, U+0160 ISOlat2
!     'Sigma':	'&#931;',  	# greek capital letter sigma, U+03A3 ISOgrk3
!     'THORN':	'\336',  	# latin capital letter THORN, U+00DE ISOlat1
!     'Tau':	'&#932;',  	# greek capital letter tau, U+03A4
!     'Theta':	'&#920;',  	# greek capital letter theta, U+0398 ISOgrk3
!     'Uacute':	'\332',  	# latin capital letter U with acute, U+00DA ISOlat1
!     'Ucirc':	'\333',  	# latin capital letter U with circumflex, U+00DB ISOlat1
!     'Ugrave':	'\331',  	# latin capital letter U with grave, U+00D9 ISOlat1
!     'Upsilon':	'&#933;',  	# greek capital letter upsilon, U+03A5 ISOgrk3
!     'Uuml':	'\334',  	# latin capital letter U with diaeresis, U+00DC ISOlat1
!     'Xi':	'&#926;',  	# greek capital letter xi, U+039E ISOgrk3
!     'Yacute':	'\335',  	# latin capital letter Y with acute, U+00DD ISOlat1
!     'Yuml':	'&#376;',  	# latin capital letter Y with diaeresis, U+0178 ISOlat2
!     'Zeta':	'&#918;',  	# greek capital letter zeta, U+0396
!     'aacute':	'\341',  	# latin small letter a with acute, U+00E1 ISOlat1
!     'acirc':	'\342',  	# latin small letter a with circumflex, U+00E2 ISOlat1
!     'acute':	'\264',  	# acute accent = spacing acute, U+00B4 ISOdia
!     'aelig':	'\346',  	# latin small letter ae = latin small ligature ae, U+00E6 ISOlat1
!     'agrave':	'\340',  	# latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1
!     'alefsym':	'&#8501;',  	# alef symbol = first transfinite cardinal, U+2135 NEW
!     'alpha':	'&#945;',  	# greek small letter alpha, U+03B1 ISOgrk3
!     'amp':	'\46',  	# ampersand, U+0026 ISOnum
!     'and':	'&#8743;',  	# logical and = wedge, U+2227 ISOtech
!     'ang':	'&#8736;',  	# angle, U+2220 ISOamso
!     'aring':	'\345',  	# latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1
!     'asymp':	'&#8776;',  	# almost equal to = asymptotic to, U+2248 ISOamsr
!     'atilde':	'\343',  	# latin small letter a with tilde, U+00E3 ISOlat1
!     'auml':	'\344',  	# latin small letter a with diaeresis, U+00E4 ISOlat1
!     'bdquo':	'&#8222;',  	# double low-9 quotation mark, U+201E NEW
!     'beta':	'&#946;',  	# greek small letter beta, U+03B2 ISOgrk3
!     'brvbar':	'\246',  	# broken bar = broken vertical bar, U+00A6 ISOnum
!     'bull':	'&#8226;',  	# bullet = black small circle, U+2022 ISOpub
!     'cap':	'&#8745;',  	# intersection = cap, U+2229 ISOtech
!     'ccedil':	'\347',  	# latin small letter c with cedilla, U+00E7 ISOlat1
!     'cedil':	'\270',  	# cedilla = spacing cedilla, U+00B8 ISOdia
!     'cent':	'\242',  	# cent sign, U+00A2 ISOnum
!     'chi':	'&#967;',  	# greek small letter chi, U+03C7 ISOgrk3
!     'circ':	'&#710;',  	# modifier letter circumflex accent, U+02C6 ISOpub
!     'clubs':	'&#9827;',  	# black club suit = shamrock, U+2663 ISOpub
!     'cong':	'&#8773;',  	# approximately equal to, U+2245 ISOtech
!     'copy':	'\251',  	# copyright sign, U+00A9 ISOnum
!     'crarr':	'&#8629;',  	# downwards arrow with corner leftwards = carriage return, U+21B5 NEW
!     'cup':	'&#8746;',  	# union = cup, U+222A ISOtech
!     'curren':	'\244',  	# currency sign, U+00A4 ISOnum
!     'dArr':	'&#8659;',  	# downwards double arrow, U+21D3 ISOamsa
!     'dagger':	'&#8224;',  	# dagger, U+2020 ISOpub
!     'darr':	'&#8595;',  	# downwards arrow, U+2193 ISOnum
!     'deg':	'\260',  	# degree sign, U+00B0 ISOnum
!     'delta':	'&#948;',  	# greek small letter delta, U+03B4 ISOgrk3
!     'diams':	'&#9830;',  	# black diamond suit, U+2666 ISOpub
!     'divide':	'\367',  	# division sign, U+00F7 ISOnum
!     'eacute':	'\351',  	# latin small letter e with acute, U+00E9 ISOlat1
!     'ecirc':	'\352',  	# latin small letter e with circumflex, U+00EA ISOlat1
!     'egrave':	'\350',  	# latin small letter e with grave, U+00E8 ISOlat1
!     'empty':	'&#8709;',  	# empty set = null set = diameter, U+2205 ISOamso
!     'emsp':	'&#8195;',  	# em space, U+2003 ISOpub
!     'ensp':	'&#8194;',  	# en space, U+2002 ISOpub
!     'epsilon':	'&#949;',  	# greek small letter epsilon, U+03B5 ISOgrk3
!     'equiv':	'&#8801;',  	# identical to, U+2261 ISOtech
!     'eta':	'&#951;',  	# greek small letter eta, U+03B7 ISOgrk3
!     'eth':	'\360',  	# latin small letter eth, U+00F0 ISOlat1
!     'euml':	'\353',  	# latin small letter e with diaeresis, U+00EB ISOlat1
!     'euro':	'&#8364;',  	# euro sign, U+20AC NEW
!     'exist':	'&#8707;',  	# there exists, U+2203 ISOtech
!     'fnof':	'&#402;',  	# latin small f with hook = function = florin, U+0192 ISOtech
!     'forall':	'&#8704;',  	# for all, U+2200 ISOtech
!     'frac12':	'\275',  	# vulgar fraction one half = fraction one half, U+00BD ISOnum
!     'frac14':	'\274',  	# vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum
!     'frac34':	'\276',  	# vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum
!     'frasl':	'&#8260;',  	# fraction slash, U+2044 NEW
!     'gamma':	'&#947;',  	# greek small letter gamma, U+03B3 ISOgrk3
!     'ge':	'&#8805;',  	# greater-than or equal to, U+2265 ISOtech
!     'gt':	'\76',  	# greater-than sign, U+003E ISOnum
!     'hArr':	'&#8660;',  	# left right double arrow, U+21D4 ISOamsa
!     'harr':	'&#8596;',  	# left right arrow, U+2194 ISOamsa
!     'hearts':	'&#9829;',  	# black heart suit = valentine, U+2665 ISOpub
!     'hellip':	'&#8230;',  	# horizontal ellipsis = three dot leader, U+2026 ISOpub
!     'iacute':	'\355',  	# latin small letter i with acute, U+00ED ISOlat1
!     'icirc':	'\356',  	# latin small letter i with circumflex, U+00EE ISOlat1
!     'iexcl':	'\241',  	# inverted exclamation mark, U+00A1 ISOnum
!     'igrave':	'\354',  	# latin small letter i with grave, U+00EC ISOlat1
!     'image':	'&#8465;',  	# blackletter capital I = imaginary part, U+2111 ISOamso
!     'infin':	'&#8734;',  	# infinity, U+221E ISOtech
!     'int':	'&#8747;',  	# integral, U+222B ISOtech
!     'iota':	'&#953;',  	# greek small letter iota, U+03B9 ISOgrk3
!     'iquest':	'\277',  	# inverted question mark = turned question mark, U+00BF ISOnum
!     'isin':	'&#8712;',  	# element of, U+2208 ISOtech
!     'iuml':	'\357',  	# latin small letter i with diaeresis, U+00EF ISOlat1
!     'kappa':	'&#954;',  	# greek small letter kappa, U+03BA ISOgrk3
!     'lArr':	'&#8656;',  	# leftwards double arrow, U+21D0 ISOtech
!     'lambda':	'&#955;',  	# greek small letter lambda, U+03BB ISOgrk3
!     'lang':	'&#9001;',  	# left-pointing angle bracket = bra, U+2329 ISOtech
!     'laquo':	'\253',  	# left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum
!     'larr':	'&#8592;',  	# leftwards arrow, U+2190 ISOnum
!     'lceil':	'&#8968;',  	# left ceiling = apl upstile, U+2308 ISOamsc
!     'ldquo':	'&#8220;',  	# left double quotation mark, U+201C ISOnum
!     'le':	'&#8804;',  	# less-than or equal to, U+2264 ISOtech
!     'lfloor':	'&#8970;',  	# left floor = apl downstile, U+230A ISOamsc
!     'lowast':	'&#8727;',  	# asterisk operator, U+2217 ISOtech
!     'loz':	'&#9674;',  	# lozenge, U+25CA ISOpub
!     'lrm':	'&#8206;',  	# left-to-right mark, U+200E NEW RFC 2070
!     'lsaquo':	'&#8249;',  	# single left-pointing angle quotation mark, U+2039 ISO proposed
!     'lsquo':	'&#8216;',  	# left single quotation mark, U+2018 ISOnum
!     'lt':	'\74',  	# less-than sign, U+003C ISOnum
!     'macr':	'\257',  	# macron = spacing macron = overline = APL overbar, U+00AF ISOdia
!     'mdash':	'&#8212;',  	# em dash, U+2014 ISOpub
!     'micro':	'\265',  	# micro sign, U+00B5 ISOnum
!     'middot':	'\267',  	# middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum
!     'minus':	'&#8722;',  	# minus sign, U+2212 ISOtech
!     'mu':	'&#956;',  	# greek small letter mu, U+03BC ISOgrk3
!     'nabla':	'&#8711;',  	# nabla = backward difference, U+2207 ISOtech
!     'nbsp':	'\240',  	# no-break space = non-breaking space, U+00A0 ISOnum
!     'ndash':	'&#8211;',  	# en dash, U+2013 ISOpub
!     'ne':	'&#8800;',  	# not equal to, U+2260 ISOtech
!     'ni':	'&#8715;',  	# contains as member, U+220B ISOtech
!     'not':	'\254',  	# not sign, U+00AC ISOnum
!     'notin':	'&#8713;',  	# not an element of, U+2209 ISOtech
!     'nsub':	'&#8836;',  	# not a subset of, U+2284 ISOamsn
!     'ntilde':	'\361',  	# latin small letter n with tilde, U+00F1 ISOlat1
!     'nu':	'&#957;',  	# greek small letter nu, U+03BD ISOgrk3
!     'oacute':	'\363',  	# latin small letter o with acute, U+00F3 ISOlat1
!     'ocirc':	'\364',  	# latin small letter o with circumflex, U+00F4 ISOlat1
!     'oelig':	'&#339;',  	# latin small ligature oe, U+0153 ISOlat2
!     'ograve':	'\362',  	# latin small letter o with grave, U+00F2 ISOlat1
!     'oline':	'&#8254;',  	# overline = spacing overscore, U+203E NEW
!     'omega':	'&#969;',  	# greek small letter omega, U+03C9 ISOgrk3
!     'omicron':	'&#959;',  	# greek small letter omicron, U+03BF NEW
!     'oplus':	'&#8853;',  	# circled plus = direct sum, U+2295 ISOamsb
!     'or':	'&#8744;',  	# logical or = vee, U+2228 ISOtech
!     'ordf':	'\252',  	# feminine ordinal indicator, U+00AA ISOnum
!     'ordm':	'\272',  	# masculine ordinal indicator, U+00BA ISOnum
!     'oslash':	'\370',  	# latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1
!     'otilde':	'\365',  	# latin small letter o with tilde, U+00F5 ISOlat1
!     'otimes':	'&#8855;',  	# circled times = vector product, U+2297 ISOamsb
!     'ouml':	'\366',  	# latin small letter o with diaeresis, U+00F6 ISOlat1
!     'para':	'\266',  	# pilcrow sign = paragraph sign, U+00B6 ISOnum
!     'part':	'&#8706;',  	# partial differential, U+2202 ISOtech
!     'permil':	'&#8240;',  	# per mille sign, U+2030 ISOtech
!     'perp':	'&#8869;',  	# up tack = orthogonal to = perpendicular, U+22A5 ISOtech
!     'phi':	'&#966;',  	# greek small letter phi, U+03C6 ISOgrk3
!     'pi':	'&#960;',  	# greek small letter pi, U+03C0 ISOgrk3
!     'piv':	'&#982;',  	# greek pi symbol, U+03D6 ISOgrk3
!     'plusmn':	'\261',  	# plus-minus sign = plus-or-minus sign, U+00B1 ISOnum
!     'pound':	'\243',  	# pound sign, U+00A3 ISOnum
!     'prime':	'&#8242;',  	# prime = minutes = feet, U+2032 ISOtech
!     'prod':	'&#8719;',  	# n-ary product = product sign, U+220F ISOamsb
!     'prop':	'&#8733;',  	# proportional to, U+221D ISOtech
!     'psi':	'&#968;',  	# greek small letter psi, U+03C8 ISOgrk3
!     'quot':	'\42',  	# quotation mark = APL quote, U+0022 ISOnum
!     'rArr':	'&#8658;',  	# rightwards double arrow, U+21D2 ISOtech
!     'radic':	'&#8730;',  	# square root = radical sign, U+221A ISOtech
!     'rang':	'&#9002;',  	# right-pointing angle bracket = ket, U+232A ISOtech
!     'raquo':	'\273',  	# right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum
!     'rarr':	'&#8594;',  	# rightwards arrow, U+2192 ISOnum
!     'rceil':	'&#8969;',  	# right ceiling, U+2309 ISOamsc
!     'rdquo':	'&#8221;',  	# right double quotation mark, U+201D ISOnum
!     'real':	'&#8476;',  	# blackletter capital R = real part symbol, U+211C ISOamso
!     'reg':	'\256',  	# registered sign = registered trade mark sign, U+00AE ISOnum
!     'rfloor':	'&#8971;',  	# right floor, U+230B ISOamsc
!     'rho':	'&#961;',  	# greek small letter rho, U+03C1 ISOgrk3
!     'rlm':	'&#8207;',  	# right-to-left mark, U+200F NEW RFC 2070
!     'rsaquo':	'&#8250;',  	# single right-pointing angle quotation mark, U+203A ISO proposed
!     'rsquo':	'&#8217;',  	# right single quotation mark, U+2019 ISOnum
!     'sbquo':	'&#8218;',  	# single low-9 quotation mark, U+201A NEW
!     'scaron':	'&#353;',  	# latin small letter s with caron, U+0161 ISOlat2
!     'sdot':	'&#8901;',  	# dot operator, U+22C5 ISOamsb
!     'sect':	'\247',  	# section sign, U+00A7 ISOnum
!     'shy':	'\255',  	# soft hyphen = discretionary hyphen, U+00AD ISOnum
!     'sigma':	'&#963;',  	# greek small letter sigma, U+03C3 ISOgrk3
!     'sigmaf':	'&#962;',  	# greek small letter final sigma, U+03C2 ISOgrk3
!     'sim':	'&#8764;',  	# tilde operator = varies with = similar to, U+223C ISOtech
!     'spades':	'&#9824;',  	# black spade suit, U+2660 ISOpub
!     'sub':	'&#8834;',  	# subset of, U+2282 ISOtech
!     'sube':	'&#8838;',  	# subset of or equal to, U+2286 ISOtech
!     'sum':	'&#8721;',  	# n-ary sumation, U+2211 ISOamsb
!     'sup':	'&#8835;',  	# superset of, U+2283 ISOtech
!     'sup1':	'\271',  	# superscript one = superscript digit one, U+00B9 ISOnum
!     'sup2':	'\262',  	# superscript two = superscript digit two = squared, U+00B2 ISOnum
!     'sup3':	'\263',  	# superscript three = superscript digit three = cubed, U+00B3 ISOnum
!     'supe':	'&#8839;',  	# superset of or equal to, U+2287 ISOtech
!     'szlig':	'\337',  	# latin small letter sharp s = ess-zed, U+00DF ISOlat1
!     'tau':	'&#964;',  	# greek small letter tau, U+03C4 ISOgrk3
!     'there4':	'&#8756;',  	# therefore, U+2234 ISOtech
!     'theta':	'&#952;',  	# greek small letter theta, U+03B8 ISOgrk3
!     'thetasym':	'&#977;',  	# greek small letter theta symbol, U+03D1 NEW
!     'thinsp':	'&#8201;',  	# thin space, U+2009 ISOpub
!     'thorn':	'\376',  	# latin small letter thorn with, U+00FE ISOlat1
!     'tilde':	'&#732;',  	# small tilde, U+02DC ISOdia
!     'times':	'\327',  	# multiplication sign, U+00D7 ISOnum
!     'trade':	'&#8482;',  	# trade mark sign, U+2122 ISOnum
!     'uArr':	'&#8657;',  	# upwards double arrow, U+21D1 ISOamsa
!     'uacute':	'\372',  	# latin small letter u with acute, U+00FA ISOlat1
!     'uarr':	'&#8593;',  	# upwards arrow, U+2191 ISOnum
!     'ucirc':	'\373',  	# latin small letter u with circumflex, U+00FB ISOlat1
!     'ugrave':	'\371',  	# latin small letter u with grave, U+00F9 ISOlat1
!     'uml':	'\250',  	# diaeresis = spacing diaeresis, U+00A8 ISOdia
!     'upsih':	'&#978;',  	# greek upsilon with hook symbol, U+03D2 NEW
!     'upsilon':	'&#965;',  	# greek small letter upsilon, U+03C5 ISOgrk3
!     'uuml':	'\374',  	# latin small letter u with diaeresis, U+00FC ISOlat1
!     'weierp':	'&#8472;',  	# script capital P = power set = Weierstrass p, U+2118 ISOamso
!     'xi':	'&#958;',  	# greek small letter xi, U+03BE ISOgrk3
!     'yacute':	'\375',  	# latin small letter y with acute, U+00FD ISOlat1
!     'yen':	'\245',  	# yen sign = yuan sign, U+00A5 ISOnum
!     'yuml':	'\377',  	# latin small letter y with diaeresis, U+00FF ISOlat1
!     'zeta':	'&#950;',  	# greek small letter zeta, U+03B6 ISOgrk3
!     'zwj':	'&#8205;',  	# zero width joiner, U+200D NEW RFC 2070
!     'zwnj':	'&#8204;',  	# zero width non-joiner, U+200C NEW RFC 2070
! 
  }

Index: linecach.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/linecach.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** linecach.py	1996/07/22 15:21:58	1.1
--- linecach.py	2000/05/08 17:31:00	1.2
***************
*** 1,7 ****
! # Cache lines from files.
! # This is intended to read lines from modules imported -- hence if a filename
! # is not found, it will look down the module search path for a file by
! # that name.
  
  import sys
  import os
--- 1,9 ----
! """Cache lines from files.
  
+ This is intended to read lines from modules imported -- hence if a filename
+ is not found, it will look down the module search path for a file by
+ that name.
+ """
+ 
  import sys
  import os
***************
*** 9,17 ****
  
  def getline(filename, lineno):
! 	lines = getlines(filename)
! 	if 1 <= lineno <= len(lines):
! 		return lines[lineno-1]
! 	else:
! 		return ''
  
  
--- 11,19 ----
  
  def getline(filename, lineno):
!     lines = getlines(filename)
!     if 1 <= lineno <= len(lines):
!         return lines[lineno-1]
!     else:
!         return ''
  
  
***************
*** 21,90 ****
  
  
- # Clear the cache entirely
- 
  def clearcache():
! 	global cache
! 	cache = {}
  
  
- # Get the lines for a file from the cache.
- # Update the cache if it doesn't contain an entry for this file already.
  
  def getlines(filename):
! 	if cache.has_key(filename):
! 		return cache[filename][2]
! 	else:
! 		return updatecache(filename)
  
  
- # Discard cache entries that are out of date.
- # (This is not checked upon each call!)
  
  def checkcache():
! 	for filename in cache.keys():
! 		size, mtime, lines, fullname = cache[filename]
! 		try:
! 			stat = os.stat(fullname)
! 		except os.error:
! 			del cache[filename]
! 			continue
! 		if size <> stat[ST_SIZE] or mtime <> stat[ST_MTIME]:
! 			del cache[filename]
  
  
- # Update a cache entry and return its list of lines.
- # If something's wrong, print a message, discard the cache entry,
- # and return an empty list.
  
  def updatecache(filename):
! 	if cache.has_key(filename):
! 		del cache[filename]
! 	if not filename or filename[0] + filename[-1] == '<>':
! 		return []
! 	fullname = filename
! 	try:
! 		stat = os.stat(fullname)
! 	except os.error, msg:
! 		# Try looking through the module search path
! 		basename = os.path.split(filename)[1]
! 		for dirname in sys.path:
! 			fullname = os.path.join(dirname, basename)
! 			try:
! 				stat = os.stat(fullname)
! 				break
! 			except os.error:
! 				pass
! 		else:
! 			# No luck
! ##			print '*** Cannot stat', filename, ':', msg
! 			return []
! 	try:
! 		fp = open(fullname, 'r')
! 		lines = fp.readlines()
! 		fp.close()
! 	except IOError, msg:
! ##		print '*** Cannot open', fullname, ':', msg
! 		return []
! 	size, mtime = stat[ST_SIZE], stat[ST_MTIME]
! 	cache[filename] = size, mtime, lines, fullname
! 	return lines
--- 23,92 ----
  
  
  def clearcache():
!     """Clear the cache entirely."""
  
+     global cache
+     cache = {}
  
  
  def getlines(filename):
!     """Get the lines for a file from the cache.
!     Update the cache if it doesn't contain an entry for this file already."""
  
+     if cache.has_key(filename):
+         return cache[filename][2]
+     else:
+         return updatecache(filename)
  
  
  def checkcache():
!     """Discard cache entries that are out of date.
!     (This is not checked upon each call!)"""
  
+     for filename in cache.keys():
+         size, mtime, lines, fullname = cache[filename]
+         try:
+             stat = os.stat(fullname)
+         except os.error:
+             del cache[filename]
+             continue
+         if size <> stat[ST_SIZE] or mtime <> stat[ST_MTIME]:
+             del cache[filename]
  
  
  def updatecache(filename):
!     """Update a cache entry and return its list of lines.
!     If something's wrong, print a message, discard the cache entry,
!     and return an empty list."""
! 
!     if cache.has_key(filename):
!         del cache[filename]
!     if not filename or filename[0] + filename[-1] == '<>':
!         return []
!     fullname = filename
!     try:
!         stat = os.stat(fullname)
!     except os.error, msg:
!         # Try looking through the module search path
!         basename = os.path.split(filename)[1]
!         for dirname in sys.path:
!             fullname = os.path.join(dirname, basename)
!             try:
!                 stat = os.stat(fullname)
!                 break
!             except os.error:
!                 pass
!         else:
!             # No luck
! ##          print '*** Cannot stat', filename, ':', msg
!             return []
!     try:
!         fp = open(fullname, 'r')
!         lines = fp.readlines()
!         fp.close()
!     except IOError, msg:
! ##      print '*** Cannot open', fullname, ':', msg
!         return []
!     size, mtime = stat[ST_SIZE], stat[ST_MTIME]
!     cache[filename] = size, mtime, lines, fullname
!     return lines

Index: macurl2p.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/macurl2p.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** macurl2p.py	1998/08/12 02:37:55	1.5
--- macurl2p.py	2000/05/08 17:31:00	1.6
***************
*** 1,5 ****
! """Mac specific module for conversion between pathnames and URLs.
! Do not import directly, use urllib instead."""
  
  import string
  import urllib
--- 1,6 ----
! """Macintosh-specific module for conversion between pathnames and URLs.
  
+ Do not import directly; use urllib instead."""
+ 
  import string
  import urllib
***************
*** 13,16 ****
--- 14,22 ----
      tp = urllib.splittype(pathname)[0]
      if tp and tp <> 'file':
+         raise RuntimeError, 'Cannot convert non-local URL to pathname'
+     # Turn starting /// into /, an empty hostname means current host
+     if pathname[:3] == '///':
+     	pathname = pathname[2:]
+     elif pathname[:2] == '//':
          raise RuntimeError, 'Cannot convert non-local URL to pathname'
      components = string.split(pathname, '/')

Index: mimetool.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/mimetool.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** mimetool.py	1998/08/12 02:37:55	1.6
--- mimetool.py	2000/05/08 17:31:00	1.7
***************
*** 1,3 ****
! # Various tools used by MIME-reading or MIME-writing programs.
  
  
--- 1,3 ----
! """Various tools used by MIME-reading or MIME-writing programs."""
  
  
***************
*** 8,15 ****
  
  
- # A derived class of rfc822.Message that knows about MIME headers and
- # contains some hooks for decoding encoded and multipart messages.
- 
  class Message(rfc822.Message):
  
  	def __init__(self, fp, seekable = 1):
--- 8,14 ----
  
  
  class Message(rfc822.Message):
+ 	"""A derived class of rfc822.Message that knows about MIME headers and
+ 	contains some hooks for decoding encoded and multipart messages."""
  
  	def __init__(self, fp, seekable = 1):
***************
*** 97,111 ****
  
  
- # Return a random string usable as a multipart boundary.
- # The method used is so that it is *very* unlikely that the same
- # string of characters will every occur again in the Universe,
- # so the caller needn't check the data it is packing for the
- # occurrence of the boundary.
- #
- # The boundary contains dots so you have to quote it in the header.
- 
  _prefix = None
  
  def choose_boundary():
  	global _prefix
  	import time
--- 96,110 ----
  
  
  _prefix = None
  
  def choose_boundary():
+ 	"""Return a random string usable as a multipart boundary.
+ 	The method used is so that it is *very* unlikely that the same
+ 	string of characters will every occur again in the Universe,
+ 	so the caller needn't check the data it is packing for the
+ 	occurrence of the boundary.
+ 
+ 	The boundary contains dots so you have to quote it in the header."""
+ 
  	global _prefix
  	import time
***************
*** 132,135 ****
--- 131,135 ----
  
  def decode(input, output, encoding):
+ 	"""Decode common content-transfer-encodings (base64, quopri, uuencode)."""
  	if encoding == 'base64':
  		import base64
***************
*** 141,144 ****
--- 141,146 ----
  		import uu
  		return uu.decode(input, output)
+ 	if encoding in ('7bit', '8bit'):
+ 		output.write(input.read())
  	if decodetab.has_key(encoding):
  		pipethrough(input, decodetab[encoding], output)
***************
*** 148,151 ****
--- 150,154 ----
  
  def encode(input, output, encoding):
+ 	"""Encode common content-transfer-encodings (base64, quopri, uuencode)."""
  	if encoding == 'base64':
  		import base64
***************
*** 157,160 ****
--- 160,165 ----
  		import uu
  		return uu.encode(input, output)
+ 	if encoding in ('7bit', '8bit'):
+ 		output.write(input.read())
  	if encodetab.has_key(encoding):
  		pipethrough(input, encodetab[encoding], output)

Index: mimetype.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/mimetype.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** mimetype.py	1999/04/08 20:27:42	1.5
--- mimetype.py	2000/05/08 17:31:00	1.6
***************
*** 31,36 ****
      "/usr/local/etc/httpd/conf/mime.types",
      "/usr/local/lib/netscape/mime.types",
!     "/usr/local/etc/httpd/conf/mime.types",	# Apache 1.2
!     "/usr/local/etc/mime.types",		# Apache 1.3
      ]
  
--- 31,36 ----
      "/usr/local/etc/httpd/conf/mime.types",
      "/usr/local/lib/netscape/mime.types",
!     "/usr/local/etc/httpd/conf/mime.types",     # Apache 1.2
!     "/usr/local/etc/mime.types",                # Apache 1.3
      ]
  
***************
*** 57,78 ****
      scheme, url = urllib.splittype(url)
      if scheme == 'data':
! 	# syntax of data URLs:
! 	# dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
! 	# mediatype := [ type "/" subtype ] *( ";" parameter )
! 	# data      := *urlchar
! 	# parameter := attribute "=" value
! 	# type/subtype defaults to "text/plain"
! 	comma = string.find(url, ',')
! 	if comma < 0:
! 	    # bad data URL
! 	    return None, None
! 	semi = string.find(url, ';', 0, comma)
! 	if semi >= 0:
! 	    type = url[:semi]
! 	else:
! 	    type = url[:comma]
! 	if '=' in type or '/' not in type:
! 	    type = 'text/plain'
! 	return type, None		# never compressed, so encoding is None
      base, ext = posixpath.splitext(url)
      while suffix_map.has_key(ext):
--- 57,78 ----
      scheme, url = urllib.splittype(url)
      if scheme == 'data':
!         # syntax of data URLs:
!         # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
!         # mediatype := [ type "/" subtype ] *( ";" parameter )
!         # data      := *urlchar
!         # parameter := attribute "=" value
!         # type/subtype defaults to "text/plain"
!         comma = string.find(url, ',')
!         if comma < 0:
!             # bad data URL
!             return None, None
!         semi = string.find(url, ';', 0, comma)
!         if semi >= 0:
!             type = url[:semi]
!         else:
!             type = url[:comma]
!         if '=' in type or '/' not in type:
!             type = 'text/plain'
!         return type, None               # never compressed, so encoding is None
      base, ext = posixpath.splitext(url)
      while suffix_map.has_key(ext):
***************
*** 176,179 ****
--- 176,180 ----
      '.jpeg': 'image/jpeg',
      '.jpg': 'image/jpeg',
+     '.js': 'application/x-javascript',
      '.latex': 'application/x-latex',
      '.man': 'application/x-troff-man',

Index: multifil.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/multifil.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** multifil.py	1998/08/12 02:37:57	1.3
--- multifil.py	2000/05/08 17:31:00	1.4
***************
*** 1,28 ****
! # A class that makes each part of a multipart message "feel" like an
! # ordinary file, as long as you use fp.readline().  Allows recursive
! # use, for nested multipart messages.  Probably best used together
! # with module mimetools.
! #
! # Suggested use:
! #
! # real_fp = open(...)
! # fp = MultiFile(real_fp)
! #
! # "read some lines from fp"
! # fp.push(separator)
! # while 1:
! #	"read lines from fp until it returns an empty string" (A)
! #	if not fp.next(): break
! # fp.pop()
! # "read remaining lines from fp until it returns an empty string"
! #
! # The latter sequence may be used recursively at (A).
! # It is also allowed to use multiple push()...pop() sequences.
! #
! # If seekable is given as 0, the class code will not do the bookeeping
! # it normally attempts in order to make seeks relative to the beginning of the
! # current file part.  This may be useful when using MultiFile with a non-
! # seekable stream object.
  
  import sys
  import string
--- 1,31 ----
! """A readline()-style interface to the parts of a multipart message.
  
+ The MultiFile class makes each part of a multipart message "feel" like
+ an ordinary file, as long as you use fp.readline().  Allows recursive
+ use, for nested multipart messages.  Probably best used together
+ with module mimetools.
+ 
+ Suggested use:
+ 
+ real_fp = open(...)
+ fp = MultiFile(real_fp)
+ 
+ "read some lines from fp"
+ fp.push(separator)
+ while 1:
+ 	"read lines from fp until it returns an empty string" (A)
+ 	if not fp.next(): break
+ fp.pop()
+ "read remaining lines from fp until it returns an empty string"
+ 
+ The latter sequence may be used recursively at (A).
+ It is also allowed to use multiple push()...pop() sequences.
+ 
+ If seekable is given as 0, the class code will not do the bookeeping
+ it normally attempts in order to make seeks relative to the beginning of the
+ current file part.  This may be useful when using MultiFile with a non-
+ seekable stream object.
+ """
+ 
  import sys
  import string
***************
*** 31,37 ****
  
  class MultiFile:
! 	#
  	seekable = 0
! 	#
  	def __init__(self, fp, seekable=1):
  		self.fp = fp
--- 34,40 ----
  
  class MultiFile:
! 
  	seekable = 0
! 
  	def __init__(self, fp, seekable=1):
  		self.fp = fp
***************
*** 43,52 ****
  			self.start = self.fp.tell()
  			self.posstack = [] # Grows down
! 	#
  	def tell(self):
  		if self.level > 0:
  			return self.lastpos
  		return self.fp.tell() - self.start
! 	#
  	def seek(self, pos, whence=0):
  		here = self.tell()
--- 46,55 ----
  			self.start = self.fp.tell()
  			self.posstack = [] # Grows down
! 
  	def tell(self):
  		if self.level > 0:
  			return self.lastpos
  		return self.fp.tell() - self.start
! 
  	def seek(self, pos, whence=0):
  		here = self.tell()
***************
*** 65,69 ****
  		self.level = 0
  		self.last = 0
! 	#
  	def readline(self):
  		if self.level > 0:
--- 68,72 ----
  		self.level = 0
  		self.last = 0
! 
  	def readline(self):
  		if self.level > 0:
***************
*** 106,110 ****
  			raise Error,'Missing endmarker in MultiFile.readline()'
  		return ''
! 	#
  	def readlines(self):
  		list = []
--- 109,113 ----
  			raise Error,'Missing endmarker in MultiFile.readline()'
  		return ''
! 
  	def readlines(self):
  		list = []
***************
*** 114,121 ****
  			list.append(line)
  		return list
! 	#
  	def read(self): # Note: no size argument -- read until EOF only!
  		return string.joinfields(self.readlines(), '')
! 	#
  	def next(self):
  		while self.readline(): pass
--- 117,124 ----
  			list.append(line)
  		return list
! 
  	def read(self): # Note: no size argument -- read until EOF only!
  		return string.joinfields(self.readlines(), '')
! 
  	def next(self):
  		while self.readline(): pass
***************
*** 127,131 ****
  			self.start = self.fp.tell()
  		return 1
! 	#
  	def push(self, sep):
  		if self.level > 0:
--- 130,134 ----
  			self.start = self.fp.tell()
  		return 1
! 
  	def push(self, sep):
  		if self.level > 0:
***************
*** 135,139 ****
  			self.posstack.insert(0, self.start)
  			self.start = self.fp.tell()
! 	#
  	def pop(self):
  		if self.stack == []:
--- 138,142 ----
  			self.posstack.insert(0, self.start)
  			self.start = self.fp.tell()
! 
  	def pop(self):
  		if self.stack == []:
***************
*** 150,160 ****
  			if self.level > 0:
  				self.lastpos = abslastpos - self.start
! 	#
  	def is_data(self, line):
  		return line[:2] <> '--'
! 	#
  	def section_divider(self, str):
  		return "--" + str
! 	#
  	def end_marker(self, str):
  		return "--" + str + "--"
--- 153,163 ----
  			if self.level > 0:
  				self.lastpos = abslastpos - self.start
! 
  	def is_data(self, line):
  		return line[:2] <> '--'
! 
  	def section_divider(self, str):
  		return "--" + str
! 
  	def end_marker(self, str):
  		return "--" + str + "--"

Index: nturl2pa.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/nturl2pa.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** nturl2pa.py	1999/04/08 20:27:42	1.3
--- nturl2pa.py	2000/05/08 17:31:00	1.4
***************
*** 1,5 ****
! #
! # nturl2path convert a NT pathname to a file URL and 
! # vice versa  
  
  def url2pathname(url):
--- 1,3 ----
! """Convert a NT pathname to a file URL and vice versa."""
  
  def url2pathname(url):
***************
*** 35,39 ****
  
  def pathname2url(p):
- 
  	""" Convert a DOS path name to a file url...
  		C:\foo\bar\spam.foo
--- 33,36 ----

Index: posixfil.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/posixfil.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** posixfil.py	1999/04/08 20:27:43	1.7
--- posixfil.py	2000/05/08 17:31:00	1.8
***************
*** 1,63 ****
! #
! # Start of posixfile.py
! #
! 
! #
! # Extended file operations
! #
! # f = posixfile.open(filename, [mode, [bufsize]])
! #       will create a new posixfile object
! #
! # f = posixfile.fileopen(fileobject)
! #       will create a posixfile object from a builtin file object
! #
! # f.file()
! #       will return the original builtin file object
! #
! # f.dup()
! #       will return a new file object based on a new filedescriptor
! #
! # f.dup2(fd)
! #       will return a new file object based on the given filedescriptor
! #
! # f.flags(mode)
! #       will turn on the associated flag (merge)
! #       mode can contain the following characters:
! #
! #   (character representing a flag)
! #       a       append only flag
! #       c       close on exec flag
! #       n       no delay flag
! #       s       synchronization flag
! #   (modifiers)
! #       !       turn flags 'off' instead of default 'on'
! #       =       copy flags 'as is' instead of default 'merge'
! #       ?       return a string in which the characters represent the flags
! #               that are set
! #
! #       note: - the '!' and '=' modifiers are mutually exclusive.
! #             - the '?' modifier will return the status of the flags after they
! #               have been changed by other characters in the mode string
! #
! # f.lock(mode [, len [, start [, whence]]])
! #       will (un)lock a region
! #       mode can contain the following characters:
! #
! #   (character representing type of lock)
! #       u       unlock
! #       r       read lock
! #       w       write lock
! #   (modifiers)
! #       |       wait until the lock can be granted
! #       ?       return the first lock conflicting with the requested lock
! #               or 'None' if there is no conflict. The lock returned is in the
! #               format (mode, len, start, whence, pid) where mode is a
! #               character representing the type of lock ('r' or 'w')
! #
! #       note: - the '?' modifier prevents a region from being locked; it is
! #               query only
! #
  
  class _posixfile_:
      states = ['open', 'closed']
  
--- 1,60 ----
! """Extended file operations available in POSIX.
  
+ f = posixfile.open(filename, [mode, [bufsize]])
+       will create a new posixfile object
+ 
+ f = posixfile.fileopen(fileobject)
+       will create a posixfile object from a builtin file object
+ 
+ f.file()
+       will return the original builtin file object
+ 
+ f.dup()
+       will return a new file object based on a new filedescriptor
+ 
+ f.dup2(fd)
+       will return a new file object based on the given filedescriptor
+ 
+ f.flags(mode)
+       will turn on the associated flag (merge)
+       mode can contain the following characters:
+ 
+   (character representing a flag)
+       a       append only flag
+       c       close on exec flag
+       n       no delay flag
+       s       synchronization flag
+   (modifiers)
+       !       turn flags 'off' instead of default 'on'
+       =       copy flags 'as is' instead of default 'merge'
+       ?       return a string in which the characters represent the flags
+               that are set
+ 
+       note: - the '!' and '=' modifiers are mutually exclusive.
+             - the '?' modifier will return the status of the flags after they
+               have been changed by other characters in the mode string
+ 
+ f.lock(mode [, len [, start [, whence]]])
+       will (un)lock a region
+       mode can contain the following characters:
+ 
+   (character representing type of lock)
+       u       unlock
+       r       read lock
+       w       write lock
+   (modifiers)
+       |       wait until the lock can be granted
+       ?       return the first lock conflicting with the requested lock
+               or 'None' if there is no conflict. The lock returned is in the
+               format (mode, len, start, whence, pid) where mode is a
+               character representing the type of lock ('r' or 'w')
+ 
+       note: - the '?' modifier prevents a region from being locked; it is
+               query only
+ """
+ 
  class _posixfile_:
+     """File wrapper class that provides extra POSIX file routines."""
+ 
      states = ['open', 'closed']
  
***************
*** 179,182 ****
--- 176,180 ----
          import sys, os
          if sys.platform in ('netbsd1',
+                             'openbsd2',
                              'freebsd2', 'freebsd3',
                              'bsdos2', 'bsdos3', 'bsdos4'):
***************
*** 194,197 ****
--- 192,196 ----
          if '?' in how:
              if sys.platform in ('netbsd1',
+                                 'openbsd2',
                                  'freebsd2', 'freebsd3',
                                  'bsdos2', 'bsdos3', 'bsdos4'):
***************
*** 214,224 ****
                      return 'w', l_len, l_start, l_whence, l_pid
  
- #
- # Public routine to obtain a posixfile object
- #
  def open(name, mode='r', bufsize=-1):
      return _posixfile_().open(name, mode, bufsize)
  
  def fileopen(file):
      return _posixfile_().fileopen(file)
  
--- 213,222 ----
                      return 'w', l_len, l_start, l_whence, l_pid
  
  def open(name, mode='r', bufsize=-1):
+     """Public routine to open a file as a posixfile object."""
      return _posixfile_().open(name, mode, bufsize)
  
  def fileopen(file):
+     """Public routine to get a posixfile object from a Python file object."""
      return _posixfile_().fileopen(file)
  

Index: posixpat.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/posixpat.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** posixpat.py	1999/02/09 18:40:11	1.9
--- posixpat.py	2000/05/08 17:31:00	1.10
***************
*** 1,12 ****
! # Module 'posixpath' -- common operations on Posix pathnames.
! # Some of this can actually be useful on non-Posix systems too, e.g.
! # for manipulation of the pathname component of URLs.
! # The "os.path" name is an alias for this module on Posix systems;
! # on other systems (e.g. Mac, Windows), os.path provides the same
! # operations in a manner specific to that platform, and is an alias
! # to another module (e.g. macpath, ntpath).
! """Common pathname manipulations, Posix version. 
! Instead of importing this module
! directly, import os and refer to this module as os.path.
  """
  
--- 1,12 ----
! """Common operations on Posix pathnames.
! 
! Instead of importing this module directly, import os and refer to
! this module as os.path.  The "os.path" name is an alias for this
! module on Posix systems; on other systems (e.g. Mac, Windows),
! os.path provides the same operations in a manner specific to that
! platform, and is an alias to another module (e.g. macpath, ntpath).
! 
! Some of this can actually be useful on non-Posix systems too, e.g.
! for manipulation of the pathname component of URLs.
  """
  
***************
*** 144,148 ****
      """Return the last access time of a file, reported by os.stat()."""
      st = os.stat(filename)
!     return st[stat.ST_MTIME]
  
  
--- 144,148 ----
      """Return the last access time of a file, reported by os.stat()."""
      st = os.stat(filename)
!     return st[stat.ST_ATIME]
  
  
***************
*** 255,259 ****
  
  def walk(top, func, arg):
!     """walk(top,func,args) calls func(arg, d, files) for each directory "d" 
  in the tree  rooted at "top" (including "top" itself).  "files" is a list
  of all the files and subdirs in directory "d".
--- 255,259 ----
  
  def walk(top, func, arg):
!     """walk(top,func,arg) calls func(arg, d, files) for each directory "d" 
  in the tree  rooted at "top" (including "top" itself).  "files" is a list
  of all the files and subdirs in directory "d".
***************
*** 264,272 ****
          return
      func(arg, top, names)
-     exceptions = ('.', '..')
      for name in names:
-         if name not in exceptions:
              name = join(top, name)
!             if isdir(name) and not islink(name):
                  walk(name, func, arg)
  
--- 264,271 ----
          return
      func(arg, top, names)
      for name in names:
              name = join(top, name)
!             st = os.lstat(name)
!             if stat.S_ISDIR(st[stat.ST_MODE]):
                  walk(name, func, arg)
  
***************
*** 370,375 ****
  
  
- # Return an absolute path.
  def abspath(path):
      if not isabs(path):
          path = join(os.getcwd(), path)
--- 369,374 ----
  
  
  def abspath(path):
+     """Return an absolute path."""
      if not isabs(path):
          path = join(os.getcwd(), path)

Index: py_compi.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/py_compi.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** py_compi.py	1998/10/17 18:09:27	1.8
--- py_compi.py	2000/05/08 17:31:00	1.9
***************
*** 8,12 ****
  
  def wr_long(f, x):
!     "Internal; write a 32-bit int to a file in little-endian order."
      f.write(chr( x        & 0xff))
      f.write(chr((x >> 8)  & 0xff))
--- 8,12 ----
  
  def wr_long(f, x):
!     """Internal; write a 32-bit int to a file in little-endian order."""
      f.write(chr( x        & 0xff))
      f.write(chr((x >> 8)  & 0xff))

Index: queue.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/queue.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** queue.py	1999/02/09 18:40:12	1.6
--- queue.py	2000/05/08 17:31:00	1.7
***************
*** 1,3 ****
! # A multi-producer, multi-consumer queue.
  
  # define this exception to be compatible with Python 1.5's class
--- 1,3 ----
! """A multi-producer, multi-consumer queue."""
  
  # define this exception to be compatible with Python 1.5's class
***************
*** 16,20 ****
  
  class Queue:
!     def __init__(self, maxsize):
          """Initialize a queue object with a given maximum size.
  
--- 16,20 ----
  
  class Queue:
!     def __init__(self, maxsize=0):
          """Initialize a queue object with a given maximum size.
  

Index: regex_sy.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/regex_sy.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** regex_sy.py	1997/11/26 15:44:17	1.2
--- regex_sy.py	2000/05/08 17:31:00	1.3
***************
*** 1,4 ****
! # These bits are passed to regex.set_syntax() to choose among
! # alternative regexp syntaxes.
  
  # 1 means plain parentheses serve as grouping, and backslash
--- 1,10 ----
! """Constants for selecting regexp syntaxes for the obsolete regex module.
! 
! This module is only for backward compatibility.  "regex" has now
! been replaced by the new regular expression module, "re".
! 
! These bits are passed to regex.set_syntax() to choose among
! alternative regexp syntaxes.
! """
  
  # 1 means plain parentheses serve as grouping, and backslash

Index: rlcomple.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/rlcomple.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** rlcomple.py	1998/08/12 02:38:00	1.4
--- rlcomple.py	2000/05/08 17:31:01	1.5
***************
*** 2,6 ****
  
  This requires the latest extension to the readline module (the
- set_completer() function).  When completing a simple identifier, it
  completes keywords, built-ins and globals in __main__; when completing
  NAME.NAME..., it evaluates (!) the expression up to the last dot and
--- 2,5 ----
***************
*** 88,92 ****
          evaluabable in the globals of __main__, it will be evaluated
          and its attributes (as revealed by dir()) are used as possible
!         completions.
  
          WARNING: this can still invoke arbitrary C code, if an object
--- 87,92 ----
          evaluabable in the globals of __main__, it will be evaluated
          and its attributes (as revealed by dir()) are used as possible
!         completions.  (For class instances, class members are are also
!         considered.)
  
          WARNING: this can still invoke arbitrary C code, if an object
***************
*** 99,103 ****
              return
          expr, attr = m.group(1, 3)
!         words = dir(eval(expr, __main__.__dict__))
          matches = []
          n = len(attr)
--- 99,107 ----
              return
          expr, attr = m.group(1, 3)
!         object = eval(expr, __main__.__dict__)
!         words = dir(object)
!         if hasattr(object,'__class__'):
!             words.append('__class__')
!             words = words + get_class_members(object.__class__)
          matches = []
          n = len(attr)
***************
*** 106,109 ****
--- 110,120 ----
                  matches.append("%s.%s" % (expr, word))
          return matches
+ 
+ def get_class_members(klass):
+     ret = dir(klass)
+     if hasattr(klass,'__bases__'):
+         for base in klass.__bases__:
+             ret = ret + get_class_members(base)
+     return ret
  
  readline.set_completer(Completer().complete)

Index: simpleht.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/simpleht.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** simpleht.py	1998/12/22 13:50:31	1.4
--- simpleht.py	2000/05/08 17:31:01	1.5
***************
*** 11,21 ****
  
  import os
- import sys
- import time
- import socket
  import string
  import posixpath
- import SocketServer
  import BaseHTTPServer
  
  
--- 11,18 ----
  
  import os
  import string
  import posixpath
  import BaseHTTPServer
+ import urllib
  
  
***************
*** 82,86 ****
  
          """
!         path = posixpath.normpath(path)
          words = string.splitfields(path, '/')
          words = filter(None, words)
--- 79,83 ----
  
          """
!         path = posixpath.normpath(urllib.unquote(path))
          words = string.splitfields(path, '/')
          words = filter(None, words)

Index: socketse.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/socketse.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** socketse.py	1998/12/22 13:50:32	1.8
--- socketse.py	2000/05/08 17:31:01	1.9
***************
*** 208,212 ****
      def handle_request(self):
          """Handle one request, possibly blocking."""
!         request, client_address = self.get_request()
          if self.verify_request(request, client_address):
              try:
--- 208,215 ----
      def handle_request(self):
          """Handle one request, possibly blocking."""
!         try:
!             request, client_address = self.get_request()
!         except socket.error:
!             return
          if self.verify_request(request, client_address):
              try:
***************
*** 279,287 ****
  
      active_children = None
  
      def collect_children(self):
          """Internal routine to wait for died children."""
          while self.active_children:
!             pid, status = os.waitpid(0, os.WNOHANG)
              if not pid: break
              self.active_children.remove(pid)
--- 282,300 ----
  
      active_children = None
+     max_children = 40
  
      def collect_children(self):
          """Internal routine to wait for died children."""
          while self.active_children:
!             if len(self.active_children) < self.max_children:
!                 options = os.WNOHANG
!             else:
!                 # If the maximum number of children are already
!                 # running, block while waiting for a child to exit
!                 options = 0
!             try:
!                 pid, status = os.waitpid(0, options)
!             except os.error:
!                 pid = None
              if not pid: break
              self.active_children.remove(pid)
***************
*** 301,304 ****
--- 314,318 ----
              # This must never return, hence os._exit()!
              try:
+                 self.socket.close()
                  self.finish_request(request, client_address)
                  os._exit(0)
***************
*** 312,323 ****
  
  class ThreadingMixIn:
- 
      """Mix-in class to handle each request in a new thread."""
  
      def process_request(self, request, client_address):
          """Start a new thread to process the request."""
!         import thread
!         thread.start_new_thread(self.finish_request,
!                                 (request, client_address))
  
  
--- 326,337 ----
  
  class ThreadingMixIn:
      """Mix-in class to handle each request in a new thread."""
  
      def process_request(self, request, client_address):
          """Start a new thread to process the request."""
!         import threading
!         t = threading.Thread(target = self.finish_request,
!                              args = (request, client_address))
!         t.start()
  
  

Index: statcach.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/statcach.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** statcach.py	1996/07/22 15:22:37	1.1
--- statcach.py	2000/05/08 17:31:01	1.2
***************
*** 1,6 ****
! # Module 'statcache'
! #
! # Maintain a cache of file stats.
! # There are functions to reset the cache or to selectively remove items.
  
  import os
--- 1,6 ----
! """Maintain a cache of stat() information on files.
! 
! There are functions to reset the cache or to selectively remove items.
! """
  
  import os
***************
*** 13,19 ****
  
  
- # Stat a file, possibly out of the cache.
- #
  def stat(path):
  	if cache.has_key(path):
  		return cache[path]
--- 13,18 ----
  
  
  def stat(path):
+ 	"""Stat a file, possibly out of the cache."""
  	if cache.has_key(path):
  		return cache[path]
***************
*** 22,42 ****
  
  
- # Reset the cache completely.
- #
  def reset():
  	global cache
  	cache = {}
  
  
- # Remove a given item from the cache, if it exists.
- #
  def forget(path):
  	if cache.has_key(path):
  		del cache[path]
  
  
- # Remove all pathnames with a given prefix.
- #
  def forget_prefix(prefix):
  	n = len(prefix)
  	for path in cache.keys():
--- 21,38 ----
  
  
  def reset():
+ 	"""Reset the cache completely."""
  	global cache
  	cache = {}
  
  
  def forget(path):
+ 	"""Remove a given item from the cache, if it exists."""
  	if cache.has_key(path):
  		del cache[path]
  
  
  def forget_prefix(prefix):
+ 	"""Remove all pathnames with a given prefix."""
  	n = len(prefix)
  	for path in cache.keys():
***************
*** 45,52 ****
  
  
- # Forget about a directory and all entries in it, but not about
- # entries in subdirectories.
- #
  def forget_dir(prefix):
  	if prefix[-1:] == '/' and prefix <> '/':
  		prefix = prefix[:-1]
--- 41,47 ----
  
  
  def forget_dir(prefix):
+ 	"""Forget about a directory and all entries in it, but not about
+ 	entries in subdirectories."""
  	if prefix[-1:] == '/' and prefix <> '/':
  		prefix = prefix[:-1]
***************
*** 63,70 ****
  
  
- # Remove all pathnames except with a given prefix.
- # Normally used with prefix = '/' after a chdir().
- #
  def forget_except_prefix(prefix):
  	n = len(prefix)
  	for path in cache.keys():
--- 58,64 ----
  
  
  def forget_except_prefix(prefix):
+ 	"""Remove all pathnames except with a given prefix.
+ 	Normally used with prefix = '/' after a chdir()."""
  	n = len(prefix)
  	for path in cache.keys():
***************
*** 73,79 ****
  
  
- # Check for directory.
- #
  def isdir(path):
  	try:
  		st = stat(path)
--- 67,72 ----
  
  
  def isdir(path):
+ 	"""Check for directory."""
  	try:
  		st = stat(path)

Index: stringio.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/stringio.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** stringio.py	1998/10/02 01:23:43	1.3
--- stringio.py	2000/05/08 17:31:01	1.4
***************
*** 1,29 ****
! # class StringIO implements  file-like objects that read/write a
! # string buffer (a.k.a. "memory files").
! #
! # This implements (nearly) all stdio methods.
! #
! # f = StringIO()      # ready for writing
! # f = StringIO(buf)   # ready for reading
! # f.close()           # explicitly release resources held
! # flag = f.isatty()   # always false
! # pos = f.tell()      # get current position
! # f.seek(pos)         # set current position
! # f.seek(pos, mode)   # mode 0: absolute; 1: relative; 2: relative to EOF
! # buf = f.read()      # read until EOF
! # buf = f.read(n)     # read up to n bytes
! # buf = f.readline()  # read until end of line ('\n') or EOF
! # list = f.readlines()# list of f.readline() results until EOF
! # f.write(buf)        # write at current position
! # f.writelines(list)  # for line in list: f.write(line)
! # f.getvalue()        # return whole file's contents as a string
! #
! # Notes:
! # - Using a real file is often faster (but less convenient).
! # - fileno() is left unimplemented so that code which uses it triggers
! #   an exception early.
! # - Seeking far beyond EOF and then writing will insert real null
! #   bytes that occupy space in the buffer.
! # - There's a simple test set (see end of this file).
  
  import string
--- 1,31 ----
! """File-like objects that read from or write to a string buffer.
! 
! This implements (nearly) all stdio methods.
! 
! f = StringIO()      # ready for writing
! f = StringIO(buf)   # ready for reading
! f.close()           # explicitly release resources held
! flag = f.isatty()   # always false
! pos = f.tell()      # get current position
! f.seek(pos)         # set current position
! f.seek(pos, mode)   # mode 0: absolute; 1: relative; 2: relative to EOF
! buf = f.read()      # read until EOF
! buf = f.read(n)     # read up to n bytes
! buf = f.readline()  # read until end of line ('\n') or EOF
! list = f.readlines()# list of f.readline() results until EOF
! f.write(buf)        # write at current position
! f.writelines(list)  # for line in list: f.write(line)
! f.getvalue()        # return whole file's contents as a string
! 
! Notes:
! - Using a real file is often faster (but less convenient).
! - There's also a much faster implementation in C, called cStringIO, but
!   it's not subclassable.
! - fileno() is left unimplemented so that code which uses it triggers
!   an exception early.
! - Seeking far beyond EOF and then writing will insert real null
!   bytes that occupy space in the buffer.
! - There's a simple test set (see end of this file).
! """
  
  import string

Index: telnetli.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/telnetli.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** telnetli.py	1999/01/25 21:57:27	1.3
--- telnetli.py	2000/05/08 17:31:02	1.4
***************
*** 330,333 ****
--- 330,334 ----
                      self.msg('IAC %s %d',
                               c == WILL and 'WILL' or 'WONT', ord(c))
+                     self.sock.send(IAC + DONT + opt)
                  else:
                      self.msg('IAC %s not recognized' % `c`)

Index: test_bin.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_bin.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** test_bin.py	1998/03/26 22:13:41	1.2
--- test_bin.py	2000/05/08 17:31:02	1.3
***************
*** 1,46 ****
! #! /usr/bin/env python
! """Test script for the binascii C module
  
-    Uses the mechanism of the python binhex module
-    Roger E. Masse
- """
- import binhex
- import tempfile
  from test_support import verbose
  
! def test():
  
!     try:
!         fname1 = tempfile.mktemp()
!         fname2 = tempfile.mktemp()
!         f = open(fname1, 'w')
!     except:
!         raise ImportError, "Cannot test binascii without a temp file"
! 
!     start = 'Jack is my hero'
!     f.write(start)
!     f.close()
!     
!     binhex.binhex(fname1, fname2)
!     if verbose:
!         print 'binhex'
! 
!     binhex.hexbin(fname2, fname1)
!     if verbose:
!         print 'hexbin'
! 
!     f = open(fname1, 'r')
!     finish = f.readline()
! 
!     if start <> finish:
!         print 'Error: binhex <> hexbin'
!     elif verbose:
!         print 'binhex == hexbin'
! 
!     try:
!         import os
!         os.unlink(fname1)
!         os.unlink(fname2)
!     except:
!         pass
! test()
--- 1,93 ----
! """Test the binascii C module."""
  
  from test_support import verbose
+ import binascii
  
! # Show module doc string
! print binascii.__doc__
  
! # Show module exceptions
! print binascii.Error
! print binascii.Incomplete
! 
! # 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__)
! 
! # 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"
! 
! # 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
! 
! # 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
! 
! # 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

Index: test_cpi.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_cpi.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** test_cpi.py	1999/04/08 20:27:45	1.1
--- test_cpi.py	2000/05/08 17:31:02	1.2
***************
*** 80,96 ****
      try:
          cPickle.dump(123, f)
!     except IOError:
          pass
      else:
!         print "dump to closed file should raise IOError"
      f = open(fn, "r")
      f.close()
      try:
          cPickle.load(f)
!     except IOError:
          pass
      else:
!         print "load from closed file should raise IOError"
      os.remove(fn)
  
  dotest()
--- 80,107 ----
      try:
          cPickle.dump(123, f)
!     except ValueError:
          pass
      else:
!         print "dump to closed file should raise ValueError"
      f = open(fn, "r")
      f.close()
      try:
          cPickle.load(f)
!     except ValueError:
          pass
      else:
!         print "load from closed file should raise ValueError"
      os.remove(fn)
+ 
+     # Test specific bad cases
+     for i in range(10):
+         try:
+             x = cPickle.loads('garyp')
+         except cPickle.BadPickleGet, y:
+             del y
+         else:
+             print "unexpected success!"
+             break
+     
  
  dotest()

Index: test_fcn.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_fcn.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** test_fcn.py	1999/04/08 20:27:46	1.5
--- test_fcn.py	2000/05/08 17:31:02	1.6
***************
*** 19,23 ****
  if sys.platform in ('netbsd1',
                      'freebsd2', 'freebsd3',
!                     'bsdos2', 'bsdos3', 'bsdos4'):
      lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
  elif sys.platform in ['aix3', 'aix4']:
--- 19,24 ----
  if sys.platform in ('netbsd1',
                      'freebsd2', 'freebsd3',
!                     'bsdos2', 'bsdos3', 'bsdos4',
!                     'openbsd', 'openbsd2'):
      lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
  elif sys.platform in ['aix3', 'aix4']:

Index: test_gdb.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_gdb.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** test_gdb.py	1997/04/02 06:13:08	1.1
--- test_gdb.py	2000/05/08 17:31:02	1.2
***************
*** 6,10 ****
  import gdbm
  from gdbm import error
! from test_support import verbose
  
  filename= '/tmp/delete_me'
--- 6,10 ----
  import gdbm
  from gdbm import error
! from test_support import verbose, TestFailed
  
  filename= '/tmp/delete_me'
***************
*** 19,22 ****
--- 19,28 ----
  g.has_key('a')
  g.close()
+ try:
+     g['a']
+ except error:
+     pass
+ else:
+     raise TestFailed, "expected gdbm.error accessing closed database"
  g = gdbm.open(filename, 'r')
  g.close()

Index: test_gra.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_gra.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** test_gra.py	1997/05/08 23:14:39	1.2
--- test_gra.py	2000/05/08 17:31:02	1.3
***************
*** 141,149 ****
  ### 'def' NAME parameters ':' suite
  ### parameters: '(' [varargslist] ')'
! ### varargslist: (fpdef ['=' test] ',')* '*' NAME
! ###            | fpdef ['=' test] (',' fpdef ['=' test])* [',']
  ### fpdef: NAME | '(' fplist ')'
  ### fplist: fpdef (',' fpdef)* [',']
  def f1(): pass
  def f2(one_argument): pass
  def f3(two, arguments): pass
--- 141,155 ----
  ### 'def' NAME parameters ':' suite
  ### parameters: '(' [varargslist] ')'
! ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
! ###            | ('**'|'*' '*') NAME)
! ###            | fpdef ['=' test] (',' fpdef ['=' test])* [',']  
  ### fpdef: NAME | '(' fplist ')'
  ### fplist: fpdef (',' fpdef)* [',']
+ ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+ ### argument: [test '='] test	# Really [keyword '='] test
  def f1(): pass
+ f1()
+ f1(*())
+ f1(*(), **{})
  def f2(one_argument): pass
  def f3(two, arguments): pass
***************
*** 158,171 ****
--- 164,188 ----
  d01()
  d01(1)
+ d01(*(1,))
+ d01(**{'a':2})
  def d11(a, b=1): pass
  d11(1)
  d11(1, 2)
+ d11(1, **{'b':2})
  def d21(a, b, c=1): pass
  d21(1, 2)
  d21(1, 2, 3)
+ d21(*(1, 2, 3))
+ d21(1, *(2, 3))
+ d21(1, 2, *(3,))
+ d21(1, 2, **{'c':3})
  def d02(a=1, b=2): pass
  d02()
  d02(1)
  d02(1, 2)
+ d02(*(1, 2))
+ d02(1, *(2,))
+ d02(1, **{'b':2})
+ d02(**{'a': 1, 'b': 2})
  def d12(a, b=1, c=2): pass
  d12(1)
***************
*** 180,183 ****
--- 197,203 ----
  d01v(1)
  d01v(1, 2)
+ d01v(*(1, 2, 3, 4))
+ d01v(*(1,))
+ d01v(**{'a':2})
  def d11v(a, b=1, *rest): pass
  d11v(1)
***************
*** 188,191 ****
--- 208,213 ----
  d21v(1, 2, 3)
  d21v(1, 2, 3, 4)
+ d21v(*(1, 2, 3, 4))
+ d21v(1, 2, **{'c': 3})
  def d02v(a=1, b=2, *rest): pass
  d02v()
***************
*** 193,196 ****
--- 215,220 ----
  d02v(1, 2)
  d02v(1, 2, 3)
+ d02v(1, *(2, 3, 4))
+ d02v(**{'a': 1, 'b': 2})
  def d12v(a, b=1, c=2, *rest): pass
  d12v(1)
***************
*** 198,201 ****
--- 222,228 ----
  d12v(1, 2, 3)
  d12v(1, 2, 3, 4)
+ d12v(*(1, 2, 3, 4))
+ d12v(1, 2, *(3, 4, 5))
+ d12v(1, *(2,), **{'c': 3})
  def d22v(a, b, c=1, d=2, *rest): pass
  d22v(1, 2)
***************
*** 203,206 ****
--- 230,236 ----
  d22v(1, 2, 3, 4)
  d22v(1, 2, 3, 4, 5)
+ d22v(*(1, 2, 3, 4))
+ d22v(1, 2, *(3, 4, 5))
+ d22v(1, *(2, 3), **{'d': 4})
  
  ### stmt: simple_stmt | compound_stmt
***************
*** 456,459 ****
--- 486,490 ----
  v3(1,(2,3),4)
  v3(1,(2,3),4,5,6,7,8,9,0)
+ print
  import sys, time
  c = sys.path[0]

Index: test_lon.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_lon.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** test_lon.py	1998/10/02 01:23:44	1.1
--- test_lon.py	2000/05/08 17:31:02	1.2
***************
*** 78,81 ****
--- 78,83 ----
      q, r = divmod(x, y)
      q2, r2 = x/y, x%y
+     pab, pba = x*y, y*x
+     check(pab == pba, "multiplication does not commute for", x, y)
      check(q == q2, "divmod returns different quotient than / for", x, y)
      check(r == r2, "divmod returns different mod than % for", x, y)
***************
*** 160,164 ****
              test_bitop_identities_3(x, y, getran((lenx + leny)/2))
  
! # ------------------------------------------------------ hex oct str atol
  
  def slow_format(x, base):
--- 162,166 ----
              test_bitop_identities_3(x, y, getran((lenx + leny)/2))
  
! # ------------------------------------------------- hex oct repr str atol
  
  def slow_format(x, base):
***************
*** 182,186 ****
  def test_format_1(x):
      from string import atol
!     for base, mapper in (8, oct), (10, str), (16, hex):
          got = mapper(x)
          expected = slow_format(x, base)
--- 184,188 ----
  def test_format_1(x):
      from string import atol
!     for base, mapper in (8, oct), (10, repr), (16, hex):
          got = mapper(x)
          expected = slow_format(x, base)
***************
*** 188,191 ****
--- 190,199 ----
                got, "but expected", expected, "for", x)
          check(atol(got, 0) == x, 'atol("%s", 0) !=' % got, x)
+     # str() has to be checked a little differently since there's no
+     # trailing "L"
+     got = str(x)
+     expected = slow_format(x, 10)[:-1]
+     check(got == expected, mapper.__name__, "returned",
+           got, "but expected", expected, "for", x)
  
  def test_format(maxdigits=MAXDIGITS):

Index: test_rfc.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_rfc.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** test_rfc.py	1999/01/25 21:57:28	1.1
--- test_rfc.py	2000/05/08 17:31:03	1.2
***************
*** 12,15 ****
--- 12,16 ----
      m = rfc822.Message(fp)
      i = 0
+     
      for n, a in m.getaddrlist('to') + m.getaddrlist('cc'):
          if verbose:
***************
*** 29,32 ****
--- 30,48 ----
              print 'not found:', repr(n), repr(a)
  
+     out = m.getdate('date')
+     if out:
+         if verbose:
+             print 'Date:', m.getheader('date')
+         if out == (1999, 1, 13, 23, 57, 35, 0, 0, 0):
+             if verbose:
+                 print '    [matched]'
+         else:
+             if verbose:
+                 print '    [no match]'
+             print 'Date conversion failed:', out
+ 
+ # Note: all test cases must have the same date (in various formats),
+ # or no date!
+ 
  test('''Date:    Wed, 13 Jan 1999 23:57:35 -0500
  From:    Guido van Rossum <guido@CNRI.Reston.VA.US>
***************
*** 41,44 ****
--- 57,61 ----
  To: guido@python.org (Guido: the Barbarian)
  Subject: nonsense
+ Date: Wednesday, January 13 1999 23:57:35 -0500
  
  test''', [('Guido: the Barbarian', 'guido@python.org'),
***************
*** 48,51 ****
--- 65,69 ----
  To: guido@python.org (Guido: the Barbarian)
  Cc: "Guido: the Madman" <guido@python.org>
+ Date:  13-Jan-1999 23:57:35 EST
  
  test''', [('Guido: the Barbarian', 'guido@python.org'),
***************
*** 55,58 ****
--- 73,77 ----
  test('''To: "The monster with
       the very long name: Guido" <guido@python.org>
+ Date:    Wed, 13 Jan 1999 23:57:35 -0500
  
  test''', [('The monster with\n     the very long name: Guido',
***************
*** 64,67 ****
--- 83,87 ----
  Cc: fooz@bat.com, bart@toof.com
  Cc: goit@lip.com
+ Date:    Wed, 13 Jan 1999 23:57:35 -0500
  
  test''', [('Amit J. Patel', 'amitp@Theory.Stanford.EDU'),
***************
*** 76,79 ****
--- 96,100 ----
  # but it shouldn't be to infloop, which is what used to happen!
  test('''To: <[smtp:dd47@mail.xxx.edu]_at_hmhq@hdq-mdm1-imgout.companay.com>
+ Date:    Wed, 13 Jan 1999 23:57:35 -0500
  
  test''', [('', ''),
***************
*** 81,82 ****
--- 102,122 ----
            ('', '_at_hmhq@hdq-mdm1-imgout.companay.com')
            ])
+ 
+ # This exercises the old commas-in-a-full-name bug, which should be doing the
+ # right thing in recent versions of the module.
+ test('''To: "last, first" <userid@foo.net>
+ 
+ test''', [('last, first', 'userid@foo.net'),
+           ])
+ 
+ test('''To: (Comment stuff) "Quoted name"@somewhere.com
+ 
+ test''', [('Comment stuff', '"Quoted name"@somewhere.com'),
+           ])
+ 
+ test('''To: :
+ Cc: goit@lip.com
+ Date:    Wed, 13 Jan 1999 23:57:35 -0500
+ 
+ test''', [('', 'goit@lip.com')])
+ 

Index: test_soc.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_soc.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** test_soc.py	1998/03/26 22:14:03	1.5
--- test_soc.py	2000/05/08 17:31:03	1.6
***************
*** 98,102 ****
          # parent is server
          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
!         s.bind(hostname, PORT)
          s.listen(1)
          if verbose:
--- 98,102 ----
          # parent is server
          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
!         s.bind((hostname, PORT))
          s.listen(1)
          if verbose:
***************
*** 134,138 ****
              if verbose:
                  print 'child connecting'
!             s.connect(hostname, PORT)
              msg = 'socket test'
              s.send(msg)
--- 134,138 ----
              if verbose:
                  print 'child connecting'
!             s.connect((hostname, PORT))
              msg = 'socket test'
              s.send(msg)

Index: test_typ.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_typ.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** test_typ.py	1998/08/12 02:38:08	1.6
--- test_typ.py	2000/05/08 17:31:03	1.7
***************
*** 131,135 ****
--- 131,137 ----
  if [1,2]+[3,4] <> [1,2,3,4]: raise TestFailed, 'list concatenation'
  if [1,2]*3 <> [1,2,1,2,1,2]: raise TestFailed, 'list repetition *3'
+ if [1,2]*3L <> [1,2,1,2,1,2]: raise TestFailed, 'list repetition *3L'
  if 0*[1,2,3] <> []: raise TestFailed, 'list repetition 0*'
+ if 0L*[1,2,3] <> []: raise TestFailed, 'list repetition 0L*'
  if min([1,2]) <> 1 or max([1,2]) <> 2: raise TestFailed, 'min/max list'
  if 0 in [0,1,2] and 1 in [0,1,2] and 2 in [0,1,2] and 3 not in [0,1,2]: pass
***************
*** 151,158 ****
--- 153,167 ----
  print '6.5.3a Additional list operations'
  a = [0,1,2,3,4]
+ a[0L] = 1
+ a[1L] = 2
+ a[2L] = 3
+ if a <> [1,2,3,3,4]: raise TestFailed, 'list item assignment [0L], [1L], [2L]'
  a[0] = 5
  a[1] = 6
  a[2] = 7
  if a <> [5,6,7,3,4]: raise TestFailed, 'list item assignment [0], [1], [2]'
+ a[-2L] = 88
+ a[-1L] = 99
+ if a <> [5,6,7,88,99]: raise TestFailed, 'list item assignment [-2L], [-1L]'
  a[-2] = 8
  a[-1] = 9
***************
*** 162,165 ****
--- 171,176 ----
  a[1:1] = [1,2,3]
  if a <> [0,1,2,3,4]: raise TestFailed, 'list slice assignment'
+ a[ 1L : 4L] = [7,8,9]
+ if a <> [0,7,8,9,4]: raise TestFailed, 'list slice assignment using long ints'
  del a[1:4]
  if a <> [0,4]: raise TestFailed, 'list slice deletion'
***************
*** 168,171 ****
--- 179,189 ----
  del a[-1]
  if a <> []: raise TestFailed, 'list item deletion [-1]'
+ a=range(0,5)
+ del a[1L:4L]
+ if a <> [0,4]: raise TestFailed, 'list slice deletion'
+ del a[0L]
+ if a <> [4]: raise TestFailed, 'list item deletion [0]'
+ del a[-1L]
+ if a <> []: raise TestFailed, 'list item deletion [-1]'
  a.append(0)
  a.append(1)
***************
*** 192,195 ****
--- 210,220 ----
  z = range(12)
  z.sort(myComparison)
+ 
+ # Test extreme cases with long ints
+ a = [0,1,2,3,4]
+ if a[ -pow(2,128L): 3 ] != [0,1,2]: 
+ 	raise TestFailed, "list slicing with too-small long integer"
+ if a[ 3: pow(2,145L) ] != [3,4]: 
+ 	raise TestFailed, "list slicing with too-large long integer"
  
  print '6.6 Mappings == Dictionaries'

Index: test_zli.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/test_zli.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** test_zli.py	1999/04/08 20:27:53	1.4
--- test_zli.py	2000/05/08 17:31:03	1.5
***************
*** 81,92 ****
  for sync in [zlib.Z_NO_FLUSH, zlib.Z_SYNC_FLUSH, zlib.Z_FULL_FLUSH]:
      for level in range(10):
! 	obj = zlib.compressobj( level )
!     	d = obj.compress( buf[:3000] )
! 	d = d + obj.flush( sync )
! 	d = d + obj.compress( buf[3000:] )
! 	d = d + obj.flush()
! 	if zlib.decompress(d) != buf:
! 	    print "Decompress failed: flush mode=%i, level=%i" % (sync,level)
! 	del obj
  
  def ignore():
--- 81,92 ----
  for sync in [zlib.Z_NO_FLUSH, zlib.Z_SYNC_FLUSH, zlib.Z_FULL_FLUSH]:
      for level in range(10):
!         obj = zlib.compressobj( level )
!         d = obj.compress( buf[:3000] )
!         d = d + obj.flush( sync )
!         d = d + obj.compress( buf[3000:] )
!         d = d + obj.flush()
!         if zlib.decompress(d) != buf:
!             print "Decompress failed: flush mode=%i, level=%i" % (sync,level)
!         del obj
  
  def ignore():

Index: threadin.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/threadin.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** threadin.py	1998/10/02 01:23:47	1.1
--- threadin.py	2000/05/08 17:31:03	1.2
***************
*** 1,4 ****
! # threading.py:
! # Proposed new threading module, emulating a subset of Java's threading model
  
  import sys
--- 1,3 ----
! """Proposed new threading module, emulating a subset of Java's threading model."""
  
  import sys
***************
*** 239,243 ****
  class _Semaphore(_Verbose):
  
!     # After Tim Peters' semaphore class, but bnot quite the same (no maximum)
  
      def __init__(self, value=1, verbose=None):
--- 238,242 ----
  class _Semaphore(_Verbose):
  
!     # After Tim Peters' semaphore class, but not quite the same (no maximum)
  
      def __init__(self, value=1, verbose=None):
***************
*** 507,511 ****
      def __init__(self):
          Thread.__init__(self, name=_newname("Dummy-%d"))
!         self.__Thread_started = 1
          _active_limbo_lock.acquire()
          _active[_get_ident()] = self
--- 506,510 ----
      def __init__(self):
          Thread.__init__(self, name=_newname("Dummy-%d"))
!         self._Thread__started = 1
          _active_limbo_lock.acquire()
          _active[_get_ident()] = self

Index: tracebac.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/tracebac.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** tracebac.py	1998/03/26 22:14:18	1.6
--- tracebac.py	2000/05/08 17:31:04	1.7
***************
*** 1,3 ****
! # Format and print Python stack traces
  
  import linecache
--- 1,3 ----
! """Extract, format and print information about Python stack traces."""
  
  import linecache
***************
*** 11,14 ****
--- 11,16 ----
  
  def print_list(extracted_list, file=None):
+ 	"""Print the list of tuples as returned by extract_tb() or
+ 	extract_stack() as a formatted stack trace to the given file."""
  	if not file:
  		file = sys.stderr
***************
*** 20,23 ****
--- 22,31 ----
  
  def format_list(extracted_list):
+ 	"""Given a list of tuples as returned by extract_tb() or
+ 	extract_stack(), return a list of strings ready for printing.
+ 	Each string in the resulting list corresponds to the item with
+ 	the same index in the argument list.  Each string ends in a
+ 	newline; the strings may contain internal newlines as well, for
+ 	those items whose source text line is not None."""
  	list = []
  	for filename, lineno, name, line in extracted_list:
***************
*** 30,33 ****
--- 38,45 ----
  
  def print_tb(tb, limit=None, file=None):
+ 	"""Print up to 'limit' stack trace entries from the traceback 'tb'.
+ 	If 'limit' is omitted or None, all entries are printed.  If 'file' is
+ 	omitted or None, the output goes to sys.stderr; otherwise 'file'
+ 	should be an open file or file-like object with a write() method."""
  	if not file:
  		file = sys.stderr
***************
*** 50,56 ****
--- 62,77 ----
  
  def format_tb(tb, limit = None):
+ 	"""A shorthand for 'format_list(extract_stack(f, limit))."""
  	return format_list(extract_tb(tb, limit))
  
  def extract_tb(tb, limit = None):
+ 	"""Return a list of up to 'limit' pre-processed stack trace entries
+ 	extracted from the traceback object 'traceback'.  This is useful for
+ 	alternate formatting of stack traces.  If 'limit' is omitted or None,
+ 	all entries are extracted.  A pre-processed stack trace entry is a
+ 	quadruple (filename, line number, function name, text) representing
+ 	the information that is usually printed for a stack trace.  The text
+ 	is a string with leading and trailing whitespace stripped; if the
+ 	source is not available it is None."""
  	if limit is None:
  		if hasattr(sys, 'tracebacklimit'):
***************
*** 74,81 ****
  
  def print_exception(etype, value, tb, limit=None, file=None):
  	if not file:
  		file = sys.stderr
  	if tb:
! 		_print(file, 'Traceback (innermost last):')
  		print_tb(tb, limit, file)
  	lines = format_exception_only(etype, value)
--- 95,110 ----
  
  def print_exception(etype, value, tb, limit=None, file=None):
+ 	"""Print exception information and up to 'limit' stack trace entries
+ 	from the traceback 'tb' to 'file'.  This differs from print_tb() in
+ 	the following ways: (1) if traceback is not None, it prints a header
+ 	"Traceback (most recent call last):"; (2) it prints the exception type and
+ 	value after the stack trace; (3) if type is SyntaxError and value has
+ 	the appropriate format, it prints the line where the syntax error
+ 	occurred with a caret on the next line indicating the approximate
+ 	position of the error."""
  	if not file:
  		file = sys.stderr
  	if tb:
! 		_print(file, 'Traceback (most recent call last):')
  		print_tb(tb, limit, file)
  	lines = format_exception_only(etype, value)
***************
*** 85,90 ****
  
  def format_exception(etype, value, tb, limit = None):
  	if tb:
! 		list = ['Traceback (innermost last):\n']
  		list = list + format_tb(tb, limit)
  	else:
--- 114,125 ----
  
  def format_exception(etype, value, tb, limit = None):
+ 	"""Format a stack trace and the exception information.  The arguments
+ 	have the same meaning as the corresponding arguments to
+ 	print_exception().  The return value is a list of strings, each
+ 	ending in a newline and some containing internal newlines.  When 
+ 	these lines are contatenated and printed, exactly the same text is
+ 	printed as does print_exception()."""
  	if tb:
! 		list = ['Traceback (most recent call last):\n']
  		list = list + format_tb(tb, limit)
  	else:
***************
*** 94,97 ****
--- 129,140 ----
  
  def format_exception_only(etype, value):
+ 	"""Format the exception part of a traceback.  The arguments are the
+ 	exception type and value such as given by sys.last_type and
+ 	sys.last_value. The return value is a list of strings, each ending
+ 	in a newline.  Normally, the list contains a single string;
+ 	however, for SyntaxError exceptions, it contains several lines that
+ 	(when printed) display detailed information about where the syntax
+ 	error occurred.  The message indicating which exception occurred is
+ 	the always last string in the list."""
  	list = []
  	if type(etype) == types.ClassType:
***************
*** 129,132 ****
--- 172,179 ----
  
  def print_exc(limit=None, file=None):
+ 	"""This is a shorthand for 'print_exception(sys.exc_type,
+ 	sys.exc_value, sys.exc_traceback, limit, file)'.
+ 	(In fact, it uses sys.exc_info() to retrieve the same information
+ 	in a thread-safe way.)"""
  	if not file:
  		file = sys.stderr
***************
*** 138,141 ****
--- 185,190 ----
  
  def print_last(limit=None, file=None):
+ 	"""This is a shorthand for 'print_exception(sys.last_type,
+ 	sys.last_value, sys.last_traceback, limit, file)'."""
  	if not file:
  		file = sys.stderr
***************
*** 145,148 ****
--- 194,201 ----
  
  def print_stack(f=None, limit=None, file=None):
+ 	"""This function prints a stack trace from its invocation point.
+ 	The optional 'f' argument can be used to specify an alternate stack
+ 	frame at which to start. The optional 'limit' and 'file' arguments
+ 	have the same meaning as for print_exception()."""
  	if f is None:
  		try:
***************
*** 153,156 ****
--- 206,210 ----
  
  def format_stack(f=None, limit=None):
+ 	"""A shorthand for 'format_list(extract_stack(f, limit))'."""
  	if f is None:
  		try:
***************
*** 161,164 ****
--- 215,224 ----
  
  def extract_stack(f=None, limit = None):
+ 	"""Extract the raw traceback from the current stack frame.  The
+ 	return value has the same format as for extract_tb().  The optional
+ 	'f' and 'limit' arguments have the same meaning as for print_stack(). 
+ 	Each item in the list is a quadruple (filename, line number,
+ 	function name, text), and the entries are in order from oldest
+ 	to newest stack frame."""
  	if f is None:
  		try:
***************
*** 185,195 ****
  	return list
  
- # Calculate the correct line number of the traceback given in tb (even
- # with -O on).
- # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
- # in compile.c.
- # Revised version by Jim Hugunin to work with JPython too.
- 
  def tb_lineno(tb):
  	c = tb.tb_frame.f_code
  	if not hasattr(c, 'co_lnotab'):
--- 245,256 ----
  	return list
  
  def tb_lineno(tb):
+ 	"""Calculate the correct line number of the traceback given in tb
+ 	(even with -O on)."""
+ 
+ 	# Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
+ 	# in compile.c.
+ 	# Revised version by Jim Hugunin to work with JPython too.
+ 
  	c = tb.tb_frame.f_code
  	if not hasattr(c, 'co_lnotab'):

Index: userdict.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/userdict.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** userdict.py	1999/04/08 20:27:54	1.5
--- userdict.py	2000/05/08 17:31:04	1.6
***************
*** 1,3 ****
! # A more or less complete user-defined wrapper around dictionary objects
  
  class UserDict:
--- 1,3 ----
! """A more or less complete user-defined wrapper around dictionary objects."""
  
  class UserDict:

Index: userlist.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/dos-8x3/userlist.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** userlist.py	1999/04/08 20:27:54	1.5
--- userlist.py	2000/05/08 17:31:04	1.6
***************
*** 1,12 ****
! # A more or less complete user-defined wrapper around list objects
  
  class UserList:
!     def __init__(self, list=None):
          self.data = []
!         if list is not None:
!             if type(list) == type(self.data):
!                 self.data[:] = list
              else:
!                 self.data[:] = list.data[:]
      def __repr__(self): return repr(self.data)
      def __cmp__(self, other):
--- 1,15 ----
! """A more or less complete user-defined wrapper around list objects."""
  
  class UserList:
!     def __init__(self, initlist=None):
          self.data = []
!         if initlist is not None:
!             # XXX should this accept an arbitary sequence?
!             if type(initlist) == type(self.data):
!                 self.data[:] = initlist
!             elif isinstance(initlist, UserList):
!                 self.data[:] = initlist.data[:]
              else:
!                 self.data = list(initlist)
      def __repr__(self): return repr(self.data)
      def __cmp__(self, other):