[Python-3000-checkins] r55005 - in python/branches/p3yk: Demo/parser/unparse.py Doc/api/abstract.tex Doc/api/concrete.tex Doc/api/init.tex Doc/api/memory.tex Doc/api/newtypes.tex Doc/api/utilities.tex Doc/commontex/copyright.tex Doc/commontex/license.tex Doc/dist/dist.tex Doc/ext/newtypes.tex Doc/ext/shoddy.c Doc/inst/inst.tex Doc/lib/compiler.tex Doc/lib/email.tex Doc/lib/emailutil.tex Doc/lib/libamoeba.tex Doc/lib/libasyncore.tex Doc/lib/libbsddb.tex Doc/lib/libcfgparser.tex Doc/lib/libcgitb.tex Doc/lib/libcmath.tex Doc/lib/libcmd.tex Doc/lib/libcode.tex Doc/lib/libcodecs.tex Doc/lib/libcollections.tex Doc/lib/libcommands.tex Doc/lib/libconsts.tex Doc/lib/libcookielib.tex Doc/lib/libctypes.tex Doc/lib/libcurses.tex Doc/lib/libcursespanel.tex Doc/lib/libdatetime.tex Doc/lib/libdbhash.tex Doc/lib/libdecimal.tex Doc/lib/libdl.tex Doc/lib/libdoctest.tex Doc/lib/libdocxmlrpc.tex Doc/lib/libdumbdbm.tex Doc/lib/libetree.tex Doc/lib/libfm.tex Doc/lib/libfnmatch.tex Doc/lib/libftplib.tex Doc/lib/libfuncs.tex Doc/lib/libgettext.tex Doc/lib/libhmac.tex Doc/lib/libhotshot.tex Doc/lib/libhtmllib.tex Doc/lib/libhtmlparser.tex Doc/lib/libhttplib.tex Doc/lib/libimaplib.tex Doc/lib/liblogging.tex Doc/lib/libmailbox.tex Doc/lib/libmimetools.tex Doc/lib/libmimetypes.tex Doc/lib/libmimewriter.tex Doc/lib/libmmap.tex Doc/lib/libmsilib.tex Doc/lib/libmultifile.tex Doc/lib/libmutex.tex Doc/lib/libnetrc.tex Doc/lib/libnntplib.tex Doc/lib/liboptparse.tex Doc/lib/libos.tex Doc/lib/libpdb.tex Doc/lib/libpipes.tex Doc/lib/libplatform.tex Doc/lib/libpopen2.tex Doc/lib/libpoplib.tex Doc/lib/libposixfile.tex Doc/lib/libposixpath.tex Doc/lib/libpprint.tex Doc/lib/libqueue.tex Doc/lib/libre.tex Doc/lib/librepr.tex Doc/lib/librexec.tex Doc/lib/librfc822.tex Doc/lib/libsched.tex Doc/lib/libselect.tex Doc/lib/libshlex.tex Doc/lib/libshutil.tex Doc/lib/libsimplexmlrpc.tex Doc/lib/libsite.tex Doc/lib/libsmtplib.tex Doc/lib/libsocket.tex Doc/lib/libsqlite3.tex Doc/lib/libstdtypes.tex Doc/lib/libstring.tex Doc/lib/libsubprocess.tex Doc/lib/libsun.tex Doc/lib/libsys.tex Doc/lib/libtarfile.tex Doc/lib/libtelnetlib.tex Doc/lib/libtempfile.tex Doc/lib/libtest.tex Doc/lib/libtextwrap.tex Doc/lib/libthreading.tex Doc/lib/libtimeit.tex Doc/lib/libturtle.tex Doc/lib/libunittest.tex Doc/lib/liburllib2.tex Doc/lib/liburlparse.tex Doc/lib/libwebbrowser.tex Doc/lib/libwinreg.tex Doc/lib/libxmlrpclib.tex Doc/lib/libzipfile.tex Doc/lib/libzlib.tex Doc/mac/libframework.tex Doc/mac/libmacic.tex Doc/mac/undoc.tex Doc/mac/using.tex Doc/ref/ref1.tex Doc/ref/ref3.tex Doc/ref/ref5.tex Doc/ref/ref6.tex Doc/ref/ref7.tex Doc/texinputs/python.sty Doc/tut/tut.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew24.tex Doc/whatsnew/whatsnew25.tex Doc/whatsnew/whatsnew26.tex Include/fileobject.h Include/pydebug.h Include/pystate.h Include/setobject.h LICENSE Lib/Bastion.py Lib/CGIHTTPServer.py Lib/ConfigParser.py Lib/DocXMLRPCServer.py Lib/HTMLParser.py Lib/SimpleXMLRPCServer.py Lib/SocketServer.py Lib/_strptime.py Lib/bisect.py Lib/cmd.py Lib/collections.py Lib/commands.py Lib/copy_reg.py Lib/csv.py Lib/ctypes/__init__.py Lib/ctypes/test/test_functions.py Lib/ctypes/test/test_memfunctions.py Lib/ctypes/test/test_numbers.py Lib/ctypes/test/test_repr.py Lib/decimal.py Lib/difflib.py Lib/distutils/__init__.py Lib/distutils/command/build_ext.py Lib/distutils/msvccompiler.py Lib/doctest.py Lib/email/_parseaddr.py Lib/email/header.py Lib/email/message.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/ftplib.py Lib/genericpath.py Lib/glob.py Lib/heapq.py Lib/httplib.py Lib/idlelib/MultiCall.py Lib/imaplib.py Lib/logging/handlers.py Lib/macpath.py Lib/ntpath.py Lib/os.py Lib/pdb.doc Lib/pdb.py Lib/popen2.py Lib/poplib.py Lib/posixpath.py Lib/pydoc.py Lib/rexec.py Lib/robotparser.py Lib/sched.py Lib/site.py Lib/smtplib.py Lib/socket.py Lib/sre.py Lib/subprocess.py Lib/tarfile.py Lib/telnetlib.py Lib/tempfile.py Lib/test/README Lib/test/crashers/modify_dict_attr.py Lib/test/infinite_reload.py Lib/test/output/test_operations Lib/test/output/test_popen2 Lib/test/output/test_pty Lib/test/output/test_pyexpat Lib/test/output/test_threadedtempfile Lib/test/output/xmltests Lib/test/outstanding_bugs.py Lib/test/pickletester.py Lib/test/regrtest.py Lib/test/ssl_cert.pem Lib/test/ssl_key.pem Lib/test/string_tests.py Lib/test/test___all__.py Lib/test/test_array.py Lib/test/test_atexit.py Lib/test/test_base64.py Lib/test/test_binascii.py Lib/test/test_bool.py Lib/test/test_bsddb3.py Lib/test/test_builtin.py Lib/test/test_cfgparser.py Lib/test/test_cmath.py Lib/test/test_cmd_line.py Lib/test/test_codecencodings_cn.py Lib/test/test_codecencodings_hk.py Lib/test/test_codecencodings_jp.py Lib/test/test_codecencodings_kr.py Lib/test/test_codecencodings_tw.py Lib/test/test_codecmaps_cn.py Lib/test/test_codecmaps_hk.py Lib/test/test_codecmaps_jp.py Lib/test/test_codecmaps_kr.py Lib/test/test_codecmaps_tw.py Lib/test/test_collections.py Lib/test/test_commands.py Lib/test/test_compile.py Lib/test/test_compiler.py Lib/test/test_complex.py Lib/test/test_contextlib.py Lib/test/test_crypt.py Lib/test/test_csv.py Lib/test/test_ctypes.py Lib/test/test_curses.py Lib/test/test_datetime.py Lib/test/test_defaultdict.py Lib/test/test_deque.py Lib/test/test_descr.py Lib/test/test_descrtut.py Lib/test/test_dict.py Lib/test/test_dis.py Lib/test/test_doctest.py Lib/test/test_email.py Lib/test/test_email_codecs.py Lib/test/test_email_renamed.py Lib/test/test_exceptions.py Lib/test/test_fileinput.py Lib/test/test_fileio.py Lib/test/test_ftplib.py Lib/test/test_functools.py Lib/test/test_gc.py Lib/test/test_getopt.py Lib/test/test_gettext.py Lib/test/test_glob.py Lib/test/test_grammar.py Lib/test/test_htmlparser.py Lib/test/test_httplib.py Lib/test/test_import.py Lib/test/test_itertools.py Lib/test/test_keywordonlyarg.py Lib/test/test_locale.py Lib/test/test_logging.py Lib/test/test_long_future.py Lib/test/test_macpath.py Lib/test/test_mailbox.py Lib/test/test_metaclass.py Lib/test/test_minidom.py Lib/test/test_module.py Lib/test/test_multibytecodec.py Lib/test/test_normalization.py Lib/test/test_ntpath.py Lib/test/test_operations.py Lib/test/test_operator.py Lib/test/test_optparse.py Lib/test/test_os.py Lib/test/test_ossaudiodev.py Lib/test/test_peepholer.py Lib/test/test_popen2.py Lib/test/test_poplib.py Lib/test/test_posixpath.py Lib/test/test_pty.py Lib/test/test_pyexpat.py Lib/test/test_re.py Lib/test/test_robotparser.py Lib/test/test_sax.py Lib/test/test_scope.py Lib/test/test_set.py Lib/test/test_slice.py Lib/test/test_smtplib.py Lib/test/test_socket.py Lib/test/test_socket_ssl.py Lib/test/test_socketserver.py Lib/test/test_stringprep.py Lib/test/test_strptime.py Lib/test/test_struct.py Lib/test/test_structmembers.py Lib/test/test_support.py Lib/test/test_syntax.py Lib/test/test_tarfile.py Lib/test/test_telnetlib.py Lib/test/test_tempfile.py Lib/test/test_textwrap.py Lib/test/test_threadedtempfile.py Lib/test/test_threading_local.py Lib/test/test_unicode.py Lib/test/test_unicode_file.py Lib/test/test_unittest.py Lib/test/test_unpack.py Lib/test/test_urllib.py Lib/test/test_urllib2.py Lib/test/test_urllib2net.py Lib/test/test_userdict.py Lib/test/test_warnings.py Lib/test/test_weakref.py Lib/test/test_wsgiref.py Lib/test/test_zipfile.py Lib/test/test_zlib.py Lib/test/testtar.tar Lib/test/warning_tests.py Lib/textwrap.py Lib/timeit.py Lib/unittest.py Lib/urllib.py Lib/urllib2.py Lib/wave.py Lib/webbrowser.py Lib/zipfile.py Misc/ACKS Misc/NEWS Misc/build.sh Misc/developers.txt Misc/python-config.in Modules/_bsddb.c Modules/_collectionsmodule.c Modules/_ctypes/_ctypes.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Modules/_ctypes/libffi/fficonfig.h.in Modules/_cursesmodule.c Modules/_localemodule.c Modules/_struct.c Modules/arraymodule.c Modules/binascii.c Modules/bz2module.c Modules/cPickle.c Modules/cStringIO.c Modules/collectionsmodule.c Modules/datetimemodule.c Modules/getpath.c Modules/main.c Modules/operator.c Modules/posixmodule.c Modules/readline.c Modules/socketmodule.c Modules/timemodule.c Objects/complexobject.c Objects/dictobject.c Objects/exceptions.c Objects/fileobject.c Objects/frameobject.c Objects/longobject.c Objects/setobject.c Objects/sliceobject.c Objects/stringobject.c Objects/typeobject.c PC/VC6/pcbuild.dsw PC/_winreg.c PC/config.c PC/getpathp.c PCbuild/pythoncore.vcproj PCbuild8/pythoncore.vcproj Python/ast.c Python/bltinmodule.c Python/ceval.c Python/compile.c Python/dynload_win.c Python/errors.c Python/fmod.c Python/import.c Python/peephole.c Python/pystate.c Python/pythonrun.c Python/sysmodule.c Python/thread_nt.h README Tools/pybench/pybench.py configure.in setup.py

guido.van.rossum python-3000-checkins at python.org
Fri Apr 27 21:55:56 CEST 2007


Author: guido.van.rossum
Date: Fri Apr 27 21:54:29 2007
New Revision: 55005

Added:
   python/branches/p3yk/Doc/ext/shoddy.c
      - copied unchanged from r54985, python/trunk/Doc/ext/shoddy.c
   python/branches/p3yk/Lib/collections.py
      - copied, changed from r54985, python/trunk/Lib/collections.py
   python/branches/p3yk/Lib/test/infinite_reload.py
      - copied unchanged from r54985, python/trunk/Lib/test/infinite_reload.py
   python/branches/p3yk/Lib/test/ssl_cert.pem
      - copied unchanged from r54985, python/trunk/Lib/test/ssl_cert.pem
   python/branches/p3yk/Lib/test/ssl_key.pem
      - copied unchanged from r54985, python/trunk/Lib/test/ssl_key.pem
   python/branches/p3yk/Lib/test/test_collections.py
      - copied unchanged from r54985, python/trunk/Lib/test/test_collections.py
   python/branches/p3yk/Lib/test/test_ftplib.py
      - copied unchanged from r54985, python/trunk/Lib/test/test_ftplib.py
   python/branches/p3yk/Lib/test/test_poplib.py
      - copied unchanged from r54985, python/trunk/Lib/test/test_poplib.py
   python/branches/p3yk/Lib/test/test_smtplib.py
      - copied unchanged from r54985, python/trunk/Lib/test/test_smtplib.py
   python/branches/p3yk/Lib/test/test_telnetlib.py
      - copied unchanged from r54985, python/trunk/Lib/test/test_telnetlib.py
   python/branches/p3yk/Lib/test/warning_tests.py
      - copied unchanged from r54985, python/trunk/Lib/test/warning_tests.py
   python/branches/p3yk/Modules/_collectionsmodule.c   (contents, props changed)
Removed:
   python/branches/p3yk/Lib/test/output/test_operations
   python/branches/p3yk/Lib/test/output/test_popen2
   python/branches/p3yk/Lib/test/output/test_pty
   python/branches/p3yk/Lib/test/output/test_pyexpat
   python/branches/p3yk/Lib/test/output/test_threadedtempfile
   python/branches/p3yk/Lib/test/output/xmltests
   python/branches/p3yk/Lib/test/test_operations.py
   python/branches/p3yk/Modules/collectionsmodule.c
   python/branches/p3yk/Python/fmod.c
Modified:
   python/branches/p3yk/   (props changed)
   python/branches/p3yk/Demo/parser/unparse.py
   python/branches/p3yk/Doc/api/abstract.tex
   python/branches/p3yk/Doc/api/concrete.tex
   python/branches/p3yk/Doc/api/init.tex
   python/branches/p3yk/Doc/api/memory.tex
   python/branches/p3yk/Doc/api/newtypes.tex
   python/branches/p3yk/Doc/api/utilities.tex
   python/branches/p3yk/Doc/commontex/copyright.tex
   python/branches/p3yk/Doc/commontex/license.tex
   python/branches/p3yk/Doc/dist/dist.tex
   python/branches/p3yk/Doc/ext/newtypes.tex
   python/branches/p3yk/Doc/inst/inst.tex
   python/branches/p3yk/Doc/lib/compiler.tex
   python/branches/p3yk/Doc/lib/email.tex
   python/branches/p3yk/Doc/lib/emailutil.tex
   python/branches/p3yk/Doc/lib/libamoeba.tex
   python/branches/p3yk/Doc/lib/libasyncore.tex
   python/branches/p3yk/Doc/lib/libbsddb.tex
   python/branches/p3yk/Doc/lib/libcfgparser.tex
   python/branches/p3yk/Doc/lib/libcgitb.tex
   python/branches/p3yk/Doc/lib/libcmath.tex
   python/branches/p3yk/Doc/lib/libcmd.tex
   python/branches/p3yk/Doc/lib/libcode.tex
   python/branches/p3yk/Doc/lib/libcodecs.tex
   python/branches/p3yk/Doc/lib/libcollections.tex
   python/branches/p3yk/Doc/lib/libcommands.tex
   python/branches/p3yk/Doc/lib/libconsts.tex
   python/branches/p3yk/Doc/lib/libcookielib.tex
   python/branches/p3yk/Doc/lib/libctypes.tex
   python/branches/p3yk/Doc/lib/libcurses.tex
   python/branches/p3yk/Doc/lib/libcursespanel.tex
   python/branches/p3yk/Doc/lib/libdatetime.tex
   python/branches/p3yk/Doc/lib/libdbhash.tex
   python/branches/p3yk/Doc/lib/libdecimal.tex
   python/branches/p3yk/Doc/lib/libdl.tex
   python/branches/p3yk/Doc/lib/libdoctest.tex
   python/branches/p3yk/Doc/lib/libdocxmlrpc.tex
   python/branches/p3yk/Doc/lib/libdumbdbm.tex
   python/branches/p3yk/Doc/lib/libetree.tex
   python/branches/p3yk/Doc/lib/libfm.tex
   python/branches/p3yk/Doc/lib/libfnmatch.tex
   python/branches/p3yk/Doc/lib/libftplib.tex
   python/branches/p3yk/Doc/lib/libfuncs.tex
   python/branches/p3yk/Doc/lib/libgettext.tex
   python/branches/p3yk/Doc/lib/libhmac.tex
   python/branches/p3yk/Doc/lib/libhotshot.tex
   python/branches/p3yk/Doc/lib/libhtmllib.tex
   python/branches/p3yk/Doc/lib/libhtmlparser.tex
   python/branches/p3yk/Doc/lib/libhttplib.tex
   python/branches/p3yk/Doc/lib/libimaplib.tex
   python/branches/p3yk/Doc/lib/liblogging.tex
   python/branches/p3yk/Doc/lib/libmailbox.tex
   python/branches/p3yk/Doc/lib/libmimetools.tex
   python/branches/p3yk/Doc/lib/libmimetypes.tex
   python/branches/p3yk/Doc/lib/libmimewriter.tex
   python/branches/p3yk/Doc/lib/libmmap.tex
   python/branches/p3yk/Doc/lib/libmsilib.tex
   python/branches/p3yk/Doc/lib/libmultifile.tex
   python/branches/p3yk/Doc/lib/libmutex.tex
   python/branches/p3yk/Doc/lib/libnetrc.tex
   python/branches/p3yk/Doc/lib/libnntplib.tex
   python/branches/p3yk/Doc/lib/liboptparse.tex
   python/branches/p3yk/Doc/lib/libos.tex
   python/branches/p3yk/Doc/lib/libpdb.tex
   python/branches/p3yk/Doc/lib/libpipes.tex
   python/branches/p3yk/Doc/lib/libplatform.tex
   python/branches/p3yk/Doc/lib/libpopen2.tex
   python/branches/p3yk/Doc/lib/libpoplib.tex
   python/branches/p3yk/Doc/lib/libposixfile.tex
   python/branches/p3yk/Doc/lib/libposixpath.tex
   python/branches/p3yk/Doc/lib/libpprint.tex
   python/branches/p3yk/Doc/lib/libqueue.tex
   python/branches/p3yk/Doc/lib/libre.tex
   python/branches/p3yk/Doc/lib/librepr.tex
   python/branches/p3yk/Doc/lib/librexec.tex
   python/branches/p3yk/Doc/lib/librfc822.tex
   python/branches/p3yk/Doc/lib/libsched.tex
   python/branches/p3yk/Doc/lib/libselect.tex
   python/branches/p3yk/Doc/lib/libshlex.tex
   python/branches/p3yk/Doc/lib/libshutil.tex
   python/branches/p3yk/Doc/lib/libsimplexmlrpc.tex
   python/branches/p3yk/Doc/lib/libsite.tex
   python/branches/p3yk/Doc/lib/libsmtplib.tex
   python/branches/p3yk/Doc/lib/libsocket.tex
   python/branches/p3yk/Doc/lib/libsqlite3.tex
   python/branches/p3yk/Doc/lib/libstdtypes.tex
   python/branches/p3yk/Doc/lib/libstring.tex
   python/branches/p3yk/Doc/lib/libsubprocess.tex
   python/branches/p3yk/Doc/lib/libsun.tex
   python/branches/p3yk/Doc/lib/libsys.tex
   python/branches/p3yk/Doc/lib/libtarfile.tex
   python/branches/p3yk/Doc/lib/libtelnetlib.tex
   python/branches/p3yk/Doc/lib/libtempfile.tex
   python/branches/p3yk/Doc/lib/libtest.tex
   python/branches/p3yk/Doc/lib/libtextwrap.tex
   python/branches/p3yk/Doc/lib/libthreading.tex
   python/branches/p3yk/Doc/lib/libtimeit.tex
   python/branches/p3yk/Doc/lib/libturtle.tex
   python/branches/p3yk/Doc/lib/libunittest.tex
   python/branches/p3yk/Doc/lib/liburllib2.tex
   python/branches/p3yk/Doc/lib/liburlparse.tex
   python/branches/p3yk/Doc/lib/libwebbrowser.tex
   python/branches/p3yk/Doc/lib/libwinreg.tex
   python/branches/p3yk/Doc/lib/libxmlrpclib.tex
   python/branches/p3yk/Doc/lib/libzipfile.tex
   python/branches/p3yk/Doc/lib/libzlib.tex
   python/branches/p3yk/Doc/mac/libframework.tex
   python/branches/p3yk/Doc/mac/libmacic.tex
   python/branches/p3yk/Doc/mac/undoc.tex
   python/branches/p3yk/Doc/mac/using.tex
   python/branches/p3yk/Doc/ref/ref1.tex
   python/branches/p3yk/Doc/ref/ref3.tex
   python/branches/p3yk/Doc/ref/ref5.tex
   python/branches/p3yk/Doc/ref/ref6.tex
   python/branches/p3yk/Doc/ref/ref7.tex
   python/branches/p3yk/Doc/texinputs/python.sty
   python/branches/p3yk/Doc/tut/tut.tex
   python/branches/p3yk/Doc/whatsnew/whatsnew23.tex
   python/branches/p3yk/Doc/whatsnew/whatsnew24.tex
   python/branches/p3yk/Doc/whatsnew/whatsnew25.tex
   python/branches/p3yk/Doc/whatsnew/whatsnew26.tex
   python/branches/p3yk/Include/fileobject.h
   python/branches/p3yk/Include/pydebug.h
   python/branches/p3yk/Include/pystate.h
   python/branches/p3yk/Include/setobject.h
   python/branches/p3yk/LICENSE
   python/branches/p3yk/Lib/Bastion.py
   python/branches/p3yk/Lib/CGIHTTPServer.py
   python/branches/p3yk/Lib/ConfigParser.py
   python/branches/p3yk/Lib/DocXMLRPCServer.py
   python/branches/p3yk/Lib/HTMLParser.py
   python/branches/p3yk/Lib/SimpleXMLRPCServer.py
   python/branches/p3yk/Lib/SocketServer.py
   python/branches/p3yk/Lib/_strptime.py
   python/branches/p3yk/Lib/bisect.py
   python/branches/p3yk/Lib/cmd.py
   python/branches/p3yk/Lib/commands.py
   python/branches/p3yk/Lib/copy_reg.py
   python/branches/p3yk/Lib/csv.py
   python/branches/p3yk/Lib/ctypes/__init__.py
   python/branches/p3yk/Lib/ctypes/test/test_functions.py
   python/branches/p3yk/Lib/ctypes/test/test_memfunctions.py
   python/branches/p3yk/Lib/ctypes/test/test_numbers.py
   python/branches/p3yk/Lib/ctypes/test/test_repr.py
   python/branches/p3yk/Lib/decimal.py
   python/branches/p3yk/Lib/difflib.py
   python/branches/p3yk/Lib/distutils/__init__.py
   python/branches/p3yk/Lib/distutils/command/build_ext.py
   python/branches/p3yk/Lib/distutils/msvccompiler.py
   python/branches/p3yk/Lib/doctest.py
   python/branches/p3yk/Lib/email/_parseaddr.py
   python/branches/p3yk/Lib/email/header.py
   python/branches/p3yk/Lib/email/message.py
   python/branches/p3yk/Lib/email/test/test_email.py
   python/branches/p3yk/Lib/email/test/test_email_renamed.py
   python/branches/p3yk/Lib/ftplib.py
   python/branches/p3yk/Lib/genericpath.py
   python/branches/p3yk/Lib/glob.py
   python/branches/p3yk/Lib/heapq.py
   python/branches/p3yk/Lib/httplib.py
   python/branches/p3yk/Lib/idlelib/MultiCall.py
   python/branches/p3yk/Lib/imaplib.py
   python/branches/p3yk/Lib/logging/handlers.py
   python/branches/p3yk/Lib/macpath.py
   python/branches/p3yk/Lib/ntpath.py
   python/branches/p3yk/Lib/os.py
   python/branches/p3yk/Lib/pdb.doc
   python/branches/p3yk/Lib/pdb.py
   python/branches/p3yk/Lib/popen2.py
   python/branches/p3yk/Lib/poplib.py
   python/branches/p3yk/Lib/posixpath.py
   python/branches/p3yk/Lib/pydoc.py
   python/branches/p3yk/Lib/rexec.py
   python/branches/p3yk/Lib/robotparser.py
   python/branches/p3yk/Lib/sched.py
   python/branches/p3yk/Lib/site.py
   python/branches/p3yk/Lib/smtplib.py
   python/branches/p3yk/Lib/socket.py
   python/branches/p3yk/Lib/sre.py
   python/branches/p3yk/Lib/subprocess.py
   python/branches/p3yk/Lib/tarfile.py
   python/branches/p3yk/Lib/telnetlib.py
   python/branches/p3yk/Lib/tempfile.py
   python/branches/p3yk/Lib/test/README
   python/branches/p3yk/Lib/test/crashers/modify_dict_attr.py
   python/branches/p3yk/Lib/test/outstanding_bugs.py
   python/branches/p3yk/Lib/test/pickletester.py
   python/branches/p3yk/Lib/test/regrtest.py
   python/branches/p3yk/Lib/test/string_tests.py
   python/branches/p3yk/Lib/test/test___all__.py
   python/branches/p3yk/Lib/test/test_array.py
   python/branches/p3yk/Lib/test/test_atexit.py
   python/branches/p3yk/Lib/test/test_base64.py
   python/branches/p3yk/Lib/test/test_binascii.py
   python/branches/p3yk/Lib/test/test_bool.py
   python/branches/p3yk/Lib/test/test_bsddb3.py
   python/branches/p3yk/Lib/test/test_builtin.py
   python/branches/p3yk/Lib/test/test_cfgparser.py
   python/branches/p3yk/Lib/test/test_cmath.py
   python/branches/p3yk/Lib/test/test_cmd_line.py
   python/branches/p3yk/Lib/test/test_codecencodings_cn.py
   python/branches/p3yk/Lib/test/test_codecencodings_hk.py
   python/branches/p3yk/Lib/test/test_codecencodings_jp.py
   python/branches/p3yk/Lib/test/test_codecencodings_kr.py
   python/branches/p3yk/Lib/test/test_codecencodings_tw.py
   python/branches/p3yk/Lib/test/test_codecmaps_cn.py
   python/branches/p3yk/Lib/test/test_codecmaps_hk.py
   python/branches/p3yk/Lib/test/test_codecmaps_jp.py
   python/branches/p3yk/Lib/test/test_codecmaps_kr.py
   python/branches/p3yk/Lib/test/test_codecmaps_tw.py
   python/branches/p3yk/Lib/test/test_commands.py
   python/branches/p3yk/Lib/test/test_compile.py
   python/branches/p3yk/Lib/test/test_compiler.py
   python/branches/p3yk/Lib/test/test_complex.py
   python/branches/p3yk/Lib/test/test_contextlib.py
   python/branches/p3yk/Lib/test/test_crypt.py
   python/branches/p3yk/Lib/test/test_csv.py
   python/branches/p3yk/Lib/test/test_ctypes.py
   python/branches/p3yk/Lib/test/test_curses.py
   python/branches/p3yk/Lib/test/test_datetime.py
   python/branches/p3yk/Lib/test/test_defaultdict.py
   python/branches/p3yk/Lib/test/test_deque.py
   python/branches/p3yk/Lib/test/test_descr.py
   python/branches/p3yk/Lib/test/test_descrtut.py
   python/branches/p3yk/Lib/test/test_dict.py
   python/branches/p3yk/Lib/test/test_dis.py
   python/branches/p3yk/Lib/test/test_doctest.py
   python/branches/p3yk/Lib/test/test_email.py
   python/branches/p3yk/Lib/test/test_email_codecs.py
   python/branches/p3yk/Lib/test/test_email_renamed.py
   python/branches/p3yk/Lib/test/test_exceptions.py
   python/branches/p3yk/Lib/test/test_fileinput.py
   python/branches/p3yk/Lib/test/test_fileio.py
   python/branches/p3yk/Lib/test/test_functools.py
   python/branches/p3yk/Lib/test/test_gc.py
   python/branches/p3yk/Lib/test/test_getopt.py
   python/branches/p3yk/Lib/test/test_gettext.py
   python/branches/p3yk/Lib/test/test_glob.py
   python/branches/p3yk/Lib/test/test_grammar.py
   python/branches/p3yk/Lib/test/test_htmlparser.py
   python/branches/p3yk/Lib/test/test_httplib.py
   python/branches/p3yk/Lib/test/test_import.py
   python/branches/p3yk/Lib/test/test_itertools.py
   python/branches/p3yk/Lib/test/test_keywordonlyarg.py
   python/branches/p3yk/Lib/test/test_locale.py
   python/branches/p3yk/Lib/test/test_logging.py
   python/branches/p3yk/Lib/test/test_long_future.py
   python/branches/p3yk/Lib/test/test_macpath.py
   python/branches/p3yk/Lib/test/test_mailbox.py
   python/branches/p3yk/Lib/test/test_metaclass.py
   python/branches/p3yk/Lib/test/test_minidom.py
   python/branches/p3yk/Lib/test/test_module.py
   python/branches/p3yk/Lib/test/test_multibytecodec.py
   python/branches/p3yk/Lib/test/test_normalization.py
   python/branches/p3yk/Lib/test/test_ntpath.py
   python/branches/p3yk/Lib/test/test_operator.py
   python/branches/p3yk/Lib/test/test_optparse.py
   python/branches/p3yk/Lib/test/test_os.py
   python/branches/p3yk/Lib/test/test_ossaudiodev.py
   python/branches/p3yk/Lib/test/test_peepholer.py
   python/branches/p3yk/Lib/test/test_popen2.py
   python/branches/p3yk/Lib/test/test_posixpath.py
   python/branches/p3yk/Lib/test/test_pty.py
   python/branches/p3yk/Lib/test/test_pyexpat.py
   python/branches/p3yk/Lib/test/test_re.py
   python/branches/p3yk/Lib/test/test_robotparser.py
   python/branches/p3yk/Lib/test/test_sax.py
   python/branches/p3yk/Lib/test/test_scope.py
   python/branches/p3yk/Lib/test/test_set.py
   python/branches/p3yk/Lib/test/test_slice.py
   python/branches/p3yk/Lib/test/test_socket.py
   python/branches/p3yk/Lib/test/test_socket_ssl.py
   python/branches/p3yk/Lib/test/test_socketserver.py
   python/branches/p3yk/Lib/test/test_stringprep.py
   python/branches/p3yk/Lib/test/test_strptime.py
   python/branches/p3yk/Lib/test/test_struct.py
   python/branches/p3yk/Lib/test/test_structmembers.py
   python/branches/p3yk/Lib/test/test_support.py
   python/branches/p3yk/Lib/test/test_syntax.py
   python/branches/p3yk/Lib/test/test_tarfile.py
   python/branches/p3yk/Lib/test/test_tempfile.py
   python/branches/p3yk/Lib/test/test_textwrap.py
   python/branches/p3yk/Lib/test/test_threadedtempfile.py
   python/branches/p3yk/Lib/test/test_threading_local.py
   python/branches/p3yk/Lib/test/test_unicode.py
   python/branches/p3yk/Lib/test/test_unicode_file.py
   python/branches/p3yk/Lib/test/test_unittest.py
   python/branches/p3yk/Lib/test/test_unpack.py
   python/branches/p3yk/Lib/test/test_urllib.py
   python/branches/p3yk/Lib/test/test_urllib2.py
   python/branches/p3yk/Lib/test/test_urllib2net.py
   python/branches/p3yk/Lib/test/test_userdict.py
   python/branches/p3yk/Lib/test/test_warnings.py
   python/branches/p3yk/Lib/test/test_weakref.py
   python/branches/p3yk/Lib/test/test_wsgiref.py
   python/branches/p3yk/Lib/test/test_zipfile.py
   python/branches/p3yk/Lib/test/test_zlib.py
   python/branches/p3yk/Lib/test/testtar.tar
   python/branches/p3yk/Lib/textwrap.py
   python/branches/p3yk/Lib/timeit.py
   python/branches/p3yk/Lib/unittest.py
   python/branches/p3yk/Lib/urllib.py
   python/branches/p3yk/Lib/urllib2.py
   python/branches/p3yk/Lib/wave.py
   python/branches/p3yk/Lib/webbrowser.py
   python/branches/p3yk/Lib/zipfile.py
   python/branches/p3yk/Misc/ACKS
   python/branches/p3yk/Misc/NEWS
   python/branches/p3yk/Misc/build.sh
   python/branches/p3yk/Misc/developers.txt
   python/branches/p3yk/Misc/python-config.in
   python/branches/p3yk/Modules/_bsddb.c
   python/branches/p3yk/Modules/_ctypes/_ctypes.c
   python/branches/p3yk/Modules/_ctypes/callproc.c
   python/branches/p3yk/Modules/_ctypes/cfield.c
   python/branches/p3yk/Modules/_ctypes/libffi/configure
   python/branches/p3yk/Modules/_ctypes/libffi/configure.ac
   python/branches/p3yk/Modules/_ctypes/libffi/fficonfig.h.in
   python/branches/p3yk/Modules/_cursesmodule.c
   python/branches/p3yk/Modules/_localemodule.c
   python/branches/p3yk/Modules/_struct.c
   python/branches/p3yk/Modules/arraymodule.c
   python/branches/p3yk/Modules/binascii.c
   python/branches/p3yk/Modules/bz2module.c
   python/branches/p3yk/Modules/cPickle.c
   python/branches/p3yk/Modules/cStringIO.c
   python/branches/p3yk/Modules/datetimemodule.c
   python/branches/p3yk/Modules/getpath.c
   python/branches/p3yk/Modules/main.c
   python/branches/p3yk/Modules/operator.c
   python/branches/p3yk/Modules/posixmodule.c
   python/branches/p3yk/Modules/readline.c
   python/branches/p3yk/Modules/socketmodule.c
   python/branches/p3yk/Modules/timemodule.c
   python/branches/p3yk/Objects/complexobject.c
   python/branches/p3yk/Objects/dictobject.c
   python/branches/p3yk/Objects/exceptions.c
   python/branches/p3yk/Objects/fileobject.c
   python/branches/p3yk/Objects/frameobject.c
   python/branches/p3yk/Objects/longobject.c
   python/branches/p3yk/Objects/setobject.c
   python/branches/p3yk/Objects/sliceobject.c
   python/branches/p3yk/Objects/stringobject.c
   python/branches/p3yk/Objects/typeobject.c
   python/branches/p3yk/PC/VC6/pcbuild.dsw
   python/branches/p3yk/PC/_winreg.c
   python/branches/p3yk/PC/config.c
   python/branches/p3yk/PC/getpathp.c
   python/branches/p3yk/PCbuild/pythoncore.vcproj
   python/branches/p3yk/PCbuild8/pythoncore.vcproj
   python/branches/p3yk/Python/ast.c
   python/branches/p3yk/Python/bltinmodule.c
   python/branches/p3yk/Python/ceval.c
   python/branches/p3yk/Python/compile.c
   python/branches/p3yk/Python/dynload_win.c
   python/branches/p3yk/Python/errors.c
   python/branches/p3yk/Python/import.c
   python/branches/p3yk/Python/peephole.c
   python/branches/p3yk/Python/pystate.c
   python/branches/p3yk/Python/pythonrun.c
   python/branches/p3yk/Python/sysmodule.c
   python/branches/p3yk/Python/thread_nt.h
   python/branches/p3yk/README
   python/branches/p3yk/Tools/pybench/pybench.py
   python/branches/p3yk/configure.in
   python/branches/p3yk/setup.py
Log:
Merged revisions 53952-54987 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r53954 | jeremy.hylton | 2007-02-26 10:41:18 -0800 (Mon, 26 Feb 2007) | 10 lines
  
  Do not copy free variables to locals in class namespaces.
  
  Fixes bug 1569356, but at the cost of a minor incompatibility in
  locals().  Add test that verifies that the class namespace is not
  polluted.  Also clarify the behavior in the library docs.
  
  Along the way, cleaned up the dict_to_map and map_to_dict
  implementations and added some comments that explain what they do.
........
  r53955 | jeremy.hylton | 2007-02-26 11:00:20 -0800 (Mon, 26 Feb 2007) | 2 lines
  
  Fix assertion.
........
  r53969 | neal.norwitz | 2007-02-26 14:41:45 -0800 (Mon, 26 Feb 2007) | 3 lines
  
  When printing an unraisable error, don't print exceptions. before the name.
  This duplicates the behavior whening normally printing exceptions.
........
  r53970 | andrew.kuchling | 2007-02-26 15:02:47 -0800 (Mon, 26 Feb 2007) | 1 line
  
  Markup fix
........
  r53975 | neal.norwitz | 2007-02-26 15:48:27 -0800 (Mon, 26 Feb 2007) | 3 lines
  
  SF #1669182, 2.5 was already fixed.  Just assert in 2.6 since string exceptions
  are gone.  
........
  r53976 | andrew.kuchling | 2007-02-26 15:54:17 -0800 (Mon, 26 Feb 2007) | 1 line
  
  Add some items
........
  r53981 | jeremy.hylton | 2007-02-26 17:01:59 -0800 (Mon, 26 Feb 2007) | 4 lines
  
  Fix long-standing bug in name mangling for package imports
  
  Reported by Mike Verdone.
........
  r53993 | jeremy.hylton | 2007-02-27 08:00:06 -0800 (Tue, 27 Feb 2007) | 2 lines
  
  tabify
........
  r53994 | jeremy.hylton | 2007-02-27 08:13:23 -0800 (Tue, 27 Feb 2007) | 5 lines
  
  tabify
  
  Note that ast.c still has a mix of tabs and spaces, because it
  attempts to use four-space indents for more of the new code.
........
  r53996 | jeremy.hylton | 2007-02-27 09:24:48 -0800 (Tue, 27 Feb 2007) | 2 lines
  
  whitespace normalization
........
  r53997 | jeremy.hylton | 2007-02-27 10:29:45 -0800 (Tue, 27 Feb 2007) | 24 lines
  
  Add checking for a number of metaclass error conditions.
  
  We add some new rules that are required for preserving internal
  invariants of types.  
  
  1.  If type (or a subclass of type) appears in bases, it must appear
      before any non-type bases.  If a non-type base (like a regular
      new-style class) occurred first, it could trick type into
      allocating the new class an __dict__ which must be impossible.
  
  2. There are several checks that are made of bases when creating a
     type.  Those checks are now repeated when assigning to __bases__.
     We also add the restriction that assignment to __bases__ may not
     change the metaclass of the type.
  
  Add new tests for these cases and for a few other oddball errors that
  were no previously tested.  Remove a crasher test that was fixed.
  
  Also some internal refactoring:  Extract the code to find the most
  derived metaclass of a type and its bases.  It is now needed in two
  places.  Rewrite the TypeError checks in test_descr to use doctest.
  The tests now clearly show what exception they expect to see.
........
  r53998 | jeremy.hylton | 2007-02-27 10:33:31 -0800 (Tue, 27 Feb 2007) | 2 lines
  
  Add news about changes to metaclasses and __bases__ error checking.
........
  r54016 | armin.rigo | 2007-02-28 01:25:29 -0800 (Wed, 28 Feb 2007) | 3 lines
  
  Modify the segfaulting example to show why r53997 is not a solution to
  it.
........
  r54022 | brett.cannon | 2007-02-28 10:15:00 -0800 (Wed, 28 Feb 2007) | 2 lines
  
  Add a test for instantiating SyntaxError with no arguments.
........
  r54026 | raymond.hettinger | 2007-02-28 10:27:41 -0800 (Wed, 28 Feb 2007) | 1 line
  
  Docstring nit.
........
  r54033 | raymond.hettinger | 2007-02-28 10:37:52 -0800 (Wed, 28 Feb 2007) | 1 line
  
  Prepare collections module for pure python code entries.
........
  r54053 | raymond.hettinger | 2007-02-28 22:16:43 -0800 (Wed, 28 Feb 2007) | 1 line
  
  Add collections.NamedTuple
........
  r54054 | neal.norwitz | 2007-02-28 23:04:41 -0800 (Wed, 28 Feb 2007) | 1 line
  
  Add Pat and Eric for work on PEP 3101 in the sandbox
........
  r54061 | andrew.kuchling | 2007-03-01 06:36:12 -0800 (Thu, 01 Mar 2007) | 1 line
  
  Add NamedTuple
........
  r54080 | georg.brandl | 2007-03-02 06:37:12 -0800 (Fri, 02 Mar 2007) | 2 lines
  
  Bug #1628895: some better tries to find HTML documentation in pydoc.
........
  r54086 | raymond.hettinger | 2007-03-02 11:20:46 -0800 (Fri, 02 Mar 2007) | 1 line
  
  Fix embarrassing typo and fix constantification of None
........
  r54088 | georg.brandl | 2007-03-02 12:30:14 -0800 (Fri, 02 Mar 2007) | 2 lines
  
  Bugs #1668032, #1668036, #1669304: clarify behavior of PyMem_Realloc and _Resize.
........
  r54114 | georg.brandl | 2007-03-04 09:18:54 -0800 (Sun, 04 Mar 2007) | 2 lines
  
  Fix a bug in test_dict and test_userdict, found at the PyPy sprint.
........
  r54124 | skip.montanaro | 2007-03-04 12:52:28 -0800 (Sun, 04 Mar 2007) | 2 lines
  
  Teach setup.py how to find Berkeley DB on Macs using MacPorts.
........
  r54125 | skip.montanaro | 2007-03-04 12:54:12 -0800 (Sun, 04 Mar 2007) | 1 line
  
  note MacPorts/BerkDB change in setup.py
........
  r54136 | neal.norwitz | 2007-03-04 23:52:01 -0800 (Sun, 04 Mar 2007) | 1 line
  
  Added Pete for 3101 too
........
  r54138 | facundo.batista | 2007-03-05 08:31:54 -0800 (Mon, 05 Mar 2007) | 1 line
  
  Minor corrections to docs, and an explanation comentary
........
  r54139 | georg.brandl | 2007-03-05 14:28:08 -0800 (Mon, 05 Mar 2007) | 3 lines
  
  Patch #1674228: when assigning a slice (old-style), check for the
  sq_ass_slice instead of the sq_slice slot.
........
  r54149 | georg.brandl | 2007-03-06 01:33:01 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Nit: a struct field is set to GenericAlloc, not GenericAlloc().
........
  r54150 | georg.brandl | 2007-03-06 02:02:47 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Patch #1671450: add a section about subclassing builtin types to the
  "extending and embedding" tutorial.
........
  r54152 | martin.v.loewis | 2007-03-06 02:41:24 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Patch #1121142: Implement ZipFile.open.
........
  r54154 | georg.brandl | 2007-03-06 03:51:14 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  A test case for the fix in #1674228.
........
  r54156 | georg.brandl | 2007-03-06 03:52:24 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Patch #1672481: fix bug in idlelib.MultiCall.
........
  r54159 | georg.brandl | 2007-03-06 04:17:50 -0800 (Tue, 06 Mar 2007) | 1 line
  
  Bug #1674503: close the file opened by execfile() in an error condition.
........
  r54160 | georg.brandl | 2007-03-06 05:32:52 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Fix another reincarnation of bug #1576657 in defaultdict.
........
  r54162 | georg.brandl | 2007-03-06 05:35:00 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  A test case for the defaultdict KeyError bug.
........
  r54164 | georg.brandl | 2007-03-06 05:37:45 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Patch #1663234: you can now run doctest on test files and modules
  using "python -m doctest [-v] filename ...".
........
  r54165 | martin.v.loewis | 2007-03-06 06:43:00 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Patch #912410: Replace HTML entity references for attribute values 
  in HTMLParser.
........
  r54166 | skip.montanaro | 2007-03-06 07:41:38 -0800 (Tue, 06 Mar 2007) | 1 line
  
  patch 1673619 - identify extension modules which cannot be built
........
  r54167 | guido.van.rossum | 2007-03-06 07:50:01 -0800 (Tue, 06 Mar 2007) | 5 lines
  
  Patch #1646728: datetime.fromtimestamp fails with negative
  fractional times.  With unittest.
  
  Somebody please backport to 2.5.
........
  r54169 | georg.brandl | 2007-03-06 09:49:14 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Fix cmp vs. key argument for list.sort.
........
  r54170 | georg.brandl | 2007-03-06 10:21:32 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Small nit, found by Neal.
........
  r54171 | georg.brandl | 2007-03-06 10:29:58 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Patch #1602128: clarify that richcmp methods can return NotImplemented
  and should return True or False otherwise.
........
  r54173 | georg.brandl | 2007-03-06 10:41:12 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Patch #1638879: don't accept strings with embedded NUL bytes in long().
........
  r54175 | georg.brandl | 2007-03-06 10:47:31 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Patch #1673121: update README wrt. OSX default shell.
........
  r54177 | georg.brandl | 2007-03-06 10:59:11 -0800 (Tue, 06 Mar 2007) | 3 lines
  
  Patch #1654417: make operator.{get,set,del}slice use the full range
  of Py_ssize_t.
........
  r54180 | walter.doerwald | 2007-03-06 12:38:57 -0800 (Tue, 06 Mar 2007) | 4 lines
  
  Patch for bug #1633621: if curses.resizeterm() or
  curses.resize_term() is called, update _curses.LINES,
  _curses.COLS, curses.LINES and curses.COLS.
........
  r54182 | walter.doerwald | 2007-03-06 13:15:24 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Document change to curses.
........
  r54188 | georg.brandl | 2007-03-06 16:34:46 -0800 (Tue, 06 Mar 2007) | 5 lines
  
  Variant of patch #697613: don't exit the interpreter on a SystemExit
  exception if the -i command line option or PYTHONINSPECT environment
  variable is given, but break into the interactive interpreter just like
  on other exceptions or normal program exit.
   (backport)
........
  r54189 | georg.brandl | 2007-03-06 16:40:28 -0800 (Tue, 06 Mar 2007) | 4 lines
  
  Patch #703779: unset __file__ in __main__ after running a file. This
  makes the filenames the warning module prints much more sensible when
  a PYTHONSTARTUP file is used.
........
  r54192 | george.yoshida | 2007-03-06 20:21:18 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  add versionadded info
........
  r54195 | georg.brandl | 2007-03-06 23:39:06 -0800 (Tue, 06 Mar 2007) | 2 lines
  
  Patch #812285: allow multiple auth schemes in AbstractBasicAuthHandler.
........
  r54197 | georg.brandl | 2007-03-07 00:31:51 -0800 (Wed, 07 Mar 2007) | 3 lines
  
  Patch #1001604: glob.glob() now returns unicode filenames if it was
  given a unicode argument and os.listdir() returns unicode filenames.
........
  r54199 | georg.brandl | 2007-03-07 01:09:40 -0800 (Wed, 07 Mar 2007) | 3 lines
  
  Patches #1550273, #1550272: fix a few bugs in unittest and add a
  comprehensive test suite for the module.
........
  r54201 | georg.brandl | 2007-03-07 01:21:06 -0800 (Wed, 07 Mar 2007) | 3 lines
  
  Patch #787789: allow to pass custom TestRunner instances to unittest's
  main() function.
........
  r54202 | georg.brandl | 2007-03-07 01:34:45 -0800 (Wed, 07 Mar 2007) | 2 lines
  
  Patch #1669331: clarify shutil.copyfileobj() behavior wrt. file position.
........
  r54204 | martin.v.loewis | 2007-03-07 03:04:33 -0800 (Wed, 07 Mar 2007) | 2 lines
  
  Bug #1115886: os.path.splitext('.cshrc') gives now ('.cshrc', '').
........
  r54206 | georg.brandl | 2007-03-07 03:37:42 -0800 (Wed, 07 Mar 2007) | 2 lines
  
  Patch #1675471: convert test_pty to unittest.
........
  r54207 | georg.brandl | 2007-03-07 03:54:49 -0800 (Wed, 07 Mar 2007) | 4 lines
  
  Add some sanity checks to unittest.TestSuite's addTest(s) methods.
  Fixes #878275.
........
  r54209 | guido.van.rossum | 2007-03-07 07:16:29 -0800 (Wed, 07 Mar 2007) | 3 lines
  
  Windows doesn't support negative timestamps.  Skip the tests involving them
  if os.name == "nt".
........
  r54219 | martin.v.loewis | 2007-03-08 05:42:43 -0800 (Thu, 08 Mar 2007) | 2 lines
  
  Add missing ) in parenthical remark.
........
  r54220 | georg.brandl | 2007-03-08 09:49:06 -0800 (Thu, 08 Mar 2007) | 2 lines
  
  Fix #1676656: \em is different from \emph...
........
  r54222 | georg.brandl | 2007-03-08 10:37:31 -0800 (Thu, 08 Mar 2007) | 2 lines
  
  Add a NEWS entry for rev. 54207,8.
........
  r54225 | raymond.hettinger | 2007-03-08 11:24:27 -0800 (Thu, 08 Mar 2007) | 1 line
  
  SF 1676321:  empty() returned wrong result
........
  r54227 | collin.winter | 2007-03-08 11:58:14 -0800 (Thu, 08 Mar 2007) | 1 line
  
  Backported r54226 from p3yk: Move test_unittest, test_doctest and test_doctest2 higher up in the testing order.
........
  r54230 | raymond.hettinger | 2007-03-08 13:33:47 -0800 (Thu, 08 Mar 2007) | 1 line
  
  SF #1637850:  make_table in difflib did not work with unicode
........
  r54232 | collin.winter | 2007-03-08 14:16:25 -0800 (Thu, 08 Mar 2007) | 1 line
  
  Patch #1668482: don't use '-' in mkstemp
........
  r54233 | brett.cannon | 2007-03-08 15:58:11 -0800 (Thu, 08 Mar 2007) | 10 lines
  
  Introduce test.test_support.TransientResource.  It's a context manager to
  surround calls to resources that may or may not be available.  Specifying the
  expected exception and attributes to be raised if the resource is not available
  prevents overly broad catching of exceptions.
  
  This is meant to help suppress spurious failures by raising
  test.test_support.ResourceDenied if the exception matches.  It would probably
  be good to go through the various network tests and surround the calls to catch
  connection timeouts (as done with test_socket_ssl in this commit).
........
  r54234 | collin.winter | 2007-03-08 19:15:56 -0800 (Thu, 08 Mar 2007) | 1 line
  
  Patch #1481079: Support of HTTP_REFERER in CGIHTTPServer.py
........
  r54235 | collin.winter | 2007-03-08 19:26:32 -0800 (Thu, 08 Mar 2007) | 1 line
  
  Add NEWS item for patch #1481079 (r54234).
........
  r54237 | neal.norwitz | 2007-03-08 21:59:01 -0800 (Thu, 08 Mar 2007) | 1 line
  
  Fix SF #1676971, Complex OverflowError has a typo
........
  r54239 | georg.brandl | 2007-03-09 04:58:41 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Typo.
........
  r54240 | martin.v.loewis | 2007-03-09 07:35:55 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Patch #957003: Implement smtplib.LMTP.
........
  r54243 | collin.winter | 2007-03-09 10:09:10 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Bug #1629566: clarify the docs on the return values of parsedate() and parsedate_tz() in email.utils and rfc822.
........
  r54244 | thomas.heller | 2007-03-09 11:21:28 -0800 (Fri, 09 Mar 2007) | 3 lines
  
  Fix bug #1646630: ctypes.string_at(buf, 0) and ctypes.wstring_at(buf, 0)
  returned string up to the first NUL character.
........
  r54245 | martin.v.loewis | 2007-03-09 11:36:01 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Add Ziga Seilnacht.
........
  r54247 | collin.winter | 2007-03-09 12:33:07 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Patch #1491866: change the complex() constructor to allow parthensized forms. This means complex(repr(x)) now works instead of raising a ValueError.
........
  r54248 | thomas.heller | 2007-03-09 12:39:22 -0800 (Fri, 09 Mar 2007) | 7 lines
  
  Bug #1651235: When a tuple was passed to a ctypes function call,
  Python would crash instead of raising an error.
  
  The crash was caused by a section of code that should have been
  removed long ago, at that time ctypes had other ways to pass
  parameters to function calls.
........
  r54250 | collin.winter | 2007-03-09 15:30:39 -0800 (Fri, 09 Mar 2007) | 1 line
  
  Hashing simplification pointed out by Thomas Wouters.
........
  r54252 | collin.winter | 2007-03-09 18:23:40 -0800 (Fri, 09 Mar 2007) | 5 lines
  
  * Unlink test files before and after each test; hopefully this will cut down on recent buildbot failures in test_islink.
  * Drop safe_remove() in favor of test_support.unlink().
  * Fix the indentation of test_samefile so that it runs.
........
  r54253 | collin.winter | 2007-03-09 18:51:26 -0800 (Fri, 09 Mar 2007) | 3 lines
  
  Bug #1531963: Make SocketServer.TCPServer's server_address always be equal to calling getsockname() on the server's socket.
  Will backport.
........
  r54254 | neal.norwitz | 2007-03-09 19:19:18 -0800 (Fri, 09 Mar 2007) | 4 lines
  
  Simplify a little by handling the TCP case first.
  Update to use predominant style of spaces around = in args list
  and print to stderr if debugging.
........
  r54256 | collin.winter | 2007-03-09 19:35:34 -0800 (Fri, 09 Mar 2007) | 1 line
  
  Add proper attribution for a bug fix.
........
  r54257 | georg.brandl | 2007-03-09 23:38:14 -0800 (Fri, 09 Mar 2007) | 2 lines
  
  Typos.
........
  r54260 | collin.winter | 2007-03-10 06:33:32 -0800 (Sat, 10 Mar 2007) | 1 line
  
  Convert an assert to a raise so it works even in the presence of -O.
........
  r54262 | collin.winter | 2007-03-10 06:41:48 -0800 (Sat, 10 Mar 2007) | 2 lines
  
  Patch #1599845: Add an option to disable the implicit calls to server_bind() and server_activate() in the constructors for TCPServer, SimpleXMLRPCServer and DocXMLRPCServer. 
........
  r54268 | georg.brandl | 2007-03-11 00:28:46 -0800 (Sun, 11 Mar 2007) | 2 lines
  
  Add missing "return" statements in exception handler.
........
  r54270 | ziga.seilnacht | 2007-03-11 08:54:54 -0700 (Sun, 11 Mar 2007) | 3 lines
  
  Patch #1675981: remove unreachable code from type.__new__() method.
  __dict__ and __weakref__ are removed from the slots tuple earlier
  in the code, in the loop that mangles slot names. Will backport.
........
  r54271 | collin.winter | 2007-03-11 09:00:20 -0700 (Sun, 11 Mar 2007) | 3 lines
  
  Patch #1192590: Fix pdb's "ignore" and "condition" commands so they trap the IndexError caused by passing in an invalid breakpoint number.
  Will backport.
........
  r54274 | vinay.sajip | 2007-03-11 11:32:07 -0700 (Sun, 11 Mar 2007) | 1 line
  
  Fix resource leak reported in SF #1516995.
........
  r54278 | collin.winter | 2007-03-11 18:55:54 -0700 (Sun, 11 Mar 2007) | 4 lines
  
  Patch #1678662: ftp.python.org does not exist. So the testcode in urllib.py must use a more
  stable FTP.
  Will backport.
........
  r54280 | barry.warsaw | 2007-03-11 20:20:01 -0700 (Sun, 11 Mar 2007) | 8 lines
  
  Tokio Kikuchi's fix for SF bug #1629369; folding whitespace allowed in the
  display name of an email address, e.g.
  
  Foo
  \tBar <foo at example.com>
  
  Test case added by Barry.
........
  r54282 | skip.montanaro | 2007-03-11 20:30:50 -0700 (Sun, 11 Mar 2007) | 4 lines
  
  Sane humans would call these invalid tests, but Andrew McNamara pointed out
  that given the inputs in these tests Excel does indeed produce the output
  these tests expect.  Document that for future confused folks.
........
  r54283 | martin.v.loewis | 2007-03-12 03:50:39 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Bug #1675511: Use -Kpic instead of -xcode=pic32 on Solaris/x86.
........
  r54285 | martin.v.loewis | 2007-03-12 04:01:10 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Patch #1677862: Require a space or tab after import in .pth files.
........
  r54287 | georg.brandl | 2007-03-12 06:17:36 -0700 (Mon, 12 Mar 2007) | 8 lines
  
  Backport from Py3k branch:
  
  Patch #1591665: implement the __dir__() special function lookup in PyObject_Dir.
  
  Had to change a few bits of the patch because classobjs and __methods__ are still
  in Py2.6.
........
  r54288 | georg.brandl | 2007-03-12 07:30:05 -0700 (Mon, 12 Mar 2007) | 3 lines
  
  Bug #1678647: write a newline after printing an exception in any
  case, even when converting the value to a string failed.
........
  r54290 | collin.winter | 2007-03-12 08:57:19 -0700 (Mon, 12 Mar 2007) | 1 line
  
  Patch #1678088: convert test_operations to use unittest, fold the result into test_dict.
........
  r54291 | collin.winter | 2007-03-12 09:11:39 -0700 (Mon, 12 Mar 2007) | 3 lines
  
  Bug #742342: make Python stop segfaulting on infinitely-recursive reload()s. Fixed by patch #922167.
  Will backport.
........
  r54292 | georg.brandl | 2007-03-12 09:15:09 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Typo fix.
........
  r54295 | collin.winter | 2007-03-12 10:24:07 -0700 (Mon, 12 Mar 2007) | 1 line
  
  Patch #1670993: Refactor test_threadedtempfile.py to use unittest.
........
  r54296 | tim.peters | 2007-03-12 11:07:52 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Whitespace normalization.
........
  r54297 | tim.peters | 2007-03-12 11:09:22 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Set missing svn:eol-style property on text files.
........
  r54315 | brett.cannon | 2007-03-12 19:34:09 -0700 (Mon, 12 Mar 2007) | 8 lines
  
  Add test.test_support.transient_internet .  Returns a context manager that
  nests test.test_support.TransientResource context managers that capture
  exceptions raised when the Internet connection is flaky.
  
  Initially using in test_socket_ssl but should probably be expanded to cover any
  test that should not raise the captured exceptions if the Internet connection
  works.
........
  r54316 | brett.cannon | 2007-03-12 20:05:40 -0700 (Mon, 12 Mar 2007) | 2 lines
  
  Fix a typo where the variable name was not updated.
........
  r54318 | neal.norwitz | 2007-03-12 21:59:58 -0700 (Mon, 12 Mar 2007) | 1 line
  
  Add Jerry Seutter for a bunch of his recent patches refactoring tests
........
  r54319 | neal.norwitz | 2007-03-12 22:07:14 -0700 (Mon, 12 Mar 2007) | 7 lines
  
  Add some other acks for recent checkins:
  
  Brian Leair  - 922167
  Tomer Filiba - 1591665
  Jeremy Jones - 1192590
........
  r54321 | neal.norwitz | 2007-03-12 22:31:38 -0700 (Mon, 12 Mar 2007) | 9 lines
  
  Fix some style nits:
    * lines too long
    * wrong indentation
    * space after a function name
    * wrong function name in error string
    * simplifying some logic
  
  Also add an error check to PyDict_SetItemString.
........
  r54322 | georg.brandl | 2007-03-13 00:23:16 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Typo and grammar fixes.
........
  r54323 | georg.brandl | 2007-03-13 00:50:57 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Patch #1679379: add documentation for fnmatch.translate().
........
  r54325 | georg.brandl | 2007-03-13 00:57:51 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Patch #1642844: comments to clarify the complexobject constructor.
........
  r54326 | georg.brandl | 2007-03-13 01:14:27 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1668100: urllib2 now correctly raises URLError instead of
  OSError if accessing a local file via the file:// protocol fails.
........
  r54327 | georg.brandl | 2007-03-13 02:32:11 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1635454: the csv.DictWriter class now includes the offending
  field names in its exception message if you try to write a record with
  a dictionary containing fields not in the CSV field names list.
........
  r54328 | georg.brandl | 2007-03-13 02:41:31 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1555098: use str.join() instead of repeated string
  concatenation in robotparser.
........
  r54329 | georg.brandl | 2007-03-13 03:06:48 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1542681: add entries for "with", "as" and "CONTEXTMANAGERS" to
  pydoc's help keywords.
........
  r54331 | georg.brandl | 2007-03-13 03:19:22 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1569798: fix a bug in distutils when building Python from a
  directory within sys.exec_prefix.
........
  r54333 | martin.v.loewis | 2007-03-13 03:24:00 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1449244: Support Unicode strings in
  email.message.Message.{set_charset,get_content_charset}.
  Will backport.
........
  r54335 | lars.gustaebel | 2007-03-13 03:47:19 -0700 (Tue, 13 Mar 2007) | 34 lines
  
  This is the implementation of POSIX.1-2001 (pax) format read/write
  support.
  
  The TarInfo class now contains all necessary logic to process and
  create tar header data which has been moved there from the TarFile
  class. The fromtarfile() method was added. The new path and linkpath
  properties are aliases for the name and linkname attributes in
  correspondence to the pax naming scheme.
  
  The TarFile constructor and classmethods now accept a number of
  keyword arguments which could only be set as attributes before (e.g.
  dereference, ignore_zeros). The encoding and pax_headers arguments
  were added for pax support. There is a new tarinfo keyword argument
  that allows using subclassed TarInfo objects in TarFile.
  
  The boolean TarFile.posix attribute is deprecated, because now three
  tar formats are supported. Instead, the desired format for writing is
  specified using the constants USTAR_FORMAT, GNU_FORMAT and PAX_FORMAT
  as the format keyword argument. This change affects TarInfo.tobuf()
  as well.
  
  The test suite has been heavily reorganized and partially rewritten.
  A new testtar.tar was added that contains sample data in many formats
  from 4 different tar programs.
  
  Some bugs and quirks that also have been fixed:
  Directory names do no longer have a trailing slash in TarInfo.name or
  TarFile.getnames().
  Adding the same file twice does not create a hardlink file member.
  The TarFile constructor does no longer need a name argument.
  The TarFile._mode attribute was renamed to mode and contains either
  'r', 'w' or 'a'.
........
  r54336 | georg.brandl | 2007-03-13 05:34:25 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Bug #1622896: fix a rare corner case where the bz2 module raised an
  error in spite of a succesful compression.
........
  r54338 | lars.gustaebel | 2007-03-13 08:47:07 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Quick fix for tests that fail on systems with an encoding other
  than 'iso8859-1'.
........
  r54339 | georg.brandl | 2007-03-13 10:43:32 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1603688: ConfigParser.SafeConfigParser now checks values that
  are set for invalid interpolation sequences that would lead to errors
  on reading back those values.
........
  r54341 | georg.brandl | 2007-03-13 11:15:41 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1581073: add a flag to textwrap that prevents the dropping of
  whitespace while wrapping.
........
  r54343 | georg.brandl | 2007-03-13 11:24:40 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Patch #1605192: list allowed states in error messages for imaplib.
........
  r54344 | georg.brandl | 2007-03-13 11:31:49 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1537850: tempfile.NamedTemporaryFile now has a "delete" parameter
  which can be set to False to prevent the default delete-on-close
  behavior.
........
  r54345 | collin.winter | 2007-03-13 11:53:04 -0700 (Tue, 13 Mar 2007) | 9 lines
  
  Add acks for recent patch checkins:
  
  Arvin Schnell - 1668482
  S?\195?\169bastien Martini - 1481079
  Heiko Wundram - 1491866
  Damon Kohler - 1545011
  Peter Parente - 1599845
  Bjorn Lindqvist - 1678662
........
  r54346 | georg.brandl | 2007-03-13 12:00:36 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Acks for recent patches.
........
  r54347 | georg.brandl | 2007-03-13 12:18:18 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Fix a tab.
........
  r54348 | georg.brandl | 2007-03-13 12:32:21 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1533909: the timeit module now accepts callables in addition to
  strings for the code to time and the setup code. Also added two
  convenience functions for instantiating a Timer and calling its methods.
........
  r54352 | georg.brandl | 2007-03-13 13:02:57 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1530482: add pydoc.render_doc() which returns the documentation
  for a thing instead of paging it to stdout, which pydoc.doc() does.
........
  r54357 | thomas.heller | 2007-03-13 13:42:52 -0700 (Tue, 13 Mar 2007) | 1 line
  
  Patch #1649190: Adding support for _Bool to ctypes as c_bool, by David Remahl.
........
  r54358 | georg.brandl | 2007-03-13 13:46:32 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Patch #1444529: the builtin compile() now accepts keyword arguments.
   (backport)
........
  r54359 | thomas.heller | 2007-03-13 14:01:39 -0700 (Tue, 13 Mar 2007) | 1 line
  
  Add versionadded marker for ctypes.c_bool.
........
  r54360 | georg.brandl | 2007-03-13 14:08:15 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Patch #1393667: pdb now has a "run" command which restarts the debugged
  Python program, optionally with different arguments.
........
  r54361 | georg.brandl | 2007-03-13 14:32:01 -0700 (Tue, 13 Mar 2007) | 3 lines
  
  Deprecate commands.getstatus().
........
  r54362 | georg.brandl | 2007-03-13 14:32:56 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  NEWS entry for getstatus() deprecation.
........
  r54363 | georg.brandl | 2007-03-13 14:58:44 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #1429539: pdb now correctly initializes the __main__ module for
  the debugged script, which means that imports from __main__ work
  correctly now.
........
  r54364 | georg.brandl | 2007-03-13 15:07:36 -0700 (Tue, 13 Mar 2007) | 4 lines
  
  Patch #957650: "%var%" environment variable references are now properly
  expanded in ntpath.expandvars(), also "~user" home directory references
  are recognized and handled on Windows.
........
  r54365 | georg.brandl | 2007-03-13 15:16:30 -0700 (Tue, 13 Mar 2007) | 2 lines
  
  Patch #1194449: correctly detect unbound methods in pydoc.
........
  r54367 | georg.brandl | 2007-03-13 15:49:43 -0700 (Tue, 13 Mar 2007) | 5 lines
  
  Patch #1185447: binascii.b2a_qp() now correctly quotes binary characters
  with ASCII value less than 32. Also, it correctly quotes dots only if
  they occur on a single line, as opposed to the previous behavior of
  quoting dots if they are the second character of any line.
........
  r54368 | collin.winter | 2007-03-13 16:02:15 -0700 (Tue, 13 Mar 2007) | 1 line
  
  Inline PyImport_GetModulesReloading().
........
  r54371 | barry.warsaw | 2007-03-13 21:59:50 -0700 (Tue, 13 Mar 2007) | 6 lines
  
  SF bug #1582282; decode_header() incorrectly splits not-conformant RFC
  2047-like headers where there is no whitespace between encoded words.  This
  fix changes the matching regexp to include a trailing lookahead assertion that
  the closing ?= must be followed by whitespace, newline, or end-of-string.
  This also changes the regexp to add the MULTILINE flag.
........
  r54372 | gregory.p.smith | 2007-03-14 00:17:40 -0700 (Wed, 14 Mar 2007) | 2 lines
  
  correct order and names of the less often used keyword parameters.
........
  r54373 | gregory.p.smith | 2007-03-14 00:19:50 -0700 (Wed, 14 Mar 2007) | 5 lines
  
  Its time to stop listing (Unix, Windows) when we really mean "everything but Mac OS 9"
  now that nobody is likely to use Python on Mac OS 9 and most of the (Mac) platform
  items are all OS X special API specific since OS X is unixy enough for these modules
  to be available out of the box.
........
  r54376 | georg.brandl | 2007-03-14 01:27:52 -0700 (Wed, 14 Mar 2007) | 4 lines
  
  Bug #767111: fix long-standing bug in urllib which caused an
  AttributeError instead of an IOError when the server's response didn't
  contain a valid HTTP status line.
........
  r54378 | ziga.seilnacht | 2007-03-14 05:24:09 -0700 (Wed, 14 Mar 2007) | 4 lines
  
  Patch #1680015: Don't modify __slots__ tuple if it contains an unicode
  name. Remove a reference leak that happened if the name could not be
  converted to string. Will backport.
........
  r54386 | martin.v.loewis | 2007-03-14 13:02:31 -0700 (Wed, 14 Mar 2007) | 3 lines
  
  Patch #1559413: Fix test_cmd_line if sys.executable contains a space.
  Will backport.
........
  r54389 | brett.cannon | 2007-03-14 14:40:13 -0700 (Wed, 14 Mar 2007) | 3 lines
  
  Note how test_socket_ssl has various exceptions that deal with a flaky Net
  connection are silenced.
........
  r54390 | brett.cannon | 2007-03-14 14:44:15 -0700 (Wed, 14 Mar 2007) | 2 lines
  
  Raise ResourceDenied in test_urllib2net when the Net connection goes bad.
........
  r54391 | neal.norwitz | 2007-03-14 21:41:20 -0700 (Wed, 14 Mar 2007) | 1 line
  
  Wrap a long line and fix a typo (is -> if)
........
  r54392 | georg.brandl | 2007-03-15 00:38:14 -0700 (Thu, 15 Mar 2007) | 3 lines
  
  Patch #1680978: consistently use "alive" instead of "active" in the
  thread lib doc.
........
  r54394 | georg.brandl | 2007-03-15 00:41:30 -0700 (Thu, 15 Mar 2007) | 3 lines
  
  Patch #1681153: the wave module now closes a file object it opened if
  initialization failed.
........
  r54397 | ziga.seilnacht | 2007-03-15 04:44:55 -0700 (Thu, 15 Mar 2007) | 3 lines
  
  Patch #1462488: prevent a segfault in object_reduce_ex() by splitting
  the implementation for __reduce__ and __reduce_ex__ into two separate
  functions. Fixes bug #931877. Will backport.
........
  r54404 | collin.winter | 2007-03-15 21:11:30 -0700 (Thu, 15 Mar 2007) | 3 lines
  
  Patch #1642547: Fix an error/crash when encountering syntax errors in complex if statements.
  Will backport.
........
  r54406 | georg.brandl | 2007-03-16 00:55:09 -0700 (Fri, 16 Mar 2007) | 5 lines
  
  Bug #1681228: the webbrowser module now correctly uses the default
  GNOME or KDE browser, depending on whether there is a session of one
  of those present. Also, it tries the Windows default browser before
  trying Mozilla variants.
   (backport)
........
  r54407 | georg.brandl | 2007-03-16 01:22:40 -0700 (Fri, 16 Mar 2007) | 4 lines
  
  Patch #1273829: os.walk() now has a "followlinks" parameter. If set to
  True (which is not the default), it visits symlinks pointing to
  directories.
........
  r54408 | georg.brandl | 2007-03-16 01:24:21 -0700 (Fri, 16 Mar 2007) | 2 lines
  
  Add \versionadded tag.
........
  r54409 | georg.brandl | 2007-03-16 01:33:47 -0700 (Fri, 16 Mar 2007) | 2 lines
  
  RFE #1670167: fix in isinstance() docs.
........
  r54412 | ziga.seilnacht | 2007-03-16 04:59:38 -0700 (Fri, 16 Mar 2007) | 3 lines
  
  Patch #1623563: allow __class__ assignment for classes with __slots__.
  The old and the new class are still required to have the same slot
  names, but the order in which they are specified is not relevant.
........
  r54413 | ziga.seilnacht | 2007-03-16 05:11:11 -0700 (Fri, 16 Mar 2007) | 2 lines
  
  Whitespace cleanup. Also remove the empty lines
  from the previous check in.
........
  r54414 | jeremy.hylton | 2007-03-16 07:49:11 -0700 (Fri, 16 Mar 2007) | 2 lines
  
  Remove warning: funcion declaration isn't a prototype
........
  r54415 | jeremy.hylton | 2007-03-16 08:59:47 -0700 (Fri, 16 Mar 2007) | 11 lines
  
  Clean up formatting of this file.
  
  The file should now follow PEP 7, except that it uses 4 space indents
  (in the style of Py3k).  This particular code would be really hard to
  read with the regular tab idents.
  
  Other changes:
   - reflow long lines
   - change multi-line conditionals to have test at end of line
........
  r54417 | collin.winter | 2007-03-16 14:13:35 -0700 (Fri, 16 Mar 2007) | 1 line
  
  Patch #1676994: Refactor test_popen2 to use unittest.
........
  r54418 | collin.winter | 2007-03-16 14:15:35 -0700 (Fri, 16 Mar 2007) | 1 line
  
  Remove test/output/test_popen2 (missed in r54417).
........
  r54419 | collin.winter | 2007-03-16 15:16:08 -0700 (Fri, 16 Mar 2007) | 1 line
  
  Patch 1339796: add a relpath() function to os.path.
........
  r54421 | georg.brandl | 2007-03-17 09:08:45 -0700 (Sat, 17 Mar 2007) | 5 lines
  
  Patch #1675423: PyComplex_AsCComplex() now tries to convert an object
  to complex using its __complex__() method before falling back to the
  __float__() method. Therefore, the functions in the cmath module now
  can operate on objects that define a __complex__() method.
   (backport)
........
  r54423 | gregory.p.smith | 2007-03-17 15:33:35 -0700 (Sat, 17 Mar 2007) | 2 lines
  
  move note to the correct section
........
  r54426 | georg.brandl | 2007-03-18 01:25:00 -0700 (Sun, 18 Mar 2007) | 2 lines
  
  Patch #1682878: the new socket methods are recv_into and recvfrom_into, not *_buf.
........
  r54432 | georg.brandl | 2007-03-18 11:28:25 -0700 (Sun, 18 Mar 2007) | 2 lines
  
  Patch #1678339: test case for bug in difflib.
........
  r54439 | collin.winter | 2007-03-19 11:52:08 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Patch #1630118: add a SpooledTemporaryFile class to tempfile.
........
  r54441 | georg.brandl | 2007-03-19 12:02:48 -0700 (Mon, 19 Mar 2007) | 2 lines
  
  Patch #1683328: fixes and enhancements for "unparse" demo.
........
  r54456 | neal.norwitz | 2007-03-19 22:07:28 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Add some doc that was left out from some change to platform.py
........
  r54457 | neal.norwitz | 2007-03-19 22:08:23 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Add a comment about 3k migration
........
  r54458 | neal.norwitz | 2007-03-19 22:21:21 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Get rid of deprecation warning when testing commands.getstatus()
........
  r54459 | neal.norwitz | 2007-03-19 22:23:09 -0700 (Mon, 19 Mar 2007) | 4 lines
  
  Try backing out 54407 to see if it corrects the problems on the Windows
  buildbots.  This rev was backported, so we will need to keep both branches
  in sync, pending the outcome of the test after this checkin.
........
  r54460 | neal.norwitz | 2007-03-19 23:13:25 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Try to make this test more resistant to dropping from previous runs (ie, files that may exist but cause the test to fail).  Should be backported (assuming it works :-)
........
  r54461 | neal.norwitz | 2007-03-19 23:16:26 -0700 (Mon, 19 Mar 2007) | 1 line
  
  Try to make this test more resistant to dropping from previous runs (ie, files that may exist but cause the test to fail).  Should be backported (assuming it works :-)
........
  r54462 | neal.norwitz | 2007-03-19 23:53:17 -0700 (Mon, 19 Mar 2007) | 5 lines
  
  Try to be a little more resilient to errors.  This might help the test
  pass, but my guess is that it won't.  I'm guessing that some other
  test is leaving this file open which means it can't be removed
  under Windows AFAIK.
........
  r54463 | neal.norwitz | 2007-03-20 01:14:57 -0700 (Tue, 20 Mar 2007) | 8 lines
  
  Try to get test_urllib to pass on Windows by closing the file.
  I'm guessing that's the problem.  h.getfile() must be called *after*
  h.getreply() and the fp can be None.
  
  I'm not entirely convinced this is the best fix (or even correct).
  The buildbots will tell us if things improve or not.  I don't
  know if this needs to be backported (assuming it actually works).
........
  r54465 | raymond.hettinger | 2007-03-20 14:27:24 -0700 (Tue, 20 Mar 2007) | 1 line
  
  Extend work on rev 52962 and 53829 eliminating redundant PyObject_Hash() calls and fixing set/dict interoperability.
........
  r54468 | georg.brandl | 2007-03-20 16:05:14 -0700 (Tue, 20 Mar 2007) | 2 lines
  
  Fix for glob.py if filesystem encoding is None.
........
  r54479 | neal.norwitz | 2007-03-20 23:39:48 -0700 (Tue, 20 Mar 2007) | 1 line
  
  Remove unused file spotted by Paul Hankin
........
  r54480 | georg.brandl | 2007-03-21 02:00:39 -0700 (Wed, 21 Mar 2007) | 3 lines
  
  Patch #1682205: a TypeError while unpacking an iterable is no longer
  masked by a generic one with the message "unpack non-sequence".
........
  r54482 | georg.brandl | 2007-03-21 02:10:29 -0700 (Wed, 21 Mar 2007) | 2 lines
  
  New test for rev. 54407 which only uses directories under TESTFN.
........
  r54483 | georg.brandl | 2007-03-21 02:16:53 -0700 (Wed, 21 Mar 2007) | 2 lines
  
  Patch #1684834: document some utility C API functions.
........
  r54485 | georg.brandl | 2007-03-21 04:51:25 -0700 (Wed, 21 Mar 2007) | 2 lines
  
  Fix #1684254: split BROWSER contents with shlex to avoid displaying 'URL'.
........
  r54487 | andrew.kuchling | 2007-03-21 07:32:43 -0700 (Wed, 21 Mar 2007) | 1 line
  
  Add comments on maintenance of this file
........
  r54489 | andrew.kuchling | 2007-03-21 09:57:32 -0700 (Wed, 21 Mar 2007) | 1 line
  
  Fix sentence, and fix typo in example
........
  r54490 | andrew.kuchling | 2007-03-21 09:59:20 -0700 (Wed, 21 Mar 2007) | 1 line
  
  Put code examples at left margin instead of indenting them
........
  r54491 | facundo.batista | 2007-03-21 12:41:24 -0700 (Wed, 21 Mar 2007) | 1 line
  
  Minor clarification, saying that blocking means no timeout (from bug #882297)
........
  r54492 | ziga.seilnacht | 2007-03-21 13:07:56 -0700 (Wed, 21 Mar 2007) | 2 lines
  
  Bug #1675967: re patterns pickled with older Python versions can
  now be unpickled. Will backport.
........
  r54495 | raymond.hettinger | 2007-03-21 13:33:57 -0700 (Wed, 21 Mar 2007) | 1 line
  
  Add test and fix for fromkeys() optional argument.
........
  r54524 | georg.brandl | 2007-03-22 01:05:45 -0700 (Thu, 22 Mar 2007) | 2 lines
  
  Bug #1685704: use -m switch in timeit docs.
........
  r54533 | thomas.heller | 2007-03-22 12:44:31 -0700 (Thu, 22 Mar 2007) | 5 lines
  
  Back out "Patch #1643874: memory leak in ctypes fixed."
  
  The code in this patch leaves no way to give up the ownership of a
  BSTR instance.
........
  r54538 | thomas.heller | 2007-03-22 13:34:37 -0700 (Thu, 22 Mar 2007) | 2 lines
  
  Explain the purpose of the b_needsfree flag (forward ported from release25-maint).
........
  r54539 | guido.van.rossum | 2007-03-22 21:58:42 -0700 (Thu, 22 Mar 2007) | 12 lines
  
  - Bug #1683368: The object.__init__() and object.__new__() methods are
    now stricter in rejecting excess arguments.  The only time when
    either allows excess arguments is when it is not overridden and the
    other one is.  For backwards compatibility, when both are
    overridden, it is a deprecation warning (for now; maybe a Py3k
    warning later).
  
  When merging this into 3.0, the warnings should become errors.
  
  Note: without the change to string.py, lots of spurious warnings happen.
  What's going on there?
........
  r54540 | neal.norwitz | 2007-03-22 22:17:23 -0700 (Thu, 22 Mar 2007) | 1 line
  
  Add Mark Dickinson for SF # 1675423.
........
  r54541 | martin.v.loewis | 2007-03-23 03:35:49 -0700 (Fri, 23 Mar 2007) | 3 lines
  
  Patch #1686451: Fix return type for PySequence_{Count,Index,Fast_GET_SIZE}.
  Will backport.
........
  r54543 | martin.v.loewis | 2007-03-23 06:27:15 -0700 (Fri, 23 Mar 2007) | 3 lines
  
  Bug #978833: Revert r50844, as it broke _socketobject.dup.
  Will backport.
........
  r54545 | guido.van.rossum | 2007-03-23 11:53:03 -0700 (Fri, 23 Mar 2007) | 8 lines
  
  Add a type.__init__() method that enforces the same signature as
  type.__new__(), and then calls object.__init__(cls), just to be anal.
  
  This allows us to restore the code in string.py's _TemplateMetaclass
  that called super(...).__init__(name, bases, dct), which I commented
  out yesterday since it broke due to the stricter argument checking
  added to object.__init__().
........
  r54546 | facundo.batista | 2007-03-23 11:54:07 -0700 (Fri, 23 Mar 2007) | 4 lines
  
  
  Added a 'create_connect()' function to socket.py, which creates a
  connection with an optional timeout, and modified httplib.py to 
  use this function in HTTPConnection. Applies patch 1676823.
........
  r54547 | guido.van.rossum | 2007-03-23 12:39:01 -0700 (Fri, 23 Mar 2007) | 2 lines
  
  Add note about type.__init__().
........
  r54553 | thomas.heller | 2007-03-23 12:55:27 -0700 (Fri, 23 Mar 2007) | 5 lines
  
  Prevent creation (followed by a segfault) of array types when the size
  overflows the valid Py_ssize_t range.  Check return values of
  PyMem_Malloc.
  
  Will backport to release25-maint.
........
  r54555 | facundo.batista | 2007-03-23 13:23:08 -0700 (Fri, 23 Mar 2007) | 6 lines
  
  
  Surrounded with try/finally to socket's default timeout setting
  changes in the tests, so failing one test won't produce strange
  results in others. Also relaxed the timeout settings in the test
  (where actually the value didn't mean anything).
........
  r54556 | collin.winter | 2007-03-23 15:24:39 -0700 (Fri, 23 Mar 2007) | 1 line
  
  Make test_relpath() pass on Windows.
........
  r54559 | ziga.seilnacht | 2007-03-24 07:24:26 -0700 (Sat, 24 Mar 2007) | 6 lines
  
  Patch #1489771: update syntax rules in Python Reference Manual.
  Python 2.5 added support for explicit relative import statements and
  yield expressions, which were missing in the manual.
  Also fix grammar productions that used the names from the Grammar file,
  markup that broke the generated grammar.txt, and wrap some lines that
  broke the pdf output.  Will backport.
........
  r54565 | georg.brandl | 2007-03-24 15:20:34 -0700 (Sat, 24 Mar 2007) | 2 lines
  
  Remove typo accent.
........
  r54566 | georg.brandl | 2007-03-24 15:27:56 -0700 (Sat, 24 Mar 2007) | 2 lines
  
  Revert accidental change.
........
  r54567 | brett.cannon | 2007-03-24 18:32:36 -0700 (Sat, 24 Mar 2007) | 3 lines
  
  Change the docs to no longer claim that unittest is preferred over doctest for
  regression tests.
........
  r54568 | facundo.batista | 2007-03-24 18:53:21 -0700 (Sat, 24 Mar 2007) | 4 lines
  
  
  Redone the tests, using the infrastructure already present
  for threading and socket serving.
........
  r54570 | facundo.batista | 2007-03-24 20:20:05 -0700 (Sat, 24 Mar 2007) | 3 lines
  
  
  Closing the HTTP connection after each test, and listening more.
........
  r54572 | georg.brandl | 2007-03-25 11:44:35 -0700 (Sun, 25 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54573 | georg.brandl | 2007-03-25 12:04:55 -0700 (Sun, 25 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54580 | facundo.batista | 2007-03-26 13:18:31 -0700 (Mon, 26 Mar 2007) | 5 lines
  
  
  Added an optional timeout to FTP class. Also I started a test_ftplib.py
  file to test the ftp lib (right now I included a basic test, the timeout
  one, and nothing else).
........
  r54581 | georg.brandl | 2007-03-26 13:28:28 -0700 (Mon, 26 Mar 2007) | 2 lines
  
  Some nits.
........
  r54582 | facundo.batista | 2007-03-26 13:56:09 -0700 (Mon, 26 Mar 2007) | 4 lines
  
  
  Forgot to add the file before the previous commit, here go
  the ftplib tests.
........
  r54585 | facundo.batista | 2007-03-27 11:23:21 -0700 (Tue, 27 Mar 2007) | 5 lines
  
  
  Added an optional timeout to poplib.POP3. Also created a
  test_poplib.py file with a basic test and the timeout
  ones. Docs are also updated.
........
  r54586 | facundo.batista | 2007-03-27 11:50:29 -0700 (Tue, 27 Mar 2007) | 3 lines
  
  
  The basic test cases of poplib.py.
........
  r54594 | facundo.batista | 2007-03-27 20:45:20 -0700 (Tue, 27 Mar 2007) | 4 lines
  
  
  Bug 1688393. Adds a control of negative values in
  socket.recvfrom, which caused an ugly crash.
........
  r54599 | facundo.batista | 2007-03-28 11:25:54 -0700 (Wed, 28 Mar 2007) | 5 lines
  
  
  Added timeout to smtplib (to SMTP and SMTP_SSL). Also created
  the test_smtplib.py file, with a basic test and the timeout
  ones. Docs are updated too.
........
  r54603 | collin.winter | 2007-03-28 16:34:06 -0700 (Wed, 28 Mar 2007) | 3 lines
  
  Consolidate patches #1690164, 1683397, and 1690169, all of which refactor XML-related test suites. The patches are applied together because they use a common output/xmltests file.
  Thanks to Jerry Seutter for all three patches.
........
  r54604 | collin.winter | 2007-03-28 19:28:16 -0700 (Wed, 28 Mar 2007) | 1 line
  
  Make test_zipfile clean up its temporary files properly.
........
  r54605 | georg.brandl | 2007-03-29 00:41:32 -0700 (Thu, 29 Mar 2007) | 2 lines
  
  These are actually methods.
........
  r54606 | georg.brandl | 2007-03-29 05:42:07 -0700 (Thu, 29 Mar 2007) | 4 lines
  
  In Windows' time.clock(), when QueryPerformanceFrequency() fails,
  the C lib's clock() is used, but it must be divided by CLOCKS_PER_SEC
  as for the POSIX implementation (thanks to #pypy).
........
  r54608 | facundo.batista | 2007-03-29 11:22:35 -0700 (Thu, 29 Mar 2007) | 5 lines
  
  
  Added timout parameter to telnetlib.Telnet. Also created
  test_telnetlib.py with a basic test and timeout ones.
  Docs are also updated.
........
  r54613 | facundo.batista | 2007-03-30 06:00:35 -0700 (Fri, 30 Mar 2007) | 4 lines
  
  
  Added the posibility to pass the timeout to FTP.connect, not only when
  instantiating the class. Docs and tests are updated.
........
  r54614 | collin.winter | 2007-03-30 07:01:25 -0700 (Fri, 30 Mar 2007) | 1 line
  
  Bug #1688274: add documentation for C-level class objects.
........
  r54615 | marc-andre.lemburg | 2007-03-30 08:01:42 -0700 (Fri, 30 Mar 2007) | 4 lines
  
  Bump the patch level version of distutils since there were a few bug fixes since
  the 2.5.0 release.
........
  r54617 | georg.brandl | 2007-03-30 08:49:05 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54618 | georg.brandl | 2007-03-30 10:39:39 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Label name fix.
........
  r54619 | georg.brandl | 2007-03-30 10:47:21 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Duplicate label fix.
........
  r54620 | georg.brandl | 2007-03-30 10:48:39 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54623 | andrew.kuchling | 2007-03-30 11:00:15 -0700 (Fri, 30 Mar 2007) | 1 line
  
  Add item.  (Oops, accidentally checked this in on my branch)
........
  r54624 | georg.brandl | 2007-03-30 12:01:38 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Duplicate label fix.
........
  r54625 | georg.brandl | 2007-03-30 12:14:02 -0700 (Fri, 30 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54629 | georg.brandl | 2007-03-31 03:17:31 -0700 (Sat, 31 Mar 2007) | 2 lines
  
  repair string literal.
........
  r54630 | georg.brandl | 2007-03-31 04:54:58 -0700 (Sat, 31 Mar 2007) | 2 lines
  
  Markup fix.
........
  r54631 | georg.brandl | 2007-03-31 04:58:36 -0700 (Sat, 31 Mar 2007) | 2 lines
  
  Duplicate label fix.
........
  r54632 | georg.brandl | 2007-03-31 04:59:54 -0700 (Sat, 31 Mar 2007) | 2 lines
  
  Typo fix.
........
  r54633 | neal.norwitz | 2007-03-31 11:54:18 -0700 (Sat, 31 Mar 2007) | 1 line
  
  Fix method names.  Will backport.
........
  r54634 | georg.brandl | 2007-03-31 11:56:11 -0700 (Sat, 31 Mar 2007) | 4 lines
  
  Bug #1655392: don't add -L/usr/lib/pythonX.Y/config to the LDFLAGS
  returned by python-config if Python was built with --enable-shared
  because that prevented the shared library from being used.
........
  r54637 | collin.winter | 2007-03-31 12:31:34 -0700 (Sat, 31 Mar 2007) | 1 line
  
  Shut up an occaisonal buildbot error due to test files being left around.
........
  r54644 | neal.norwitz | 2007-04-01 11:24:22 -0700 (Sun, 01 Apr 2007) | 11 lines
  
  SF #1685563, MSVCCompiler creates redundant and long PATH strings
  
  If MSVCCompiler.initialize() was called multiple times, the path
  would get duplicated.  On Windows, this is a problem because the
  path is limited to 4k.  There's no benefit in adding a path multiple
  times, so prevent that from occuring.  We also normalize the path
  before checking for duplicates so things like /a and /a/ won't both
  be stored.
  
  Will backport.
........
  r54646 | brett.cannon | 2007-04-01 11:47:27 -0700 (Sun, 01 Apr 2007) | 8 lines
  
  time.strptime's caching of its locale object was being recreated when the
  locale changed but not used during the function call it was recreated during.
  
  The test in this checkin is untested (OS X does not have the proper locale
  support for me to test), although the fix for the bug this deals with
  was tested by the OP (#1290505).  Once the buildbots verify the test at least
  doesn't fail it becomes a backport candidate.
........
  r54647 | brett.cannon | 2007-04-01 12:46:19 -0700 (Sun, 01 Apr 2007) | 3 lines
  
  Fix the test for recreating the locale cache object by not worrying about if
  one of the test locales cannot be set.
........
  r54649 | georg.brandl | 2007-04-01 14:29:15 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Fix a lot of markup and meta-information glitches.
........
  r54650 | georg.brandl | 2007-04-01 14:39:52 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Another fix.
........
  r54651 | georg.brandl | 2007-04-01 15:39:10 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Lots of explicit class names for method and member descs.
........
  r54652 | georg.brandl | 2007-04-01 15:40:12 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Explicit class names.
........
  r54653 | georg.brandl | 2007-04-01 15:47:31 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Some semantic fixes.
........
  r54654 | georg.brandl | 2007-04-01 16:29:10 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Remove bogus entry.
........
  r54655 | georg.brandl | 2007-04-01 16:31:30 -0700 (Sun, 01 Apr 2007) | 2 lines
  
  Fix the class name of strings.
........
  r54658 | raymond.hettinger | 2007-04-02 10:29:30 -0700 (Mon, 02 Apr 2007) | 1 line
  
  SF #1693079:  Cannot save empty array in shelve
........
  r54663 | raymond.hettinger | 2007-04-02 15:54:21 -0700 (Mon, 02 Apr 2007) | 3 lines
  
  Array module's buffer interface can now handle empty arrays.
........
  r54664 | guido.van.rossum | 2007-04-02 16:55:37 -0700 (Mon, 02 Apr 2007) | 5 lines
  
  Fix warnings about object.__init__() signature.
  Two (test_array and test_descr) were bug IMO; the third (copy_reg)
  is a work-around which recognizes that object.__init__() doesn't do
  anything.
........
  r54666 | raymond.hettinger | 2007-04-02 17:02:11 -0700 (Mon, 02 Apr 2007) | 1 line
  
  SF 1602378 Clarify docstrings for bisect
........
  r54668 | raymond.hettinger | 2007-04-02 18:39:43 -0700 (Mon, 02 Apr 2007) | 3 lines
  
  SF #1382213:  Tutorial section 9.5.1 ignores MRO for new-style classes
........
  r54669 | matthias.klose | 2007-04-02 21:35:59 -0700 (Mon, 02 Apr 2007) | 4 lines
  
  - Fix an off-by-one bug in locale.strxfrm().
  
    patch taken from http://bugs.debian.org/416934.
........
  r54671 | georg.brandl | 2007-04-03 00:04:27 -0700 (Tue, 03 Apr 2007) | 9 lines
  
  Fix the strange case of 
  
  \begin{methoddesc}[NNTP]{...}
  
  where 
  
  \ifx#1\@undefined ended up comparing N and N, therefore executing
  the true part of the conditional, blowing up at \@undefined.
........
  r54672 | facundo.batista | 2007-04-03 07:05:08 -0700 (Tue, 03 Apr 2007) | 4 lines
  
  
  Now using unittest for the tests infraestructure. Also split the 
  tests in those who need the network, and that who doesn't.
........
  r54673 | walter.doerwald | 2007-04-03 09:08:10 -0700 (Tue, 03 Apr 2007) | 4 lines
  
  Move the functionality for catching warnings in test_warnings.py into a separate
  class to that reusing the functionality in test_structmembers.py doesn't rerun
  the tests from test_warnings.py.
........
  r54674 | walter.doerwald | 2007-04-03 09:16:24 -0700 (Tue, 03 Apr 2007) | 2 lines
  
  Document that CatchWarningTests is reused by test_structmembers.py.
........
  r54675 | walter.doerwald | 2007-04-03 09:53:43 -0700 (Tue, 03 Apr 2007) | 4 lines
  
  Add tests for the filename.
  
  Test that the stacklevel is handled correctly.
........
  r54676 | facundo.batista | 2007-04-03 10:29:48 -0700 (Tue, 03 Apr 2007) | 6 lines
  
  
  Added a SSL server to test_socket_ssl.py to be able to test
  locally. Now, it checks if have openssl available and run
  those specific tests (it starts openssl at the beggining of
  all the tests and then kills it at the end).
........
  r54677 | walter.doerwald | 2007-04-03 11:33:29 -0700 (Tue, 03 Apr 2007) | 6 lines
  
  Implement a contextmanager test.test_support.catch_warning that can
  be used to catch the last warning issued by the warning framework.
  
  Change test_warnings.py and test_structmembers.py to use this
  new contextmanager.
........
  r54678 | facundo.batista | 2007-04-03 14:15:34 -0700 (Tue, 03 Apr 2007) | 4 lines
  
  
  Changed the whole structure of startup and checking if the 
  server is available. Hope to not get more false alarms.
........
  r54681 | facundo.batista | 2007-04-04 07:10:40 -0700 (Wed, 04 Apr 2007) | 4 lines
  
  
  Fixed the way that the .pem files are looked for, and changed
  how to kill the process in win32 to use the _handle attribute.
........
  r54682 | guido.van.rossum | 2007-04-04 10:43:02 -0700 (Wed, 04 Apr 2007) | 4 lines
  
  Fix a race condition in this test -- instead of assuming that it will take
  the test server thread at most 0.5 seconds to get ready, use an event
  variable.
........
  r54683 | collin.winter | 2007-04-04 11:14:17 -0700 (Wed, 04 Apr 2007) | 1 line
  
  Clean up imports.
........
  r54684 | collin.winter | 2007-04-04 11:16:24 -0700 (Wed, 04 Apr 2007) | 1 line
  
  Stop using test_support.verify().
........
  r54685 | martin.v.loewis | 2007-04-04 11:30:36 -0700 (Wed, 04 Apr 2007) | 2 lines
  
  Bug #1686475: Support stat'ing open files on Windows again.
  Will backport to 2.5.
........
  r54687 | collin.winter | 2007-04-04 11:33:40 -0700 (Wed, 04 Apr 2007) | 1 line
  
  Make test_getopt use unittest.
........
  r54688 | collin.winter | 2007-04-04 11:36:30 -0700 (Wed, 04 Apr 2007) | 1 line
  
  Make test_softspace use unittest.
........
  r54689 | ziga.seilnacht | 2007-04-04 11:38:47 -0700 (Wed, 04 Apr 2007) | 2 lines
  
  Fix WalkTests.test_traversal() on Windows.  The cleanup in
  MakedirTests.setUp() can now be removed.
........
  r54695 | raymond.hettinger | 2007-04-05 11:00:03 -0700 (Thu, 05 Apr 2007) | 3 lines
  
  Bug #1563759: struct.unpack doens't support buffer protocol objects
........
  r54697 | collin.winter | 2007-04-05 13:05:07 -0700 (Thu, 05 Apr 2007) | 1 line
  
  Convert test_long_future to use unittest.
........
  r54698 | collin.winter | 2007-04-05 13:08:56 -0700 (Thu, 05 Apr 2007) | 1 line
  
  Convert test_normalization to use unittest.
........
  r54699 | andrew.kuchling | 2007-04-05 18:11:58 -0700 (Thu, 05 Apr 2007) | 1 line
  
  Some grammar fixes
........
  r54704 | collin.winter | 2007-04-06 12:27:40 -0700 (Fri, 06 Apr 2007) | 1 line
  
  Convert test_stringprep to use unittest.
........
  r54705 | collin.winter | 2007-04-06 12:32:32 -0700 (Fri, 06 Apr 2007) | 1 line
  
  Import cleanup in test_crypt.
........
  r54706 | collin.winter | 2007-04-06 13:00:05 -0700 (Fri, 06 Apr 2007) | 1 line
  
  Convert test_gc to use unittest.
........
  r54707 | collin.winter | 2007-04-06 13:03:11 -0700 (Fri, 06 Apr 2007) | 1 line
  
  Convert test_module to use unittest.
........
  r54711 | collin.winter | 2007-04-06 21:40:43 -0700 (Fri, 06 Apr 2007) | 1 line
  
  Convert test_fileinput to use unittest.
........
  r54712 | brett.cannon | 2007-04-07 21:29:32 -0700 (Sat, 07 Apr 2007) | 5 lines
  
  Doc that file.next() has undefined behaviour when called on a file opened with
  'w'.  Closes bug #1569057.
  
  To be backported once 2.5 branch is unfrozen.
........
  r54726 | vinay.sajip | 2007-04-09 09:16:10 -0700 (Mon, 09 Apr 2007) | 1 line
  
  Added optional timeout to SocketHandler.makeSocket (SF #1695948)
........
  r54727 | ziga.seilnacht | 2007-04-09 12:10:29 -0700 (Mon, 09 Apr 2007) | 3 lines
  
  Patch #1695862: remove old test directory that causes test_urllib failures
  on Windows buildbots.  The change is a one time fix and will be removed
  after a successful buildbot run.
........
  r54729 | facundo.batista | 2007-04-09 20:00:37 -0700 (Mon, 09 Apr 2007) | 3 lines
  
  
  Minor fix to the tests pass ok even with -O.
........
  r54730 | collin.winter | 2007-04-09 21:44:49 -0700 (Mon, 09 Apr 2007) | 1 line
  
  Typo fix.
........
  r54732 | facundo.batista | 2007-04-10 05:58:45 -0700 (Tue, 10 Apr 2007) | 5 lines
  
  
  General clean-up. Lot of margin corrections, comments, some typos.
  Exceptions now are raised in the new style. And a mockup class is
  now also new style. Thanks Santiago Pereson.
........
  r54741 | georg.brandl | 2007-04-10 14:39:38 -0700 (Tue, 10 Apr 2007) | 2 lines
  
  Repair a duplicate label and some obsolete uses of \setindexsubitem.
........
  r54746 | andrew.kuchling | 2007-04-11 06:39:00 -0700 (Wed, 11 Apr 2007) | 1 line
  
  Add window.chgat() method, submitted via e-mail by Fabian Kreutz
........
  r54747 | andrew.kuchling | 2007-04-11 06:42:25 -0700 (Wed, 11 Apr 2007) | 1 line
  
  Point readers at the patch submission instructions
........
  r54748 | andrew.kuchling | 2007-04-11 06:47:13 -0700 (Wed, 11 Apr 2007) | 1 line
  
  Describe undocumented third argument to touchline()
........
  r54757 | georg.brandl | 2007-04-11 10:16:24 -0700 (Wed, 11 Apr 2007) | 3 lines
  
  Add some missing NULL checks which trigger crashes on low-memory conditions.
  Found by Victor Stinner. Will backport when 2.5 branch is unfrozen.
........
  r54760 | raymond.hettinger | 2007-04-11 11:40:58 -0700 (Wed, 11 Apr 2007) | 1 line
  
  SF 1191699:  Make slices picklable
........
  r54762 | georg.brandl | 2007-04-11 12:25:11 -0700 (Wed, 11 Apr 2007) | 2 lines
  
  Exceptions are no longer old-style instances. Fix accordingly.
........
  r54763 | georg.brandl | 2007-04-11 16:28:44 -0700 (Wed, 11 Apr 2007) | 2 lines
  
  Repair missing spaces after \UNIX.
........
  r54772 | raymond.hettinger | 2007-04-11 21:10:00 -0700 (Wed, 11 Apr 2007) | 1 line
  
  SF 1193128:  Let str.translate(None) be an identity transformation
........
  r54784 | georg.brandl | 2007-04-12 00:01:19 -0700 (Thu, 12 Apr 2007) | 2 lines
  
  Patch #1698951: clarify deprecation message in rexec and Bastion
........
  r54785 | ziga.seilnacht | 2007-04-12 01:46:51 -0700 (Thu, 12 Apr 2007) | 2 lines
  
  Patch #1695862: remove the cleanup code, now that Windows buildbots are green
  again.
........
  r54786 | walter.doerwald | 2007-04-12 03:35:00 -0700 (Thu, 12 Apr 2007) | 3 lines
  
  Fix utf-8-sig incremental decoder, which didn't recognise a BOM when the
  first chunk fed to the decoder started with a BOM, but was longer than 3 bytes.
........
  r54807 | barry.warsaw | 2007-04-13 11:47:14 -0700 (Fri, 13 Apr 2007) | 8 lines
  
  Port r54805 from python25-maint branch:
  
  Add code to read from master_fd in the parent, breaking when we get an OSError
  (EIO can occur on Linux) or there's no more data to read.  Without this,
  test_pty.py can hang on the waitpid() because the child is blocking on the
  stdout write.  This will definitely happen on Mac OS X and could potentially
  happen on other platforms.  See the comment for details.
........
  r54812 | kristjan.jonsson | 2007-04-13 15:07:33 -0700 (Fri, 13 Apr 2007) | 1 line
  
  Fix a bug when using the __lltrace__ opcode tracer, and a problem sith signed chars in frameobject.c which can occur with opcodes > 127
........
  r54814 | kristjan.jonsson | 2007-04-13 15:20:13 -0700 (Fri, 13 Apr 2007) | 1 line
  
  Fix potential crash in path manipulation on windows
........
  r54816 | trent.mick | 2007-04-13 16:22:05 -0700 (Fri, 13 Apr 2007) | 4 lines
  
  Add the necessary dependency for the Windows VC6 build to ensure 'pythoncore'
  is built before '_ctypes' is attempted.
  Will backport to 2.5 once it is unfrozen for 2.5.1.
........
  r54825 | neal.norwitz | 2007-04-13 22:25:50 -0700 (Fri, 13 Apr 2007) | 3 lines
  
  When __slots__ are set to a unicode string, make it work the same as 
  setting a plain string, ie don't expand to single letter identifiers.
........
  r54841 | neal.norwitz | 2007-04-16 00:37:55 -0700 (Mon, 16 Apr 2007) | 1 line
  
  SF #1701207, Fix bogus assertion (and test it!)
........
  r54844 | collin.winter | 2007-04-16 15:10:32 -0700 (Mon, 16 Apr 2007) | 1 line
  
  Check the availability of the urlfetch resource earlier than before.
........
  r54849 | martin.v.loewis | 2007-04-16 22:02:01 -0700 (Mon, 16 Apr 2007) | 2 lines
  
  Add Travis Oliphant.
........
  r54873 | brett.cannon | 2007-04-18 20:44:17 -0700 (Wed, 18 Apr 2007) | 2 lines
  
  Silence a compiler warning about incompatible pointer types.
........
  r54874 | neal.norwitz | 2007-04-18 22:52:37 -0700 (Wed, 18 Apr 2007) | 2 lines
  
  SF #1703270, add missing declaration in readline.c to avoid compiler warning.
........
  r54875 | armin.rigo | 2007-04-19 07:44:48 -0700 (Thu, 19 Apr 2007) | 8 lines
  
  Revert r53997 as per
  http://mail.python.org/pipermail/python-dev/2007-March/071796.html .
  
  I've kept a couple of still-valid extra tests in test_descr, but didn't
  bother to sort through the new comments and refactorings added in r53997
  to see if some of them could be kept.  If so, they could go in a
  follow-up check-in.
........
  r54876 | armin.rigo | 2007-04-19 07:56:48 -0700 (Thu, 19 Apr 2007) | 2 lines
  
  Fix a usage of the dangerous pattern decref - modify field - incref.
........
  r54884 | neal.norwitz | 2007-04-19 22:20:38 -0700 (Thu, 19 Apr 2007) | 9 lines
  
  Add an optional address to copy the failure mails to.
  
  Detect a conflict in the only file that should have outstanding changes
  when this script is run.  This doesn't matter on the trunk, but does
  when run on a branch.  Trunk always has the date set to today in
  boilerplate.tex.  Each time a release is cut with a different date,
  a conflict occurs.  (We could copy a known good version, but then
  we would lose changes to this file.)
........
  r54918 | georg.brandl | 2007-04-21 13:35:38 -0700 (Sat, 21 Apr 2007) | 3 lines
  
  Bug #1704790: bind name "sys" locally in __del__ method so that it is
  not cleared before __del__ is run.
........
  r54920 | facundo.batista | 2007-04-21 18:18:56 -0700 (Sat, 21 Apr 2007) | 5 lines
  
  
  Added tests for other methods of SSL object. Now we cover
  all the object methods. This is the final step to close 
  the #451607 bug.
........
  r54927 | facundo.batista | 2007-04-23 10:08:31 -0700 (Mon, 23 Apr 2007) | 5 lines
  
  
  As specified in RFC 2616, 2xx code indicates that the client's
  request was successfully received, understood, and accepted.
  Now in these cases no error is raised. Also fixed tests.
........
  r54929 | collin.winter | 2007-04-23 20:43:46 -0700 (Mon, 23 Apr 2007) | 1 line
  
  Convert PyUnit -> unittest.
........
  r54931 | collin.winter | 2007-04-23 21:09:52 -0700 (Mon, 23 Apr 2007) | 1 line
  
  Remove code that hasn't been called in years.
........
  r54932 | neal.norwitz | 2007-04-23 21:53:12 -0700 (Mon, 23 Apr 2007) | 1 line
  
  Fix SF #1703110, Incorrect example for add_password() (use uri, not host)
........
  r54934 | georg.brandl | 2007-04-24 03:36:42 -0700 (Tue, 24 Apr 2007) | 2 lines
  
  Some new year updates.
........
  r54938 | facundo.batista | 2007-04-24 06:54:38 -0700 (Tue, 24 Apr 2007) | 4 lines
  
  
  Added a comment about last change in urllib2.py (all 2xx responses
  are ok now).
........
  r54939 | georg.brandl | 2007-04-24 08:10:09 -0700 (Tue, 24 Apr 2007) | 2 lines
  
  Bug #1705717: error in sys.argv docs.
........
  r54941 | georg.brandl | 2007-04-24 08:27:13 -0700 (Tue, 24 Apr 2007) | 4 lines
  
  Bug #1706381: Specifying the SWIG option "-c++" in the setup.py file
  (as opposed to the command line) will now write file names ending in
  ".cpp" too.
........
  r54944 | raymond.hettinger | 2007-04-24 15:13:43 -0700 (Tue, 24 Apr 2007) | 1 line
  
  Fix markup
........
  r54945 | kristjan.jonsson | 2007-04-24 17:10:50 -0700 (Tue, 24 Apr 2007) | 1 line
  
  Merge change 54909 from release25-maint:  Fix several minor issues discovered using code analysis in VisualStudio 2005 Team Edition
........
  r54947 | kristjan.jonsson | 2007-04-24 17:17:39 -0700 (Tue, 24 Apr 2007) | 1 line
  
  Make pythoncore compile cleanly with VisualStudio 2005.  Used an explicit typecast to get a 64 bit integer, and undefined the Yield macro that conflicts with winbase.h
........
  r54948 | kristjan.jonsson | 2007-04-24 17:19:26 -0700 (Tue, 24 Apr 2007) | 1 line
  
  Remove obsolete comment. Importing of .dll files has been discontinued, only .pyd files supported on windows now.
........
  r54949 | georg.brandl | 2007-04-24 23:24:59 -0700 (Tue, 24 Apr 2007) | 2 lines
  
  Patch #1698768: updated the "using Python on the Mac" intro.
........
  r54951 | georg.brandl | 2007-04-24 23:25:55 -0700 (Tue, 24 Apr 2007) | 2 lines
  
  Markup fix.
........
  r54953 | neal.norwitz | 2007-04-24 23:30:05 -0700 (Tue, 24 Apr 2007) | 3 lines
  
  Whitespace normalization.  Ugh, we really need to do this more often.
  You might want to review this change as it's my first time.  Be gentle. :-)
........
  r54956 | collin.winter | 2007-04-25 10:29:52 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Standardize on test.test_support.run_unittest() (as opposed to a mix of run_unittest() and run_suite()). Also, add functionality to run_unittest() that admits usage of unittest.TestLoader.loadTestsFromModule().
........
  r54957 | collin.winter | 2007-04-25 10:37:35 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Remove functionality from test_datetime.test_main() that does reference count checking; 'regrtest.py -R' is the way to do this kind of testing.
........
  r54958 | collin.winter | 2007-04-25 10:57:53 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Change test_support.have_unicode to use True/False instead of 1/0.
........
  r54959 | tim.peters | 2007-04-25 11:47:18 -0700 (Wed, 25 Apr 2007) | 2 lines
  
  Whitespace normalization.
........
  r54960 | tim.peters | 2007-04-25 11:48:35 -0700 (Wed, 25 Apr 2007) | 2 lines
  
  Set missing svn:eol-style property on text files.
........
  r54961 | collin.winter | 2007-04-25 11:54:36 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Import and raise statement cleanup.
........
  r54969 | collin.winter | 2007-04-25 13:41:34 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Convert test_ossaudiodev to use unittest.
........
  r54974 | collin.winter | 2007-04-25 14:50:25 -0700 (Wed, 25 Apr 2007) | 1 line
  
  Fix an issue related to the unittest conversion.
........
  r54979 | fred.drake | 2007-04-25 21:42:19 -0700 (Wed, 25 Apr 2007) | 1 line
  
  fix some markup errors
........
  r54982 | kristjan.jonsson | 2007-04-26 02:15:08 -0700 (Thu, 26 Apr 2007) | 1 line
  
  Export function sanitize_the_mode from fileobject.c as _PyFile_SanitizeMode().  Use this function in posixmodule.c when implementing fdopen().  This fixes test_subprocess.py for a VisualStudio 2005 compile.
........
  r54983 | kristjan.jonsson | 2007-04-26 06:44:16 -0700 (Thu, 26 Apr 2007) | 1 line
  
  The locale "En" appears not to be valid on windows underi VisualStudio.2005.  Added "English" to the test_locale.py to make the testsuite pass for that build
........
  r54984 | steve.holden | 2007-04-26 07:23:12 -0700 (Thu, 26 Apr 2007) | 1 line
  
  Minor wording change on slicing aide-memoire.
........
  r54985 | kristjan.jonsson | 2007-04-26 08:24:54 -0700 (Thu, 26 Apr 2007) | 1 line
  
  Accomodate 64 bit time_t in the _bsddb module.
........


Modified: python/branches/p3yk/Demo/parser/unparse.py
==============================================================================
--- python/branches/p3yk/Demo/parser/unparse.py	(original)
+++ python/branches/p3yk/Demo/parser/unparse.py	Fri Apr 27 21:54:29 2007
@@ -4,6 +4,19 @@
 import cStringIO
 import os
 
+def interleave(inter, f, seq):
+    """Call f on each item in seq, calling inter() in between.
+    """
+    seq = iter(seq)
+    try:
+        f(seq.next())
+    except StopIteration:
+        pass
+    else:
+        for x in seq:
+            inter()
+            f(x)
+
 class Unparser:
     """Methods in this class recursively traverse an AST and
     output source code for the abstract syntax; original formatting
@@ -63,26 +76,13 @@
 
     def _Import(self, t):
         self.fill("import ")
-        first = True
-        for a in t.names:
-            if first:
-                first = False
-            else:
-                self.write(", ")
-            self.write(a.name)
-            if a.asname:
-                self.write(" as "+a.asname)
+        interleave(lambda: self.write(", "), self.dispatch, t.names)
 
     def _ImportFrom(self, t):
         self.fill("from ")
         self.write(t.module)
         self.write(" import ")
-        for i, a in enumerate(t.names):
-            if i == 0:
-                self.write(", ")
-            self.write(a.name)
-            if a.asname:
-                self.write(" as "+a.asname)
+        interleave(lambda: self.write(", "), self.dispatch, t.names)
         # XXX(jpe) what is level for?
 
     def _Assign(self, t):
@@ -99,8 +99,9 @@
         self.dispatch(t.value)
 
     def _Return(self, t):
-        self.fill("return ")
+        self.fill("return")
         if t.value:
+            self.write(" ")
             self.dispatch(t.value)
 
     def _Pass(self, t):
@@ -138,18 +139,16 @@
             self.write(",")
 
     def _Global(self, t):
-        self.fill("global")
-        for i, n in enumerate(t.names):
-            if i != 0:
-                self.write(",")
-            self.write(" " + n)
+        self.fill("global ")
+        interleave(lambda: self.write(", "), self.write, t.names)
 
     def _Yield(self, t):
-        self.fill("yield")
+        self.write("(")
+        self.write("yield")
         if t.value:
-            self.write(" (")
+            self.write(" ")
             self.dispatch(t.value)
-            self.write(")")
+        self.write(")")
 
     def _Raise(self, t):
         self.fill('raise ')
@@ -188,8 +187,9 @@
         self.leave()
 
     def _excepthandler(self, t):
-        self.fill("except ")
+        self.fill("except")
         if t.type:
+            self.write(" ")
             self.dispatch(t.type)
         if t.name:
             self.write(", ")
@@ -289,9 +289,7 @@
 
     def _List(self, t):
         self.write("[")
-        for e in t.elts:
-            self.dispatch(e)
-            self.write(", ")
+        interleave(lambda: self.write(", "), self.dispatch, t.elts)
         self.write("]")
 
     def _ListComp(self, t):
@@ -318,30 +316,31 @@
             self.dispatch(if_clause)
 
     def _IfExp(self, t):
+        self.write("(")
         self.dispatch(t.body)
         self.write(" if ")
         self.dispatch(t.test)
-        if t.orelse:
-            self.write(" else ")
-            self.dispatch(t.orelse)
+        self.write(" else ")
+        self.dispatch(t.orelse)
+        self.write(")")
 
     def _Dict(self, t):
         self.write("{")
-        for k,v in zip(t.keys, t.values):
+        def writem((k, v)):
             self.dispatch(k)
-            self.write(" : ")
+            self.write(": ")
             self.dispatch(v)
-            self.write(", ")
+        interleave(lambda: self.write(", "), writem, zip(t.keys, t.values))
         self.write("}")
 
     def _Tuple(self, t):
-        if not t.elts:
-            self.write("()")
-            return
         self.write("(")
-        for e in t.elts:
-            self.dispatch(e)
-            self.write(", ")
+        if len(t.elts) == 1:
+            (elt,) = t.elts
+            self.dispatch(elt)
+            self.write(",")
+        else:
+            interleave(lambda: self.write(", "), self.dispatch, t.elts)
         self.write(")")
 
     unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
@@ -357,7 +356,7 @@
     def _BinOp(self, t):
         self.write("(")
         self.dispatch(t.left)
-        self.write(")" + self.binop[t.op.__class__.__name__] + "(")
+        self.write(" " + self.binop[t.op.__class__.__name__] + " ")
         self.dispatch(t.right)
         self.write(")")
 
@@ -367,17 +366,15 @@
         self.write("(")
         self.dispatch(t.left)
         for o, e in zip(t.ops, t.comparators):
-            self.write(") " +self.cmpops[o.__class__.__name__] + " (")
+            self.write(" " + self.cmpops[o.__class__.__name__] + " ")
             self.dispatch(e)
             self.write(")")
 
     boolops = {_ast.And: 'and', _ast.Or: 'or'}
     def _BoolOp(self, t):
         self.write("(")
-        self.dispatch(t.values[0])
-        for v in t.values[1:]:
-            self.write(" %s " % self.boolops[t.op.__class__])
-            self.dispatch(v)
+        s = " %s " % self.boolops[t.op.__class__]
+        interleave(lambda: self.write(s), self.dispatch, t.values)
         self.write(")")
 
     def _Attribute(self,t):
@@ -433,10 +430,7 @@
             self.dispatch(t.step)
 
     def _ExtSlice(self, t):
-        for i, d in enumerate(t.dims):
-            if i != 0:
-                self.write(': ')
-            self.dispatch(d)
+        interleave(lambda: self.write(', '), self.dispatch, t.dims)
 
     # others
     def _arguments(self, t):
@@ -472,9 +466,14 @@
         self.write(": ")
         self.dispatch(t.body)
 
+    def _alias(self, t):
+        self.write(t.name)
+        if t.asname:
+            self.write(" as "+t.asname)
+
 def roundtrip(filename, output=sys.stdout):
     source = open(filename).read()
-    tree = compile(source, filename, "exec", 0x400)
+    tree = compile(source, filename, "exec", _ast.PyCF_ONLY_AST)
     Unparser(tree, output)
 
 

Modified: python/branches/p3yk/Doc/api/abstract.tex
==============================================================================
--- python/branches/p3yk/Doc/api/abstract.tex	(original)
+++ python/branches/p3yk/Doc/api/abstract.tex	Fri Apr 27 21:54:29 2007
@@ -790,7 +790,7 @@
   the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}.
 \end{cfuncdesc}
 
-\begin{cfuncdesc}{int}{PySequence_Count}{PyObject *o, PyObject *value}
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Count}{PyObject *o, PyObject *value}
   Return the number of occurrences of \var{value} in \var{o}, that is,
   return the number of keys for which \code{\var{o}[\var{key}] ==
   \var{value}}.  On failure, return \code{-1}.  This is equivalent to
@@ -804,7 +804,7 @@
   expression \samp{\var{value} in \var{o}}.
 \end{cfuncdesc}
 
-\begin{cfuncdesc}{int}{PySequence_Index}{PyObject *o, PyObject *value}
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Index}{PyObject *o, PyObject *value}
   Return the first index \var{i} for which \code{\var{o}[\var{i}] ==
   \var{value}}.  On error, return \code{-1}.    This is equivalent to
   the Python expression \samp{\var{o}.index(\var{value})}.
@@ -854,7 +854,7 @@
   \versionadded{2.3}
 \end{cfuncdesc}
 
-\begin{cfuncdesc}{int}{PySequence_Fast_GET_SIZE}{PyObject *o}
+\begin{cfuncdesc}{Py_ssize_t}{PySequence_Fast_GET_SIZE}{PyObject *o}
   Returns the length of \var{o}, assuming that \var{o} was
   returned by \cfunction{PySequence_Fast()} and that \var{o} is
   not \NULL.  The size can also be gotten by calling

Modified: python/branches/p3yk/Doc/api/concrete.tex
==============================================================================
--- python/branches/p3yk/Doc/api/concrete.tex	(original)
+++ python/branches/p3yk/Doc/api/concrete.tex	Fri Apr 27 21:54:29 2007
@@ -442,7 +442,9 @@
 
 \begin{cfuncdesc}{double}{PyFloat_AsDouble}{PyObject *pyfloat}
   Return a C \ctype{double} representation of the contents of
-  \var{pyfloat}.
+  \var{pyfloat}.  If \var{pyfloat} is not a Python floating point
+  object but has a \method{__float__} method, this method will first
+  be called to convert \var{pyfloat} into a float.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{double}{PyFloat_AS_DOUBLE}{PyObject *pyfloat}
@@ -557,8 +559,11 @@
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{Py_complex}{PyComplex_AsCComplex}{PyObject *op}
-  Return the \ctype{Py_complex} value of the complex number
-  \var{op}.
+  Return the \ctype{Py_complex} value of the complex number \var{op}.
+  \versionchanged[If \var{op} is not a Python complex number object
+                  but has a \method{__complex__} method, this method
+		  will first be called to convert \var{op} to a Python
+		  complex number object]{2.6}
 \end{cfuncdesc}
 
 
@@ -2156,6 +2161,35 @@
 
 \section{Other Objects \label{otherObjects}}
 
+\subsection{Class Objects \label{classObjects}}
+
+\obindex{class}
+Note that the class objects described here represent old-style classes,
+which will go away in Python 3. When creating new types for extension
+modules, you will want to work with type objects (section
+\ref{typeObjects}).
+
+\begin{ctypedesc}{PyClassObject}
+  The C structure of the objects used to describe built-in classes.
+\end{ctypedesc}
+
+\begin{cvardesc}{PyObject*}{PyClass_Type}
+  This is the type object for class objects; it is the same object as
+  \code{types.ClassType} in the Python layer.
+  \withsubitem{(in module types)}{\ttindex{ClassType}}
+\end{cvardesc}
+
+\begin{cfuncdesc}{int}{PyClass_Check}{PyObject *o}
+  Return true if the object \var{o} is a class object, including
+  instances of types derived from the standard class object.  Return
+  false in all other cases.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyClass_IsSubclass}{PyObject *klass, PyObject *base}
+  Return true if \var{klass} is a subclass of \var{base}. Return false in
+  all other cases.
+\end{cfuncdesc}
+
 \subsection{File Objects \label{fileObjects}}
 
 \obindex{file}

Modified: python/branches/p3yk/Doc/api/init.tex
==============================================================================
--- python/branches/p3yk/Doc/api/init.tex	(original)
+++ python/branches/p3yk/Doc/api/init.tex	Fri Apr 27 21:54:29 2007
@@ -245,7 +245,7 @@
   program name (set by \cfunction{Py_SetProgramName()} above) and some
   environment variables.  The returned string consists of a series of
   directory names separated by a platform dependent delimiter
-  character.  The delimiter character is \character{:} on \UNIX and Mac OS X,
+  character.  The delimiter character is \character{:} on \UNIX{} and Mac OS X,
   \character{;} on Windows.  The returned string points into
   static storage; the caller should not modify its value.  The value
   is available to Python code as the list

Modified: python/branches/p3yk/Doc/api/memory.tex
==============================================================================
--- python/branches/p3yk/Doc/api/memory.tex	(original)
+++ python/branches/p3yk/Doc/api/memory.tex	Fri Apr 27 21:54:29 2007
@@ -100,7 +100,9 @@
   memory block is resized but is not freed, and the returned pointer
   is non-\NULL.  Unless \var{p} is \NULL, it must have been
   returned by a previous call to \cfunction{PyMem_Malloc()} or
-  \cfunction{PyMem_Realloc()}.
+  \cfunction{PyMem_Realloc()}. If the request fails,
+  \cfunction{PyMem_Realloc()} returns \NULL{} and \var{p} remains a
+  valid pointer to the previous memory area.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{void}{PyMem_Free}{void *p}
@@ -124,7 +126,8 @@
 \begin{cfuncdesc}{\var{TYPE}*}{PyMem_Resize}{void *p, TYPE, size_t n}
   Same as \cfunction{PyMem_Realloc()}, but the memory block is resized
   to \code{(\var{n} * sizeof(\var{TYPE}))} bytes.  Returns a pointer
-  cast to \ctype{\var{TYPE}*}.
+  cast to \ctype{\var{TYPE}*}. On return, \var{p} will be a pointer to
+  the new memory area, or \NULL{} in the event of failure.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{void}{PyMem_Del}{void *p}

Modified: python/branches/p3yk/Doc/api/newtypes.tex
==============================================================================
--- python/branches/p3yk/Doc/api/newtypes.tex	(original)
+++ python/branches/p3yk/Doc/api/newtypes.tex	Fri Apr 27 21:54:29 2007
@@ -1316,7 +1316,7 @@
 
   This field is inherited by static subtypes, but not by dynamic
   subtypes (subtypes created by a class statement); in the latter,
-  this field is always set to \cfunction{PyType_GenericAlloc()}, to
+  this field is always set to \cfunction{PyType_GenericAlloc}, to
   force a standard heap allocation strategy.  That is also the
   recommended value for statically defined types.
 \end{cmemberdesc}

Modified: python/branches/p3yk/Doc/api/utilities.tex
==============================================================================
--- python/branches/p3yk/Doc/api/utilities.tex	(original)
+++ python/branches/p3yk/Doc/api/utilities.tex	Fri Apr 27 21:54:29 2007
@@ -930,3 +930,94 @@
   If there is an error in the format string, the
   \exception{SystemError} exception is set and \NULL{} returned.
 \end{cfuncdesc}
+
+\section{String conversion and formatting \label{string-formatting}}
+
+Functions for number conversion and formatted string output.
+
+\begin{cfuncdesc}{int}{PyOS_snprintf}{char *str, size_t size, 
+                                      const char *format, \moreargs}
+Output not more than \var{size} bytes to \var{str} according to the format
+string \var{format} and the extra arguments. See the \UNIX{} man
+page \manpage{snprintf}{2}.
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyOS_vsnprintf}{char *str, size_t size,
+                                       const char *format, va_list va}
+Output not more than \var{size} bytes to \var{str} according to the format
+string \var{format} and the variable argument list \var{va}. \UNIX{}
+man page \manpage{vsnprintf}{2}.
+\end{cfuncdesc}
+
+\cfunction{PyOS_snprintf} and \cfunction{PyOS_vsnprintf} wrap the
+Standard C library functions \cfunction{snprintf()} and
+\cfunction{vsnprintf()}. Their purpose is to guarantee consistent
+behavior in corner cases, which the Standard C functions do not.
+
+The wrappers ensure that \var{str}[\var{size}-1] is always
+\character{\textbackslash0} upon return. They never write more than
+\var{size} bytes (including the trailing \character{\textbackslash0}
+into str. Both functions require that \code{\var{str} != NULL},
+\code{\var{size} > 0} and \code{\var{format} != NULL}.
+
+If the platform doesn't have \cfunction{vsnprintf()} and the buffer
+size needed to avoid truncation exceeds \var{size} by more than 512
+bytes, Python aborts with a \var{Py_FatalError}.
+
+The return value (\var{rv}) for these functions should be interpreted
+as follows:
+
+\begin{itemize}
+
+\item When \code{0 <= \var{rv} < \var{size}}, the output conversion
+  was successful and \var{rv} characters were written to \var{str}
+  (excluding the trailing \character{\textbackslash0} byte at
+  \var{str}[\var{rv}]).
+
+\item When \code{\var{rv} >= \var{size}}, the output conversion was
+  truncated and a buffer with \code{\var{rv} + 1} bytes would have
+  been needed to succeed. \var{str}[\var{size}-1] is
+  \character{\textbackslash0} in this case.
+
+\item When \code{\var{rv} < 0}, ``something bad happened.''
+  \var{str}[\var{size}-1] is \character{\textbackslash0} in this case
+  too, but the rest of \var{str} is undefined. The exact cause of the
+  error depends on the underlying platform.
+
+\end{itemize}
+
+The following functions provide locale-independent string to number
+conversions.
+
+\begin{cfuncdesc}{double}{PyOS_ascii_strtod}{const char *nptr, char **endptr}
+Convert a string to a \ctype{double}. This function behaves like the
+Standard C function \cfunction{strtod()} does in the C locale. It does
+this without changing the current locale, since that would not be
+thread-safe.
+
+\cfunction{PyOS_ascii_strtod} should typically be used for reading
+configuration files or other non-user input that should be locale
+independent. \versionadded{2.4}
+
+See the \UNIX{} man page \manpage{strtod}{2} for details.
+
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{char *}{PyOS_ascii_formatd}{char *buffer, size_t buf_len,
+                                              const char *format, double d}
+Convert a \ctype{double} to a string using the \character{.} as the
+decimal separator. \var{format} is a \cfunction{printf()}-style format
+string specifying the number format. Allowed conversion characters are
+\character{e}, \character{E}, \character{f}, \character{F},
+\character{g} and \character{G}.
+
+The return value is a pointer to \var{buffer} with the converted
+string or NULL if the conversion failed. \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{double}{PyOS_ascii_atof}{const char *nptr}
+Convert a string to a \ctype{double} in a locale-independent
+way. \versionadded{2.4}
+
+See the \UNIX{} man page \manpage{atof}{2} for details.
+\end{cfuncdesc}

Modified: python/branches/p3yk/Doc/commontex/copyright.tex
==============================================================================
--- python/branches/p3yk/Doc/commontex/copyright.tex	(original)
+++ python/branches/p3yk/Doc/commontex/copyright.tex	Fri Apr 27 21:54:29 2007
@@ -1,4 +1,4 @@
-Copyright \copyright{} 2001-2006 Python Software Foundation.
+Copyright \copyright{} 2001-2007 Python Software Foundation.
 All rights reserved.
 
 Copyright \copyright{} 2000 BeOpen.com.

Modified: python/branches/p3yk/Doc/commontex/license.tex
==============================================================================
--- python/branches/p3yk/Doc/commontex/license.tex	(original)
+++ python/branches/p3yk/Doc/commontex/license.tex	Fri Apr 27 21:54:29 2007
@@ -52,6 +52,7 @@
   \linev{2.4.3}{2.4.2}{2006}{PSF}{yes}
   \linev{2.4.4}{2.4.3}{2006}{PSF}{yes}
   \linev{2.5}{2.4}{2006}{PSF}{yes}
+  \linev{2.5.1}{2.5}{2007}{PSF}{yes}
 \end{tablev}
 
 \note{GPL-compatible doesn't mean that we're distributing
@@ -82,7 +83,7 @@
 prepare derivative works, distribute, and otherwise use Python
 \version{} alone or in any derivative version, provided, however, that
 PSF's License Agreement and PSF's notice of copyright, i.e.,
-``Copyright \copyright{} 2001-2006 Python Software Foundation; All
+``Copyright \copyright{} 2001-2007 Python Software Foundation; All
 Rights Reserved'' are retained in Python \version{} alone or in any
 derivative version prepared by Licensee.
 

Modified: python/branches/p3yk/Doc/dist/dist.tex
==============================================================================
--- python/branches/p3yk/Doc/dist/dist.tex	(original)
+++ python/branches/p3yk/Doc/dist/dist.tex	Fri Apr 27 21:54:29 2007
@@ -1802,9 +1802,9 @@
         setup.py
         foo.py
 \end{verbatim}
-(In all diagrams in this section, \verb|<root>| will refer to the
-distribution root directory.)  A minimal setup script to describe this
-situation would be:
+(In all diagrams in this section, \var{\textless root\textgreater}
+will refer to the distribution root directory.)  A minimal setup script
+to describe this situation would be:
 \begin{verbatim}
 from distutils.core import setup
 setup(name='foo',
@@ -3179,7 +3179,7 @@
 
 Note that this is not a fully-fledged string interpolation function. A
 valid \code{\$variable} can consist only of upper and lower case letters,
-numbers and an underscore. No \{ \} or \( \) style quoting is available.
+numbers and an underscore. No \{ \} or ( ) style quoting is available.
 \end{funcdesc}
 
 \begin{funcdesc}{grok_environment_error}{exc\optional{, prefix=\samp{'error: '}}}
@@ -3733,7 +3733,7 @@
 
 Subclasses of \class{Command} must define the following methods.
 
-\begin{methoddesc}{initialize_options()}
+\begin{methoddesc}[Command]{initialize_options()}
 Set default values for all the options that this command
 supports.  Note that these defaults may be overridden by other
 commands, by the setup script, by config files, or by the
@@ -3742,7 +3742,7 @@
 are just a bunch of \samp{self.foo = None} assignments.
 \end{methoddesc}
 
-\begin{methoddesc}{finalize_options}{}
+\begin{methoddesc}[Command]{finalize_options}{}
 Set final values for all the options that this command supports.
 This is always called as late as possible, ie.  after any option
 assignments from the command-line or from other commands have been
@@ -3751,7 +3751,7 @@
 \var{bar} as long as \var{foo} still has the same value it was assigned in
 \method{initialize_options()}.
 \end{methoddesc}
-\begin{methoddesc}{run}{}
+\begin{methoddesc}[Command]{run}{}
 A command's raison d'etre: carry out the action it exists to
 perform, controlled by the options initialized in
 \method{initialize_options()}, customized by other commands, the setup

Modified: python/branches/p3yk/Doc/ext/newtypes.tex
==============================================================================
--- python/branches/p3yk/Doc/ext/newtypes.tex	(original)
+++ python/branches/p3yk/Doc/ext/newtypes.tex	Fri Apr 27 21:54:29 2007
@@ -489,7 +489,6 @@
   garbage collection, there are calls that can be made to ``untrack''
   the object from garbage collection, however, these calls are
   advanced and not covered here.}
-\item
 \end{itemize}
 
 
@@ -930,6 +929,102 @@
 collection. Most extensions will use the versions automatically
 provided.
 
+\subsection{Subclassing other types}
+
+It is possible to create new extension types that are derived from existing
+types. It is easiest to inherit from the built in types, since an extension
+can easily use the \class{PyTypeObject} it needs. It can be difficult to
+share these \class{PyTypeObject} structures between extension modules.
+
+In this example we will create a \class{Shoddy} type that inherits from
+the builtin \class{list} type. The new type will be completely compatible
+with regular lists, but will have an additional \method{increment()} method
+that increases an internal counter.
+
+\begin{verbatim}
+>>> import shoddy
+>>> s = shoddy.Shoddy(range(3))
+>>> s.extend(s)
+>>> print len(s)
+6
+>>> print s.increment()
+1
+>>> print s.increment()
+2
+\end{verbatim}
+
+\verbatiminput{shoddy.c}
+
+As you can see, the source code closely resembles the \class{Noddy} examples in previous
+sections. We will break down the main differences between them.
+
+\begin{verbatim}
+typedef struct {
+	PyListObject list;
+	int state;
+} Shoddy;
+\end{verbatim}
+
+The primary difference for derived type objects is that the base type's
+object structure must be the first value. The base type will already
+include the \cfunction{PyObject_HEAD} at the beginning of its structure.
+
+When a Python object is a \class{Shoddy} instance, its \var{PyObject*} pointer
+can be safely cast to both \var{PyListObject*} and \var{Shoddy*}.
+
+\begin{verbatim}
+static int
+Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
+{
+	if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
+		return -1;
+	self->state = 0;
+	return 0;
+}
+\end{verbatim}
+
+In the \member{__init__} method for our type, we can see how to call through
+to the \member{__init__} method of the base type.
+
+This pattern is important when writing a type with custom \member{new} and
+\member{dealloc} methods. The \member{new} method should not actually create the
+memory for the object with \member{tp_alloc}, that will be handled by
+the base class when calling its \member{tp_new}.
+
+When filling out the \cfunction{PyTypeObject} for the \class{Shoddy} type,
+you see a slot for \cfunction{tp_base}. Due to cross platform compiler
+issues, you can't fill that field directly with the \cfunction{PyList_Type};
+it can be done later in the module's \cfunction{init} function.
+
+\begin{verbatim}
+PyMODINIT_FUNC
+initshoddy(void)
+{
+	PyObject *m;
+
+	ShoddyType.tp_base = &PyList_Type;
+	if (PyType_Ready(&ShoddyType) < 0)
+		return;
+
+	m = Py_InitModule3("shoddy", NULL, "Shoddy module");
+	if (m == NULL)
+		return;
+
+	Py_INCREF(&ShoddyType);
+	PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
+}
+\end{verbatim}
+
+Before calling \cfunction{PyType_Ready}, the type structure must have the
+\member{tp_base} slot filled in. When we are deriving a new type, it is
+not necessary to fill out the \member{tp_alloc} slot with
+\cfunction{PyType_GenericNew} -- the allocate function from the base type
+will be inherited.
+
+After that, calling \cfunction{PyType_Ready} and adding the type object
+to the module is the same as with the basic \class{Noddy} examples.
+
+
 \section{Type Methods
          \label{dnt-type-methods}}
 

Modified: python/branches/p3yk/Doc/inst/inst.tex
==============================================================================
--- python/branches/p3yk/Doc/inst/inst.tex	(original)
+++ python/branches/p3yk/Doc/inst/inst.tex	Fri Apr 27 21:54:29 2007
@@ -296,7 +296,7 @@
 \filevar{prefix} and \filevar{exec-prefix} stand for the directories
 that Python is installed to, and where it finds its libraries at
 run-time.  They are always the same under Windows, and very
-often the same under \UNIX and Mac OS X.  You can find out what your Python
+often the same under \UNIX{} and Mac OS X.  You can find out what your Python
 installation uses for \filevar{prefix} and \filevar{exec-prefix} by
 running Python in interactive mode and typing a few simple commands.
 Under \UNIX, just type \code{python} at the shell prompt.  Under

Modified: python/branches/p3yk/Doc/lib/compiler.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/compiler.tex	(original)
+++ python/branches/p3yk/Doc/lib/compiler.tex	Fri Apr 27 21:54:29 2007
@@ -103,8 +103,7 @@
 construct.  The root of the tree is \class{Module} object.
 
 The abstract syntax offers a higher level interface to parsed Python
-source code.  The \ulink{\module{parser}}
-{http://www.python.org/doc/current/lib/module-parser.html}
+source code.  The \refmodule{parser}
 module and the compiler written in C for the Python interpreter use a
 concrete syntax tree.  The concrete syntax is tied closely to the
 grammar description used for the Python parser.  Instead of a single

Modified: python/branches/p3yk/Doc/lib/email.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/email.tex	(original)
+++ python/branches/p3yk/Doc/lib/email.tex	Fri Apr 27 21:54:29 2007
@@ -1,4 +1,4 @@
-% Copyright (C) 2001-2006 Python Software Foundation
+% Copyright (C) 2001-2007 Python Software Foundation
 % Author: barry at python.org (Barry Warsaw)
 
 \section{\module{email} ---
@@ -239,7 +239,7 @@
 
 The \module{email} package was originally prototyped as a separate
 library called
-\ulink{\module{mimelib}}{http://mimelib.sf.net/}.
+\ulink{\texttt{mimelib}}{http://mimelib.sf.net/}.
 Changes have been made so that
 method names are more consistent, and some methods or modules have
 either been added or removed.  The semantics of some of the methods

Modified: python/branches/p3yk/Doc/lib/emailutil.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/emailutil.tex	(original)
+++ python/branches/p3yk/Doc/lib/emailutil.tex	Fri Apr 27 21:54:29 2007
@@ -56,7 +56,7 @@
 \code{"Mon, 20 Nov 1995 19:12:08 -0500"}.  If it succeeds in parsing
 the date, \function{parsedate()} returns a 9-tuple that can be passed
 directly to \function{time.mktime()}; otherwise \code{None} will be
-returned.  Note that fields 6, 7, and 8 of the result tuple are not
+returned.  Note that indexes 6, 7, and 8 of the result tuple are not
 usable.
 \end{funcdesc}
 
@@ -70,7 +70,7 @@
 variable for the same timezone; the latter variable follows the
 \POSIX{} standard while this module follows \rfc{2822}.}.  If the input
 string has no timezone, the last element of the tuple returned is
-\code{None}.  Note that fields 6, 7, and 8 of the result tuple are not
+\code{None}.  Note that indexes 6, 7, and 8 of the result tuple are not
 usable.
 \end{funcdesc}
 

Modified: python/branches/p3yk/Doc/lib/libamoeba.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libamoeba.tex	(original)
+++ python/branches/p3yk/Doc/lib/libamoeba.tex	Fri Apr 27 21:54:29 2007
@@ -89,25 +89,24 @@
 %
 The following methods are defined for capability objects.
 
-\setindexsubitem{(capability method)}
-\begin{funcdesc}{dir_list}{}
+\begin{methoddesc}[capability]{dir_list}{}
 Returns a list of the names of the entries in an Amoeba directory.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{b_read}{offset, maxsize}
+\begin{methoddesc}[capability]{b_read}{offset, maxsize}
 Reads (at most)
 \var{maxsize}
 bytes from a bullet file at offset
 \var{offset.}
 The data is returned as a string.
 EOF is reported as an empty string.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{b_size}{}
+\begin{methoddesc}[capability]{b_size}{}
 Returns the size of a bullet file.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{dir_append}{}
+\begin{methoddesc}[capability]{dir_append}{}
 \funcline{dir_delete}{}
 \funcline{dir_lookup}{}
 \funcline{dir_replace}{}
@@ -116,17 +115,17 @@
 functions, but with a path relative to the capability.
 (For paths beginning with a slash the capability is ignored, since this
 is the defined semantics for Amoeba.)
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{std_info}{}
+\begin{methoddesc}[capability]{std_info}{}
 Returns the standard info string of the object.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{tod_gettime}{}
+\begin{methoddesc}[capability]{tod_gettime}{}
 Returns the time (in seconds since the Epoch, in UCT, as for \POSIX) from
 a time server.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{tod_settime}{t}
+\begin{methoddesc}[capability]{tod_settime}{t}
 Sets the time kept by a time server.
-\end{funcdesc}
+\end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libasyncore.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libasyncore.tex	(original)
+++ python/branches/p3yk/Doc/lib/libasyncore.tex	Fri Apr 27 21:54:29 2007
@@ -46,7 +46,7 @@
 \begin{funcdesc}{loop}{\optional{timeout\optional{, use_poll\optional{,
                        map\optional{,count}}}}}
   Enter a polling loop that terminates after count passes or all open
-  channels have been closed.  All arguments are optional.  The \var(count)
+  channels have been closed.  All arguments are optional.  The \var{count}
   parameter defaults to None, resulting in the loop terminating only
   when all channels have been closed.  The \var{timeout} argument sets the
   timeout parameter for the appropriate \function{select()} or

Modified: python/branches/p3yk/Doc/lib/libbsddb.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libbsddb.tex	(original)
+++ python/branches/p3yk/Doc/lib/libbsddb.tex	Fri Apr 27 21:54:29 2007
@@ -2,7 +2,6 @@
          Interface to Berkeley DB library}
 
 \declaremodule{extension}{bsddb}
-  \platform{Unix, Windows}
 \modulesynopsis{Interface to Berkeley DB database library}
 \sectionauthor{Skip Montanaro}{skip at mojam.com}
 
@@ -46,10 +45,10 @@
 instances.
 
 \begin{funcdesc}{hashopen}{filename\optional{, flag\optional{,
-                           mode\optional{, bsize\optional{,
+                           mode\optional{, pgsize\optional{,
                            ffactor\optional{, nelem\optional{,
-                           cachesize\optional{, hash\optional{,
-                           lorder}}}}}}}}}
+                           cachesize\optional{, lorder\optional{,
+                           hflags}}}}}}}}}
 Open the hash format file named \var{filename}.  Files never intended
 to be preserved on disk may be created by passing \code{None} as the 
 \var{filename}.  The optional
@@ -80,7 +79,7 @@
 
 \begin{funcdesc}{rnopen}{filename\optional{, flag\optional{, mode\optional{,
 rnflags\optional{, cachesize\optional{, pgsize\optional{, lorder\optional{,
-reclen\optional{, bval\optional{, bfname}}}}}}}}}}
+rlen\optional{, delim\optional{, source\optional{, pad}}}}}}}}}}}
 
 Open a DB record format file named \var{filename}.  Files never intended 
 to be preserved on disk may be created by passing \code{None} as the 
@@ -114,23 +113,23 @@
 the methods listed below.
 \versionchanged[Added dictionary methods]{2.3.1}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[bsddbobject]{close}{}
 Close the underlying file.  The object can no longer be accessed.  Since
 there is no open \method{open} method for these objects, to open the file
 again a new \module{bsddb} module open function must be called.
 \end{methoddesc}
 
-\begin{methoddesc}{keys}{}
+\begin{methoddesc}[bsddbobject]{keys}{}
 Return the list of keys contained in the DB file.  The order of the list is
 unspecified and should not be relied on.  In particular, the order of the
 list returned is different for different file formats.
 \end{methoddesc}
 
-\begin{methoddesc}{has_key}{key}
+\begin{methoddesc}[bsddbobject]{has_key}{key}
 Return \code{1} if the DB file contains the argument as a key.
 \end{methoddesc}
 
-\begin{methoddesc}{set_location}{key}
+\begin{methoddesc}[bsddbobject]{set_location}{key}
 Set the cursor to the item indicated by \var{key} and return a tuple
 containing the key and its value.  For binary tree databases (opened
 using \function{btopen()}), if \var{key} does not actually exist in
@@ -140,32 +139,32 @@
 database.
 \end{methoddesc}
 
-\begin{methoddesc}{first}{}
+\begin{methoddesc}[bsddbobject]{first}{}
 Set the cursor to the first item in the DB file and return it.  The order of 
 keys in the file is unspecified, except in the case of B-Tree databases.
 This method raises \exception{bsddb.error} if the database is empty.
 \end{methoddesc}
 
-\begin{methoddesc}{next}{}
+\begin{methoddesc}[bsddbobject]{next}{}
 Set the cursor to the next item in the DB file and return it.  The order of 
 keys in the file is unspecified, except in the case of B-Tree databases.
 \end{methoddesc}
 
-\begin{methoddesc}{previous}{}
+\begin{methoddesc}[bsddbobject]{previous}{}
 Set the cursor to the previous item in the DB file and return it.  The
 order of keys in the file is unspecified, except in the case of B-Tree
 databases.  This is not supported on hashtable databases (those opened
 with \function{hashopen()}).
 \end{methoddesc}
 
-\begin{methoddesc}{last}{}
+\begin{methoddesc}[bsddbobject]{last}{}
 Set the cursor to the last item in the DB file and return it.  The
 order of keys in the file is unspecified.  This is not supported on
 hashtable databases (those opened with \function{hashopen()}).
 This method raises \exception{bsddb.error} if the database is empty.
 \end{methoddesc}
 
-\begin{methoddesc}{sync}{}
+\begin{methoddesc}[bsddbobject]{sync}{}
 Synchronize the database on disk.
 \end{methoddesc}
 

Modified: python/branches/p3yk/Doc/lib/libcfgparser.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcfgparser.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcfgparser.tex	Fri Apr 27 21:54:29 2007
@@ -155,37 +155,37 @@
 
 \class{RawConfigParser} instances have the following methods:
 
-\begin{methoddesc}{defaults}{}
+\begin{methoddesc}[RawConfigParser]{defaults}{}
 Return a dictionary containing the instance-wide defaults.
 \end{methoddesc}
 
-\begin{methoddesc}{sections}{}
+\begin{methoddesc}[RawConfigParser]{sections}{}
 Return a list of the sections available; \code{DEFAULT} is not
 included in the list.
 \end{methoddesc}
 
-\begin{methoddesc}{add_section}{section}
+\begin{methoddesc}[RawConfigParser]{add_section}{section}
 Add a section named \var{section} to the instance.  If a section by
 the given name already exists, \exception{DuplicateSectionError} is
 raised.
 \end{methoddesc}
 
-\begin{methoddesc}{has_section}{section}
+\begin{methoddesc}[RawConfigParser]{has_section}{section}
 Indicates whether the named section is present in the
 configuration. The \code{DEFAULT} section is not acknowledged.
 \end{methoddesc}
 
-\begin{methoddesc}{options}{section}
+\begin{methoddesc}[RawConfigParser]{options}{section}
 Returns a list of options available in the specified \var{section}.
 \end{methoddesc}
 
-\begin{methoddesc}{has_option}{section, option}
+\begin{methoddesc}[RawConfigParser]{has_option}{section, option}
 If the given section exists, and contains the given option,
 return \constant{True}; otherwise return \constant{False}.
 \versionadded{1.6}
 \end{methoddesc}
 
-\begin{methoddesc}{read}{filenames}
+\begin{methoddesc}[RawConfigParser]{read}{filenames}
 Attempt to read and parse a list of filenames, returning a list of filenames
 which were successfully parsed.  If \var{filenames} is a string or
 Unicode string, it is treated as a single filename.
@@ -210,28 +210,28 @@
 \versionchanged[Returns list of successfully parsed filenames]{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{readfp}{fp\optional{, filename}}
+\begin{methoddesc}[RawConfigParser]{readfp}{fp\optional{, filename}}
 Read and parse configuration data from the file or file-like object in
 \var{fp} (only the \method{readline()} method is used).  If
 \var{filename} is omitted and \var{fp} has a \member{name} attribute,
 that is used for \var{filename}; the default is \samp{<???>}.
 \end{methoddesc}
 
-\begin{methoddesc}{get}{section, option}
+\begin{methoddesc}[RawConfigParser]{get}{section, option}
 Get an \var{option} value for the named \var{section}.
 \end{methoddesc}
 
-\begin{methoddesc}{getint}{section, option}
+\begin{methoddesc}[RawConfigParser]{getint}{section, option}
 A convenience method which coerces the \var{option} in the specified
 \var{section} to an integer.
 \end{methoddesc}
 
-\begin{methoddesc}{getfloat}{section, option}
+\begin{methoddesc}[RawConfigParser]{getfloat}{section, option}
 A convenience method which coerces the \var{option} in the specified
 \var{section} to a floating point number.
 \end{methoddesc}
 
-\begin{methoddesc}{getboolean}{section, option}
+\begin{methoddesc}[RawConfigParser]{getboolean}{section, option}
 A convenience method which coerces the \var{option} in the specified
 \var{section} to a Boolean value.  Note that the accepted values
 for the option are \code{"1"}, \code{"yes"}, \code{"true"}, and \code{"on"},
@@ -241,12 +241,12 @@
 cause it to raise \exception{ValueError}.
 \end{methoddesc}
 
-\begin{methoddesc}{items}{section}
+\begin{methoddesc}[RawConfigParser]{items}{section}
 Return a list of \code{(\var{name}, \var{value})} pairs for each
 option in the given \var{section}.
 \end{methoddesc}
 
-\begin{methoddesc}{set}{section, option, value}
+\begin{methoddesc}[RawConfigParser]{set}{section, option, value}
 If the given section exists, set the given option to the specified
 value; otherwise raise \exception{NoSectionError}.  While it is
 possible to use \class{RawConfigParser} (or \class{ConfigParser} with
@@ -256,14 +256,14 @@
 \versionadded{1.6}
 \end{methoddesc}
 
-\begin{methoddesc}{write}{fileobject}
+\begin{methoddesc}[RawConfigParser]{write}{fileobject}
 Write a representation of the configuration to the specified file
 object.  This representation can be parsed by a future \method{read()}
 call.
 \versionadded{1.6}
 \end{methoddesc}
 
-\begin{methoddesc}{remove_option}{section, option}
+\begin{methoddesc}[RawConfigParser]{remove_option}{section, option}
 Remove the specified \var{option} from the specified \var{section}.
 If the section does not exist, raise \exception{NoSectionError}. 
 If the option existed to be removed, return \constant{True};
@@ -271,13 +271,13 @@
 \versionadded{1.6}
 \end{methoddesc}
 
-\begin{methoddesc}{remove_section}{section}
+\begin{methoddesc}[RawConfigParser]{remove_section}{section}
 Remove the specified \var{section} from the configuration.
 If the section in fact existed, return \code{True}.
 Otherwise return \code{False}.
 \end{methoddesc}
 
-\begin{methoddesc}{optionxform}{option}
+\begin{methoddesc}[RawConfigParser]{optionxform}{option}
 Transforms the option name \var{option} as found in an input file or
 as passed in by  client code to the form that should be used in the
 internal structures.  The default implementation returns a lower-case
@@ -293,14 +293,14 @@
 The \class{ConfigParser} class extends some methods of the
 \class{RawConfigParser} interface, adding some optional arguments.
 
-\begin{methoddesc}{get}{section, option\optional{, raw\optional{, vars}}}
+\begin{methoddesc}[ConfigParser]{get}{section, option\optional{, raw\optional{, vars}}}
 Get an \var{option} value for the named \var{section}.  All the
 \character{\%} interpolations are expanded in the return values, based
 on the defaults passed into the constructor, as well as the options
 \var{vars} provided, unless the \var{raw} argument is true.
 \end{methoddesc}
 
-\begin{methoddesc}{items}{section\optional{, raw\optional{, vars}}}
+\begin{methoddesc}[ConfigParser]{items}{section\optional{, raw\optional{, vars}}}
 Return a list of \code{(\var{name}, \var{value})} pairs for each
 option in the given \var{section}. Optional arguments have the
 same meaning as for the \method{get()} method.
@@ -313,7 +313,7 @@
 The \class{SafeConfigParser} class implements the same extended
 interface as \class{ConfigParser}, with the following addition:
 
-\begin{methoddesc}{set}{section, option, value}
+\begin{methoddesc}[SafeConfigParser]{set}{section, option, value}
 If the given section exists, set the given option to the specified
 value; otherwise raise \exception{NoSectionError}.  \var{value} must
 be a string (\class{str} or \class{unicode}); if not,

Modified: python/branches/p3yk/Doc/lib/libcgitb.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcgitb.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcgitb.tex	Fri Apr 27 21:54:29 2007
@@ -38,7 +38,7 @@
                          context\optional{, format}}}}}
   This function causes the \module{cgitb} module to take over the
   interpreter's default handling for exceptions by setting the
-  value of \code{\refmodule{sys}.excepthook}.
+  value of \member{\refmodule{sys}.excepthook}.
   \withsubitem{(in module sys)}{\ttindex{excepthook()}}
 
   The optional argument \var{display} defaults to \code{1} and can be set
@@ -61,7 +61,7 @@
   report it using \module{cgitb}.  The optional \var{info} argument
   should be a 3-tuple containing an exception type, exception
   value, and traceback object, exactly like the tuple returned by
-  \code{\refmodule{sys}.exc_info()}.  If the \var{info} argument
+  \function{\refmodule{sys}.exc_info()}.  If the \var{info} argument
   is not supplied, the current exception is obtained from
-  \code{\refmodule{sys}.exc_info()}.
+  \function{\refmodule{sys}.exc_info()}.
 \end{funcdesc}

Modified: python/branches/p3yk/Doc/lib/libcmath.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcmath.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcmath.tex	Fri Apr 27 21:54:29 2007
@@ -5,7 +5,14 @@
 \modulesynopsis{Mathematical functions for complex numbers.}
 
 This module is always available.  It provides access to mathematical
-functions for complex numbers.  The functions are:
+functions for complex numbers.  The functions in this module accept
+integers, floating-point numbers or complex numbers as arguments.
+They will also accept any Python object that has either a
+\method{__complex__} or a \method{__float__} method: these methods are
+used to convert the object to a complex or floating-point number, respectively, and
+the function is then applied to the result of the conversion.
+
+The functions are:
 
 \begin{funcdesc}{acos}{x}
 Return the arc cosine of \var{x}.

Modified: python/branches/p3yk/Doc/lib/libcmd.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcmd.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcmd.tex	Fri Apr 27 21:54:29 2007
@@ -37,7 +37,7 @@
 
 A \class{Cmd} instance has the following methods:
 
-\begin{methoddesc}{cmdloop}{\optional{intro}}
+\begin{methoddesc}[Cmd]{cmdloop}{\optional{intro}}
 Repeatedly issue a prompt, accept input, parse an initial prefix off
 the received input, and dispatch to action methods, passing them the
 remainder of the line as argument.
@@ -82,7 +82,7 @@
 any undocumented commands.
 \end{methoddesc}
 
-\begin{methoddesc}{onecmd}{str}
+\begin{methoddesc}[Cmd]{onecmd}{str}
 Interpret the argument as though it had been typed in response to the
 prompt.  This may be overridden, but should not normally need to be;
 see the \method{precmd()} and \method{postcmd()} methods for useful
@@ -93,25 +93,25 @@
 \method{default()} method is returned.
 \end{methoddesc}
 
-\begin{methoddesc}{emptyline}{}
+\begin{methoddesc}[Cmd]{emptyline}{}
 Method called when an empty line is entered in response to the prompt.
 If this method is not overridden, it repeats the last nonempty command
 entered.  
 \end{methoddesc}
 
-\begin{methoddesc}{default}{line}
+\begin{methoddesc}[Cmd]{default}{line}
 Method called on an input line when the command prefix is not
 recognized. If this method is not overridden, it prints an
 error message and returns.
 \end{methoddesc}
 
-\begin{methoddesc}{completedefault}{text, line, begidx, endidx}
+\begin{methoddesc}[Cmd]{completedefault}{text, line, begidx, endidx}
 Method called to complete an input line when no command-specific
 \method{complete_*()} method is available.  By default, it returns an
 empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{precmd}{line}
+\begin{methoddesc}[Cmd]{precmd}{line}
 Hook method executed just before the command line \var{line} is
 interpreted, but after the input prompt is generated and issued.  This
 method is a stub in \class{Cmd}; it exists to be overridden by
@@ -121,7 +121,7 @@
 unchanged.
 \end{methoddesc}
 
-\begin{methoddesc}{postcmd}{stop, line}
+\begin{methoddesc}[Cmd]{postcmd}{stop, line}
 Hook method executed just after a command dispatch is finished.  This
 method is a stub in \class{Cmd}; it exists to be overridden by
 subclasses.  \var{line} is the command line which was executed, and
@@ -133,13 +133,13 @@
 to continue.
 \end{methoddesc}
 
-\begin{methoddesc}{preloop}{}
+\begin{methoddesc}[Cmd]{preloop}{}
 Hook method executed once when \method{cmdloop()} is called.  This
 method is a stub in \class{Cmd}; it exists to be overridden by
 subclasses.
 \end{methoddesc}
 
-\begin{methoddesc}{postloop}{}
+\begin{methoddesc}[Cmd]{postloop}{}
 Hook method executed once when \method{cmdloop()} is about to return.
 This method is a stub in \class{Cmd}; it exists to be overridden by
 subclasses.
@@ -147,42 +147,52 @@
 
 Instances of \class{Cmd} subclasses have some public instance variables:
 
-\begin{memberdesc}{prompt}
+\begin{memberdesc}[Cmd]{prompt}
 The prompt issued to solicit input.
 \end{memberdesc}
 
-\begin{memberdesc}{identchars}
+\begin{memberdesc}[Cmd]{identchars}
 The string of characters accepted for the command prefix.
 \end{memberdesc}
 
-\begin{memberdesc}{lastcmd}
+\begin{memberdesc}[Cmd]{lastcmd}
 The last nonempty command prefix seen. 
 \end{memberdesc}
 
-\begin{memberdesc}{intro}
+\begin{memberdesc}[Cmd]{intro}
 A string to issue as an intro or banner.  May be overridden by giving
 the \method{cmdloop()} method an argument.
 \end{memberdesc}
 
-\begin{memberdesc}{doc_header}
+\begin{memberdesc}[Cmd]{doc_header}
 The header to issue if the help output has a section for documented
 commands.
 \end{memberdesc}
 
-\begin{memberdesc}{misc_header}
+\begin{memberdesc}[Cmd]{misc_header}
 The header to issue if the help output has a section for miscellaneous 
 help topics (that is, there are \method{help_*()} methods without
 corresponding \method{do_*()} methods).
 \end{memberdesc}
 
-\begin{memberdesc}{undoc_header}
+\begin{memberdesc}[Cmd]{undoc_header}
 The header to issue if the help output has a section for undocumented 
 commands (that is, there are \method{do_*()} methods without
 corresponding \method{help_*()} methods).
 \end{memberdesc}
 
-\begin{memberdesc}{ruler}
+\begin{memberdesc}[Cmd]{ruler}
 The character used to draw separator lines under the help-message
 headers.  If empty, no ruler line is drawn.  It defaults to
 \character{=}.
 \end{memberdesc}
+
+\begin{memberdesc}[Cmd]{use_rawinput}
+A flag, defaulting to true.  If true, \method{cmdloop()} uses
+\function{input()} to display a prompt and read the next command;
+if false, \method{sys.stdout.write()} and
+\method{sys.stdin.readline()} are used. (This means that by
+importing \refmodule{readline}, on systems that support it, the
+interpreter will automatically support \program{Emacs}-like line editing 
+and command-history keystrokes.)
+\end{memberdesc}

Modified: python/branches/p3yk/Doc/lib/libcode.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcode.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcode.tex	Fri Apr 27 21:54:29 2007
@@ -68,7 +68,7 @@
 \subsection{Interactive Interpreter Objects
             \label{interpreter-objects}}
 
-\begin{methoddesc}{runsource}{source\optional{, filename\optional{, symbol}}}
+\begin{methoddesc}[InteractiveInterpreter]{runsource}{source\optional{, filename\optional{, symbol}}}
 Compile and run some source in the interpreter.
 Arguments are the same as for \function{compile_command()}; the
 default for \var{filename} is \code{'<input>'}, and for
@@ -98,7 +98,7 @@
 \code{sys.ps1} or \code{sys.ps2} to prompt the next line.
 \end{methoddesc}
 
-\begin{methoddesc}{runcode}{code}
+\begin{methoddesc}[InteractiveInterpreter]{runcode}{code}
 Execute a code object.
 When an exception occurs, \method{showtraceback()} is called to
 display a traceback.  All exceptions are caught except
@@ -109,7 +109,7 @@
 should be prepared to deal with it.
 \end{methoddesc}
 
-\begin{methoddesc}{showsyntaxerror}{\optional{filename}}
+\begin{methoddesc}[InteractiveInterpreter]{showsyntaxerror}{\optional{filename}}
 Display the syntax error that just occurred.  This does not display
 a stack trace because there isn't one for syntax errors.
 If \var{filename} is given, it is stuffed into the exception instead
@@ -118,13 +118,13 @@
 The output is written by the \method{write()} method.
 \end{methoddesc}
 
-\begin{methoddesc}{showtraceback}{}
+\begin{methoddesc}[InteractiveInterpreter]{showtraceback}{}
 Display the exception that just occurred.  We remove the first stack
 item because it is within the interpreter object implementation.
 The output is written by the \method{write()} method.
 \end{methoddesc}
 
-\begin{methoddesc}{write}{data}
+\begin{methoddesc}[InteractiveInterpreter]{write}{data}
 Write a string to the standard error stream (\code{sys.stderr}).
 Derived classes should override this to provide the appropriate output
 handling as needed.
@@ -138,7 +138,7 @@
 \class{InteractiveInterpreter}, and so offers all the methods of the
 interpreter objects as well as the following additions.
 
-\begin{methoddesc}{interact}{\optional{banner}}
+\begin{methoddesc}[InteractiveConsole]{interact}{\optional{banner}}
 Closely emulate the interactive Python console.
 The optional banner argument specify the banner to print before the
 first interaction; by default it prints a banner similar to the one
@@ -147,7 +147,7 @@
 with the real interpreter -- since it's so close!).
 \end{methoddesc}
 
-\begin{methoddesc}{push}{line}
+\begin{methoddesc}[InteractiveConsole]{push}{line}
 Push a line of source text to the interpreter.
 The line should not have a trailing newline; it may have internal
 newlines.  The line is appended to a buffer and the interpreter's
@@ -160,11 +160,11 @@
 \method{runsource()}).
 \end{methoddesc}
 
-\begin{methoddesc}{resetbuffer}{}
+\begin{methoddesc}[InteractiveConsole]{resetbuffer}{}
 Remove any unhandled source text from the input buffer.
 \end{methoddesc}
 
-\begin{methoddesc}{raw_input}{\optional{prompt}}
+\begin{methoddesc}[InteractiveConsole]{raw_input}{\optional{prompt}}
 Write a prompt and read a line.  The returned line does not include
 the trailing newline.  When the user enters the \EOF{} key sequence,
 \exception{EOFError} is raised.  The base implementation reads from

Modified: python/branches/p3yk/Doc/lib/libcodecs.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcodecs.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcodecs.tex	Fri Apr 27 21:54:29 2007
@@ -307,7 +307,7 @@
 The \class{Codec} class defines these methods which also define the
 function interfaces of the stateless encoder and decoder:
 
-\begin{methoddesc}{encode}{input\optional{, errors}}
+\begin{methoddesc}[Codec]{encode}{input\optional{, errors}}
   Encodes the object \var{input} and returns a tuple (output object,
   length consumed).  While codecs are not restricted to use with Unicode, in
   a Unicode context, encoding converts a Unicode object to a plain string
@@ -325,7 +325,7 @@
   empty object of the output object type in this situation.
 \end{methoddesc}
 
-\begin{methoddesc}{decode}{input\optional{, errors}}
+\begin{methoddesc}[Codec]{decode}{input\optional{, errors}}
   Decodes the object \var{input} and returns a tuple (output object,
   length consumed).  In a Unicode context, decoding converts a plain string
   encoded using a particular character set encoding to a Unicode object.
@@ -1233,9 +1233,8 @@
 \lineiv{idna}
          {}
          {Unicode string}
-         {Implements \rfc{3490}.
-          \versionadded{2.3}
-          See also \refmodule{encodings.idna}}
+         {Implements \rfc{3490},
+          see also \refmodule{encodings.idna}}
 
 \lineiv{mbcs}
          {dbcs}
@@ -1250,8 +1249,7 @@
 \lineiv{punycode}
          {}
          {Unicode string}
-         {Implements \rfc{3492}.
-          \versionadded{2.3}}
+         {Implements \rfc{3492}}
 
 \lineiv{quopri_codec}
          {quopri, quoted-printable, quotedprintable}
@@ -1305,6 +1303,8 @@
 
 \end{tableiv}
 
+\versionadded[The \code{idna} and \code{punycode} encodings]{2.3}
+
 \subsection{\module{encodings.idna} ---
             Internationalized Domain Names in Applications}
 

Modified: python/branches/p3yk/Doc/lib/libcollections.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcollections.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcollections.tex	Fri Apr 27 21:54:29 2007
@@ -9,14 +9,16 @@
 
 
 This module implements high-performance container datatypes.  Currently,
-there are two datatypes, deque and defaultdict.
+there are two datatypes, deque and defaultdict, and one datatype factory
+function, \function{NamedTuple}.
 Future additions may include balanced trees and ordered dictionaries.
 \versionchanged[Added defaultdict]{2.5}
+\versionchanged[Added NamedTuple]{2.6}
 
 \subsection{\class{deque} objects \label{deque-objects}}
 
-\begin{funcdesc}{deque}{\optional{iterable}}
-  Returns a new deque objected initialized left-to-right (using
+\begin{classdesc}{deque}{\optional{iterable}}
+  Returns a new deque object initialized left-to-right (using
   \method{append()}) with data from \var{iterable}.  If \var{iterable}
   is not specified, the new deque is empty.
 
@@ -30,7 +32,7 @@
   for \samp{pop(0)} and \samp{insert(0, v)} operations which change both the
   size and position of the underlying data representation.
   \versionadded{2.4}
-\end{funcdesc}
+\end{classdesc}
 
 Deque objects support the following methods:
 
@@ -219,7 +221,7 @@
 
 \subsection{\class{defaultdict} objects \label{defaultdict-objects}}
 
-\begin{funcdesc}{defaultdict}{\optional{default_factory\optional{, ...}}}
+\begin{classdesc}{defaultdict}{\optional{default_factory\optional{, ...}}}
   Returns a new dictionary-like object.  \class{defaultdict} is a subclass
   of the builtin \class{dict} class.  It overrides one method and adds one
   writable instance variable.  The remaining functionality is the same as
@@ -231,7 +233,7 @@
   passed to the \class{dict} constructor, including keyword arguments.
 
  \versionadded{2.5}
-\end{funcdesc}
+\end{classdesc}
 
 \class{defaultdict} objects support the following method in addition to
 the standard \class{dict} operations:
@@ -254,11 +256,11 @@
 
 \class{defaultdict} objects support the following instance variable:
 
-\begin{datadesc}{default_factory}
+\begin{memberdesc}{default_factory}
   This attribute is used by the \method{__missing__} method; it is initialized
   from the first argument to the constructor, if present, or to \code{None}, 
   if absent.
-\end{datadesc}
+\end{memberdesc}
 
 
 \subsubsection{\class{defaultdict} Examples \label{defaultdict-examples}}
@@ -339,3 +341,51 @@
 >>> d.items()
 [('blue', set([2, 4])), ('red', set([1, 3]))]
 \end{verbatim}
+
+
+
+\subsection{\function{NamedTuple} datatype factory function \label{named-tuple-factory}}
+
+\begin{funcdesc}{NamedTuple}{typename, fieldnames}
+  Returns a new tuple subclass named \var{typename}.  The new subclass is used
+  to create tuple-like objects that have fields accessable by attribute
+  lookup as well as being indexable and iterable.  Instances of the subclass
+  also have a helpful docstring (with typename and fieldnames) and a helpful
+  \method{__repr__()} method which lists the tuple contents in a \code{name=value}
+  format.
+  \versionadded{2.6}
+
+  The \var{fieldnames} are specified in a single string and are separated by spaces.
+  Any valid Python identifier may be used for a field name.
+
+  Example:
+  \begin{verbatim}
+>>> Point = NamedTuple('Point', 'x y')
+>>> Point.__doc__           # docstring for the new datatype
+'Point(x, y)'
+>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
+>>> p[0] + p[1]             # works just like the tuple (11, 22)
+33
+>>> x, y = p                # unpacks just like a tuple
+>>> x, y
+(11, 22)
+>>> p.x + p.y               # fields also accessable by name
+33
+>>> p                       # readable __repr__ with name=value style
+Point(x=11, y=22)  
+\end{verbatim}
+
+  The use cases are the same as those for tuples.  The named factories
+  assign meaning to each tuple position and allow for more readable,
+  self-documenting code.  Named tuples can also be used to assign field names 
+  to tuples
+  returned by the \module{csv} or \module{sqlite3} modules.  For example:
+
+  \begin{verbatim}
+import csv
+EmployeeRecord = NamedTuple('EmployeeRecord', 'name age title department paygrade')
+for tup in csv.reader(open("employees.csv", "rb")):
+    print EmployeeRecord(*tup)
+\end{verbatim}
+
+\end{funcdesc}

Modified: python/branches/p3yk/Doc/lib/libcommands.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcommands.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcommands.tex	Fri Apr 27 21:54:29 2007
@@ -39,6 +39,10 @@
 Return the output of \samp{ls -ld \var{file}} as a string.  This
 function uses the \function{getoutput()} function, and properly
 escapes backslashes and dollar signs in the argument.
+
+\deprecated{2.6}{This function is nonobvious and useless,
+                 also the name is misleading in the presence of
+		 \function{getstatusoutput()}.}
 \end{funcdesc}
 
 Example:

Modified: python/branches/p3yk/Doc/lib/libconsts.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libconsts.tex	(original)
+++ python/branches/p3yk/Doc/lib/libconsts.tex	Fri Apr 27 21:54:29 2007
@@ -13,7 +13,7 @@
 \end{datadesc}
 
 \begin{datadesc}{None}
-  The sole value of \code{\refmodule{types}.NoneType}.  \code{None} is
+  The sole value of \member{\refmodule{types}.NoneType}.  \code{None} is
   frequently used to represent the absence of a value, as when default
   arguments are not passed to a function.
 \end{datadesc}

Modified: python/branches/p3yk/Doc/lib/libcookielib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcookielib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcookielib.tex	Fri Apr 27 21:54:29 2007
@@ -292,12 +292,12 @@
 
 \class{FileCookieJar} instances have the following public attributes:
 
-\begin{memberdesc}{filename}
+\begin{memberdesc}[FileCookieJar]{filename}
 Filename of default file in which to keep cookies.  This attribute may
 be assigned to.
 \end{memberdesc}
 
-\begin{memberdesc}{delayload}
+\begin{memberdesc}[FileCookieJar]{delayload}
 If true, load cookies lazily from disk.  This attribute should not be
 assigned to.  This is only a hint, since this only affects
 performance, not behaviour (unless the cookies on disk are changing).
@@ -400,13 +400,13 @@
 attributes, indicating which protocols should be used, and how.  All
 of these attributes may be assigned to.
 
-\begin{memberdesc}{netscape}
+\begin{memberdesc}[CookiePolicy]{netscape}
 Implement Netscape protocol.
 \end{memberdesc}
-\begin{memberdesc}{rfc2965}
+\begin{memberdesc}[CookiePolicy]{rfc2965}
 Implement RFC 2965 protocol.
 \end{memberdesc}
-\begin{memberdesc}{hide_cookie2}
+\begin{memberdesc}[CookiePolicy]{hide_cookie2}
 Don't add \mailheader{Cookie2} header to requests (the presence of
 this header indicates to the server that we understand RFC 2965
 cookies).
@@ -504,7 +504,7 @@
 which are all initialised from the constructor arguments of the same
 name, and which may all be assigned to.
 
-\begin{memberdesc}{rfc2109_as_netscape}
+\begin{memberdesc}[DefaultCookiePolicy]{rfc2109_as_netscape}
 If true, request that the \class{CookieJar} instance downgrade RFC
 2109 cookies (ie. cookies received in a \mailheader{Set-Cookie} header
 with a version cookie-attribute of 1) to Netscape cookies by setting
@@ -517,7 +517,7 @@
 
 General strictness switches:
 
-\begin{memberdesc}{strict_domain}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_domain}
 Don't allow sites to set two-component domains with country-code
 top-level domains like \code{.co.uk}, \code{.gov.uk},
 \code{.co.nz}.etc.  This is far from perfect and isn't guaranteed to
@@ -526,7 +526,7 @@
 
 RFC 2965 protocol strictness switches:
 
-\begin{memberdesc}{strict_rfc2965_unverifiable}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_rfc2965_unverifiable}
 Follow RFC 2965 rules on unverifiable transactions (usually, an
 unverifiable transaction is one resulting from a redirect or a request
 for an image hosted on another site).  If this is false, cookies are
@@ -535,19 +535,19 @@
 
 Netscape protocol strictness switches:
 
-\begin{memberdesc}{strict_ns_unverifiable}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_ns_unverifiable}
 apply RFC 2965 rules on unverifiable transactions even to Netscape
 cookies
 \end{memberdesc}
-\begin{memberdesc}{strict_ns_domain}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_ns_domain}
 Flags indicating how strict to be with domain-matching rules for
 Netscape cookies.  See below for acceptable values.
 \end{memberdesc}
-\begin{memberdesc}{strict_ns_set_initial_dollar}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_ns_set_initial_dollar}
 Ignore cookies in Set-Cookie: headers that have names starting with
 \code{'\$'}.
 \end{memberdesc}
-\begin{memberdesc}{strict_ns_set_path}
+\begin{memberdesc}[DefaultCookiePolicy]{strict_ns_set_path}
 Don't allow setting cookies whose path doesn't path-match request URI.
 \end{memberdesc}
 
@@ -556,30 +556,30 @@
 \code{DomainStrictNoDots|DomainStrictNonDomain} means both flags are
 set).
 
-\begin{memberdesc}{DomainStrictNoDots}
+\begin{memberdesc}[DefaultCookiePolicy]{DomainStrictNoDots}
 When setting cookies, the 'host prefix' must not contain a dot
 (eg. \code{www.foo.bar.com} can't set a cookie for \code{.bar.com},
 because \code{www.foo} contains a dot).
 \end{memberdesc}
-\begin{memberdesc}{DomainStrictNonDomain}
+\begin{memberdesc}[DefaultCookiePolicy]{DomainStrictNonDomain}
 Cookies that did not explicitly specify a \code{domain}
 cookie-attribute can only be returned to a domain equal to the domain
 that set the cookie (eg. \code{spam.example.com} won't be returned
 cookies from \code{example.com} that had no \code{domain}
 cookie-attribute).
 \end{memberdesc}
-\begin{memberdesc}{DomainRFC2965Match}
+\begin{memberdesc}[DefaultCookiePolicy]{DomainRFC2965Match}
 When setting cookies, require a full RFC 2965 domain-match.
 \end{memberdesc}
 
 The following attributes are provided for convenience, and are the
 most useful combinations of the above flags:
 
-\begin{memberdesc}{DomainLiberal}
+\begin{memberdesc}[DefaultCookiePolicy]{DomainLiberal}
 Equivalent to 0 (ie. all of the above Netscape domain strictness flags
 switched off).
 \end{memberdesc}
-\begin{memberdesc}{DomainStrict}
+\begin{memberdesc}[DefaultCookiePolicy]{DomainStrict}
 Equivalent to \code{DomainStrictNoDots|DomainStrictNonDomain}.
 \end{memberdesc}
 

Modified: python/branches/p3yk/Doc/lib/libctypes.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libctypes.tex	(original)
+++ python/branches/p3yk/Doc/lib/libctypes.tex	Fri Apr 27 21:54:29 2007
@@ -7,21 +7,21 @@
 \versionadded{2.5}
 
 \code{ctypes} is a foreign function library for Python.  It provides C
-compatible data types, and allows to call functions in dlls/shared
+compatible data types, and allows calling functions in dlls/shared
 libraries.  It can be used to wrap these libraries in pure Python.
 
 
 \subsection{ctypes tutorial\label{ctypes-ctypes-tutorial}}
 
-Note: The code samples in this tutorial uses \code{doctest} to make sure
+Note: The code samples in this tutorial use \code{doctest} to make sure
 that they actually work.  Since some code samples behave differently
 under Linux, Windows, or Mac OS X, they contain doctest directives in
 comments.
 
-Note: Quite some code samples references the ctypes \class{c{\_}int} type.
+Note: Some code sample references the ctypes \class{c{\_}int} type.
 This type is an alias to the \class{c{\_}long} type on 32-bit systems.  So,
 you should not be confused if \class{c{\_}long} is printed if you would
-expect \class{c{\_}int} - they are actually the same type.
+expect \class{c{\_}int} --- they are actually the same type.
 
 
 \subsubsection{Loading dynamic link libraries\label{ctypes-loading-dynamic-link-libraries}}
@@ -38,7 +38,7 @@
 automatically raise \class{WindowsError} Python exceptions when the
 function call fails.
 
-Here are some examples for Windows, note that \code{msvcrt} is the MS
+Here are some examples for Windows. Note that \code{msvcrt} is the MS
 standard C library containing most standard C functions, and uses the
 cdecl calling convention:
 \begin{verbatim}
@@ -1219,7 +1219,7 @@
 It is quite interesting to see that the Windows \function{qsort} function
 needs more comparisons than the linux version!
 
-As we can easily check, our array sorted now:
+As we can easily check, our array is sorted now:
 \begin{verbatim}
 >>> for i in ia: print i,
 ...
@@ -1242,7 +1242,7 @@
 \programopt{-O} or \programopt{-OO} flag given on startup.
 
 \code{ctypes} can access values like this with the \method{in{\_}dll} class
-methods of the type.  \var{pythonapi} ìs a predefined symbol giving
+methods of the type.  \var{pythonapi} is a predefined symbol giving
 access to the Python C api:
 \begin{verbatim}
 >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
@@ -2113,7 +2113,7 @@
 \end{memberdesc}
 
 
-\subsubsection{Fundamental data types\label{ctypes-fundamental-data-types}}
+\subsubsection{Fundamental data types\label{ctypes-fundamental-data-types-2}}
 
 \begin{classdesc*}{_SimpleCData}
 This non-public class is the base class of all fundamental ctypes
@@ -2294,6 +2294,13 @@
 an integer address, or a string.
 \end{classdesc*}
 
+\begin{classdesc*}{c_bool}
+Represent the C \code{bool} datatype (more accurately, _Bool from C99).
+Its value can be True or False, and the constructor accepts any object that
+has a truth value.
+\versionadded{2.6}
+\end{classdesc*}
+
 \begin{classdesc*}{HRESULT}
 Windows only: Represents a \class{HRESULT} value, which contains success
 or error information for a function or method call.

Modified: python/branches/p3yk/Doc/lib/libcurses.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcurses.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcurses.tex	Fri Apr 27 21:54:29 2007
@@ -646,6 +646,16 @@
 corner characters are always used by this function.
 \end{methoddesc}
 
+\begin{methoddesc}[window]{chgat}{\optional{y, x, } \optional{num,} attr}
+Sets the attributes of \var{num} characters at the current cursor
+position, or at position \code{(\var{y}, \var{x})} if supplied. If no
+value of \var{num} is given or \var{num} = -1, the attribute will 
+be set on all the characters to the end of the line. 
+This function does not move the cursor. The changed line
+will be touched using the \method{touchline} method so that the
+contents will be redisplayed by the next window refresh.
+\end{methoddesc}
+
 \begin{methoddesc}[window]{clear}{}
 Like \method{erase()}, but also causes the whole window to be repainted
 upon next call to \method{refresh()}.
@@ -1014,9 +1024,11 @@
 input at the end of that time.
 \end{methoddesc}
 
-\begin{methoddesc}[window]{touchline}{start, count}
+\begin{methoddesc}[window]{touchline}{start, count\optional{, changed}}
 Pretend \var{count} lines have been changed, starting with line
-\var{start}.
+\var{start}.  If \var{changed} is supplied, it specifies
+whether the affected lines are marked as 
+having been changed (\var{changed}=1) or unchanged (\var{changed}=0).
 \end{methoddesc}
 
 \begin{methoddesc}[window]{touchwin}{}

Modified: python/branches/p3yk/Doc/lib/libcursespanel.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libcursespanel.tex	(original)
+++ python/branches/p3yk/Doc/lib/libcursespanel.tex	Fri Apr 27 21:54:29 2007
@@ -45,52 +45,52 @@
 
 Panel objects have the following methods:
 
-\begin{methoddesc}{above}{}
+\begin{methoddesc}[Panel]{above}{}
 Returns the panel above the current panel.
 \end{methoddesc}
 
-\begin{methoddesc}{below}{}
+\begin{methoddesc}[Panel]{below}{}
 Returns the panel below the current panel.
 \end{methoddesc}
 
-\begin{methoddesc}{bottom}{}
+\begin{methoddesc}[Panel]{bottom}{}
 Push the panel to the bottom of the stack.
 \end{methoddesc}
 
-\begin{methoddesc}{hidden}{}
+\begin{methoddesc}[Panel]{hidden}{}
 Returns true if the panel is hidden (not visible), false otherwise.
 \end{methoddesc}
 
-\begin{methoddesc}{hide}{}
+\begin{methoddesc}[Panel]{hide}{}
 Hide the panel. This does not delete the object, it just makes the
 window on screen invisible.
 \end{methoddesc}
 
-\begin{methoddesc}{move}{y, x}
+\begin{methoddesc}[Panel]{move}{y, x}
 Move the panel to the screen coordinates \code{(\var{y}, \var{x})}.
 \end{methoddesc}
 
-\begin{methoddesc}{replace}{win}
+\begin{methoddesc}[Panel]{replace}{win}
 Change the window associated with the panel to the window \var{win}.
 \end{methoddesc}
 
-\begin{methoddesc}{set_userptr}{obj}
+\begin{methoddesc}[Panel]{set_userptr}{obj}
 Set the panel's user pointer to \var{obj}. This is used to associate an
 arbitrary piece of data with the panel, and can be any Python object.
 \end{methoddesc}
 
-\begin{methoddesc}{show}{}
+\begin{methoddesc}[Panel]{show}{}
 Display the panel (which might have been hidden).
 \end{methoddesc}
 
-\begin{methoddesc}{top}{}
+\begin{methoddesc}[Panel]{top}{}
 Push panel to the top of the stack.
 \end{methoddesc}
 
-\begin{methoddesc}{userptr}{}
+\begin{methoddesc}[Panel]{userptr}{}
 Returns the user pointer for the panel.  This might be any Python object.
 \end{methoddesc}
 
-\begin{methoddesc}{window}{}
+\begin{methoddesc}[Panel]{window}{}
 Returns the window object associated with the panel.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libdatetime.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdatetime.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdatetime.tex	Fri Apr 27 21:54:29 2007
@@ -1154,7 +1154,7 @@
 uses made of aware \module{datetime} objects.  If in doubt, simply
 implement all of them.
 
-\begin{methoddesc}{utcoffset}{self, dt}
+\begin{methoddesc}[tzinfo]{utcoffset}{self, dt}
   Return offset of local time from UTC, in minutes east of UTC.  If
   local time is west of UTC, this should be negative.  Note that this
   is intended to be the total offset from UTC; for example, if a
@@ -1178,7 +1178,7 @@
     \exception{NotImplementedError}.
 \end{methoddesc}
 
-\begin{methoddesc}{dst}{self, dt}
+\begin{methoddesc}[tzinfo]{dst}{self, dt}
   Return the daylight saving time (DST) adjustment, in minutes east of
   UTC, or \code{None} if DST information isn't known.  Return
   \code{timedelta(0)} if DST is not in effect.
@@ -1237,7 +1237,7 @@
   \exception{NotImplementedError}.
 \end{methoddesc}
 
-\begin{methoddesc}{tzname}{self, dt}
+\begin{methoddesc}[tzinfo]{tzname}{self, dt}
   Return the time zone name corresponding to the \class{datetime}
   object \var{dt}, as a string.
   Nothing about string names is defined by the
@@ -1278,7 +1278,7 @@
 There is one more \class{tzinfo} method that a subclass may wish to
 override:
 
-\begin{methoddesc}{fromutc}{self, dt}
+\begin{methoddesc}[tzinfo]{fromutc}{self, dt}
   This is called from the default \class{datetime.astimezone()}
   implementation.  When called from that, \code{\var{dt}.tzinfo} is
   \var{self}, and \var{dt}'s date and time members are to be viewed as

Modified: python/branches/p3yk/Doc/lib/libdbhash.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdbhash.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdbhash.tex	Fri Apr 27 21:54:29 2007
@@ -2,7 +2,6 @@
          DBM-style interface to the BSD database library}
 
 \declaremodule{standard}{dbhash}
-  \platform{Unix, Windows}
 \modulesynopsis{DBM-style interface to the BSD database library.}
 \sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org}
 

Modified: python/branches/p3yk/Doc/lib/libdecimal.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdecimal.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdecimal.tex	Fri Apr 27 21:54:29 2007
@@ -425,7 +425,7 @@
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%            
-\subsection{Context objects \label{decimal-decimal}}
+\subsection{Context objects \label{decimal-context}}
 
 Contexts are environments for arithmetic operations.  They govern precision,
 set rules for rounding, determine which signals are treated as exceptions, and

Modified: python/branches/p3yk/Doc/lib/libdl.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdl.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdl.tex	Fri Apr 27 21:54:29 2007
@@ -67,11 +67,11 @@
 Dl objects, as returned by \function{open()} above, have the
 following methods:
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[dl]{close}{}
 Free all resources, except the memory.
 \end{methoddesc}
 
-\begin{methoddesc}{sym}{name}
+\begin{methoddesc}[dl]{sym}{name}
 Return the pointer for the function named \var{name}, as a number, if
 it exists in the referenced shared object, otherwise \code{None}. This
 is useful in code like:
@@ -87,7 +87,7 @@
 \NULL{} pointer)
 \end{methoddesc}
 
-\begin{methoddesc}{call}{name\optional{, arg1\optional{, arg2\ldots}}}
+\begin{methoddesc}[dl]{call}{name\optional{, arg1\optional{, arg2\ldots}}}
 Call the function named \var{name} in the referenced shared object.
 The arguments must be either Python integers, which will be 
 passed as is, Python strings, to which a pointer will be passed, 

Modified: python/branches/p3yk/Doc/lib/libdoctest.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdoctest.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdoctest.tex	Fri Apr 27 21:54:29 2007
@@ -201,6 +201,19 @@
 \code{sys.argv} is not examined by \function{testmod()} (so passing
 \programopt{-v} or not has no effect).
 
+Since Python 2.6, there is also a command line shortcut for running
+\function{testmod()}.  You can instruct the Python interpreter to run
+the doctest module directly from the standard library and pass the module
+name(s) on the command line:
+
+\begin{verbatim}
+python -m doctest -v example.py
+\end{verbatim}
+
+This will import \file{example.py} as a standalone module and run
+\function{testmod()} on it.  Note that this may not work correctly if the
+file is part of a package and imports other submodules from that package.
+
 For more information on \function{testmod()}, see
 section~\ref{doctest-basic-api}.
 
@@ -267,6 +280,18 @@
 set with the \programopt{-v} command-line switch or with the optional
 keyword argument \var{verbose}.
 
+Since Python 2.6, there is also a command line shortcut for running
+\function{testfile()}.  You can instruct the Python interpreter to run
+the doctest module directly from the standard library and pass the file
+name(s) on the command line:
+
+\begin{verbatim}
+python -m doctest -v example.txt
+\end{verbatim}
+
+Because the file name does not end with \file{.py}, \module{doctest} infers
+that it must be run with \function{testfile()}, not \function{testmod()}.
+
 For more information on \function{testfile()}, see
 section~\ref{doctest-basic-api}.
 
@@ -1716,7 +1741,7 @@
 >>>
 \end{verbatim}
 
-    \versionchanged[The ability to use \code{\refmodule{pdb}.set_trace()}
+    \versionchanged[The ability to use \function{\refmodule{pdb}.set_trace()}
                     usefully inside doctests was added]{2.4}
 \end{itemize}
 
@@ -1800,10 +1825,10 @@
   used.  If \var{pm} has a true value, the script file is run directly, and
   the debugger gets involved only if the script terminates via raising an
   unhandled exception.  If it does, then post-mortem debugging is invoked,
-  via \code{\refmodule{pdb}.post_mortem()}, passing the traceback object
+  via \function{\refmodule{pdb}.post_mortem()}, passing the traceback object
   from the unhandled exception.  If \var{pm} is not specified, or is false,
   the script is run under the debugger from the start, via passing an
-  appropriate \function{execfile()} call to \code{\refmodule{pdb}.run()}.
+  appropriate \function{execfile()} call to \function{\refmodule{pdb}.run()}.
 
   \versionadded{2.3}
 

Modified: python/branches/p3yk/Doc/lib/libdocxmlrpc.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdocxmlrpc.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdocxmlrpc.tex	Fri Apr 27 21:54:29 2007
@@ -14,8 +14,12 @@
 \class{DocXMLRPCServer}, or embedded in a CGI environment, using
 \class{DocCGIXMLRPCRequestHandler}.
 
-\begin{classdesc}{DocXMLRPCServer}{addr\optional{, 
-                                   requestHandler\optional{, logRequests}}}
+\begin{classdesc}{DocXMLRPCServer}{addr\optional{,
+                                   requestHandler\optional{,
+			                       logRequests\optional{,
+                                   allow_none\optional{, 
+                                   encoding\optional{,
+                                   bind_and_activate}}}}}}
 
 Create a new server instance. All parameters have the same meaning as
 for \class{SimpleXMLRPCServer.SimpleXMLRPCServer};
@@ -47,14 +51,14 @@
 handled by generating pydoc-style HTML documentation. This allows a
 server to provide its own web-based documentation.
 
-\begin{methoddesc}{set_server_title}{server_title}
+\begin{methoddesc}[DocXMLRPCServer]{set_server_title}{server_title}
 
 Set the title used in the generated HTML documentation. This title
 will be used inside the HTML "title" element.
 
 \end{methoddesc}
 
-\begin{methoddesc}{set_server_name}{server_name}
+\begin{methoddesc}[DocXMLRPCServer]{set_server_name}{server_name}
 
 Set the name used in the generated HTML documentation. This name will
 appear at the top of the generated documentation inside a "h1"
@@ -63,7 +67,7 @@
 \end{methoddesc}
 
 
-\begin{methoddesc}{set_server_documentation}{server_documentation}
+\begin{methoddesc}[DocXMLRPCServer]{set_server_documentation}{server_documentation}
 
 Set the description used in the generated HTML documentation. This
 description will appear as a paragraph, below the server name, in the
@@ -80,14 +84,14 @@
 generating pydoc-style HTML documentation. This allows a server to
 provide its own web-based documentation.
 
-\begin{methoddesc}{set_server_title}{server_title}
+\begin{methoddesc}[DocCGIXMLRPCRequestHandler]{set_server_title}{server_title}
 
 Set the title used in the generated HTML documentation. This title
 will be used inside the HTML "title" element.
 
 \end{methoddesc}
 
-\begin{methoddesc}{set_server_name}{server_name}
+\begin{methoddesc}[DocCGIXMLRPCRequestHandler]{set_server_name}{server_name}
 
 Set the name used in the generated HTML documentation. This name will
 appear at the top of the generated documentation inside a "h1"
@@ -96,7 +100,7 @@
 \end{methoddesc}
 
 
-\begin{methoddesc}{set_server_documentation}{server_documentation}
+\begin{methoddesc}[DocCGIXMLRPCRequestHandler]{set_server_documentation}{server_documentation}
 
 Set the description used in the generated HTML documentation. This
 description will appear as a paragraph, below the server name, in the

Modified: python/branches/p3yk/Doc/lib/libdumbdbm.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libdumbdbm.tex	(original)
+++ python/branches/p3yk/Doc/lib/libdumbdbm.tex	Fri Apr 27 21:54:29 2007
@@ -57,7 +57,7 @@
 In addition to the methods provided by the \class{UserDict.DictMixin} class,
 \class{dumbdbm} objects provide the following methods.
 
-\begin{methoddesc}{sync}{}
+\begin{methoddesc}[dumbdbm]{sync}{}
 Synchronize the on-disk directory and data files.  This method is called by
 the \method{sync} method of \class{Shelve} objects.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libetree.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libetree.tex	(original)
+++ python/branches/p3yk/Doc/lib/libetree.tex	Fri Apr 27 21:54:29 2007
@@ -144,12 +144,12 @@
 Element objects returned by Element or SubElement have the 
 following methods and attributes.
 
-\begin{memberdesc}{tag}
+\begin{memberdesc}[Element]{tag}
 A string identifying what kind of data this element represents
 (the element type, in other words).
 \end{memberdesc}
 
-\begin{memberdesc}{text}
+\begin{memberdesc}[Element]{text}
 The \var{text} attribute can be used to hold additional data
 associated with the element.
 As the name implies this attribute is usually a string but may be any
@@ -158,7 +158,7 @@
 any text found between the element tags.
 \end{memberdesc}
 
-\begin{memberdesc}{tail}
+\begin{memberdesc}[Element]{tail}
 The \var{tail} attribute can be used to hold additional data
 associated with the element.
 This attribute is usually a string but may be any application-specific object.
@@ -166,7 +166,7 @@
 any text found after the element's end tag and before the next tag.
 \end{memberdesc}
 
-\begin{memberdesc}{attrib}
+\begin{memberdesc}[Element]{attrib}
 A dictionary containing the element's attributes.
 Note that while the \var{attrib} value is always a real mutable Python
 dictionary, an ElementTree implementation may choose to use another
@@ -177,52 +177,52 @@
 
 The following dictionary-like methods work on the element attributes.
 
-\begin{methoddesc}{clear}{}
+\begin{methoddesc}[Element]{clear}{}
 Resets an element.  This function removes all subelements, clears
 all attributes, and sets the text and tail attributes to None.
 \end{methoddesc}
 
-\begin{methoddesc}{get}{key\optional{, default=None}}
+\begin{methoddesc}[Element]{get}{key\optional{, default=None}}
 Gets the element attribute named \var{key}.
 
 Returns the attribute value, or \var{default} if the
 attribute was not found.
 \end{methoddesc}
 
-\begin{methoddesc}{items}{}
+\begin{methoddesc}[Element]{items}{}
 Returns the element attributes as a sequence of (name, value) pairs.
 The attributes are returned in an arbitrary order.
 \end{methoddesc}
 
-\begin{methoddesc}{keys}{}
+\begin{methoddesc}[Element]{keys}{}
 Returns the elements attribute names as a list.
 The names are returned in an arbitrary order.
 \end{methoddesc}
 
-\begin{methoddesc}{set}{key, value}
+\begin{methoddesc}[Element]{set}{key, value}
 Set the attribute \var{key} on the element to \var{value}.  
 \end{methoddesc}
 
 The following methods work on the element's children (subelements).
 
-\begin{methoddesc}{append}{subelement}
+\begin{methoddesc}[Element]{append}{subelement}
 Adds the element \var{subelement} to the end of this elements internal list
 of subelements.
 \end{methoddesc}
 
-\begin{methoddesc}{find}{match}
+\begin{methoddesc}[Element]{find}{match}
 Finds the first subelement matching \var{match}. 
 \var{match} may be a tag name or path.
 Returns an element instance or \code{None}.
 \end{methoddesc}
 
-\begin{methoddesc}{findall}{match}
+\begin{methoddesc}[Element]{findall}{match}
 Finds all subelements matching \var{match}. 
 \var{match} may be a tag name or path.
 Returns an iterable yielding all matching elements in document order.
 \end{methoddesc}
 
-\begin{methoddesc}{findtext}{condition\optional{, default=None}}
+\begin{methoddesc}[Element]{findtext}{condition\optional{, default=None}}
 Finds text for the first subelement matching \var{condition}. 
 \var{condition} may be a tag name or path.
 Returns the text content of the first matching element, or
@@ -230,11 +230,11 @@
 matching element has no text content an empty string is returned.
 \end{methoddesc}
 
-\begin{methoddesc}{getchildren}{}
+\begin{methoddesc}[Element]{getchildren}{}
 Returns all subelements.  The elements are returned in document order.
 \end{methoddesc}
 
-\begin{methoddesc}{getiterator}{\optional{tag=None}}
+\begin{methoddesc}[Element]{getiterator}{\optional{tag=None}}
 Creates a tree iterator with the current element as the root.  
 The iterator iterates over this element and all elements below it 
 that match the given tag. If tag
@@ -243,16 +243,16 @@
 order.
 \end{methoddesc}
 
-\begin{methoddesc}{insert}{index, element}
+\begin{methoddesc}[Element]{insert}{index, element}
 Inserts a subelement at the given position in this element.
 \end{methoddesc}
 
-\begin{methoddesc}{makeelement}{tag, attrib}
+\begin{methoddesc}[Element]{makeelement}{tag, attrib}
 Creates a new element object of the same type as this element.
 Do not call this method, use the SubElement factory function instead.
 \end{methoddesc}
 
-\begin{methoddesc}{remove}{subelement}
+\begin{methoddesc}[Element]{remove}{subelement}
 Removes \var{subelement} from the element.  
 Unlike the findXXX methods this method compares elements based on 
 the instance identity, not on tag value or contents.

Modified: python/branches/p3yk/Doc/lib/libfm.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libfm.tex	(original)
+++ python/branches/p3yk/Doc/lib/libfm.tex	Fri Apr 27 21:54:29 2007
@@ -55,40 +55,39 @@
 
 Font handle objects support the following operations:
 
-\setindexsubitem{(font handle method)}
-\begin{funcdesc}{scalefont}{factor}
+\begin{methoddesc}[font handle]{scalefont}{factor}
 Returns a handle for a scaled version of this font.
 Calls \code{fmscalefont(\var{fh}, \var{factor})}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{setfont}{}
+\begin{methoddesc}[font handle]{setfont}{}
 Makes this font the current font.
 Note: the effect is undone silently when the font handle object is
 deleted.
 Calls \code{fmsetfont(\var{fh})}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{getfontname}{}
+\begin{methoddesc}[font handle]{getfontname}{}
 Returns this font's name.
 Calls \code{fmgetfontname(\var{fh})}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{getcomment}{}
+\begin{methoddesc}[font handle]{getcomment}{}
 Returns the comment string associated with this font.
 Raises an exception if there is none.
 Calls \code{fmgetcomment(\var{fh})}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{getfontinfo}{}
+\begin{methoddesc}[font handle]{getfontinfo}{}
 Returns a tuple giving some pertinent data about this font.
 This is an interface to \code{fmgetfontinfo()}.
 The returned tuple contains the following numbers:
 \code{(}\var{printermatched}, \var{fixed_width}, \var{xorig},
 \var{yorig}, \var{xsize}, \var{ysize}, \var{height},
 \var{nglyphs}\code{)}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{getstrwidth}{string}
+\begin{methoddesc}[font handle]{getstrwidth}{string}
 Returns the width, in pixels, of \var{string} when drawn in this font.
 Calls \code{fmgetstrwidth(\var{fh}, \var{string})}.
-\end{funcdesc}
+\end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libfnmatch.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libfnmatch.tex	(original)
+++ python/branches/p3yk/Doc/lib/libfnmatch.tex	Fri Apr 27 21:54:29 2007
@@ -36,6 +36,19 @@
 require a case-sensitive comparison regardless of whether that's
 standard for your operating system, use \function{fnmatchcase()}
 instead.
+
+This example will print all file names in the current directory with the
+extension \code{.txt}:
+
+\begin{verbatim}
+import fnmatch
+import os
+
+for file in os.listdir('.'):
+    if fnmatch.fnmatch(file, '*.txt'):
+        print file
+\end{verbatim}
+
 \end{funcdesc}
 
 \begin{funcdesc}{fnmatchcase}{filename, pattern}
@@ -50,6 +63,24 @@
 \versionadded{2.2}
 \end{funcdesc}
 
+\begin{funcdesc}{translate}{pattern}
+Return the shell-style \var{pattern} converted to a regular
+expression.
+
+Example:
+
+\begin{verbatim}
+>>> import fnmatch, re
+>>>
+>>> regex = fnmatch.translate('*.txt')
+>>> regex
+'.*\\.txt$'
+>>> reobj = re.compile(regex)
+>>> print reobj.match('foobar.txt')
+<_sre.SRE_Match object at 0x...>
+\end{verbatim}
+\end{funcdesc}
+
 \begin{seealso}
   \seemodule{glob}{\UNIX{} shell-style path expansion.}
 \end{seealso}

Modified: python/branches/p3yk/Doc/lib/libftplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libftplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libftplib.tex	Fri Apr 27 21:54:29 2007
@@ -37,12 +37,15 @@
 The module defines the following items:
 
 \begin{classdesc}{FTP}{\optional{host\optional{, user\optional{,
-                       passwd\optional{, acct}}}}}
+                       passwd\optional{, acct\optional{, timeout}}}}}}
 Return a new instance of the \class{FTP} class.  When
 \var{host} is given, the method call \code{connect(\var{host})} is
 made.  When \var{user} is given, additionally the method call
 \code{login(\var{user}, \var{passwd}, \var{acct})} is made (where
 \var{passwd} and \var{acct} default to the empty string when not given).
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if is not specified, or passed as None, the global
+default timeout setting will be used).
 \end{classdesc}
 
 \begin{datadesc}{all_errors}
@@ -92,7 +95,7 @@
 
 \class{FTP} instances have the following methods:
 
-\begin{methoddesc}{set_debuglevel}{level}
+\begin{methoddesc}[FTP]{set_debuglevel}{level}
 Set the instance's debugging level.  This controls the amount of
 debugging output printed.  The default, \code{0}, produces no
 debugging output.  A value of \code{1} produces a moderate amount of
@@ -101,22 +104,28 @@
 logging each line sent and received on the control connection.
 \end{methoddesc}
 
-\begin{methoddesc}{connect}{host\optional{, port}}
+\begin{methoddesc}[FTP]{connect}{host\optional{, port\optional{, timeout}}}
 Connect to the given host and port.  The default port number is \code{21}, as
 specified by the FTP protocol specification.  It is rarely needed to
 specify a different port number.  This function should be called only
 once for each instance; it should not be called at all if a host was
 given when the instance was created.  All other methods can only be
 used after a connection has been made.
+
+The optional \var{timeout} parameter specifies a timeout in seconds for
+the connection attempt. If is not specified, or passed as None, the 
+object timeout is used (the timeout that you passed when instantiating the
+class); if the object timeout is also None, the global default timeout 
+setting will be used.
 \end{methoddesc}
 
-\begin{methoddesc}{getwelcome}{}
+\begin{methoddesc}[FTP]{getwelcome}{}
 Return the welcome message sent by the server in reply to the initial
 connection.  (This message sometimes contains disclaimers or help
 information that may be relevant to the user.)
 \end{methoddesc}
 
-\begin{methoddesc}{login}{\optional{user\optional{, passwd\optional{, acct}}}}
+\begin{methoddesc}[FTP]{login}{\optional{user\optional{, passwd\optional{, acct}}}}
 Log in as the given \var{user}.  The \var{passwd} and \var{acct}
 parameters are optional and default to the empty string.  If no
 \var{user} is specified, it defaults to \code{'anonymous'}.  If
@@ -128,23 +137,23 @@
 client has logged in.
 \end{methoddesc}
 
-\begin{methoddesc}{abort}{}
+\begin{methoddesc}[FTP]{abort}{}
 Abort a file transfer that is in progress.  Using this does not always
 work, but it's worth a try.
 \end{methoddesc}
 
-\begin{methoddesc}{sendcmd}{command}
+\begin{methoddesc}[FTP]{sendcmd}{command}
 Send a simple command string to the server and return the response
 string.
 \end{methoddesc}
 
-\begin{methoddesc}{voidcmd}{command}
+\begin{methoddesc}[FTP]{voidcmd}{command}
 Send a simple command string to the server and handle the response.
 Return nothing if a response code in the range 200--299 is received.
 Raise an exception otherwise.
 \end{methoddesc}
 
-\begin{methoddesc}{retrbinary}{command,
+\begin{methoddesc}[FTP]{retrbinary}{command,
     callback\optional{, maxblocksize\optional{, rest}}}
 Retrieve a file in binary transfer mode.  \var{command} should be an
 appropriate \samp{RETR} command: \code{'RETR \var{filename}'}.
@@ -157,7 +166,7 @@
 same thing as in the \method{transfercmd()} method.
 \end{methoddesc}
 
-\begin{methoddesc}{retrlines}{command\optional{, callback}}
+\begin{methoddesc}[FTP]{retrlines}{command\optional{, callback}}
 Retrieve a file or directory listing in \ASCII{} transfer mode.
 \var{command} should be an appropriate \samp{RETR} command (see
 \method{retrbinary()}) or a \samp{LIST} command (usually just the string
@@ -166,13 +175,13 @@
 the line to \code{sys.stdout}.
 \end{methoddesc}
 
-\begin{methoddesc}{set_pasv}{boolean}
+\begin{methoddesc}[FTP]{set_pasv}{boolean}
 Enable ``passive'' mode if \var{boolean} is true, other disable
 passive mode.  (In Python 2.0 and before, passive mode was off by
 default; in Python 2.1 and later, it is on by default.)
 \end{methoddesc}
 
-\begin{methoddesc}{storbinary}{command, file\optional{, blocksize}}
+\begin{methoddesc}[FTP]{storbinary}{command, file\optional{, blocksize}}
 Store a file in binary transfer mode.  \var{command} should be an
 appropriate \samp{STOR} command: \code{"STOR \var{filename}"}.
 \var{file} is an open file object which is read until \EOF{} using its
@@ -181,14 +190,14 @@
 \versionchanged[default for \var{blocksize} added]{2.1}
 \end{methoddesc}
 
-\begin{methoddesc}{storlines}{command, file}
+\begin{methoddesc}[FTP]{storlines}{command, file}
 Store a file in \ASCII{} transfer mode.  \var{command} should be an
 appropriate \samp{STOR} command (see \method{storbinary()}).  Lines are
 read until \EOF{} from the open file object \var{file} using its
 \method{readline()} method to provide the data to be stored.
 \end{methoddesc}
 
-\begin{methoddesc}{transfercmd}{cmd\optional{, rest}}
+\begin{methoddesc}[FTP]{transfercmd}{cmd\optional{, rest}}
 Initiate a transfer over the data connection.  If the transfer is
 active, send a \samp{EPRT} or  \samp{PORT} command and the transfer command specified
 by \var{cmd}, and accept the connection.  If the server is passive,
@@ -210,7 +219,7 @@
 simply call \method{transfercmd()} without a \var{rest} argument.
 \end{methoddesc}
 
-\begin{methoddesc}{ntransfercmd}{cmd\optional{, rest}}
+\begin{methoddesc}[FTP]{ntransfercmd}{cmd\optional{, rest}}
 Like \method{transfercmd()}, but returns a tuple of the data
 connection and the expected size of the data.  If the expected size
 could not be computed, \code{None} will be returned as the expected
@@ -218,14 +227,14 @@
 \method{transfercmd()}.
 \end{methoddesc}
 
-\begin{methoddesc}{nlst}{argument\optional{, \ldots}}
+\begin{methoddesc}[FTP]{nlst}{argument\optional{, \ldots}}
 Return a list of files as returned by the \samp{NLST} command.  The
 optional \var{argument} is a directory to list (default is the current
 server directory).  Multiple arguments can be used to pass
 non-standard options to the \samp{NLST} command.
 \end{methoddesc}
 
-\begin{methoddesc}{dir}{argument\optional{, \ldots}}
+\begin{methoddesc}[FTP]{dir}{argument\optional{, \ldots}}
 Produce a directory listing as returned by the \samp{LIST} command,
 printing it to standard output.  The optional \var{argument} is a
 directory to list (default is the current server directory).  Multiple
@@ -235,41 +244,41 @@
 prints to \code{sys.stdout}.  This method returns \code{None}.
 \end{methoddesc}
 
-\begin{methoddesc}{rename}{fromname, toname}
+\begin{methoddesc}[FTP]{rename}{fromname, toname}
 Rename file \var{fromname} on the server to \var{toname}.
 \end{methoddesc}
 
-\begin{methoddesc}{delete}{filename}
+\begin{methoddesc}[FTP]{delete}{filename}
 Remove the file named \var{filename} from the server.  If successful,
 returns the text of the response, otherwise raises
 \exception{error_perm} on permission errors or
 \exception{error_reply} on other errors.
 \end{methoddesc}
 
-\begin{methoddesc}{cwd}{pathname}
+\begin{methoddesc}[FTP]{cwd}{pathname}
 Set the current directory on the server.
 \end{methoddesc}
 
-\begin{methoddesc}{mkd}{pathname}
+\begin{methoddesc}[FTP]{mkd}{pathname}
 Create a new directory on the server.
 \end{methoddesc}
 
-\begin{methoddesc}{pwd}{}
+\begin{methoddesc}[FTP]{pwd}{}
 Return the pathname of the current directory on the server.
 \end{methoddesc}
 
-\begin{methoddesc}{rmd}{dirname}
+\begin{methoddesc}[FTP]{rmd}{dirname}
 Remove the directory named \var{dirname} on the server.
 \end{methoddesc}
 
-\begin{methoddesc}{size}{filename}
+\begin{methoddesc}[FTP]{size}{filename}
 Request the size of the file named \var{filename} on the server.  On
 success, the size of the file is returned as an integer, otherwise
 \code{None} is returned.  Note that the \samp{SIZE} command is not 
 standardized, but is supported by many common server implementations.
 \end{methoddesc}
 
-\begin{methoddesc}{quit}{}
+\begin{methoddesc}[FTP]{quit}{}
 Send a \samp{QUIT} command to the server and close the connection.
 This is the ``polite'' way to close a connection, but it may raise an
 exception of the server reponds with an error to the
@@ -278,7 +287,7 @@
 calls (see below).
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[FTP]{close}{}
 Close the connection unilaterally.  This should not be applied to an
 already closed connection such as after a successful call to
 \method{quit()}.  After this call the \class{FTP} instance should not

Modified: python/branches/p3yk/Doc/lib/libfuncs.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libfuncs.tex	(original)
+++ python/branches/p3yk/Doc/lib/libfuncs.tex	Fri Apr 27 21:54:29 2007
@@ -175,15 +175,15 @@
   \code{\var{x} > \var{y}}.
 \end{funcdesc}
 
-\begin{funcdesc}{compile}{string, filename, kind\optional{,
+\begin{funcdesc}{compile}{source, filename, mode\optional{,
                           flags\optional{, dont_inherit}}}
-  Compile the \var{string} into a code object.  Code objects can be
+  Compile the \var{source} into a code object.  Code objects can be
   executed by a call to \function{exec()} or evaluated by a call to
   \function{eval()}.  The \var{filename} argument should
   give the file from which the code was read; pass some recognizable value
   if it wasn't read from a file (\code{'<string>'} is commonly used).
-  The \var{kind} argument specifies what kind of code must be
-  compiled; it can be \code{'exec'} if \var{string} consists of a
+  The \var{mode} argument specifies what kind of code must be
+  compiled; it can be \code{'exec'} if \var{source} consists of a
   sequence of statements, \code{'eval'} if it consists of a single
   expression, or \code{'single'} if it consists of a single
   interactive statement (in the latter case, expression statements
@@ -198,7 +198,7 @@
 
   The optional arguments \var{flags} and \var{dont_inherit}
   (which are new in Python 2.2) control which future statements (see
-  \pep{236}) affect the compilation of \var{string}.  If neither is
+  \pep{236}) affect the compilation of \var{source}.  If neither is
   present (or both are zero) the code is compiled with those future
   statements that are in effect in the code that is calling compile.
   If the \var{flags} argument is given and \var{dont_inherit} is not
@@ -582,8 +582,9 @@
 \begin{funcdesc}{isinstance}{object, classinfo}
   Return true if the \var{object} argument is an instance of the
   \var{classinfo} argument, or of a (direct or indirect) subclass
-  thereof.  Also return true if \var{classinfo} is a type object and
-  \var{object} is an object of that type.  If \var{object} is not a
+  thereof.  Also return true if \var{classinfo} is a type object
+  (new-style class) and \var{object} is an object of that type or of a
+  (direct or indirect) subclass thereof.  If \var{object} is not a
   class instance or an object of the given type, the function always
   returns false.  If \var{classinfo} is neither a class object nor a
   type object, it may be a tuple of class or type objects, or may
@@ -641,6 +642,11 @@
   \warning{The contents of this dictionary should not be modified;
   changes may not affect the values of local variables used by the
   interpreter.}
+
+  Free variables are returned by \var{locals} when it is called in
+  a function block.  Modifications of free variables may not affect
+  the values used by the interpreter.  Free variables are not
+  returned in class blocks.
 \end{funcdesc}
 
 \begin{funcdesc}{long}{\optional{x\optional{, radix}}}
@@ -980,7 +986,7 @@
 
 \begin{funcdesc}{reversed}{seq}
   Return a reverse iterator.  \var{seq} must be an object which
-  supports the sequence protocol (the __len__() method and the
+  supports the sequence protocol (the \method{__len__()} method and the
   \method{__getitem__()} method with integer arguments starting at
   \code{0}).
   \versionadded{2.4}
@@ -1148,7 +1154,7 @@
   as detailed below.
 \end{funcdesc}
 
-\begin{funcdesc}{type}{name, bases, dict}
+\begin{funcdescni}{type}{name, bases, dict}
   Return a new type object.  This is essentially a dynamic form of the
   \keyword{class} statement. The \var{name} string is the class name
   and becomes the \member{__name__} attribute; the \var{bases} tuple
@@ -1165,7 +1171,7 @@
   >>> X = type('X', (object,), dict(a=1))
 \end{verbatim}
 \versionadded{2.2}          
-\end{funcdesc}
+\end{funcdescni}
 
 \begin{funcdesc}{unichr}{i}
   Return the Unicode string of one character whose Unicode code is the

Modified: python/branches/p3yk/Doc/lib/libgettext.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libgettext.tex	(original)
+++ python/branches/p3yk/Doc/lib/libgettext.tex	Fri Apr 27 21:54:29 2007
@@ -102,9 +102,9 @@
 return \var{plural} otherwise.
 
 The Plural formula is taken from the catalog header. It is a C or
-Python expression that has a free variable n; the expression evaluates
+Python expression that has a free variable \var{n}; the expression evaluates
 to the index of the plural in the catalog. See the GNU gettext
-documentation for the precise syntax to be used in .po files, and the
+documentation for the precise syntax to be used in \file{.po} files and the
 formulas for a variety of languages.
 
 \versionadded{2.3}

Modified: python/branches/p3yk/Doc/lib/libhmac.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libhmac.tex	(original)
+++ python/branches/p3yk/Doc/lib/libhmac.tex	Fri Apr 27 21:54:29 2007
@@ -15,7 +15,7 @@
   Return a new hmac object.  If \var{msg} is present, the method call
   \code{update(\var{msg})} is made. \var{digestmod} is the digest
   constructor or module for the HMAC object to use. It defaults to 
-  the \code{\refmodule{hashlib}.md5} constructor.  \note{The md5 hash
+  the \function{\refmodule{hashlib}.md5} constructor.  \note{The md5 hash
   has known weaknesses but remains the default for backwards compatibility.
   Choose a better one for your application.}
 \end{funcdesc}

Modified: python/branches/p3yk/Doc/lib/libhotshot.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libhotshot.tex	(original)
+++ python/branches/p3yk/Doc/lib/libhotshot.tex	Fri Apr 27 21:54:29 2007
@@ -48,25 +48,25 @@
 
 Profile objects have the following methods:
 
-\begin{methoddesc}{addinfo}{key, value}
+\begin{methoddesc}[Profile]{addinfo}{key, value}
 Add an arbitrary labelled value to the profile output.
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[Profile]{close}{}
 Close the logfile and terminate the profiler.
 \end{methoddesc}
 
-\begin{methoddesc}{fileno}{}
+\begin{methoddesc}[Profile]{fileno}{}
 Return the file descriptor of the profiler's log file.
 \end{methoddesc}
 
-\begin{methoddesc}{run}{cmd}
+\begin{methoddesc}[Profile]{run}{cmd}
 Profile an \function{exec()}-compatible string in the script environment.
 The globals from the \refmodule[main]{__main__} module are used as
 both the globals and locals for the script.
 \end{methoddesc}
 
-\begin{methoddesc}{runcall}{func, *args, **keywords}
+\begin{methoddesc}[Profile]{runcall}{func, *args, **keywords}
 Profile a single call of a callable.
 Additional positional and keyword arguments may be passed
 along; the result of the call is returned, and exceptions are
@@ -75,16 +75,16 @@
 \end{methoddesc}
 
 
-\begin{methoddesc}{runctx}{cmd, globals, locals}
+\begin{methoddesc}[Profile]{runctx}{cmd, globals, locals}
 Profile an \function{exec()}-compatible string in a specific environment.
 The string is compiled before profiling begins.
 \end{methoddesc}
 
-\begin{methoddesc}{start}{}
+\begin{methoddesc}[Profile]{start}{}
 Start the profiler.
 \end{methoddesc}
 
-\begin{methoddesc}{stop}{}
+\begin{methoddesc}[Profile]{stop}{}
 Stop the profiler.
 \end{methoddesc}
 

Modified: python/branches/p3yk/Doc/lib/libhtmllib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libhtmllib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libhtmllib.tex	Fri Apr 27 21:54:29 2007
@@ -96,11 +96,11 @@
 In addition to tag methods, the \class{HTMLParser} class provides some
 additional methods and instance variables for use within tag methods.
 
-\begin{memberdesc}{formatter}
+\begin{memberdesc}[HTMLParser]{formatter}
 This is the formatter instance associated with the parser.
 \end{memberdesc}
 
-\begin{memberdesc}{nofill}
+\begin{memberdesc}[HTMLParser]{nofill}
 Boolean flag which should be true when whitespace should not be
 collapsed, or false when it should be.  In general, this should only
 be true when character data is to be treated as ``preformatted'' text,
@@ -109,7 +109,7 @@
 \end{memberdesc}
 
 
-\begin{methoddesc}{anchor_bgn}{href, name, type}
+\begin{methoddesc}[HTMLParser]{anchor_bgn}{href, name, type}
 This method is called at the start of an anchor region.  The arguments
 correspond to the attributes of the \code{<A>} tag with the same
 names.  The default implementation maintains a list of hyperlinks
@@ -118,27 +118,27 @@
 \member{anchorlist}.
 \end{methoddesc}
 
-\begin{methoddesc}{anchor_end}{}
+\begin{methoddesc}[HTMLParser]{anchor_end}{}
 This method is called at the end of an anchor region.  The default
 implementation adds a textual footnote marker using an index into the
 list of hyperlinks created by \method{anchor_bgn()}.
 \end{methoddesc}
 
-\begin{methoddesc}{handle_image}{source, alt\optional{, ismap\optional{,
+\begin{methoddesc}[HTMLParser]{handle_image}{source, alt\optional{, ismap\optional{,
                                  align\optional{, width\optional{, height}}}}}
 This method is called to handle images.  The default implementation
 simply passes the \var{alt} value to the \method{handle_data()}
 method.
 \end{methoddesc}
 
-\begin{methoddesc}{save_bgn}{}
+\begin{methoddesc}[HTMLParser]{save_bgn}{}
 Begins saving character data in a buffer instead of sending it to the
 formatter object.  Retrieve the stored data via \method{save_end()}.
 Use of the \method{save_bgn()} / \method{save_end()} pair may not be
 nested.
 \end{methoddesc}
 
-\begin{methoddesc}{save_end}{}
+\begin{methoddesc}[HTMLParser]{save_end}{}
 Ends buffering character data and returns all data saved since the
 preceding call to \method{save_bgn()}.  If the \member{nofill} flag is
 false, whitespace is collapsed to single spaces.  A call to this

Modified: python/branches/p3yk/Doc/lib/libhtmlparser.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libhtmlparser.tex	(original)
+++ python/branches/p3yk/Doc/lib/libhtmlparser.tex	Fri Apr 27 21:54:29 2007
@@ -75,14 +75,18 @@
 be overridden by a derived class; the base class implementation does
 nothing.  
 
-The \var{tag} argument is the name of the tag converted to
-lower case.  The \var{attrs} argument is a list of \code{(\var{name},
-\var{value})} pairs containing the attributes found inside the tag's
-\code{<>} brackets.  The \var{name} will be translated to lower case
-and double quotes and backslashes in the \var{value} have been
-interpreted.  For instance, for the tag \code{<A
-HREF="http://www.cwi.nl/">}, this method would be called as
+The \var{tag} argument is the name of the tag converted to lower case.
+The \var{attrs} argument is a list of \code{(\var{name}, \var{value})}
+pairs containing the attributes found inside the tag's \code{<>}
+brackets.  The \var{name} will be translated to lower case, and quotes
+in the \var{value} have been removed, and character and entity
+references have been replaced.  For instance, for the tag \code{<A
+  HREF="http://www.cwi.nl/">}, this method would be called as
 \samp{handle_starttag('a', [('href', 'http://www.cwi.nl/')])}.
+
+\versionchanged[All entity references from htmlentitydefs are now
+replaced in the attribute values]{2.6}
+
 \end{methoddesc}
 
 \begin{methoddesc}{handle_startendtag}{tag, attrs}

Modified: python/branches/p3yk/Doc/lib/libhttplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libhttplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libhttplib.tex	Fri Apr 27 21:54:29 2007
@@ -26,18 +26,27 @@
 
 The module provides the following classes:
 
-\begin{classdesc}{HTTPConnection}{host\optional{, port}}
+\begin{classdesc}{HTTPConnection}{host\optional{, port\optional{,
+		  strict\optional{, timeout}}}}
 An \class{HTTPConnection} instance represents one transaction with an HTTP
 server.  It should be instantiated passing it a host and optional port number.
 If no port number is passed, the port is extracted from the host string if it
 has the form \code{\var{host}:\var{port}}, else the default HTTP port (80) is
-used.  For example, the following calls all create instances that connect to
+used.  When True, the optional parameter \var{strict}
+causes \code{BadStatusLine} to be raised if the status line can't be parsed
+as a valid HTTP/1.0 or 1.1 status line.  If the optional \var{timeout}
+parameter is given, connection attempts will timeout after that many
+seconds (if it is not given or \code{None}, the global default 
+timeout setting is used).
+
+For example, the following calls all create instances that connect to
 the server at the same host and port:
 
 \begin{verbatim}
 >>> h1 = httplib.HTTPConnection('www.cwi.nl')
 >>> h2 = httplib.HTTPConnection('www.cwi.nl:80')
 >>> h3 = httplib.HTTPConnection('www.cwi.nl', 80)
+>>> h3 = httplib.HTTPConnection('www.cwi.nl', 80, timeout=10)
 \end{verbatim}
 \versionadded{2.0}
 \end{classdesc}
@@ -300,7 +309,7 @@
 
 \class{HTTPConnection} instances have the following methods:
 
-\begin{methoddesc}{request}{method, url\optional{, body\optional{, headers}}}
+\begin{methoddesc}[HTTPConnection]{request}{method, url\optional{, body\optional{, headers}}}
 This will send a request to the server using the HTTP request method
 \var{method} and the selector \var{url}.  If the \var{body} argument is
 present, it should be a string of data to send after the headers are finished.
@@ -314,24 +323,24 @@
 \versionchanged[\var{body} can be a file object]{2.6}
 \end{methoddesc}
 
-\begin{methoddesc}{getresponse}{}
+\begin{methoddesc}[HTTPConnection]{getresponse}{}
 Should be called after a request is sent to get the response from the server.
 Returns an \class{HTTPResponse} instance.
 \note{Note that you must have read the whole response before you can send a new
 request to the server.}
 \end{methoddesc}
 
-\begin{methoddesc}{set_debuglevel}{level}
+\begin{methoddesc}[HTTPConnection]{set_debuglevel}{level}
 Set the debugging level (the amount of debugging output printed).
 The default debug level is \code{0}, meaning no debugging output is
 printed.
 \end{methoddesc}
 
-\begin{methoddesc}{connect}{}
+\begin{methoddesc}[HTTPConnection]{connect}{}
 Connect to the server specified when the object was created.
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[HTTPConnection]{close}{}
 Close the connection to the server.
 \end{methoddesc}
 
@@ -339,7 +348,7 @@
 you can also send your request step by step, by using the four functions
 below.
 
-\begin{methoddesc}{putrequest}{request, selector\optional{,
+\begin{methoddesc}[HTTPConnection]{putrequest}{request, selector\optional{,
 skip\_host\optional{, skip_accept_encoding}}}
 This should be the first call after the connection to the server has
 been made.  It sends a line to the server consisting of the
@@ -351,18 +360,18 @@
 \versionchanged[\var{skip_accept_encoding} argument added]{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{putheader}{header, argument\optional{, ...}}
+\begin{methoddesc}[HTTPConnection]{putheader}{header, argument\optional{, ...}}
 Send an \rfc{822}-style header to the server.  It sends a line to the
 server consisting of the header, a colon and a space, and the first
 argument.  If more arguments are given, continuation lines are sent,
 each consisting of a tab and an argument.
 \end{methoddesc}
 
-\begin{methoddesc}{endheaders}{}
+\begin{methoddesc}[HTTPConnection]{endheaders}{}
 Send a blank line to the server, signalling the end of the headers.
 \end{methoddesc}
 
-\begin{methoddesc}{send}{data}
+\begin{methoddesc}[HTTPConnection]{send}{data}
 Send data to the server.  This should be used directly only after the
 \method{endheaders()} method has been called and before
 \method{getresponse()} is called.
@@ -372,34 +381,34 @@
 
 \class{HTTPResponse} instances have the following methods and attributes:
 
-\begin{methoddesc}{read}{\optional{amt}}
+\begin{methoddesc}[HTTPResponse]{read}{\optional{amt}}
 Reads and returns the response body, or up to the next \var{amt} bytes.
 \end{methoddesc}
 
-\begin{methoddesc}{getheader}{name\optional{, default}}
+\begin{methoddesc}[HTTPResponse]{getheader}{name\optional{, default}}
 Get the contents of the header \var{name}, or \var{default} if there is no
 matching header.
 \end{methoddesc}
 
-\begin{methoddesc}{getheaders}{}
+\begin{methoddesc}[HTTPResponse]{getheaders}{}
 Return a list of (header, value) tuples. \versionadded{2.4}
 \end{methoddesc}
 
-\begin{datadesc}{msg}
+\begin{memberdesc}[HTTPResponse]{msg}
   A \class{mimetools.Message} instance containing the response headers.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{version}
+\begin{memberdesc}[HTTPResponse]{version}
   HTTP protocol version used by server.  10 for HTTP/1.0, 11 for HTTP/1.1.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{status}
+\begin{memberdesc}[HTTPResponse]{status}
   Status code returned by server.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{reason}
+\begin{memberdesc}[HTTPResponse]{reason}
   Reason phrase returned by server.
-\end{datadesc}
+\end{memberdesc}
 
 
 \subsection{Examples \label{httplib-examples}}

Modified: python/branches/p3yk/Doc/lib/libimaplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libimaplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libimaplib.tex	Fri Apr 27 21:54:29 2007
@@ -153,11 +153,11 @@
 An \class{IMAP4} instance has the following methods:
 
 
-\begin{methoddesc}{append}{mailbox, flags, date_time, message}
+\begin{methoddesc}[IMAP4]{append}{mailbox, flags, date_time, message}
   Append \var{message} to named mailbox. 
 \end{methoddesc}
 
-\begin{methoddesc}{authenticate}{mechanism, authobject}
+\begin{methoddesc}[IMAP4]{authenticate}{mechanism, authobject}
   Authenticate command --- requires response processing.
 
   \var{mechanism} specifies which authentication mechanism is to be
@@ -176,115 +176,115 @@
   be sent instead.
 \end{methoddesc}
 
-\begin{methoddesc}{check}{}
+\begin{methoddesc}[IMAP4]{check}{}
   Checkpoint mailbox on server. 
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[IMAP4]{close}{}
   Close currently selected mailbox. Deleted messages are removed from
   writable mailbox. This is the recommended command before
   \samp{LOGOUT}.
 \end{methoddesc}
 
-\begin{methoddesc}{copy}{message_set, new_mailbox}
+\begin{methoddesc}[IMAP4]{copy}{message_set, new_mailbox}
   Copy \var{message_set} messages onto end of \var{new_mailbox}. 
 \end{methoddesc}
 
-\begin{methoddesc}{create}{mailbox}
+\begin{methoddesc}[IMAP4]{create}{mailbox}
   Create new mailbox named \var{mailbox}.
 \end{methoddesc}
 
-\begin{methoddesc}{delete}{mailbox}
+\begin{methoddesc}[IMAP4]{delete}{mailbox}
   Delete old mailbox named \var{mailbox}.
 \end{methoddesc}
 
-\begin{methoddesc}{deleteacl}{mailbox, who}
+\begin{methoddesc}[IMAP4]{deleteacl}{mailbox, who}
   Delete the ACLs (remove any rights) set for who on mailbox.
 \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{expunge}{}
+\begin{methoddesc}[IMAP4]{expunge}{}
   Permanently remove deleted items from selected mailbox. Generates an
   \samp{EXPUNGE} response for each deleted message. Returned data
   contains a list of \samp{EXPUNGE} message numbers in order
   received.
 \end{methoddesc}
 
-\begin{methoddesc}{fetch}{message_set, message_parts}
+\begin{methoddesc}[IMAP4]{fetch}{message_set, message_parts}
   Fetch (parts of) messages.  \var{message_parts} should be
   a string of message part names enclosed within parentheses,
   eg: \samp{"(UID BODY[TEXT])"}.  Returned data are tuples
   of message part envelope and data.
 \end{methoddesc}
 
-\begin{methoddesc}{getacl}{mailbox}
+\begin{methoddesc}[IMAP4]{getacl}{mailbox}
   Get the \samp{ACL}s for \var{mailbox}.
   The method is non-standard, but is supported by the \samp{Cyrus} server.
 \end{methoddesc}
 
-\begin{methoddesc}{getannotation}{mailbox, entry, attribute}
+\begin{methoddesc}[IMAP4]{getannotation}{mailbox, entry, attribute}
   Retrieve the specified \samp{ANNOTATION}s for \var{mailbox}.
   The method is non-standard, but is supported by the \samp{Cyrus} server.
 \versionadded{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}{getquota}{root}
+\begin{methoddesc}[IMAP4]{getquota}{root}
   Get the \samp{quota} \var{root}'s resource usage and limits.
   This method is part of the IMAP4 QUOTA extension defined in rfc2087.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{getquotaroot}{mailbox}
+\begin{methoddesc}[IMAP4]{getquotaroot}{mailbox}
   Get the list of \samp{quota} \samp{roots} for the named \var{mailbox}.
   This method is part of the IMAP4 QUOTA extension defined in rfc2087.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{list}{\optional{directory\optional{, pattern}}}
+\begin{methoddesc}[IMAP4]{list}{\optional{directory\optional{, pattern}}}
   List mailbox names in \var{directory} matching
   \var{pattern}.  \var{directory} defaults to the top-level mail
   folder, and \var{pattern} defaults to match anything.  Returned data
   contains a list of \samp{LIST} responses.
 \end{methoddesc}
 
-\begin{methoddesc}{login}{user, password}
+\begin{methoddesc}[IMAP4]{login}{user, password}
   Identify the client using a plaintext password.
   The \var{password} will be quoted.
 \end{methoddesc}
 
-\begin{methoddesc}{login_cram_md5}{user, password}
+\begin{methoddesc}[IMAP4]{login_cram_md5}{user, password}
   Force use of \samp{CRAM-MD5} authentication when identifying the
   client to protect the password.  Will only work if the server
   \samp{CAPABILITY} response includes the phrase \samp{AUTH=CRAM-MD5}.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{logout}{}
+\begin{methoddesc}[IMAP4]{logout}{}
   Shutdown connection to server. Returns server \samp{BYE} response.
 \end{methoddesc}
 
-\begin{methoddesc}{lsub}{\optional{directory\optional{, pattern}}}
+\begin{methoddesc}[IMAP4]{lsub}{\optional{directory\optional{, pattern}}}
   List subscribed mailbox names in directory matching pattern.
   \var{directory} defaults to the top level directory and
   \var{pattern} defaults to match any mailbox.
   Returned data are tuples of message part envelope and data.
 \end{methoddesc}
 
-\begin{methoddesc}{myrights}{mailbox}
+\begin{methoddesc}[IMAP4]{myrights}{mailbox}
   Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).
 \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{namespace}{}
+\begin{methoddesc}[IMAP4]{namespace}{}
   Returns IMAP namespaces as defined in RFC2342.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{noop}{}
+\begin{methoddesc}[IMAP4]{noop}{}
   Send \samp{NOOP} to server.
 \end{methoddesc}
 
-\begin{methoddesc}{open}{host, port}
+\begin{methoddesc}[IMAP4]{open}{host, port}
   Opens socket to \var{port} at \var{host}.
   The connection objects established by this method
   will be used in the \code{read}, \code{readline}, \code{send}, and
@@ -292,42 +292,42 @@
   You may override this method.
 \end{methoddesc}
 
-\begin{methoddesc}{partial}{message_num, message_part, start, length}
+\begin{methoddesc}[IMAP4]{partial}{message_num, message_part, start, length}
   Fetch truncated part of a message.
   Returned data is a tuple of message part envelope and data.
 \end{methoddesc}
 
-\begin{methoddesc}{proxyauth}{user}
+\begin{methoddesc}[IMAP4]{proxyauth}{user}
   Assume authentication as \var{user}.
   Allows an authorised administrator to proxy into any user's mailbox.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{read}{size}
+\begin{methoddesc}[IMAP4]{read}{size}
   Reads \var{size} bytes from the remote server.
   You may override this method.
 \end{methoddesc}
 
-\begin{methoddesc}{readline}{}
+\begin{methoddesc}[IMAP4]{readline}{}
   Reads one line from the remote server.
   You may override this method.
 \end{methoddesc}
 
-\begin{methoddesc}{recent}{}
+\begin{methoddesc}[IMAP4]{recent}{}
   Prompt server for an update. Returned data is \code{None} if no new
   messages, else value of \samp{RECENT} response.
 \end{methoddesc}
 
-\begin{methoddesc}{rename}{oldmailbox, newmailbox}
+\begin{methoddesc}[IMAP4]{rename}{oldmailbox, newmailbox}
   Rename mailbox named \var{oldmailbox} to \var{newmailbox}.
 \end{methoddesc}
 
-\begin{methoddesc}{response}{code}
+\begin{methoddesc}[IMAP4]{response}{code}
   Return data for response \var{code} if received, or
   \code{None}. Returns the given code, instead of the usual type.
 \end{methoddesc}
 
-\begin{methoddesc}{search}{charset, criterion\optional{, ...}}
+\begin{methoddesc}[IMAP4]{search}{charset, criterion\optional{, ...}}
   Search mailbox for matching messages.  \var{charset} may be
   \code{None}, in which case no \samp{CHARSET} will be specified in the
   request to the server.  The IMAP protocol requires that at least one
@@ -345,45 +345,45 @@
 \end{verbatim}
 \end{methoddesc}
 
-\begin{methoddesc}{select}{\optional{mailbox\optional{, readonly}}}
+\begin{methoddesc}[IMAP4]{select}{\optional{mailbox\optional{, readonly}}}
   Select a mailbox. Returned data is the count of messages in
   \var{mailbox} (\samp{EXISTS} response).  The default \var{mailbox}
   is \code{'INBOX'}.  If the \var{readonly} flag is set, modifications
   to the mailbox are not allowed.
 \end{methoddesc}
 
-\begin{methoddesc}{send}{data}
+\begin{methoddesc}[IMAP4]{send}{data}
   Sends \code{data} to the remote server.
   You may override this method.
 \end{methoddesc}
 
-\begin{methoddesc}{setacl}{mailbox, who, what}
+\begin{methoddesc}[IMAP4]{setacl}{mailbox, who, what}
   Set an \samp{ACL} for \var{mailbox}.
   The method is non-standard, but is supported by the \samp{Cyrus} server.
 \end{methoddesc}
 
-\begin{methoddesc}{setannotation}{mailbox, entry, attribute\optional{, ...}}
+\begin{methoddesc}[IMAP4]{setannotation}{mailbox, entry, attribute\optional{, ...}}
   Set \samp{ANNOTATION}s for \var{mailbox}.
   The method is non-standard, but is supported by the \samp{Cyrus} server.
 \versionadded{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}{setquota}{root, limits}
+\begin{methoddesc}[IMAP4]{setquota}{root, limits}
   Set the \samp{quota} \var{root}'s resource \var{limits}.
   This method is part of the IMAP4 QUOTA extension defined in rfc2087.
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{shutdown}{}
+\begin{methoddesc}[IMAP4]{shutdown}{}
   Close connection established in \code{open}.
   You may override this method.
 \end{methoddesc}
 
-\begin{methoddesc}{socket}{}
+\begin{methoddesc}[IMAP4]{socket}{}
   Returns socket instance used to connect to server.
 \end{methoddesc}
 
-\begin{methoddesc}{sort}{sort_criteria, charset, search_criterion\optional{, ...}}
+\begin{methoddesc}[IMAP4]{sort}{sort_criteria, charset, search_criterion\optional{, ...}}
   The \code{sort} command is a variant of \code{search} with sorting
   semantics for the results.  Returned data contains a space separated
   list of matching message numbers.
@@ -402,11 +402,11 @@
   This is an \samp{IMAP4rev1} extension command.
 \end{methoddesc}
 
-\begin{methoddesc}{status}{mailbox, names}
+\begin{methoddesc}[IMAP4]{status}{mailbox, names}
   Request named status conditions for \var{mailbox}. 
 \end{methoddesc}
 
-\begin{methoddesc}{store}{message_set, command, flag_list}
+\begin{methoddesc}[IMAP4]{store}{message_set, command, flag_list}
   Alters flag dispositions for messages in mailbox.  \var{command} is
   specified by section 6.4.6 of \rfc{2060} as being one of "FLAGS", "+FLAGS",
   or "-FLAGS", optionally with a suffix of ".SILENT".
@@ -421,11 +421,11 @@
 \end{verbatim}
 \end{methoddesc}
 
-\begin{methoddesc}{subscribe}{mailbox}
+\begin{methoddesc}[IMAP4]{subscribe}{mailbox}
   Subscribe to new mailbox.
 \end{methoddesc}
 
-\begin{methoddesc}{thread}{threading_algorithm, charset,
+\begin{methoddesc}[IMAP4]{thread}{threading_algorithm, charset,
                            search_criterion\optional{, ...}}
   The \code{thread} command is a variant of \code{search} with
   threading semantics for the results.  Returned data contains a space
@@ -448,18 +448,18 @@
   This is an \samp{IMAP4rev1} extension command. \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{uid}{command, arg\optional{, ...}}
+\begin{methoddesc}[IMAP4]{uid}{command, arg\optional{, ...}}
   Execute command args with messages identified by UID, rather than
   message number.  Returns response appropriate to command.  At least
   one argument must be supplied; if none are provided, the server will
   return an error and an exception will be raised.
 \end{methoddesc}
 
-\begin{methoddesc}{unsubscribe}{mailbox}
+\begin{methoddesc}[IMAP4]{unsubscribe}{mailbox}
   Unsubscribe from old mailbox.
 \end{methoddesc}
 
-\begin{methoddesc}{xatom}{name\optional{, arg\optional{, ...}}}
+\begin{methoddesc}[IMAP4]{xatom}{name\optional{, arg\optional{, ...}}}
   Allow simple extension commands notified by server in
   \samp{CAPABILITY} response.
 \end{methoddesc}
@@ -467,7 +467,7 @@
 
 Instances of \class{IMAP4_SSL} have just one additional method:
 
-\begin{methoddesc}{ssl}{}
+\begin{methoddesc}[IMAP4_SSL]{ssl}{}
   Returns SSLObject instance used for the secure connection with the server.
 \end{methoddesc}
 
@@ -475,12 +475,12 @@
 The following attributes are defined on instances of \class{IMAP4}:
 
 
-\begin{memberdesc}{PROTOCOL_VERSION}
+\begin{memberdesc}[IMAP4]{PROTOCOL_VERSION}
 The most recent supported protocol in the
 \samp{CAPABILITY} response from the server.
 \end{memberdesc}
 
-\begin{memberdesc}{debug}
+\begin{memberdesc}[IMAP4]{debug}
 Integer value to control debugging output.  The initialize value is
 taken from the module variable \code{Debug}.  Values greater than
 three trace each command.

Modified: python/branches/p3yk/Doc/lib/liblogging.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/liblogging.tex	(original)
+++ python/branches/p3yk/Doc/lib/liblogging.tex	Fri Apr 27 21:54:29 2007
@@ -364,13 +364,13 @@
 never instantiated directly, but always through the module-level function
 \function{logging.getLogger(name)}.
 
-\begin{datadesc}{propagate}
+\begin{memberdesc}[Logger]{propagate}
 If this evaluates to false, logging messages are not passed by this
 logger or by child loggers to higher level (ancestor) loggers. The
 constructor sets this attribute to 1.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{methoddesc}{setLevel}{lvl}
+\begin{methoddesc}[Logger]{setLevel}{lvl}
 Sets the threshold for this logger to \var{lvl}. Logging messages
 which are less severe than \var{lvl} will be ignored. When a logger is
 created, the level is set to \constant{NOTSET} (which causes all messages
@@ -393,21 +393,21 @@
 as the effective level.
 \end{methoddesc}
 
-\begin{methoddesc}{isEnabledFor}{lvl}
+\begin{methoddesc}[Logger]{isEnabledFor}{lvl}
 Indicates if a message of severity \var{lvl} would be processed by
 this logger.  This method checks first the module-level level set by
 \function{logging.disable(lvl)} and then the logger's effective level as
 determined by \method{getEffectiveLevel()}.
 \end{methoddesc}
 
-\begin{methoddesc}{getEffectiveLevel}{}
+\begin{methoddesc}[Logger]{getEffectiveLevel}{}
 Indicates the effective level for this logger. If a value other than
 \constant{NOTSET} has been set using \method{setLevel()}, it is returned.
 Otherwise, the hierarchy is traversed towards the root until a value
 other than \constant{NOTSET} is found, and that value is returned.
 \end{methoddesc}
 
-\begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{debug}{msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with level \constant{DEBUG} on this logger.
 The \var{msg} is the message format string, and the \var{args} are the
 arguments which are merged into \var{msg} using the string formatting
@@ -462,67 +462,67 @@
 
 \end{methoddesc}
 
-\begin{methoddesc}{info}{msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{info}{msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with level \constant{INFO} on this logger.
 The arguments are interpreted as for \method{debug()}.
 \end{methoddesc}
 
-\begin{methoddesc}{warning}{msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{warning}{msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with level \constant{WARNING} on this logger.
 The arguments are interpreted as for \method{debug()}.
 \end{methoddesc}
 
-\begin{methoddesc}{error}{msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{error}{msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with level \constant{ERROR} on this logger.
 The arguments are interpreted as for \method{debug()}.
 \end{methoddesc}
 
-\begin{methoddesc}{critical}{msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{critical}{msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with level \constant{CRITICAL} on this logger.
 The arguments are interpreted as for \method{debug()}.
 \end{methoddesc}
 
-\begin{methoddesc}{log}{lvl, msg\optional{, *args\optional{, **kwargs}}}
+\begin{methoddesc}[Logger]{log}{lvl, msg\optional{, *args\optional{, **kwargs}}}
 Logs a message with integer level \var{lvl} on this logger.
 The other arguments are interpreted as for \method{debug()}.
 \end{methoddesc}
 
-\begin{methoddesc}{exception}{msg\optional{, *args}}
+\begin{methoddesc}[Logger]{exception}{msg\optional{, *args}}
 Logs a message with level \constant{ERROR} on this logger.
 The arguments are interpreted as for \method{debug()}. Exception info
 is added to the logging message. This method should only be called
 from an exception handler.
 \end{methoddesc}
 
-\begin{methoddesc}{addFilter}{filt}
+\begin{methoddesc}[Logger]{addFilter}{filt}
 Adds the specified filter \var{filt} to this logger.
 \end{methoddesc}
 
-\begin{methoddesc}{removeFilter}{filt}
+\begin{methoddesc}[Logger]{removeFilter}{filt}
 Removes the specified filter \var{filt} from this logger.
 \end{methoddesc}
 
-\begin{methoddesc}{filter}{record}
+\begin{methoddesc}[Logger]{filter}{record}
 Applies this logger's filters to the record and returns a true value if
 the record is to be processed.
 \end{methoddesc}
 
-\begin{methoddesc}{addHandler}{hdlr}
+\begin{methoddesc}[Logger]{addHandler}{hdlr}
 Adds the specified handler \var{hdlr} to this logger.
 \end{methoddesc}
 
-\begin{methoddesc}{removeHandler}{hdlr}
+\begin{methoddesc}[Logger]{removeHandler}{hdlr}
 Removes the specified handler \var{hdlr} from this logger.
 \end{methoddesc}
 
-\begin{methoddesc}{findCaller}{}
+\begin{methoddesc}[Logger]{findCaller}{}
 Finds the caller's source filename and line number. Returns the filename,
 line number and function name as a 3-element tuple.
 \versionchanged[The function name was added. In earlier versions, the
 filename and line number were returned as a 2-element tuple.]{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}{handle}{record}
+\begin{methoddesc}[Logger]{handle}{record}
 Handles a record by passing it to all handlers associated with this logger
 and its ancestors (until a false value of \var{propagate} is found).
 This method is used for unpickled records received from a socket, as well
@@ -530,8 +530,8 @@
 \method{filter()}.
 \end{methoddesc}
 
-\begin{methoddesc}{makeRecord}{name, lvl, fn, lno, msg, args, exc_info
-                               \optional{, func, extra}}
+\begin{methoddesc}[Logger]{makeRecord}{name, lvl, fn, lno, msg, args, exc_info
+                                       \optional{, func, extra}}
 This is a factory method which can be overridden in subclasses to create
 specialized \class{LogRecord} instances.
 \versionchanged[\var{func} and \var{extra} were added]{2.5}
@@ -875,66 +875,66 @@
 base for more useful subclasses. However, the \method{__init__()}
 method in subclasses needs to call \method{Handler.__init__()}.
 
-\begin{methoddesc}{__init__}{level=\constant{NOTSET}}
+\begin{methoddesc}[Handler]{__init__}{level=\constant{NOTSET}}
 Initializes the \class{Handler} instance by setting its level, setting
 the list of filters to the empty list and creating a lock (using
 \method{createLock()}) for serializing access to an I/O mechanism.
 \end{methoddesc}
 
-\begin{methoddesc}{createLock}{}
+\begin{methoddesc}[Handler]{createLock}{}
 Initializes a thread lock which can be used to serialize access to
 underlying I/O functionality which may not be threadsafe.
 \end{methoddesc}
 
-\begin{methoddesc}{acquire}{}
+\begin{methoddesc}[Handler]{acquire}{}
 Acquires the thread lock created with \method{createLock()}.
 \end{methoddesc}
 
-\begin{methoddesc}{release}{}
+\begin{methoddesc}[Handler]{release}{}
 Releases the thread lock acquired with \method{acquire()}.
 \end{methoddesc}
 
-\begin{methoddesc}{setLevel}{lvl}
+\begin{methoddesc}[Handler]{setLevel}{lvl}
 Sets the threshold for this handler to \var{lvl}. Logging messages which are
 less severe than \var{lvl} will be ignored. When a handler is created, the
 level is set to \constant{NOTSET} (which causes all messages to be processed).
 \end{methoddesc}
 
-\begin{methoddesc}{setFormatter}{form}
+\begin{methoddesc}[Handler]{setFormatter}{form}
 Sets the \class{Formatter} for this handler to \var{form}.
 \end{methoddesc}
 
-\begin{methoddesc}{addFilter}{filt}
+\begin{methoddesc}[Handler]{addFilter}{filt}
 Adds the specified filter \var{filt} to this handler.
 \end{methoddesc}
 
-\begin{methoddesc}{removeFilter}{filt}
+\begin{methoddesc}[Handler]{removeFilter}{filt}
 Removes the specified filter \var{filt} from this handler.
 \end{methoddesc}
 
-\begin{methoddesc}{filter}{record}
+\begin{methoddesc}[Handler]{filter}{record}
 Applies this handler's filters to the record and returns a true value if
 the record is to be processed.
 \end{methoddesc}
 
-\begin{methoddesc}{flush}{}
+\begin{methoddesc}[Handler]{flush}{}
 Ensure all logging output has been flushed. This version does
 nothing and is intended to be implemented by subclasses.
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[Handler]{close}{}
 Tidy up any resources used by the handler. This version does
 nothing and is intended to be implemented by subclasses.
 \end{methoddesc}
 
-\begin{methoddesc}{handle}{record}
+\begin{methoddesc}[Handler]{handle}{record}
 Conditionally emits the specified logging record, depending on
 filters which may have been added to the handler. Wraps the actual
 emission of the record with acquisition/release of the I/O thread
 lock.
 \end{methoddesc}
 
-\begin{methoddesc}{handleError}{record}
+\begin{methoddesc}[Handler]{handleError}{record}
 This method should be called from handlers when an exception is
 encountered during an \method{emit()} call. By default it does nothing,
 which means that exceptions get silently ignored. This is what is
@@ -945,12 +945,12 @@
 processed when the exception occurred.
 \end{methoddesc}
 
-\begin{methoddesc}{format}{record}
+\begin{methoddesc}[Handler]{format}{record}
 Do formatting for a record - if a formatter is set, use it.
 Otherwise, use the default formatter for the module.
 \end{methoddesc}
 
-\begin{methoddesc}{emit}{record}
+\begin{methoddesc}[Handler]{emit}{record}
 Do whatever it takes to actually log the specified logging record.
 This version is intended to be implemented by subclasses and so
 raises a \exception{NotImplementedError}.
@@ -1138,9 +1138,6 @@
 Closes the socket.
 \end{methoddesc}
 
-\begin{methoddesc}{handleError}{}
-\end{methoddesc}
-
 \begin{methoddesc}{emit}{}
 Pickles the record's attribute dictionary and writes it to the socket in
 binary format. If there is an error with the socket, silently drops the

Modified: python/branches/p3yk/Doc/lib/libmailbox.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmailbox.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmailbox.tex	Fri Apr 27 21:54:29 2007
@@ -1203,7 +1203,6 @@
 \end{tableii}
 
 \subsection{Exceptions}
-\label{mailbox-deprecated}
 
 The following exception classes are defined in the \module{mailbox} module:
 
@@ -1247,7 +1246,7 @@
 Older mailbox objects support only iteration and provide a single public
 method:
 
-\begin{methoddesc}{next}{}
+\begin{methoddesc}[oldmailbox]{next}{}
 Return the next message in the mailbox, created with the optional \var{factory}
 argument passed into the mailbox object's constructor. By default this is an
 \class{rfc822.Message} object (see the \refmodule{rfc822} module).  Depending
@@ -1286,13 +1285,13 @@
 separated by any line that begins exactly with the string \code{'From
 '} (note the trailing space) if preceded by exactly two newlines.
 Because of the wide-range of variations in practice, nothing else on
-the From_ line should be considered.  However, the current
+the \samp{From_} line should be considered.  However, the current
 implementation doesn't check for the leading two newlines.  This is
 usually fine for most applications.
 
 The \class{UnixMailbox} class implements a more strict version of
-From_ line checking, using a regular expression that usually correctly
-matched From_ delimiters.  It considers delimiter line to be separated
+\samp{From_} line checking, using a regular expression that usually correctly
+matched \samp{From_} delimiters.  It considers delimiter line to be separated
 by \samp{From \var{name} \var{time}} lines.  For maximum portability,
 use the \class{PortableUnixMailbox} class instead.  This class is
 identical to \class{UnixMailbox} except that individual messages are

Modified: python/branches/p3yk/Doc/lib/libmimetools.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmimetools.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmimetools.tex	Fri Apr 27 21:54:29 2007
@@ -76,7 +76,7 @@
 The \class{Message} class defines the following methods in
 addition to the \class{rfc822.Message} methods:
 
-\begin{methoddesc}{getplist}{}
+\begin{methoddesc}[Message]{getplist}{}
 Return the parameter list of the \mailheader{Content-Type} header.
 This is a list of strings.  For parameters of the form
 \samp{\var{key}=\var{value}}, \var{key} is converted to lower case but
@@ -86,34 +86,34 @@
 'spam=2', 'Spam']}.
 \end{methoddesc}
 
-\begin{methoddesc}{getparam}{name}
+\begin{methoddesc}[Message]{getparam}{name}
 Return the \var{value} of the first parameter (as returned by
 \method{getplist()}) of the form \samp{\var{name}=\var{value}} for the
 given \var{name}.  If \var{value} is surrounded by quotes of the form
 `\code{<}...\code{>}' or `\code{"}...\code{"}', these are removed.
 \end{methoddesc}
 
-\begin{methoddesc}{getencoding}{}
+\begin{methoddesc}[Message]{getencoding}{}
 Return the encoding specified in the
 \mailheader{Content-Transfer-Encoding} message header.  If no such
 header exists, return \code{'7bit'}.  The encoding is converted to
 lower case.
 \end{methoddesc}
 
-\begin{methoddesc}{gettype}{}
+\begin{methoddesc}[Message]{gettype}{}
 Return the message type (of the form \samp{\var{type}/\var{subtype}})
 as specified in the \mailheader{Content-Type} header.  If no such
 header exists, return \code{'text/plain'}.  The type is converted to
 lower case.
 \end{methoddesc}
 
-\begin{methoddesc}{getmaintype}{}
+\begin{methoddesc}[Message]{getmaintype}{}
 Return the main type as specified in the \mailheader{Content-Type}
 header.  If no such header exists, return \code{'text'}.  The main
 type is converted to lower case.
 \end{methoddesc}
 
-\begin{methoddesc}{getsubtype}{}
+\begin{methoddesc}[Message]{getsubtype}{}
 Return the subtype as specified in the \mailheader{Content-Type}
 header.  If no such header exists, return \code{'plain'}.  The subtype
 is converted to lower case.

Modified: python/branches/p3yk/Doc/lib/libmimetypes.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmimetypes.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmimetypes.tex	Fri Apr 27 21:54:29 2007
@@ -178,49 +178,49 @@
 \class{MimeTypes} instances provide an interface which is very like
 that of the \refmodule{mimetypes} module.
 
-\begin{datadesc}{suffix_map}
+\begin{memberdesc}[MimeTypes]{suffix_map}
   Dictionary mapping suffixes to suffixes.  This is used to allow
   recognition of encoded files for which the encoding and the type are
   indicated by the same extension.  For example, the \file{.tgz}
   extension is mapped to \file{.tar.gz} to allow the encoding and type
   to be recognized separately.  This is initially a copy of the global
   \code{suffix_map} defined in the module.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{encodings_map}
+\begin{memberdesc}[MimeTypes]{encodings_map}
   Dictionary mapping filename extensions to encoding types.  This is
   initially a copy of the global \code{encodings_map} defined in the
   module.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{types_map}
+\begin{memberdesc}[MimeTypes]{types_map}
   Dictionary mapping filename extensions to MIME types.  This is
   initially a copy of the global \code{types_map} defined in the
   module.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{datadesc}{common_types}
+\begin{memberdesc}[MimeTypes]{common_types}
   Dictionary mapping filename extensions to non-standard, but commonly
   found MIME types.  This is initially a copy of the global
   \code{common_types} defined in the module.
-\end{datadesc}
+\end{memberdesc}
 
-\begin{methoddesc}{guess_extension}{type\optional{, strict}}
+\begin{methoddesc}[MimeTypes]{guess_extension}{type\optional{, strict}}
   Similar to the \function{guess_extension()} function, using the
   tables stored as part of the object.
 \end{methoddesc}
 
-\begin{methoddesc}{guess_type}{url\optional{, strict}}
+\begin{methoddesc}[MimeTypes]{guess_type}{url\optional{, strict}}
   Similar to the \function{guess_type()} function, using the tables
   stored as part of the object.
 \end{methoddesc}
 
-\begin{methoddesc}{read}{path}
+\begin{methoddesc}[MimeTypes]{read}{path}
   Load MIME information from a file named \var{path}.  This uses
   \method{readfp()} to parse the file.
 \end{methoddesc}
 
-\begin{methoddesc}{readfp}{file}
+\begin{methoddesc}[MimeTypes]{readfp}{file}
   Load MIME type information from an open file.  The file must have
   the format of the standard \file{mime.types} files.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libmimewriter.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmimewriter.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmimewriter.tex	Fri Apr 27 21:54:29 2007
@@ -31,7 +31,7 @@
 
 \class{MimeWriter} instances have the following methods:
 
-\begin{methoddesc}{addheader}{key, value\optional{, prefix}}
+\begin{methoddesc}[MimeWriter]{addheader}{key, value\optional{, prefix}}
 Add a header line to the MIME message. The \var{key} is the name of
 the header, where the \var{value} obviously provides the value of the
 header. The optional argument \var{prefix} determines where the header 
@@ -39,14 +39,14 @@
 the start. The default is to append.
 \end{methoddesc}
 
-\begin{methoddesc}{flushheaders}{}
+\begin{methoddesc}[MimeWriter]{flushheaders}{}
 Causes all headers accumulated so far to be written out (and
 forgotten). This is useful if you don't need a body part at all,
 e.g.\ for a subpart of type \mimetype{message/rfc822} that's (mis)used
 to store some header-like information.
 \end{methoddesc}
 
-\begin{methoddesc}{startbody}{ctype\optional{, plist\optional{, prefix}}}
+\begin{methoddesc}[MimeWriter]{startbody}{ctype\optional{, plist\optional{, prefix}}}
 Returns a file-like object which can be used to write to the
 body of the message.  The content-type is set to the provided
 \var{ctype}, and the optional parameter \var{plist} provides
@@ -55,8 +55,8 @@
 insert at the start.
 \end{methoddesc}
 
-\begin{methoddesc}{startmultipartbody}{subtype\optional{,
-                   boundary\optional{, plist\optional{, prefix}}}}
+\begin{methoddesc}[MimeWriter]{startmultipartbody}{subtype\optional{,
+                               boundary\optional{, plist\optional{, prefix}}}}
 Returns a file-like object which can be used to write to the
 body of the message.  Additionally, this method initializes the
 multi-part code, where \var{subtype} provides the multipart subtype,
@@ -66,7 +66,7 @@
 created using \method{nextpart()}.
 \end{methoddesc}
 
-\begin{methoddesc}{nextpart}{}
+\begin{methoddesc}[MimeWriter]{nextpart}{}
 Returns a new instance of \class{MimeWriter} which represents an
 individual part in a multipart message.  This may be used to write the 
 part as well as used for creating recursively complex multipart
@@ -74,7 +74,7 @@
 \method{startmultipartbody()} before using \method{nextpart()}.
 \end{methoddesc}
 
-\begin{methoddesc}{lastpart}{}
+\begin{methoddesc}[MimeWriter]{lastpart}{}
 This is used to designate the last part of a multipart message, and
 should \emph{always} be used when writing multipart messages.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libmmap.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmmap.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmmap.tex	Fri Apr 27 21:54:29 2007
@@ -89,18 +89,18 @@
 Memory-mapped file objects support the following methods:
 
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[mmap]{close}{}
   Close the file.  Subsequent calls to other methods of the object
   will result in an exception being raised.
 \end{methoddesc}
 
-\begin{methoddesc}{find}{string\optional{, start}}
+\begin{methoddesc}[mmap]{find}{string\optional{, start}}
   Returns the lowest index in the object where the substring
   \var{string} is found.  Returns \code{-1} on failure.  \var{start}
   is the index at which the search begins, and defaults to zero.
 \end{methoddesc}
 
-\begin{methoddesc}{flush}{\optional{offset, size}}
+\begin{methoddesc}[mmap]{flush}{\optional{offset, size}}
   Flushes changes made to the in-memory copy of a file back to disk.
   Without use of this call there is no guarantee that changes are
   written back before the object is destroyed.  If \var{offset} and
@@ -109,36 +109,36 @@
   is flushed.
 \end{methoddesc}
 
-\begin{methoddesc}{move}{\var{dest}, \var{src}, \var{count}}
+\begin{methoddesc}[mmap]{move}{\var{dest}, \var{src}, \var{count}}
   Copy the \var{count} bytes starting at offset \var{src} to the
   destination index \var{dest}.  If the mmap was created with
   \constant{ACCESS_READ}, then calls to move will throw a
   \exception{TypeError} exception.
 \end{methoddesc}
 
-\begin{methoddesc}{read}{\var{num}}
+\begin{methoddesc}[mmap]{read}{\var{num}}
   Return a string containing up to \var{num} bytes starting from the
   current file position; the file position is updated to point after the
   bytes that were returned.
 \end{methoddesc}
 
-\begin{methoddesc}{read_byte}{}
+\begin{methoddesc}[mmap]{read_byte}{}
   Returns a string of length 1 containing the character at the current
   file position, and advances the file position by 1.
 \end{methoddesc}
 
-\begin{methoddesc}{readline}{}
+\begin{methoddesc}[mmap]{readline}{}
   Returns a single line, starting at the current file position and up to
   the next newline.
 \end{methoddesc}
 
-\begin{methoddesc}{resize}{\var{newsize}}
+\begin{methoddesc}[mmap]{resize}{\var{newsize}}
   Resizes the map and the underlying file, if any.
   If the mmap was created with \constant{ACCESS_READ} or
   \constant{ACCESS_COPY}, resizing the map will throw a \exception{TypeError} exception.
 \end{methoddesc}
 
-\begin{methoddesc}{seek}{pos\optional{, whence}}
+\begin{methoddesc}[mmap]{seek}{pos\optional{, whence}}
   Set the file's current position.  \var{whence} argument is optional
   and defaults to \code{os.SEEK_SET} or \code{0} (absolute file
   positioning); other values are \code{os.SEEK_CUR} or \code{1} (seek
@@ -146,16 +146,16 @@
   (seek relative to the file's end).
 \end{methoddesc}
 
-\begin{methoddesc}{size}{}
+\begin{methoddesc}[mmap]{size}{}
   Return the length of the file, which can be larger than the size of
   the memory-mapped area.
 \end{methoddesc}
 
-\begin{methoddesc}{tell}{}
+\begin{methoddesc}[mmap]{tell}{}
   Returns the current position of the file pointer.
 \end{methoddesc}
 
-\begin{methoddesc}{write}{\var{string}}
+\begin{methoddesc}[mmap]{write}{\var{string}}
   Write the bytes in \var{string} into memory at the current position
   of the file pointer; the file position is updated to point after the
   bytes that were written. If the mmap was created with
@@ -163,7 +163,7 @@
   \exception{TypeError} exception.
 \end{methoddesc}
 
-\begin{methoddesc}{write_byte}{\var{byte}}
+\begin{methoddesc}[mmap]{write_byte}{\var{byte}}
   Write the single-character string \var{byte} into memory at the
   current position of the file pointer; the file position is advanced
   by \code{1}. If the mmap was created with \constant{ACCESS_READ},

Modified: python/branches/p3yk/Doc/lib/libmsilib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmsilib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmsilib.tex	Fri Apr 27 21:54:29 2007
@@ -121,17 +121,17 @@
 
 \subsection{Database Objects\label{database-objects}}
 
-\begin{methoddesc}{OpenView}{sql}
+\begin{methoddesc}[Database]{OpenView}{sql}
   Return a view object, by calling \cfunction{MSIDatabaseOpenView}.
   \var{sql} is the SQL statement to execute.
 \end{methoddesc}
 
-\begin{methoddesc}{Commit}{}
+\begin{methoddesc}[Database]{Commit}{}
   Commit the changes pending in the current transaction,
   by calling \cfunction{MSIDatabaseCommit}.
 \end{methoddesc}
 
-\begin{methoddesc}{GetSummaryInformation}{count}
+\begin{methoddesc}[Database]{GetSummaryInformation}{count}
   Return a new summary information object, by calling
   \cfunction{MsiGetSummaryInformation}.  \var{count} is the maximum number of
   updated values.
@@ -145,24 +145,24 @@
 
 \subsection{View Objects\label{view-objects}}
 
-\begin{methoddesc}{Execute}{\optional{params=None}}
+\begin{methoddesc}[View]{Execute}{\optional{params=None}}
   Execute the SQL query of the view, through \cfunction{MSIViewExecute}.
   \var{params} is an optional record describing actual values
   of the parameter tokens in the query.
 \end{methoddesc}
 
-\begin{methoddesc}{GetColumnInfo}{kind}
+\begin{methoddesc}[View]{GetColumnInfo}{kind}
   Return a record describing the columns of the view, through
   calling \cfunction{MsiViewGetColumnInfo}. \var{kind} can be either
   \code{MSICOLINFO_NAMES} or \code{MSICOLINFO_TYPES}.
 \end{methoddesc}
 
-\begin{methoddesc}{Fetch}{}
+\begin{methoddesc}[View]{Fetch}{}
   Return a result record of the query, through calling
   \cfunction{MsiViewFetch}.
 \end{methoddesc}
 
-\begin{methoddesc}{Modify}{kind, data}
+\begin{methoddesc}[View]{Modify}{kind, data}
   Modify the view, by calling \cfunction{MsiViewModify}. \var{kind}
   can be one of  \code{MSIMODIFY_SEEK}, \code{MSIMODIFY_REFRESH},
   \code{MSIMODIFY_INSERT}, \code{MSIMODIFY_UPDATE}, \code{MSIMODIFY_ASSIGN},
@@ -174,7 +174,7 @@
   \var{data} must be a record describing the new data.
 \end{methoddesc}
 
-\begin{methoddesc}{Close}{}
+\begin{methoddesc}[View]{Close}{}
   Close the view, through \cfunction{MsiViewClose}.
 \end{methoddesc}
 
@@ -188,7 +188,7 @@
 
 \subsection{Summary Information Objects\label{summary-objects}}
 
-\begin{methoddesc}{GetProperty}{field}
+\begin{methoddesc}[SummaryInformation]{GetProperty}{field}
   Return a property of the summary, through \cfunction{MsiSummaryInfoGetProperty}.
   \var{field} is the name of the property, and can be one of the
   constants
@@ -200,19 +200,19 @@
   \code{PID_APPNAME}, or \code{PID_SECURITY}.
 \end{methoddesc}
 
-\begin{methoddesc}{GetPropertyCount}{}
+\begin{methoddesc}[SummaryInformation]{GetPropertyCount}{}
   Return the number of summary properties, through
   \cfunction{MsiSummaryInfoGetPropertyCount}.
 \end{methoddesc}
 
-\begin{methoddesc}{SetProperty}{field, value}
+\begin{methoddesc}[SummaryInformation]{SetProperty}{field, value}
   Set a property through \cfunction{MsiSummaryInfoSetProperty}. \var{field}
   can have the same values as in \method{GetProperty}, \var{value}
   is the new value of the property. Possible value types are integer
   and string.
 \end{methoddesc}
 
-\begin{methoddesc}{Persist}{}
+\begin{methoddesc}[SummaryInformation]{Persist}{}
   Write the modified properties to the summary information stream,
   using \cfunction{MsiSummaryInfoPersist}.
 \end{methoddesc}
@@ -226,27 +226,27 @@
 
 \subsection{Record Objects\label{record-objects}}
 
-\begin{methoddesc}{GetFieldCount}{}
+\begin{methoddesc}[Record]{GetFieldCount}{}
   Return the number of fields of the record, through \cfunction{MsiRecordGetFieldCount}.
 \end{methoddesc}
 
-\begin{methoddesc}{SetString}{field, value}
+\begin{methoddesc}[Record]{SetString}{field, value}
   Set \var{field} to \var{value} through \cfunction{MsiRecordSetString}.
   \var{field} must be an integer; \var{value} a string.
 \end{methoddesc}
 
-\begin{methoddesc}{SetStream}{field, value}
+\begin{methoddesc}[Record]{SetStream}{field, value}
   Set \var{field} to the contents of the file named \var{value},
   through \cfunction{MsiRecordSetStream}.
   \var{field} must be an integer; \var{value} a string.
 \end{methoddesc}
 
-\begin{methoddesc}{SetInteger}{field, value}
+\begin{methoddesc}[Record]{SetInteger}{field, value}
   Set \var{field} to \var{value} through \cfunction{MsiRecordSetInteger}.
   Both \var{field} and \var{value} must be an integer.
 \end{methoddesc}
 
-\begin{methoddesc}{ClearData}{}
+\begin{methoddesc}[Record]{ClearData}{}
   Set all fields of the record to 0, through \cfunction{MsiRecordClearData}.
 \end{methoddesc}
 
@@ -274,7 +274,7 @@
   \var{name} is the name of the CAB file in the MSI file.
 \end{classdesc}
 
-\begin{methoddesc}[CAB]{append}{full, logical}
+\begin{methoddesc}[CAB]{append}{full, file, logical}
   Add the file with the pathname \var{full} to the CAB file,
   under the name \var{logical}. If there is already a file
   named \var{logical}, a new file name is created.
@@ -283,7 +283,7 @@
   new name of the file inside the CAB file.
 \end{methoddesc}
 
-\begin{methoddesc}[CAB]{append}{database}
+\begin{methoddesc}[CAB]{commit}{database}
   Generate a CAB file, add it as a stream to the MSI file,
   put it into the \code{Media} table, and remove the generated
   file from the disk.

Modified: python/branches/p3yk/Doc/lib/libmultifile.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmultifile.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmultifile.tex	Fri Apr 27 21:54:29 2007
@@ -48,7 +48,7 @@
 
 A \class{MultiFile} instance has the following methods:
 
-\begin{methoddesc}{readline}{str}
+\begin{methoddesc}[MultiFile]{readline}{str}
 Read a line.  If the line is data (not a section-divider or end-marker
 or real EOF) return it.  If the line matches the most-recently-stacked
 boundary, return \code{''} and set \code{self.last} to 1 or 0 according as
@@ -58,33 +58,33 @@
 all boundaries have been popped.
 \end{methoddesc}
 
-\begin{methoddesc}{readlines}{str}
+\begin{methoddesc}[MultiFile]{readlines}{str}
 Return all lines remaining in this part as a list of strings.
 \end{methoddesc}
 
-\begin{methoddesc}{read}{}
+\begin{methoddesc}[MultiFile]{read}{}
 Read all lines, up to the next section.  Return them as a single
 (multiline) string.  Note that this doesn't take a size argument!
 \end{methoddesc}
 
-\begin{methoddesc}{seek}{pos\optional{, whence}}
+\begin{methoddesc}[MultiFile]{seek}{pos\optional{, whence}}
 Seek.  Seek indices are relative to the start of the current section.
 The \var{pos} and \var{whence} arguments are interpreted as for a file
 seek.
 \end{methoddesc}
 
-\begin{methoddesc}{tell}{}
+\begin{methoddesc}[MultiFile]{tell}{}
 Return the file position relative to the start of the current section.
 \end{methoddesc}
 
-\begin{methoddesc}{next}{}
+\begin{methoddesc}[MultiFile]{next}{}
 Skip lines to the next section (that is, read lines until a
 section-divider or end-marker has been consumed).  Return true if
 there is such a section, false if an end-marker is seen.  Re-enable
 the most-recently-pushed boundary.
 \end{methoddesc}
 
-\begin{methoddesc}{is_data}{str}
+\begin{methoddesc}[MultiFile]{is_data}{str}
 Return true if \var{str} is data and false if it might be a section
 boundary.  As written, it tests for a prefix other than \code{'-}\code{-'} at
 start of line (which all MIME boundaries have) but it is declared so
@@ -95,7 +95,7 @@
 processing, not cause it to fail.
 \end{methoddesc}
 
-\begin{methoddesc}{push}{str}
+\begin{methoddesc}[MultiFile]{push}{str}
 Push a boundary string.  When a decorated version of this boundary 
 is found as an input line, it will be interpreted as a section-divider 
 or end-marker (depending on the decoration, see \rfc{2045}).  All subsequent
@@ -108,12 +108,12 @@
 boundary will raise an error.
 \end{methoddesc}
 
-\begin{methoddesc}{pop}{}
+\begin{methoddesc}[MultiFile]{pop}{}
 Pop a section boundary.  This boundary will no longer be interpreted
 as EOF.
 \end{methoddesc}
 
-\begin{methoddesc}{section_divider}{str}
+\begin{methoddesc}[MultiFile]{section_divider}{str}
 Turn a boundary into a section-divider line.  By default, this
 method prepends \code{'-}\code{-'} (which MIME section boundaries have) but
 it is declared so it can be overridden in derived classes.  This
@@ -121,7 +121,7 @@
 ignores trailing whitespace. 
 \end{methoddesc}
 
-\begin{methoddesc}{end_marker}{str}
+\begin{methoddesc}[MultiFile]{end_marker}{str}
 Turn a boundary string into an end-marker line.  By default, this
 method prepends \code{'-}\code{-'} and appends \code{'-}\code{-'} (like a
 MIME-multipart end-of-message marker) but it is declared so it can be
@@ -131,11 +131,11 @@
 
 Finally, \class{MultiFile} instances have two public instance variables:
 
-\begin{memberdesc}{level}
+\begin{memberdesc}[MultiFile]{level}
 Nesting depth of the current part.
 \end{memberdesc}
 
-\begin{memberdesc}{last}
+\begin{memberdesc}[MultiFile]{last}
 True if the last end-of-file was for an end-of-message marker. 
 \end{memberdesc}
 

Modified: python/branches/p3yk/Doc/lib/libmutex.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libmutex.tex	(original)
+++ python/branches/p3yk/Doc/lib/libmutex.tex	Fri Apr 27 21:54:29 2007
@@ -35,23 +35,23 @@
 
 \class{mutex} objects have following methods:
 
-\begin{methoddesc}{test}{}
+\begin{methoddesc}[mutex]{test}{}
 Check whether the mutex is locked.
 \end{methoddesc}
 
-\begin{methoddesc}{testandset}{}
+\begin{methoddesc}[mutex]{testandset}{}
 ``Atomic'' test-and-set, grab the lock if it is not set,
 and return \code{True}, otherwise, return \code{False}.
 \end{methoddesc}
 
-\begin{methoddesc}{lock}{function, argument}
+\begin{methoddesc}[mutex]{lock}{function, argument}
 Execute \code{\var{function}(\var{argument})}, unless the mutex is locked.
 In the case it is locked, place the function and argument on the queue.
 See \method{unlock} for explanation of when
 \code{\var{function}(\var{argument})} is executed in that case.
 \end{methoddesc}
 
-\begin{methoddesc}{unlock}{}
+\begin{methoddesc}[mutex]{unlock}{}
 Unlock the mutex if queue is empty, otherwise execute the first element
 in the queue.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libnetrc.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libnetrc.tex	(original)
+++ python/branches/p3yk/Doc/lib/libnetrc.tex	Fri Apr 27 21:54:29 2007
@@ -35,7 +35,7 @@
 
 A \class{netrc} instance has the following methods:
 
-\begin{methoddesc}{authenticators}{host}
+\begin{methoddesc}[netrc]{authenticators}{host}
 Return a 3-tuple \code{(\var{login}, \var{account}, \var{password})}
 of authenticators for \var{host}.  If the netrc file did not
 contain an entry for the given host, return the tuple associated with
@@ -43,20 +43,20 @@
 available, return \code{None}.
 \end{methoddesc}
 
-\begin{methoddesc}{__repr__}{}
+\begin{methoddesc}[netrc]{__repr__}{}
 Dump the class data as a string in the format of a netrc file.
 (This discards comments and may reorder the entries.)
 \end{methoddesc}
 
 Instances of \class{netrc} have public instance variables:
 
-\begin{memberdesc}{hosts}
+\begin{memberdesc}[netrc]{hosts}
 Dictionary mapping host names to \code{(\var{login}, \var{account},
 \var{password})} tuples.  The `default' entry, if any, is represented
 as a pseudo-host by that name.
 \end{memberdesc}
 
-\begin{memberdesc}{macros}
+\begin{memberdesc}[netrc]{macros}
 Dictionary mapping macro names to string lists.
 \end{memberdesc}
 

Modified: python/branches/p3yk/Doc/lib/libnntplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libnntplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libnntplib.tex	Fri Apr 27 21:54:29 2007
@@ -121,13 +121,13 @@
 the above exceptions.
 
 
-\begin{methoddesc}{getwelcome}{}
+\begin{methoddesc}[NNTP]{getwelcome}{}
 Return the welcome message sent by the server in reply to the initial
 connection.  (This message sometimes contains disclaimers or help
 information that may be relevant to the user.)
 \end{methoddesc}
 
-\begin{methoddesc}{set_debuglevel}{level}
+\begin{methoddesc}[NNTP]{set_debuglevel}{level}
 Set the instance's debugging level.  This controls the amount of
 debugging output printed.  The default, \code{0}, produces no debugging
 output.  A value of \code{1} produces a moderate amount of debugging
@@ -137,7 +137,7 @@
 message text).
 \end{methoddesc}
 
-\begin{methoddesc}{newgroups}{date, time, \optional{file}}
+\begin{methoddesc}[NNTP]{newgroups}{date, time, \optional{file}}
 Send a \samp{NEWGROUPS} command.  The \var{date} argument should be a
 string of the form \code{'\var{yy}\var{mm}\var{dd}'} indicating the
 date, and \var{time} should be a string of the form
@@ -152,7 +152,7 @@
 If \var{file} is supplied, then the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{newnews}{group, date, time, \optional{file}}
+\begin{methoddesc}[NNTP]{newnews}{group, date, time, \optional{file}}
 Send a \samp{NEWNEWS} command.  Here, \var{group} is a group name or
 \code{'*'}, and \var{date} and \var{time} have the same meaning as for
 \method{newgroups()}.  Return a pair \code{(\var{response},
@@ -165,7 +165,7 @@
 If \var{file} is supplied, then the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{list}{\optional{file}}
+\begin{methoddesc}[NNTP]{list}{\optional{file}}
 Send a \samp{LIST} command.  Return a pair \code{(\var{response},
 \var{list})} where \var{list} is a list of tuples.  Each tuple has the
 form \code{(\var{group}, \var{last}, \var{first}, \var{flag})}, where
@@ -182,7 +182,7 @@
 If \var{file} is supplied, then the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{descriptions}{grouppattern}
+\begin{methoddesc}[NNTP]{descriptions}{grouppattern}
 Send a \samp{LIST NEWSGROUPS} command, where \var{grouppattern} is a wildmat
 string as specified in RFC2980 (it's essentially the same as DOS or UNIX
 shell wildcard strings).  Return a pair \code{(\var{response},
@@ -192,7 +192,7 @@
 \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{description}{group}
+\begin{methoddesc}[NNTP]{description}{group}
 Get a description for a single group \var{group}.  If more than one group
 matches (if 'group' is a real wildmat string), return the first match.  
 If no group matches, return an empty string.
@@ -203,7 +203,7 @@
 \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}{group}{name}
+\begin{methoddesc}[NNTP]{group}{name}
 Send a \samp{GROUP} command, where \var{name} is the group name.
 Return a tuple \code{(\var{response}, \var{count}, \var{first},
 \var{last}, \var{name})} where \var{count} is the (estimated) number
@@ -212,7 +212,7 @@
 \var{name} is the group name.  The numbers are returned as strings.
 \end{methoddesc}
 
-\begin{methoddesc}{help}{\optional{file}}
+\begin{methoddesc}[NNTP]{help}{\optional{file}}
 Send a \samp{HELP} command.  Return a pair \code{(\var{response},
 \var{list})} where \var{list} is a list of help strings.
 If the \var{file} parameter is supplied, then the output of the 
@@ -223,7 +223,7 @@
 If \var{file} is supplied, then the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{stat}{id}
+\begin{methoddesc}[NNTP]{stat}{id}
 Send a \samp{STAT} command, where \var{id} is the message id (enclosed
 in \character{<} and \character{>}) or an article number (as a string).
 Return a triple \code{(\var{response}, \var{number}, \var{id})} where
@@ -231,15 +231,15 @@
 message id  (enclosed in \character{<} and \character{>}).
 \end{methoddesc}
 
-\begin{methoddesc}{next}{}
+\begin{methoddesc}[NNTP]{next}{}
 Send a \samp{NEXT} command.  Return as for \method{stat()}.
 \end{methoddesc}
 
-\begin{methoddesc}{last}{}
+\begin{methoddesc}[NNTP]{last}{}
 Send a \samp{LAST} command.  Return as for \method{stat()}.
 \end{methoddesc}
 
-\begin{methoddesc}{head}{id}
+\begin{methoddesc}[NNTP]{head}{id}
 Send a \samp{HEAD} command, where \var{id} has the same meaning as for
 \method{stat()}.  Return a tuple
 \code{(\var{response}, \var{number}, \var{id}, \var{list})}
@@ -248,7 +248,7 @@
 list of lines, without trailing newlines).
 \end{methoddesc}
 
-\begin{methoddesc}{body}{id,\optional{file}}
+\begin{methoddesc}[NNTP]{body}{id,\optional{file}}
 Send a \samp{BODY} command, where \var{id} has the same meaning as for
 \method{stat()}.  If the \var{file} parameter is supplied, then
 the body is stored in a file.  If \var{file} is a string, then
@@ -259,16 +259,16 @@
 the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{article}{id}
+\begin{methoddesc}[NNTP]{article}{id}
 Send an \samp{ARTICLE} command, where \var{id} has the same meaning as
 for \method{stat()}.  Return as for \method{head()}.
 \end{methoddesc}
 
-\begin{methoddesc}{slave}{}
+\begin{methoddesc}[NNTP]{slave}{}
 Send a \samp{SLAVE} command.  Return the server's \var{response}.
 \end{methoddesc}
 
-\begin{methoddesc}{xhdr}{header, string, \optional{file}}
+\begin{methoddesc}[NNTP]{xhdr}{header, string, \optional{file}}
 Send an \samp{XHDR} command.  This command is not defined in the RFC
 but is a common extension.  The \var{header} argument is a header
 keyword, e.g. \code{'subject'}.  The \var{string} argument should have
@@ -286,7 +286,7 @@
 If \var{file} is supplied, then the returned \var{list} is an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}{post}{file}
+\begin{methoddesc}[NNTP]{post}{file}
 Post an article using the \samp{POST} command.  The \var{file}
 argument is an open file object which is read until EOF using its
 \method{readline()} method.  It should be a well-formed news article,
@@ -294,14 +294,14 @@
 automatically escapes lines beginning with \samp{.}.
 \end{methoddesc}
 
-\begin{methoddesc}{ihave}{id, file}
+\begin{methoddesc}[NNTP]{ihave}{id, file}
 Send an \samp{IHAVE} command. \var{id} is a message id (enclosed in 
 \character{<} and \character{>}).
 If the response is not an error, treat
 \var{file} exactly as for the \method{post()} method.
 \end{methoddesc}
 
-\begin{methoddesc}{date}{}
+\begin{methoddesc}[NNTP]{date}{}
 Return a triple \code{(\var{response}, \var{date}, \var{time})},
 containing the current date and time in a form suitable for the
 \method{newnews()} and \method{newgroups()} methods.
@@ -309,7 +309,7 @@
 servers.
 \end{methoddesc}
 
-\begin{methoddesc}{xgtitle}{name, \optional{file}}
+\begin{methoddesc}[NNTP]{xgtitle}{name, \optional{file}}
 Process an \samp{XGTITLE} command, returning a pair \code{(\var{response},
 \var{list})}, where \var{list} is a list of tuples containing
 \code{(\var{name}, \var{title})}.
@@ -327,7 +327,7 @@
 \method{descriptions()} or \method{description()} instead.
 \end{methoddesc}
 
-\begin{methoddesc}{xover}{start, end, \optional{file}}
+\begin{methoddesc}[NNTP]{xover}{start, end, \optional{file}}
 Return a pair \code{(\var{resp}, \var{list})}.  \var{list} is a list
 of tuples, one for each article in the range delimited by the \var{start}
 and \var{end} article numbers.  Each tuple is of the form
@@ -343,13 +343,13 @@
 servers.
 \end{methoddesc}
 
-\begin{methoddesc}{xpath}{id}
+\begin{methoddesc}[NNTP]{xpath}{id}
 Return a pair \code{(\var{resp}, \var{path})}, where \var{path} is the
 directory path to the article with message ID \var{id}.  This is an
 optional NNTP extension, and may not be supported by all servers.
 \end{methoddesc}
 
-\begin{methoddesc}{quit}{}
+\begin{methoddesc}[NNTP]{quit}{}
 Send a \samp{QUIT} command and close the connection.  Once this method
 has been called, no other methods of the NNTP object should be called.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/liboptparse.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/liboptparse.tex	(original)
+++ python/branches/p3yk/Doc/lib/liboptparse.tex	Fri Apr 27 21:54:29 2007
@@ -518,7 +518,7 @@
 is then printed before the detailed option help.
 
 If you don't supply a usage string, \module{optparse} uses a bland but sensible
-default: ``\code{usage: {\%}prog {[}options]"}, which is fine if your script
+default: \code{"usage: {\%}prog {[}options]"}, which is fine if your script
 doesn't take any positional arguments.
 
 \item {} 

Modified: python/branches/p3yk/Doc/lib/libos.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libos.tex	(original)
+++ python/branches/p3yk/Doc/lib/libos.tex	Fri Apr 27 21:54:29 2007
@@ -1233,7 +1233,8 @@
 \end{funcdesc}
 
 \begin{funcdesc}{walk}{top\optional{, topdown\code{=True}
-                       \optional{, onerror\code{=None}}}}
+                       \optional{, onerror\code{=None}\optional{,
+		       followlinks\code{=False}}}}}
 \index{directory!walking}
 \index{directory!traversal}
 \function{walk()} generates the file names in a directory tree, by
@@ -1273,6 +1274,18 @@
 to abort the walk.  Note that the filename is available as the
 \code{filename} attribute of the exception object.
 
+By default, \function{walk()} will not walk down into symbolic links that
+resolve to directories. Set \var{followlinks} to True to visit directories
+pointed to by symlinks, on systems that support them.
+
+\versionadded[The \var{followlinks} parameter]{2.6}
+
+\begin{notice}
+Be aware that setting \var{followlinks} to true can lead to infinite recursion
+if a link points to a parent directory of itself. \function{walk()} does not
+keep track of the directories it visited already.
+\end{notice}
+
 \begin{notice}
 If you pass a relative pathname, don't change the current working
 directory between resumptions of \function{walk()}.  \function{walk()}
@@ -1280,15 +1293,6 @@
 doesn't either.
 \end{notice}
 
-\begin{notice}
-On systems that support symbolic links, links to subdirectories appear
-in \var{dirnames} lists, but \function{walk()} will not visit them
-(infinite loops are hard to avoid when following symbolic links).
-To visit linked directories, you can identify them with
-\code{os.path.islink(\var{path})}, and invoke \code{walk(\var{path})}
-on each directly.
-\end{notice}
-
 This example displays the number of bytes taken by non-directory files
 in each directory under the starting directory, except that it doesn't
 look under any CVS subdirectory:

Modified: python/branches/p3yk/Doc/lib/libpdb.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libpdb.tex	(original)
+++ python/branches/p3yk/Doc/lib/libpdb.tex	Fri Apr 27 21:54:29 2007
@@ -378,6 +378,14 @@
 (Pdb)
 \end{verbatim}
 
+\item[run \optional{\var{args} ...}]
+Restart the debugged python program. If an argument is supplied, it is
+splitted with "shlex" and the result is used as the new sys.argv.
+History, breakpoints, actions and debugger options are preserved.
+"restart" is an alias for "run".
+
+\versionadded{2.6}
+
 \item[q(uit)]
 
 Quit from the debugger.

Modified: python/branches/p3yk/Doc/lib/libpipes.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libpipes.tex	(original)
+++ python/branches/p3yk/Doc/lib/libpipes.tex	Fri Apr 27 21:54:29 2007
@@ -39,21 +39,21 @@
 
 Template objects following methods:
 
-\begin{methoddesc}{reset}{}
+\begin{methoddesc}[Template]{reset}{}
 Restore a pipeline template to its initial state.
 \end{methoddesc}
 
-\begin{methoddesc}{clone}{}
+\begin{methoddesc}[Template]{clone}{}
 Return a new, equivalent, pipeline template.
 \end{methoddesc}
 
-\begin{methoddesc}{debug}{flag}
+\begin{methoddesc}[Template]{debug}{flag}
 If \var{flag} is true, turn debugging on. Otherwise, turn debugging
 off. When debugging is on, commands to be executed are printed, and
 the shell is given \code{set -x} command to be more verbose.
 \end{methoddesc}
 
-\begin{methoddesc}{append}{cmd, kind}
+\begin{methoddesc}[Template]{append}{cmd, kind}
 Append a new action at the end. The \var{cmd} variable must be a valid
 bourne shell command. The \var{kind} variable consists of two letters.
 
@@ -68,17 +68,17 @@
 the command does not write anything, and hence must be last.)
 \end{methoddesc}
 
-\begin{methoddesc}{prepend}{cmd, kind}
+\begin{methoddesc}[Template]{prepend}{cmd, kind}
 Add a new action at the beginning. See \method{append()} for explanations
 of the arguments.
 \end{methoddesc}
 
-\begin{methoddesc}{open}{file, mode}
+\begin{methoddesc}[Template]{open}{file, mode}
 Return a file-like object, open to \var{file}, but read from or
 written to by the pipeline.  Note that only one of \code{'r'},
 \code{'w'} may be given.
 \end{methoddesc}
 
-\begin{methoddesc}{copy}{infile, outfile}
+\begin{methoddesc}[Template]{copy}{infile, outfile}
 Copy \var{infile} to \var{outfile} through the pipe.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libplatform.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libplatform.tex	(original)
+++ python/branches/p3yk/Doc/lib/libplatform.tex	Fri Apr 27 21:54:29 2007
@@ -80,6 +80,22 @@
   Returns a string identifying the compiler used for compiling Python.
 \end{funcdesc}
 
+\begin{funcdesc}{python_branch}{}
+  Returns a string identifying the Python implementation SCM branch.
+  \versionadded{2.6}
+\end{funcdesc}
+
+\begin{funcdesc}{python_implementation}{}
+  Returns a string identifying the Python implementation.
+  Possible return values are: 'CPython', 'IronPython', 'Jython'
+  \versionadded{2.6}
+\end{funcdesc}
+
+\begin{funcdesc}{python_revision}{}
+  Returns a string identifying the Python implementation SCM revision.
+  \versionadded{2.6}
+\end{funcdesc}
+
 \begin{funcdesc}{python_version}{}
   Returns the Python version as string \code{'major.minor.patchlevel'}
 
@@ -205,6 +221,7 @@
   which defaults to the args given as parameters.
 \end{funcdesc}
 
+% Document linux_distribution()?
 
 \begin{funcdesc}{libc_ver}{executable=sys.executable, lib='',
                            version='', chunksize=2048}

Modified: python/branches/p3yk/Doc/lib/libpopen2.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libpopen2.tex	(original)
+++ python/branches/p3yk/Doc/lib/libpopen2.tex	Fri Apr 27 21:54:29 2007
@@ -2,7 +2,6 @@
          Subprocesses with accessible I/O streams}
 
 \declaremodule{standard}{popen2}
-  \platform{Unix, Windows}
 \modulesynopsis{Subprocesses with accessible standard I/O streams.}
 \sectionauthor{Drew Csillag}{drew_csillag at geocities.com}
 
@@ -85,12 +84,12 @@
 Instances of the \class{Popen3} and \class{Popen4} classes have the
 following methods:
 
-\begin{methoddesc}{poll}{}
+\begin{methoddesc}[Popen3]{poll}{}
 Returns \code{-1} if child process hasn't completed yet, or its return 
 code otherwise.
 \end{methoddesc}
 
-\begin{methoddesc}{wait}{}
+\begin{methoddesc}[Popen3]{wait}{}
 Waits for and returns the status code of the child process.  The
 status code encodes both the return code of the process and
 information about whether it exited using the \cfunction{exit()}
@@ -102,24 +101,24 @@
 
 The following attributes are also available: 
 
-\begin{memberdesc}{fromchild}
+\begin{memberdesc}[Popen3]{fromchild}
 A file object that provides output from the child process.  For
 \class{Popen4} instances, this will provide both the standard output
 and standard error streams.
 \end{memberdesc}
 
-\begin{memberdesc}{tochild}
+\begin{memberdesc}[Popen3]{tochild}
 A file object that provides input to the child process.
 \end{memberdesc}
 
-\begin{memberdesc}{childerr}
+\begin{memberdesc}[Popen3]{childerr}
 A file object that provides error output from the child process, if
 \var{capturestderr} was true for the constructor, otherwise
 \code{None}.  This will always be \code{None} for \class{Popen4}
 instances.
 \end{memberdesc}
 
-\begin{memberdesc}{pid}
+\begin{memberdesc}[Popen3]{pid}
 The process ID of the child process.
 \end{memberdesc}
 

Modified: python/branches/p3yk/Doc/lib/libpoplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libpoplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libpoplib.tex	Fri Apr 27 21:54:29 2007
@@ -23,15 +23,18 @@
 Note that POP3, though widely supported, is obsolescent.  The
 implementation quality of POP3 servers varies widely, and too many are
 quite poor. If your mailserver supports IMAP, you would be better off
-using the \code{\refmodule{imaplib}.\class{IMAP4}} class, as IMAP
+using the \class{\refmodule{imaplib}.IMAP4} class, as IMAP
 servers tend to be better implemented.
 
 A single class is provided by the \module{poplib} module:
 
-\begin{classdesc}{POP3}{host\optional{, port}}
+\begin{classdesc}{POP3}{host\optional{, port\optional{, timeout}}}
 This class implements the actual POP3 protocol.  The connection is
 created when the instance is initialized.
 If \var{port} is omitted, the standard POP3 port (110) is used.
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if not specified, or passed as None, the global default
+timeout setting will be used).
 \end{classdesc}
 
 \begin{classdesc}{POP3_SSL}{host\optional{, port\optional{, keyfile\optional{, certfile}}}}
@@ -47,8 +50,9 @@
 One exception is defined as an attribute of the \module{poplib} module:
 
 \begin{excdesc}{error_proto}
-Exception raised on any errors.  The reason for the exception is
-passed to the constructor as a string.
+Exception raised on any errors from this module (errors from
+\module{socket} module are not caught). The reason for the exception
+is passed to the constructor as a string.
 \end{excdesc}
 
 \begin{seealso}
@@ -70,7 +74,7 @@
 An \class{POP3} instance has the following methods:
 
 
-\begin{methoddesc}{set_debuglevel}{level}
+\begin{methoddesc}[POP3]{set_debuglevel}{level}
 Set the instance's debugging level.  This controls the amount of
 debugging output printed.  The default, \code{0}, produces no
 debugging output.  A value of \code{1} produces a moderate amount of
@@ -79,64 +83,64 @@
 logging each line sent and received on the control connection.
 \end{methoddesc}
 
-\begin{methoddesc}{getwelcome}{}
+\begin{methoddesc}[POP3]{getwelcome}{}
 Returns the greeting string sent by the POP3 server.
 \end{methoddesc}
 
-\begin{methoddesc}{user}{username}
+\begin{methoddesc}[POP3]{user}{username}
 Send user command, response should indicate that a password is required.
 \end{methoddesc}
 
-\begin{methoddesc}{pass_}{password}
+\begin{methoddesc}[POP3]{pass_}{password}
 Send password, response includes message count and mailbox size.
 Note: the mailbox on the server is locked until \method{quit()} is
 called.
 \end{methoddesc}
 
-\begin{methoddesc}{apop}{user, secret}
+\begin{methoddesc}[POP3]{apop}{user, secret}
 Use the more secure APOP authentication to log into the POP3 server.
 \end{methoddesc}
 
-\begin{methoddesc}{rpop}{user}
+\begin{methoddesc}[POP3]{rpop}{user}
 Use RPOP authentication (similar to UNIX r-commands) to log into POP3 server.
 \end{methoddesc}
 
-\begin{methoddesc}{stat}{}
+\begin{methoddesc}[POP3]{stat}{}
 Get mailbox status.  The result is a tuple of 2 integers:
 \code{(\var{message count}, \var{mailbox size})}.
 \end{methoddesc}
 
-\begin{methoddesc}{list}{\optional{which}}
+\begin{methoddesc}[POP3]{list}{\optional{which}}
 Request message list, result is in the form
 \code{(\var{response}, ['mesg_num octets', ...], \var{octets})}.
 If \var{which} is set, it is the message to list.
 \end{methoddesc}
 
-\begin{methoddesc}{retr}{which}
+\begin{methoddesc}[POP3]{retr}{which}
 Retrieve whole message number \var{which}, and set its seen flag.
 Result is in form  \code{(\var{response}, ['line', ...], \var{octets})}.
 \end{methoddesc}
 
-\begin{methoddesc}{dele}{which}
+\begin{methoddesc}[POP3]{dele}{which}
 Flag message number \var{which} for deletion.  On most servers
 deletions are not actually performed until QUIT (the major exception is
 Eudora QPOP, which deliberately violates the RFCs by doing pending
 deletes on any disconnect).
 \end{methoddesc}
 
-\begin{methoddesc}{rset}{}
+\begin{methoddesc}[POP3]{rset}{}
 Remove any deletion marks for the mailbox.
 \end{methoddesc}
 
-\begin{methoddesc}{noop}{}
+\begin{methoddesc}[POP3]{noop}{}
 Do nothing.  Might be used as a keep-alive.
 \end{methoddesc}
 
-\begin{methoddesc}{quit}{}
+\begin{methoddesc}[POP3]{quit}{}
 Signoff:  commit changes, unlock mailbox, drop connection.
 \end{methoddesc}
 
-\begin{methoddesc}{top}{which, howmuch}
+\begin{methoddesc}[POP3]{top}{which, howmuch}
 Retrieves the message header plus \var{howmuch} lines of the message
 after the header of message number \var{which}. Result is in form
 \code{(\var{response}, ['line', ...], \var{octets})}.
@@ -148,7 +152,7 @@
 trusting it.
 \end{methoddesc}
 
-\begin{methoddesc}{uidl}{\optional{which}}
+\begin{methoddesc}[POP3]{uidl}{\optional{which}}
 Return message digest (unique id) list.
 If \var{which} is specified, result contains the unique id for that
 message in the form \code{'\var{response}\ \var{mesgnum}\ \var{uid}},

Modified: python/branches/p3yk/Doc/lib/libposixfile.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libposixfile.tex	(original)
+++ python/branches/p3yk/Doc/lib/libposixfile.tex	Fri Apr 27 21:54:29 2007
@@ -62,8 +62,7 @@
 
 The posixfile object defines the following additional methods:
 
-\setindexsubitem{(posixfile method)}
-\begin{funcdesc}{lock}{fmt, \optional{len\optional{, start\optional{, whence}}}}
+\begin{methoddesc}[posixfile]{lock}{fmt, \optional{len\optional{, start\optional{, whence}}}}
  Lock the specified section of the file that the file object is
  referring to.  The format is explained
  below in a table.  The \var{len} argument specifies the length of the
@@ -74,9 +73,9 @@
  \constant{SEEK_CUR} or \constant{SEEK_END}.  The default is
  \constant{SEEK_SET}.  For more information about the arguments refer
  to the \manpage{fcntl}{2} manual page on your system.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{flags}{\optional{flags}}
+\begin{methoddesc}[posixfile]{flags}{\optional{flags}}
  Set the specified flags for the file that the file object is referring
  to.  The new flags are ORed with the old flags, unless specified
  otherwise.  The format is explained below in a table.  Without
@@ -84,25 +83,25 @@
  a string indicating the current flags is returned (this is
  the same as the \samp{?} modifier).  For more information about the
  flags refer to the \manpage{fcntl}{2} manual page on your system.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{dup}{}
+\begin{methoddesc}[posixfile]{dup}{}
  Duplicate the file object and the underlying file pointer and file
  descriptor.  The resulting object behaves as if it were newly
  opened.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{dup2}{fd}
+\begin{methoddesc}[posixfile]{dup2}{fd}
  Duplicate the file object and the underlying file pointer and file
  descriptor.  The new object will have the given file descriptor.
  Otherwise the resulting object behaves as if it were newly opened.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{file}{}
+\begin{methoddesc}[posixfile]{file}{}
  Return the standard file object that the posixfile object is based
  on.  This is sometimes necessary for functions that insist on a
  standard file object.
-\end{funcdesc}
+\end{methoddesc}
 
 All methods raise \exception{IOError} when the request fails.
 

Modified: python/branches/p3yk/Doc/lib/libposixpath.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libposixpath.tex	(original)
+++ python/branches/p3yk/Doc/lib/libposixpath.tex	Fri Apr 27 21:54:29 2007
@@ -58,18 +58,20 @@
 \end{funcdesc}
 
 \begin{funcdesc}{expanduser}{path}
-On \UNIX, return the argument with an initial component of \samp{\~} or
-\samp{\~\var{user}} replaced by that \var{user}'s home directory.
-An initial \samp{\~} is replaced by the environment variable
+On \UNIX{} and Windows, return the argument with an initial component of
+\samp{\~} or \samp{\~\var{user}} replaced by that \var{user}'s home directory.
+
+On \UNIX, an initial \samp{\~} is replaced by the environment variable
 \envvar{HOME} if it is set; otherwise the current user's home directory
 is looked up in the password directory through the built-in module
 \refmodule{pwd}\refbimodindex{pwd}.
 An initial \samp{\~\var{user}} is looked up directly in the
 password directory.
 
-On Windows, only \samp{\~} is supported; it is replaced by the
-environment variable \envvar{HOME} or by a combination of
-\envvar{HOMEDRIVE} and \envvar{HOMEPATH}.
+On Windows, \envvar{HOME} and \envvar{USERPROFILE} will be used if set,
+otherwise a combination of \envvar{HOMEPATH} and \envvar{HOMEDRIVE} will be
+used.  An initial \samp{\~\var{user}} is handled by stripping the last
+directory component from the created user path derived above.
 
 If the expansion fails or if the
 path does not begin with a tilde, the path is returned unchanged.
@@ -81,6 +83,9 @@
 replaced by the value of environment variable \var{name}.  Malformed
 variable names and references to non-existing variables are left
 unchanged.
+
+On Windows, \samp{\%\var{name}\%} expansions are supported in addition to
+\samp{\$\var{name}} and \samp{\$\{\var{name}\}}.
 \end{funcdesc}
 
 \begin{funcdesc}{getatime}{path}
@@ -184,6 +189,15 @@
 \versionadded{2.2}
 \end{funcdesc}
 
+\begin{funcdesc}{relpath}{path\optional{, start}}
+Return a relative filepath to \var{path} either from the current
+directory or from an optional \var{start} point.
+
+\var{start} defaults to \member{os.curdir}.
+Availability:  Windows, \UNIX.
+\versionadded{2.6}
+\end{funcdesc}
+
 \begin{funcdesc}{samefile}{path1, path2}
 Return \code{True} if both pathname arguments refer to the same file or
 directory (as indicated by device number and i-node number).
@@ -234,7 +248,12 @@
 Split the pathname \var{path} into a pair \code{(\var{root}, \var{ext})} 
 such that \code{\var{root} + \var{ext} == \var{path}},
 and \var{ext} is empty or begins with a period and contains
-at most one period.
+at most one period. Leading periods on the basename are 
+ignored; \code{\var{splitext}.('.cshrc')} returns 
+\code{('.cshrc', '')}.
+
+\versionchanged[Earlier versions could produce an empty root when
+the only period was the first character]{2.6}
 \end{funcdesc}
 
 \begin{funcdesc}{splitunc}{path}

Modified: python/branches/p3yk/Doc/lib/libpprint.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libpprint.tex	(original)
+++ python/branches/p3yk/Doc/lib/libpprint.tex	Fri Apr 27 21:54:29 2007
@@ -158,12 +158,12 @@
 \class{PrettyPrinter} instances have the following methods:
 
 
-\begin{methoddesc}{pformat}{object}
+\begin{methoddesc}[PrettyPrinter]{pformat}{object}
 Return the formatted representation of \var{object}.  This takes into
 account the options passed to the \class{PrettyPrinter} constructor.
 \end{methoddesc}
 
-\begin{methoddesc}{pprint}{object}
+\begin{methoddesc}[PrettyPrinter]{pprint}{object}
 Print the formatted representation of \var{object} on the configured
 stream, followed by a newline.
 \end{methoddesc}
@@ -173,7 +173,7 @@
 instance is slightly more efficient since new \class{PrettyPrinter}
 objects don't need to be created.
 
-\begin{methoddesc}{isreadable}{object}
+\begin{methoddesc}[PrettyPrinter]{isreadable}{object}
 Determine if the formatted representation of the object is
 ``readable,'' or can be used to reconstruct the value using
 \function{eval()}\bifuncindex{eval}.  Note that this returns false for
@@ -182,7 +182,7 @@
 this returns false.
 \end{methoddesc}
 
-\begin{methoddesc}{isrecursive}{object}
+\begin{methoddesc}[PrettyPrinter]{isrecursive}{object}
 Determine if the object requires a recursive representation.
 \end{methoddesc}
 
@@ -190,7 +190,7 @@
 way objects are converted to strings.  The default implementation uses
 the internals of the \function{saferepr()} implementation.
 
-\begin{methoddesc}{format}{object, context, maxlevels, level}
+\begin{methoddesc}[PrettyPrinter]{format}{object, context, maxlevels, level}
 Returns three values: the formatted version of \var{object} as a
 string, a flag indicating whether the result is readable, and a flag
 indicating whether recursion was detected.  The first argument is the

Modified: python/branches/p3yk/Doc/lib/libqueue.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libqueue.tex	(original)
+++ python/branches/p3yk/Doc/lib/libqueue.tex	Fri Apr 27 21:54:29 2007
@@ -45,22 +45,22 @@
 is not described here.  See the source code for details.  The public
 methods are:
 
-\begin{methoddesc}{qsize}{}
+\begin{methoddesc}[Queue]{qsize}{}
 Return the approximate size of the queue.  Because of multithreading
 semantics, this number is not reliable.
 \end{methoddesc}
 
-\begin{methoddesc}{empty}{}
+\begin{methoddesc}[Queue]{empty}{}
 Return \code{True} if the queue is empty, \code{False} otherwise.
 Because of multithreading semantics, this is not reliable.
 \end{methoddesc}
 
-\begin{methoddesc}{full}{}
+\begin{methoddesc}[Queue]{full}{}
 Return \code{True} if the queue is full, \code{False} otherwise.
 Because of multithreading semantics, this is not reliable.
 \end{methoddesc}
 
-\begin{methoddesc}{put}{item\optional{, block\optional{, timeout}}}
+\begin{methoddesc}[Queue]{put}{item\optional{, block\optional{, timeout}}}
 Put \var{item} into the queue. If optional args \var{block} is true
 and \var{timeout} is None (the default), block if necessary until a
 free slot is available. If \var{timeout} is a positive number, it
@@ -74,11 +74,11 @@
 
 \end{methoddesc}
 
-\begin{methoddesc}{put_nowait}{item}
+\begin{methoddesc}[Queue]{put_nowait}{item}
 Equivalent to \code{put(\var{item}, False)}.
 \end{methoddesc}
 
-\begin{methoddesc}{get}{\optional{block\optional{, timeout}}}
+\begin{methoddesc}[Queue]{get}{\optional{block\optional{, timeout}}}
 Remove and return an item from the queue. If optional args
 \var{block} is true and \var{timeout} is None (the default),
 block if necessary until an item is available. If \var{timeout} is
@@ -92,14 +92,14 @@
 
 \end{methoddesc}
 
-\begin{methoddesc}{get_nowait}{}
+\begin{methoddesc}[Queue]{get_nowait}{}
 Equivalent to \code{get(False)}.
 \end{methoddesc}
 
 Two methods are offered to support tracking whether enqueued tasks have
 been fully processed by daemon consumer threads.
 
-\begin{methoddesc}{task_done}{}
+\begin{methoddesc}[Queue]{task_done}{}
 Indicate that a formerly enqueued task is complete.  Used by queue consumer
 threads.  For each \method{get()} used to fetch a task, a subsequent call to
 \method{task_done()} tells the queue that the processing on the task is complete.
@@ -113,7 +113,7 @@
 \versionadded{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}{join}{}
+\begin{methoddesc}[Queue]{join}{}
 Blocks until all items in the queue have been gotten and processed.
 
 The count of unfinished tasks goes up whenever an item is added to the

Modified: python/branches/p3yk/Doc/lib/libre.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libre.tex	(original)
+++ python/branches/p3yk/Doc/lib/libre.tex	Fri Apr 27 21:54:29 2007
@@ -812,7 +812,7 @@
 \end{methoddesc}
 
 \begin{methoddesc}[MatchObject]{start}{\optional{group}}
-\methodline{end}{\optional{group}}
+\methodline[MatchObject]{end}{\optional{group}}
 Return the indices of the start and end of the substring
 matched by \var{group}; \var{group} defaults to zero (meaning the whole
 matched substring).

Modified: python/branches/p3yk/Doc/lib/librepr.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/librepr.tex	(original)
+++ python/branches/p3yk/Doc/lib/librepr.tex	Fri Apr 27 21:54:29 2007
@@ -44,18 +44,18 @@
 and methods which format specific object types.
 
 
-\begin{memberdesc}{maxlevel}
+\begin{memberdesc}[Repr]{maxlevel}
   Depth limit on the creation of recursive representations.  The
   default is \code{6}.
 \end{memberdesc}
 
-\begin{memberdesc}{maxdict}
-\memberline{maxlist}
-\memberline{maxtuple}
-\memberline{maxset}
-\memberline{maxfrozenset}
-\memberline{maxdeque}
-\memberline{maxarray}
+\begin{memberdesc}[Repr]{maxdict}
+\memberline[Repr]{maxlist}
+\memberline[Repr]{maxtuple}
+\memberline[Repr]{maxset}
+\memberline[Repr]{maxfrozenset}
+\memberline[Repr]{maxdeque}
+\memberline[Repr]{maxarray}
   Limits on the number of entries represented for the named object
   type.  The default is \code{4} for \member{maxdict}, \code{5} for
   \member{maxarray}, and  \code{6} for the others.
@@ -63,13 +63,13 @@
   and \member{set}]{2.4}.
 \end{memberdesc}
 
-\begin{memberdesc}{maxlong}
+\begin{memberdesc}[Repr]{maxlong}
   Maximum number of characters in the representation for a long
   integer.  Digits are dropped from the middle.  The default is
   \code{40}.
 \end{memberdesc}
 
-\begin{memberdesc}{maxstring}
+\begin{memberdesc}[Repr]{maxstring}
   Limit on the number of characters in the representation of the
   string.  Note that the ``normal'' representation of the string is
   used as the character source: if escape sequences are needed in the
@@ -77,19 +77,19 @@
   shortened.  The default is \code{30}.
 \end{memberdesc}
 
-\begin{memberdesc}{maxother}
+\begin{memberdesc}[Repr]{maxother}
   This limit is used to control the size of object types for which no
   specific formatting method is available on the \class{Repr} object.
   It is applied in a similar manner as \member{maxstring}.  The
   default is \code{20}.
 \end{memberdesc}
 
-\begin{methoddesc}{repr}{obj}
+\begin{methoddesc}[Repr]{repr}{obj}
   The equivalent to the built-in \function{repr()} that uses the
   formatting imposed by the instance.
 \end{methoddesc}
 
-\begin{methoddesc}{repr1}{obj, level}
+\begin{methoddesc}[Repr]{repr1}{obj, level}
   Recursive implementation used by \method{repr()}.  This uses the
   type of \var{obj} to determine which formatting method to call,
   passing it \var{obj} and \var{level}.  The type-specific methods
@@ -98,7 +98,7 @@
   call.
 \end{methoddesc}
 
-\begin{methoddescni}{repr_\var{type}}{obj, level}
+\begin{methoddescni}[Repr]{repr_\var{type}}{obj, level}
   Formatting methods for specific types are implemented as methods
   with a name based on the type name.  In the method name, \var{type}
   is replaced by

Modified: python/branches/p3yk/Doc/lib/librexec.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/librexec.tex	(original)
+++ python/branches/p3yk/Doc/lib/librexec.tex	Fri Apr 27 21:54:29 2007
@@ -89,20 +89,20 @@
 
 \class{RExec} instances support the following methods:
 
-\begin{methoddesc}{r_eval}{code}
+\begin{methoddesc}[RExec]{r_eval}{code}
 \var{code} must either be a string containing a Python expression, or
 a compiled code object, which will be evaluated in the restricted
 environment's \module{__main__} module.  The value of the expression or
 code object will be returned.
 \end{methoddesc}
 
-\begin{methoddesc}{r_exec}{code}
+\begin{methoddesc}[RExec]{r_exec}{code}
 \var{code} must either be a string containing one or more lines of
 Python code, or a compiled code object, which will be executed in the
 restricted environment's \module{__main__} module.
 \end{methoddesc}
 
-\begin{methoddesc}{r_execfile}{filename}
+\begin{methoddesc}[RExec]{r_execfile}{filename}
 Execute the Python code contained in the file \var{filename} in the
 restricted environment's \module{__main__} module.
 \end{methoddesc}
@@ -112,17 +112,17 @@
 restricted versions of the standard I/O streams \code{sys.stdin},
 \code{sys.stderr}, and \code{sys.stdout}.
 
-\begin{methoddesc}{s_eval}{code}
+\begin{methoddesc}[RExec]{s_eval}{code}
 \var{code} must be a string containing a Python expression, which will
 be evaluated in the restricted environment.  
 \end{methoddesc}
 
-\begin{methoddesc}{s_exec}{code}
+\begin{methoddesc}[RExec]{s_exec}{code}
 \var{code} must be a string containing one or more lines of Python code,
 which will be executed in the restricted environment.  
 \end{methoddesc}
 
-\begin{methoddesc}{s_execfile}{code}
+\begin{methoddesc}[RExec]{s_execfile}{code}
 Execute the Python code contained in the file \var{filename} in the
 restricted environment.
 \end{methoddesc}
@@ -132,13 +132,13 @@
 Overriding these methods in a subclass is used to change the policies
 enforced by a restricted environment.
 
-\begin{methoddesc}{r_import}{modulename\optional{, globals\optional{,
-                             locals\optional{, fromlist}}}}
+\begin{methoddesc}[RExec]{r_import}{modulename\optional{, globals\optional{,
+                                    locals\optional{, fromlist}}}}
 Import the module \var{modulename}, raising an \exception{ImportError}
 exception if the module is considered unsafe.
 \end{methoddesc}
 
-\begin{methoddesc}{r_open}{filename\optional{, mode\optional{, bufsize}}}
+\begin{methoddesc}[RExec]{r_open}{filename\optional{, mode\optional{, bufsize}}}
 Method called when \function{open()} is called in the restricted
 environment.  The arguments are identical to those of \function{open()},
 and a file object (or a class instance compatible with file objects)
@@ -148,28 +148,28 @@
 \method{r_open()}.
 \end{methoddesc}
 
-\begin{methoddesc}{r_reload}{module}
+\begin{methoddesc}[RExec]{r_reload}{module}
 Reload the module object \var{module}, re-parsing and re-initializing it.  
 \end{methoddesc}
 
-\begin{methoddesc}{r_unload}{module}
+\begin{methoddesc}[RExec]{r_unload}{module}
 Unload the module object \var{module} (remove it from the
 restricted environment's \code{sys.modules} dictionary).
 \end{methoddesc}
 
 And their equivalents with access to restricted standard I/O streams:
 
-\begin{methoddesc}{s_import}{modulename\optional{, globals\optional{,
-                             locals\optional{, fromlist}}}}
+\begin{methoddesc}[RExec]{s_import}{modulename\optional{, globals\optional{,
+                                    locals\optional{, fromlist}}}}
 Import the module \var{modulename}, raising an \exception{ImportError}
 exception if the module is considered unsafe.
 \end{methoddesc}
 
-\begin{methoddesc}{s_reload}{module}
+\begin{methoddesc}[RExec]{s_reload}{module}
 Reload the module object \var{module}, re-parsing and re-initializing it.  
 \end{methoddesc}
 
-\begin{methoddesc}{s_unload}{module}
+\begin{methoddesc}[RExec]{s_unload}{module}
 Unload the module object \var{module}.   
 % XXX what are the semantics of this?  
 \end{methoddesc}
@@ -184,7 +184,7 @@
 Instances of the new class will then use those new values.  All these
 attributes are tuples of strings.
 
-\begin{memberdesc}{nok_builtin_names}
+\begin{memberdesc}[RExec]{nok_builtin_names}
 Contains the names of built-in functions which will \emph{not} be
 available to programs running in the restricted environment.  The
 value for \class{RExec} is \code{('open', 'reload', '__import__')}.
@@ -196,7 +196,7 @@
 this module.)
 \end{memberdesc}
 
-\begin{memberdesc}{ok_builtin_modules}
+\begin{memberdesc}[RExec]{ok_builtin_modules}
 Contains the names of built-in modules which can be safely imported.
 The value for \class{RExec} is \code{('audioop', 'array', 'binascii',
 'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator',
@@ -205,14 +205,14 @@
 applies --- use the value from the base class as a starting point.
 \end{memberdesc}
 
-\begin{memberdesc}{ok_path}
+\begin{memberdesc}[RExec]{ok_path}
 Contains the directories which will be searched when an \keyword{import}
 is performed in the restricted environment.  
 The value for \class{RExec} is the same as \code{sys.path} (at the time
 the module is loaded) for unrestricted code.
 \end{memberdesc}
 
-\begin{memberdesc}{ok_posix_names}
+\begin{memberdesc}[RExec]{ok_posix_names}
 % Should this be called ok_os_names?
 Contains the names of the functions in the \refmodule{os} module which will be
 available to programs running in the restricted environment.  The
@@ -221,14 +221,14 @@
 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')}.
 \end{memberdesc}
 
-\begin{memberdesc}{ok_sys_names}
+\begin{memberdesc}[RExec]{ok_sys_names}
 Contains the names of the functions and variables in the \refmodule{sys}
 module which will be available to programs running in the restricted
 environment.  The value for \class{RExec} is \code{('ps1', 'ps2',
 'copyright', 'version', 'platform', 'exit', 'maxint')}.
 \end{memberdesc}
 
-\begin{memberdesc}{ok_file_types}
+\begin{memberdesc}[RExec]{ok_file_types}
 Contains the file types from which modules are allowed to be loaded.
 Each file type is an integer constant defined in the \refmodule{imp} module.
 The meaningful values are \constant{PY_SOURCE}, \constant{PY_COMPILED}, and

Modified: python/branches/p3yk/Doc/lib/librfc822.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/librfc822.tex	(original)
+++ python/branches/p3yk/Doc/lib/librfc822.tex	Fri Apr 27 21:54:29 2007
@@ -100,7 +100,7 @@
 \code{'Mon, 20 Nov 1995 19:12:08 -0500'}.  If it succeeds in parsing
 the date, \function{parsedate()} returns a 9-tuple that can be passed
 directly to \function{time.mktime()}; otherwise \code{None} will be
-returned.  Note that fields 6, 7, and 8 of the result tuple are not
+returned.  Note that indexes 6, 7, and 8 of the result tuple are not
 usable.
 \end{funcdesc}
 
@@ -114,7 +114,7 @@
 variable for the same timezone; the latter variable follows the
 \POSIX{} standard while this module follows \rfc{2822}.)  If the input
 string has no timezone, the last element of the tuple returned is
-\code{None}.  Note that fields 6, 7, and 8 of the result tuple are not
+\code{None}.  Note that indexes 6, 7, and 8 of the result tuple are not
 usable.
 \end{funcdesc}
 
@@ -142,12 +142,12 @@
 
 A \class{Message} instance has the following methods:
 
-\begin{methoddesc}{rewindbody}{}
+\begin{methoddesc}[Message]{rewindbody}{}
 Seek to the start of the message body.  This only works if the file
 object is seekable.
 \end{methoddesc}
 
-\begin{methoddesc}{isheader}{line}
+\begin{methoddesc}[Message]{isheader}{line}
 Returns a line's canonicalized fieldname (the dictionary key that will
 be used to index it) if the line is a legal \rfc{2822} header; otherwise
 returns \code{None} (implying that parsing should stop here and the
@@ -155,33 +155,33 @@
 override this method in a subclass.
 \end{methoddesc}
 
-\begin{methoddesc}{islast}{line}
+\begin{methoddesc}[Message]{islast}{line}
 Return true if the given line is a delimiter on which Message should
 stop.  The delimiter line is consumed, and the file object's read
 location positioned immediately after it.  By default this method just
 checks that the line is blank, but you can override it in a subclass.
 \end{methoddesc}
 
-\begin{methoddesc}{iscomment}{line}
+\begin{methoddesc}[Message]{iscomment}{line}
 Return \code{True} if the given line should be ignored entirely, just skipped.
 By default this is a stub that always returns \code{False}, but you can
 override it in a subclass.
 \end{methoddesc}
 
-\begin{methoddesc}{getallmatchingheaders}{name}
+\begin{methoddesc}[Message]{getallmatchingheaders}{name}
 Return a list of lines consisting of all headers matching
 \var{name}, if any.  Each physical line, whether it is a continuation
 line or not, is a separate list item.  Return the empty list if no
 header matches \var{name}.
 \end{methoddesc}
 
-\begin{methoddesc}{getfirstmatchingheader}{name}
+\begin{methoddesc}[Message]{getfirstmatchingheader}{name}
 Return a list of lines comprising the first header matching
 \var{name}, and its continuation line(s), if any.  Return
 \code{None} if there is no header matching \var{name}.
 \end{methoddesc}
 
-\begin{methoddesc}{getrawheader}{name}
+\begin{methoddesc}[Message]{getrawheader}{name}
 Return a single string consisting of the text after the colon in the
 first header matching \var{name}.  This includes leading whitespace,
 the trailing linefeed, and internal linefeeds and whitespace if there
@@ -189,19 +189,19 @@
 no header matching \var{name}.
 \end{methoddesc}
 
-\begin{methoddesc}{getheader}{name\optional{, default}}
+\begin{methoddesc}[Message]{getheader}{name\optional{, default}}
 Like \code{getrawheader(\var{name})}, but strip leading and trailing
 whitespace.  Internal whitespace is not stripped.  The optional
 \var{default} argument can be used to specify a different default to
 be returned when there is no header matching \var{name}.
 \end{methoddesc}
 
-\begin{methoddesc}{get}{name\optional{, default}}
+\begin{methoddesc}[Message]{get}{name\optional{, default}}
 An alias for \method{getheader()}, to make the interface more compatible 
 with regular dictionaries.
 \end{methoddesc}
 
-\begin{methoddesc}{getaddr}{name}
+\begin{methoddesc}[Message]{getaddr}{name}
 Return a pair \code{(\var{full name}, \var{email address})} parsed
 from the string returned by \code{getheader(\var{name})}.  If no
 header matching \var{name} exists, return \code{(None, None)};
@@ -217,7 +217,7 @@
 exact same result.
 \end{methoddesc}
 
-\begin{methoddesc}{getaddrlist}{name}
+\begin{methoddesc}[Message]{getaddrlist}{name}
 This is similar to \code{getaddr(\var{list})}, but parses a header
 containing a list of email addresses (e.g.\ a \mailheader{To} header) and
 returns a list of \code{(\var{full name}, \var{email address})} pairs
@@ -229,7 +229,7 @@
 Any continuation lines the named headers contain are also parsed.
 \end{methoddesc}
 
-\begin{methoddesc}{getdate}{name}
+\begin{methoddesc}[Message]{getdate}{name}
 Retrieve a header using \method{getheader()} and parse it into a 9-tuple
 compatible with \function{time.mktime()}; note that fields 6, 7, and 8 
 are not usable.  If there is no header matching
@@ -241,7 +241,7 @@
 function may occasionally yield an incorrect result.
 \end{methoddesc}
 
-\begin{methoddesc}{getdate_tz}{name}
+\begin{methoddesc}[Message]{getdate_tz}{name}
 Retrieve a header using \method{getheader()} and parse it into a
 10-tuple; the first 9 elements will make a tuple compatible with
 \function{time.mktime()}, and the 10th is a number giving the offset
@@ -270,19 +270,19 @@
 
 Finally, \class{Message} instances have some public instance variables:
 
-\begin{memberdesc}{headers}
+\begin{memberdesc}[Message]{headers}
 A list containing the entire set of header lines, in the order in
 which they were read (except that setitem calls may disturb this
 order). Each line contains a trailing newline.  The
 blank line terminating the headers is not contained in the list.
 \end{memberdesc}
 
-\begin{memberdesc}{fp}
+\begin{memberdesc}[Message]{fp}
 The file or file-like object passed at instantiation time.  This can
 be used to read the message content.
 \end{memberdesc}
 
-\begin{memberdesc}{unixfrom}
+\begin{memberdesc}[Message]{unixfrom}
 The \UNIX{} \samp{From~} line, if the message had one, or an empty
 string.  This is needed to regenerate the message in some contexts,
 such as an \code{mbox}-style mailbox file.
@@ -293,34 +293,34 @@
 
 An \class{AddressList} instance has the following methods:
 
-\begin{methoddesc}{__len__}{}
+\begin{methoddesc}[AddressList]{__len__}{}
 Return the number of addresses in the address list.
 \end{methoddesc}
 
-\begin{methoddesc}{__str__}{}
+\begin{methoddesc}[AddressList]{__str__}{}
 Return a canonicalized string representation of the address list.
 Addresses are rendered in "name" <host at domain> form, comma-separated.
 \end{methoddesc}
 
-\begin{methoddesc}{__add__}{alist}
+\begin{methoddesc}[AddressList]{__add__}{alist}
 Return a new \class{AddressList} instance that contains all addresses
 in both \class{AddressList} operands, with duplicates removed (set
 union).
 \end{methoddesc}
 
-\begin{methoddesc}{__iadd__}{alist}
+\begin{methoddesc}[AddressList]{__iadd__}{alist}
 In-place version of \method{__add__()}; turns this \class{AddressList}
 instance into the union of itself and the right-hand instance,
 \var{alist}.
 \end{methoddesc}
 
-\begin{methoddesc}{__sub__}{alist}
+\begin{methoddesc}[AddressList]{__sub__}{alist}
 Return a new \class{AddressList} instance that contains every address
 in the left-hand \class{AddressList} operand that is not present in
 the right-hand address operand (set difference).
 \end{methoddesc}
 
-\begin{methoddesc}{__isub__}{alist}
+\begin{methoddesc}[AddressList]{__isub__}{alist}
 In-place version of \method{__sub__()}, removing addresses in this
 list which are also in \var{alist}.
 \end{methoddesc}
@@ -328,7 +328,7 @@
 
 Finally, \class{AddressList} instances have one public instance variable:
 
-\begin{memberdesc}{addresslist}
+\begin{memberdesc}[AddressList]{addresslist}
 A list of tuple string pairs, one per address.  In each member, the
 first is the canonicalized name part, the second is the
 actual route-address (\character{@}-separated username-host.domain

Modified: python/branches/p3yk/Doc/lib/libsched.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsched.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsched.tex	Fri Apr 27 21:54:29 2007
@@ -48,7 +48,7 @@
 
 \class{scheduler} instances have the following methods:
 
-\begin{methoddesc}{enterabs}{time, priority, action, argument}
+\begin{methoddesc}[scheduler]{enterabs}{time, priority, action, argument}
 Schedule a new event. The \var{time} argument should be a numeric type
 compatible with the return value of the \var{timefunc} function passed 
 to the constructor. Events scheduled for
@@ -63,23 +63,23 @@
 the event (see \method{cancel()}).
 \end{methoddesc}
 
-\begin{methoddesc}{enter}{delay, priority, action, argument}
+\begin{methoddesc}[scheduler]{enter}{delay, priority, action, argument}
 Schedule an event for \var{delay} more time units. Other then the
 relative time, the other arguments, the effect and the return value
 are the same as those for \method{enterabs()}.
 \end{methoddesc}
 
-\begin{methoddesc}{cancel}{event}
+\begin{methoddesc}[scheduler]{cancel}{event}
 Remove the event from the queue. If \var{event} is not an event
 currently in the queue, this method will raise a
 \exception{RuntimeError}.
 \end{methoddesc}
 
-\begin{methoddesc}{empty}{}
+\begin{methoddesc}[scheduler]{empty}{}
 Return true if the event queue is empty.
 \end{methoddesc}
 
-\begin{methoddesc}{run}{}
+\begin{methoddesc}[scheduler]{run}{}
 Run all scheduled events. This function will wait 
 (using the \function{delayfunc} function passed to the constructor)
 for the next event, then execute it and so on until there are no more

Modified: python/branches/p3yk/Doc/lib/libselect.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libselect.tex	(original)
+++ python/branches/p3yk/Doc/lib/libselect.tex	Fri Apr 27 21:54:29 2007
@@ -77,7 +77,7 @@
 \cfunction{select()} is O(highest file descriptor), while
 \cfunction{poll()} is O(number of file descriptors).
 
-\begin{methoddesc}{register}{fd\optional{, eventmask}}
+\begin{methoddesc}[poll]{register}{fd\optional{, eventmask}}
 Register a file descriptor with the polling object.  Future calls to
 the \method{poll()} method will then check whether the file descriptor
 has any pending I/O events.  \var{fd} can be either an integer, or an
@@ -105,7 +105,7 @@
 once.
 \end{methoddesc}
 
-\begin{methoddesc}{unregister}{fd}
+\begin{methoddesc}[poll]{unregister}{fd}
 Remove a file descriptor being tracked by a polling object.  Just like
 the \method{register()} method, \var{fd} can be an integer or an
 object with a \method{fileno()} method that returns an integer.
@@ -114,7 +114,7 @@
 causes a \exception{KeyError} exception to be raised.
 \end{methoddesc}
 
-\begin{methoddesc}{poll}{\optional{timeout}}
+\begin{methoddesc}[poll]{poll}{\optional{timeout}}
 Polls the set of registered file descriptors, and returns a
 possibly-empty list containing \code{(\var{fd}, \var{event})} 2-tuples
 for the descriptors that have events or errors to report.

Modified: python/branches/p3yk/Doc/lib/libshlex.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libshlex.tex	(original)
+++ python/branches/p3yk/Doc/lib/libshlex.tex	Fri Apr 27 21:54:29 2007
@@ -58,7 +58,7 @@
 
 A \class{shlex} instance has the following methods:
 
-\begin{methoddesc}{get_token}{}
+\begin{methoddesc}[shlex]{get_token}{}
 Return a token.  If tokens have been stacked using
 \method{push_token()}, pop a token off the stack.  Otherwise, read one
 from the input stream.  If reading encounters an immediate
@@ -66,17 +66,17 @@
 in non-\POSIX{} mode, and \code{None} in \POSIX{} mode).
 \end{methoddesc}
 
-\begin{methoddesc}{push_token}{str}
+\begin{methoddesc}[shlex]{push_token}{str}
 Push the argument onto the token stack.
 \end{methoddesc}
 
-\begin{methoddesc}{read_token}{}
+\begin{methoddesc}[shlex]{read_token}{}
 Read a raw token.  Ignore the pushback stack, and do not interpret source
 requests.  (This is not ordinarily a useful entry point, and is
 documented here only for the sake of completeness.)
 \end{methoddesc}
 
-\begin{methoddesc}{sourcehook}{filename}
+\begin{methoddesc}[shlex]{sourcehook}{filename}
 When \class{shlex} detects a source request (see
 \member{source} below) this method is given the following token as
 argument, and expected to return a tuple consisting of a filename and
@@ -106,7 +106,7 @@
 \method{push_source()} and \method{pop_source()} methods. 
 \end{methoddesc}
 
-\begin{methoddesc}{push_source}{stream\optional{, filename}}
+\begin{methoddesc}[shlex]{push_source}{stream\optional{, filename}}
 Push an input source stream onto the input stack.  If the filename
 argument is specified it will later be available for use in error
 messages.  This is the same method used internally by the
@@ -114,14 +114,14 @@
 \versionadded{2.1}
 \end{methoddesc}
 
-\begin{methoddesc}{pop_source}{}
+\begin{methoddesc}[shlex]{pop_source}{}
 Pop the last-pushed input source from the input stack.
 This is the same method used internally when the lexer reaches
 \EOF{} on a stacked input stream.
 \versionadded{2.1}
 \end{methoddesc}
 
-\begin{methoddesc}{error_leader}{\optional{file\optional{, line}}}
+\begin{methoddesc}[shlex]{error_leader}{\optional{file\optional{, line}}}
 This method generates an error message leader in the format of a
 \UNIX{} C compiler error label; the format is \code{'"\%s", line \%d: '},
 where the \samp{\%s} is replaced with the name of the current source
@@ -137,63 +137,63 @@
 variables which either control lexical analysis or can be used for
 debugging:
 
-\begin{memberdesc}{commenters}
+\begin{memberdesc}[shlex]{commenters}
 The string of characters that are recognized as comment beginners.
 All characters from the comment beginner to end of line are ignored.
 Includes just \character{\#} by default.   
 \end{memberdesc}
 
-\begin{memberdesc}{wordchars}
+\begin{memberdesc}[shlex]{wordchars}
 The string of characters that will accumulate into multi-character
 tokens.  By default, includes all \ASCII{} alphanumerics and
 underscore.
 \end{memberdesc}
 
-\begin{memberdesc}{whitespace}
+\begin{memberdesc}[shlex]{whitespace}
 Characters that will be considered whitespace and skipped.  Whitespace
 bounds tokens.  By default, includes space, tab, linefeed and
 carriage-return.
 \end{memberdesc}
 
-\begin{memberdesc}{escape}
+\begin{memberdesc}[shlex]{escape}
 Characters that will be considered as escape. This will be only used
 in \POSIX{} mode, and includes just \character{\textbackslash} by default.
 \versionadded{2.3}
 \end{memberdesc}
 
-\begin{memberdesc}{quotes}
+\begin{memberdesc}[shlex]{quotes}
 Characters that will be considered string quotes.  The token
 accumulates until the same quote is encountered again (thus, different
 quote types protect each other as in the shell.)  By default, includes
 \ASCII{} single and double quotes.
 \end{memberdesc}
 
-\begin{memberdesc}{escapedquotes}
+\begin{memberdesc}[shlex]{escapedquotes}
 Characters in \member{quotes} that will interpret escape characters
 defined in \member{escape}.  This is only used in \POSIX{} mode, and
 includes just \character{"} by default.
 \versionadded{2.3}
 \end{memberdesc}
 
-\begin{memberdesc}{whitespace_split}
+\begin{memberdesc}[shlex]{whitespace_split}
 If \code{True}, tokens will only be split in whitespaces. This is useful, for
 example, for parsing command lines with \class{shlex}, getting tokens
 in a similar way to shell arguments.
 \versionadded{2.3}
 \end{memberdesc}
 
-\begin{memberdesc}{infile}
+\begin{memberdesc}[shlex]{infile}
 The name of the current input file, as initially set at class
 instantiation time or stacked by later source requests.  It may
 be useful to examine this when constructing error messages.
 \end{memberdesc}
 
-\begin{memberdesc}{instream}
+\begin{memberdesc}[shlex]{instream}
 The input stream from which this \class{shlex} instance is reading
 characters.
 \end{memberdesc}
 
-\begin{memberdesc}{source}
+\begin{memberdesc}[shlex]{source}
 This member is \code{None} by default.  If you assign a string to it,
 that string will be recognized as a lexical-level inclusion request
 similar to the \samp{source} keyword in various shells.  That is, the
@@ -204,23 +204,23 @@
 number of levels deep.
 \end{memberdesc}
 
-\begin{memberdesc}{debug}
+\begin{memberdesc}[shlex]{debug}
 If this member is numeric and \code{1} or more, a \class{shlex}
 instance will print verbose progress output on its behavior.  If you
 need to use this, you can read the module source code to learn the
 details.
 \end{memberdesc}
 
-\begin{memberdesc}{lineno}
+\begin{memberdesc}[shlex]{lineno}
 Source line number (count of newlines seen so far plus one).
 \end{memberdesc}
 
-\begin{memberdesc}{token}
+\begin{memberdesc}[shlex]{token}
 The token buffer.  It may be useful to examine this when catching
 exceptions.
 \end{memberdesc}
 
-\begin{memberdesc}{eof}
+\begin{memberdesc}[shlex]{eof}
 Token used to determine end of file. This will be set to the empty
 string (\code{''}), in non-\POSIX{} mode, and to \code{None} in
 \POSIX{} mode.

Modified: python/branches/p3yk/Doc/lib/libshutil.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libshutil.tex	(original)
+++ python/branches/p3yk/Doc/lib/libshutil.tex	Fri Apr 27 21:54:29 2007
@@ -34,7 +34,9 @@
   is the buffer size. In particular, a negative \var{length} value
   means to copy the data without looping over the source data in
   chunks; by default the data is read in chunks to avoid uncontrolled
-  memory consumption.
+  memory consumption. Note that if the current file position of the
+  \var{fsrc} object is not 0, only the contents from the current file
+  position to the end of the file will be copied.
 \end{funcdesc}
 
 \begin{funcdesc}{copymode}{src, dst}

Modified: python/branches/p3yk/Doc/lib/libsimplexmlrpc.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsimplexmlrpc.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsimplexmlrpc.tex	Fri Apr 27 21:54:29 2007
@@ -15,7 +15,9 @@
 
 \begin{classdesc}{SimpleXMLRPCServer}{addr\optional{,
                                       requestHandler\optional{,
-					logRequests\optional{, allow_none\optional{, encoding}}}}}
+					                  logRequests\optional{,
+                                      allow_none\optional{,
+                                      encoding}}}}}
 
   Create a new server instance.  This class
   provides methods for registration of functions that can be called by
@@ -28,8 +30,13 @@
   setting this parameter to false will turn off logging.  
   The \var{allow_none} and \var{encoding} parameters are passed on to 
   \module{xmlrpclib} and control the XML-RPC responses that will be returned 
-  from the server.
+  from the server. The \var{bind_and_activate} parameter controls whether
+  \method{server_bind()} and \method{server_activate()} are called immediately
+  by the constructor; it defaults to true. Setting it to false allows code to
+  manipulate the \var{allow_reuse_address} class variable before the address
+  is bound.
   \versionchanged[The \var{allow_none} and \var{encoding} parameters were added]{2.5}
+  \versionchanged[The \var{bind_and_activate} parameter was added]{2.6}
 \end{classdesc}
 
 \begin{classdesc}{CGIXMLRPCRequestHandler}{\optional{allow_none\optional{, encoding}}}
@@ -101,13 +108,13 @@
 
 \end{methoddesc}
 
-\begin{methoddesc}{register_introspection_functions}{}
+\begin{methoddesc}[SimpleXMLRPCServer]{register_introspection_functions}{}
   Registers the XML-RPC introspection functions \code{system.listMethods},
   \code{system.methodHelp} and \code{system.methodSignature}. 
   \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{register_multicall_functions}{}
+\begin{methoddesc}[SimpleXMLRPCServer]{register_multicall_functions}{}
   Registers the XML-RPC multicall function system.multicall.
 \end{methoddesc}
 
@@ -171,7 +178,7 @@
 The \class{CGIXMLRPCRequestHandler} class can be used to 
 handle XML-RPC requests sent to Python CGI scripts.
 
-\begin{methoddesc}{register_function}{function\optional{, name}}
+\begin{methoddesc}[CGIXMLRPCRequestHandler]{register_function}{function\optional{, name}}
 Register a function that can respond to XML-RPC requests. If 
 \var{name} is given, it will be the method name associated with 
 function, otherwise \var{function.__name__} will be used. \var{name}
@@ -180,7 +187,7 @@
 character. 
 \end{methoddesc}
 
-\begin{methoddesc}{register_instance}{instance}
+\begin{methoddesc}[CGIXMLRPCRequestHandler]{register_instance}{instance}
 Register an object which is used to expose method names 
 which have not been registered using \method{register_function()}. If 
 instance contains a \method{_dispatch()} method, it is called with the 
@@ -196,17 +203,17 @@
 back to the client. 
 \end{methoddesc}
 
-\begin{methoddesc}{register_introspection_functions}{}
+\begin{methoddesc}[CGIXMLRPCRequestHandler]{register_introspection_functions}{}
 Register the XML-RPC introspection functions 
 \code{system.listMethods}, \code{system.methodHelp} and 
 \code{system.methodSignature}.
 \end{methoddesc}
 
-\begin{methoddesc}{register_multicall_functions}{}
+\begin{methoddesc}[CGIXMLRPCRequestHandler]{register_multicall_functions}{}
 Register the XML-RPC multicall function \code{system.multicall}.
 \end{methoddesc}
 
-\begin{methoddesc}{handle_request}{\optional{request_text = None}}
+\begin{methoddesc}[CGIXMLRPCRequestHandler]{handle_request}{\optional{request_text = None}}
 Handle a XML-RPC request. If \var{request_text} is given, it 
 should be the POST data provided by the HTTP server, 
 otherwise the contents of stdin will be used.

Modified: python/branches/p3yk/Doc/lib/libsite.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsite.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsite.tex	Fri Apr 27 21:54:29 2007
@@ -28,12 +28,17 @@
 
 A path configuration file is a file whose name has the form
 \file{\var{package}.pth} and exists in one of the four directories
-mentioned above; its contents are additional items (one
-per line) to be added to \code{sys.path}.  Non-existing items are
-never added to \code{sys.path}, but no check is made that the item
-refers to a directory (rather than a file).  No item is added to
-\code{sys.path} more than once.  Blank lines and lines beginning with
-\code{\#} are skipped.  Lines starting with \code{import} are executed.
+mentioned above; its contents are additional items (one per line) to
+be added to \code{sys.path}.  Non-existing items are never added to
+\code{sys.path}, but no check is made that the item refers to a
+directory (rather than a file).  No item is added to \code{sys.path}
+more than once.  Blank lines and lines beginning with \code{\#} are
+skipped.  Lines starting with \code{import} (followed by space or tab)
+are executed.
+
+\versionchanged[A space or tab is now required after the import
+keyword]{2.6}
+
 \index{package}
 \indexiii{path}{configuration}{file}
 

Modified: python/branches/p3yk/Doc/lib/libsmtplib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsmtplib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsmtplib.tex	Fri Apr 27 21:54:29 2007
@@ -15,13 +15,16 @@
 (\citetitle{SMTP Service Extensions}).
 
 \begin{classdesc}{SMTP}{\optional{host\optional{, port\optional{,
-                        local_hostname}}}}
+                        local_hostname\optional{, timeout}}}}}
 A \class{SMTP} instance encapsulates an SMTP connection.  It has
 methods that support a full repertoire of SMTP and ESMTP
 operations. If the optional host and port parameters are given, the
 SMTP \method{connect()} method is called with those parameters during
 initialization.  An \exception{SMTPConnectError} is raised if the
 specified host doesn't respond correctly.
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if not specified, or passed as None, the global
+default timeout setting will be used).
 
 For normal use, you should only require the initialization/connect,
 \method{sendmail()}, and \method{quit()} methods.  An example is
@@ -31,7 +34,7 @@
 \begin{classdesc}{SMTP_SSL}{\optional{host\optional{, port\optional{,
                         local_hostname\optional{,
                         keyfile\optional{,
-                        certfile}}}}}}
+                        certfile\optional{, timeout}}}}}}}
 A \class{SMTP_SSL} instance behaves exactly the same as instances of \class{SMTP}.
 \class{SMTP_SSL} should be used for situations where SSL is required from 
 the beginning of the connection and using \method{starttls()} is not appropriate.
@@ -39,6 +42,26 @@
 omitted, the standard SMTP-over-SSL port (465) is used. \var{keyfile} and \var{certfile}
 are also optional, and can contain a PEM formatted private key and
 certificate chain file for the SSL connection.
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if not specified, or passed as None, the global
+default timeout setting will be used).
+\end{classdesc}
+
+\begin{classdesc}{LMTP}{\optional{host\optional{, port\optional{,
+                        local_hostname}}}}
+
+The LMTP protocol, which is very similar to ESMTP, is heavily based
+on the standard SMTP client. It's common to use Unix sockets for LMTP,
+so our connect() method must support that as well as a regular
+host:port server. To specify a Unix socket, you must use an absolute
+path for \var{host}, starting with a '/'.
+
+Authentication is supported, using the regular SMTP mechanism. When
+using a Unix socket, LMTP generally don't support or require any
+authentication, but your mileage might vary.
+
+\versionadded{2.6}
+
 \end{classdesc}
 
 A nice selection of exceptions is defined as well:
@@ -103,13 +126,13 @@
 
 An \class{SMTP} instance has the following methods:
 
-\begin{methoddesc}{set_debuglevel}{level}
+\begin{methoddesc}[SMTP]{set_debuglevel}{level}
 Set the debug output level.  A true value for \var{level} results in
 debug messages for connection and for all messages sent to and
 received from the server.
 \end{methoddesc}
 
-\begin{methoddesc}{connect}{\optional{host\optional{, port}}}
+\begin{methoddesc}[SMTP]{connect}{\optional{host\optional{, port}}}
 Connect to a host on a given port.  The defaults are to connect to the
 local host at the standard SMTP port (25).
 If the hostname ends with a colon (\character{:}) followed by a
@@ -119,7 +142,7 @@
 host is specified during instantiation.
 \end{methoddesc}
 
-\begin{methoddesc}{docmd}{cmd, \optional{, argstring}}
+\begin{methoddesc}[SMTP]{docmd}{cmd, \optional{, argstring}}
 Send a command \var{cmd} to the server.  The optional argument
 \var{argstring} is simply concatenated to the command, separated by a
 space.
@@ -136,7 +159,7 @@
 \exception{SMTPServerDisconnected} will be raised.
 \end{methoddesc}
 
-\begin{methoddesc}{helo}{\optional{hostname}}
+\begin{methoddesc}[SMTP]{helo}{\optional{hostname}}
 Identify yourself to the SMTP server using \samp{HELO}.  The hostname
 argument defaults to the fully qualified domain name of the local
 host.
@@ -146,7 +169,7 @@
 when necessary.
 \end{methoddesc}
 
-\begin{methoddesc}{ehlo}{\optional{hostname}}
+\begin{methoddesc}[SMTP]{ehlo}{\optional{hostname}}
 Identify yourself to an ESMTP server using \samp{EHLO}.  The hostname
 argument defaults to the fully qualified domain name of the local
 host.  Examine the response for ESMTP option and store them for use by
@@ -157,13 +180,13 @@
 will be implicitly called by \method{sendmail()} when necessary.
 \end{methoddesc}
 
-\begin{methoddesc}{has_extn}{name}
+\begin{methoddesc}[SMTP]{has_extn}{name}
 Return \constant{True} if \var{name} is in the set of SMTP service
 extensions returned by the server, \constant{False} otherwise.
 Case is ignored.
 \end{methoddesc}
 
-\begin{methoddesc}{verify}{address}
+\begin{methoddesc}[SMTP]{verify}{address}
 Check the validity of an address on this server using SMTP \samp{VRFY}.
 Returns a tuple consisting of code 250 and a full \rfc{822} address
 (including human name) if the user address is valid. Otherwise returns
@@ -172,7 +195,7 @@
 \note{Many sites disable SMTP \samp{VRFY} in order to foil spammers.}
 \end{methoddesc}
 
-\begin{methoddesc}{login}{user, password}
+\begin{methoddesc}[SMTP]{login}{user, password}
 Log in on an SMTP server that requires authentication.
 The arguments are the username and the password to authenticate with.
 If there has been no previous \samp{EHLO} or \samp{HELO} command this
@@ -190,7 +213,7 @@
 \end{description}
 \end{methoddesc}
 
-\begin{methoddesc}{starttls}{\optional{keyfile\optional{, certfile}}}
+\begin{methoddesc}[SMTP]{starttls}{\optional{keyfile\optional{, certfile}}}
 Put the SMTP connection in TLS (Transport Layer Security) mode.  All
 SMTP commands that follow will be encrypted.  You should then call
 \method{ehlo()} again.
@@ -199,8 +222,8 @@
 the \refmodule{socket} module's \function{ssl()} function.
 \end{methoddesc}
 
-\begin{methoddesc}{sendmail}{from_addr, to_addrs, msg\optional{,
-                             mail_options, rcpt_options}}
+\begin{methoddesc}[SMTP]{sendmail}{from_addr, to_addrs, msg\optional{,
+                                   mail_options, rcpt_options}}
 Send mail.  The required arguments are an \rfc{822} from-address
 string, a list of \rfc{822} to-address strings (a bare string will be
 treated as a list with 1 address), and a message string.  The caller
@@ -256,7 +279,7 @@
 
 \end{methoddesc}
 
-\begin{methoddesc}{quit}{}
+\begin{methoddesc}[SMTP]{quit}{}
 Terminate the SMTP session and close the connection.
 \end{methoddesc}
 

Modified: python/branches/p3yk/Doc/lib/libsocket.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsocket.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsocket.tex	Fri Apr 27 21:54:29 2007
@@ -14,7 +14,7 @@
 papers: \citetitle{An Introductory 4.3BSD Interprocess Communication
 Tutorial}, by Stuart Sechrest and \citetitle{An Advanced 4.3BSD
 Interprocess Communication Tutorial}, by Samuel J.  Leffler et al,
-both in the \citetitle{\UNIX{} Programmer's Manual, Supplementary Documents 1}
+both in the \citetitle{UNIX Programmer's Manual, Supplementary Documents 1}
 (sections PS1:7 and PS1:8).  The platform-specific reference material
 for the various socket-related system calls are also a valuable source
 of information on the details of socket semantics.  For \UNIX, refer
@@ -170,6 +170,15 @@
 \versionadded{2.3}
 \end{datadesc}
 
+\begin{funcdesc}{create_connection}{address\optional{, timeout}}
+Connects to the \var{address} received (as usual, a \code{(host, port)}
+pair), with an optional timeout for the connection.  Specially useful for
+higher-level protocols, it is not normally used directly from
+application-level code.  Passing the optional \var{timeout} parameter
+will set the timeout on the socket instance (if it is not given or
+\code{None}, the global default timeout setting is used).
+\end{funcdesc}
+
 \begin{funcdesc}{getaddrinfo}{host, port\optional{, family\optional{,
                               socktype\optional{, proto\optional{,
                               flags}}}}}
@@ -548,7 +557,7 @@
 The file object references a \cfunction{dup()}ped version of the
 socket file descriptor, so the file object and socket object may be
 closed or garbage-collected independently.
-The socket must be in blocking mode.
+The socket must be in blocking mode (it can not have a timeout).
 \index{I/O control!buffering}The optional \var{mode}
 and \var{bufsize} arguments are interpreted the same way as by the
 built-in \function{file()} function; see ``Built-in Functions''
@@ -584,6 +593,7 @@
 \manpage{recv}{2} for the meaning of the optional argument
 \var{flags}; it defaults to zero.  (The format of \var{address}
 depends on the address family --- see above.)
+\versionadded{2.5}
 \end{methoddesc}
 
 \begin{methoddesc}[socket]{recv_into}{buffer\optional{, nbytes\optional{, flags}}}
@@ -593,6 +603,7 @@
 receive up to the size available in the given buffer.
 See the \UNIX{} manual page \manpage{recv}{2} for the meaning of the
 optional argument \var{flags}; it defaults to zero.
+\versionadded{2.5}
 \end{methoddesc}
 
 \begin{methoddesc}[socket]{send}{string\optional{, flags}}
@@ -722,23 +733,23 @@
 
 SSL objects have the following methods.
 
-\begin{methoddesc}{write}{s}
+\begin{methoddesc}[SSL]{write}{s}
 Writes the string \var{s} to the on the object's SSL connection.
 The return value is the number of bytes written.
 \end{methoddesc}
 
-\begin{methoddesc}{read}{\optional{n}}
+\begin{methoddesc}[SSL]{read}{\optional{n}}
 If \var{n} is provided, read \var{n} bytes from the SSL connection, otherwise
 read until EOF. The return value is a string of the bytes read.
 \end{methoddesc}
 
-\begin{methoddesc}{server}{}
+\begin{methoddesc}[SSL]{server}{}
 Returns a string describing the server's certificate.
 Useful for debugging purposes; do not parse the content of this string
 because its format can't be parsed unambiguously.
 \end{methoddesc}
 
-\begin{methoddesc}{issuer}{}
+\begin{methoddesc}[SSL]{issuer}{}
 Returns a string describing the issuer of the server's certificate.
 Useful for debugging purposes; do not parse the content of this string
 because its format can't be parsed unambiguously.

Modified: python/branches/p3yk/Doc/lib/libsqlite3.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsqlite3.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsqlite3.tex	Fri Apr 27 21:54:29 2007
@@ -210,37 +210,37 @@
 A \class{Connection} instance has the following attributes and methods:
 
 \label{sqlite3-Connection-IsolationLevel}
-\begin{memberdesc}{isolation_level}
+\begin{memberdesc}[Connection]{isolation_level}
   Get or set the current isolation level. None for autocommit mode or one of
   "DEFERRED", "IMMEDIATE" or "EXLUSIVE". See ``Controlling Transactions'', 
   section~\ref{sqlite3-Controlling-Transactions}, for a more detailed explanation.
 \end{memberdesc}
 
-\begin{methoddesc}{cursor}{\optional{cursorClass}}
+\begin{methoddesc}[Connection]{cursor}{\optional{cursorClass}}
   The cursor method accepts a single optional parameter \var{cursorClass}.
   If supplied, this must be a custom cursor class that extends 
   \class{sqlite3.Cursor}.
 \end{methoddesc}
 
-\begin{methoddesc}{execute}{sql, \optional{parameters}}
+\begin{methoddesc}[Connection]{execute}{sql, \optional{parameters}}
 This is a nonstandard shortcut that creates an intermediate cursor object by
 calling the cursor method, then calls the cursor's \method{execute} method with the
 parameters given.
 \end{methoddesc}
 
-\begin{methoddesc}{executemany}{sql, \optional{parameters}}
+\begin{methoddesc}[Connection]{executemany}{sql, \optional{parameters}}
 This is a nonstandard shortcut that creates an intermediate cursor object by
 calling the cursor method, then calls the cursor's \method{executemany} method with the
 parameters given.
 \end{methoddesc}
 
-\begin{methoddesc}{executescript}{sql_script}
+\begin{methoddesc}[Connection]{executescript}{sql_script}
 This is a nonstandard shortcut that creates an intermediate cursor object by
 calling the cursor method, then calls the cursor's \method{executescript} method with the
 parameters given.
 \end{methoddesc}
 
-\begin{methoddesc}{create_function}{name, num_params, func}
+\begin{methoddesc}[Connection]{create_function}{name, num_params, func}
 
 Creates a user-defined function that you can later use from within SQL
 statements under the function name \var{name}. \var{num_params} is the number
@@ -255,7 +255,7 @@
   \verbatiminput{sqlite3/md5func.py}
 \end{methoddesc}
 
-\begin{methoddesc}{create_aggregate}{name, num_params, aggregate_class}
+\begin{methoddesc}[Connection]{create_aggregate}{name, num_params, aggregate_class}
 
 Creates a user-defined aggregate function.
 
@@ -271,7 +271,7 @@
   \verbatiminput{sqlite3/mysumaggr.py}
 \end{methoddesc}
 
-\begin{methoddesc}{create_collation}{name, callable}
+\begin{methoddesc}[Connection]{create_collation}{name, callable}
 
 Creates a collation with the specified \var{name} and \var{callable}. The
 callable will be passed two string arguments. It should return -1 if the first
@@ -293,14 +293,14 @@
 \end{verbatim}
 \end{methoddesc}
 
-\begin{methoddesc}{interrupt}{}
+\begin{methoddesc}[Connection]{interrupt}{}
 
 You can call this method from a different thread to abort any queries that
 might be executing on the connection. The query will then abort and the caller
 will get an exception.
 \end{methoddesc}
 
-\begin{methoddesc}{set_authorizer}{authorizer_callback}
+\begin{methoddesc}[Connection]{set_authorizer}{authorizer_callback}
 
 This routine registers a callback. The callback is invoked for each attempt to
 access a column of a table in the database. The callback should return
@@ -322,7 +322,7 @@
 module.
 \end{methoddesc}
 
-\begin{memberdesc}{row_factory}
+\begin{memberdesc}[Connection]{row_factory}
   You can change this attribute to a callable that accepts the cursor and
   the original row as a tuple and will return the real result row.  This
   way, you can implement more advanced ways of returning results, such 
@@ -341,7 +341,7 @@
   % XXX what's a db_row-based solution?
 \end{memberdesc}
 
-\begin{memberdesc}{text_factory}
+\begin{memberdesc}[Connection]{text_factory}
   Using this attribute you can control what objects are returned for the
   TEXT data type. By default, this attribute is set to \class{unicode} and
   the \module{sqlite3} module will return Unicode objects for TEXT. If you want to return
@@ -359,7 +359,7 @@
   \verbatiminput{sqlite3/text_factory.py}
 \end{memberdesc}
 
-\begin{memberdesc}{total_changes}
+\begin{memberdesc}[Connection]{total_changes}
   Returns the total number of database rows that have been modified, inserted,
   or deleted since the database connection was opened.
 \end{memberdesc}
@@ -372,7 +372,7 @@
 
 A \class{Cursor} instance has the following attributes and methods:
 
-\begin{methoddesc}{execute}{sql, \optional{parameters}}
+\begin{methoddesc}[Cursor]{execute}{sql, \optional{parameters}}
 
 Executes a SQL statement. The SQL statement may be parametrized (i. e.
 placeholders instead of SQL literals). The \module{sqlite3} module supports two kinds of
@@ -394,7 +394,7 @@
 \end{methoddesc}
 
 
-\begin{methoddesc}{executemany}{sql, seq_of_parameters}
+\begin{methoddesc}[Cursor]{executemany}{sql, seq_of_parameters}
 Executes a SQL command against all parameter sequences or mappings found in the
 sequence \var{sql}. The \module{sqlite3} module also allows
 using an iterator yielding parameters instead of a sequence.
@@ -406,7 +406,7 @@
 \verbatiminput{sqlite3/executemany_2.py}
 \end{methoddesc}
 
-\begin{methoddesc}{executescript}{sql_script}
+\begin{methoddesc}[Cursor]{executescript}{sql_script}
 
 This is a nonstandard convenience method for executing multiple SQL statements
 at once. It issues a COMMIT statement first, then executes the SQL script it
@@ -419,7 +419,7 @@
 \verbatiminput{sqlite3/executescript.py}
 \end{methoddesc}
 
-\begin{memberdesc}{rowcount}
+\begin{memberdesc}[Cursor]{rowcount}
   Although the \class{Cursor} class of the \module{sqlite3} module implements this
   attribute, the database engine's own support for the determination of "rows
   affected"/"rows selected" is quirky.

Modified: python/branches/p3yk/Doc/lib/libstdtypes.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libstdtypes.tex	(original)
+++ python/branches/p3yk/Doc/lib/libstdtypes.tex	Fri Apr 27 21:54:29 2007
@@ -559,25 +559,25 @@
 These are the string methods which both 8-bit strings and Unicode
 objects support:
 
-\begin{methoddesc}[string]{capitalize}{}
+\begin{methoddesc}[str]{capitalize}{}
 Return a copy of the string with only its first character capitalized.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{center}{width\optional{, fillchar}}
+\begin{methoddesc}[str]{center}{width\optional{, fillchar}}
 Return centered in a string of length \var{width}. Padding is done
 using the specified \var{fillchar} (default is a space).
 \versionchanged[Support for the \var{fillchar} argument]{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{count}{sub\optional{, start\optional{, end}}}
+\begin{methoddesc}[str]{count}{sub\optional{, start\optional{, end}}}
 Return the number of occurrences of substring \var{sub} in string
 S\code{[\var{start}:\var{end}]}.  Optional arguments \var{start} and
 \var{end} are interpreted as in slice notation.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{decode}{\optional{encoding\optional{, errors}}}
+\begin{methoddesc}[str]{decode}{\optional{encoding\optional{, errors}}}
 Decodes the string using the codec registered for \var{encoding}.
 \var{encoding} defaults to the default string encoding.  \var{errors}
 may be given to set a different error handling scheme.  The default is
@@ -589,7 +589,7 @@
 \versionchanged[Support for other error handling schemes added]{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{encode}{\optional{encoding\optional{,errors}}}
+\begin{methoddesc}[str]{encode}{\optional{encoding\optional{,errors}}}
 Return an encoded version of the string.  Default encoding is the current
 default string encoding.  \var{errors} may be given to set a different
 error handling scheme.  The default for \var{errors} is
@@ -604,7 +604,7 @@
 \code{'backslashreplace'} and other error handling schemes added]{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{endswith}{suffix\optional{, start\optional{, end}}}
+\begin{methoddesc}[str]{endswith}{suffix\optional{, start\optional{, end}}}
 Return \code{True} if the string ends with the specified \var{suffix},
 otherwise return \code{False}.  \var{suffix} can also be a tuple of
 suffixes to look for.  With optional \var{start}, test beginning at
@@ -613,13 +613,13 @@
 \versionchanged[Accept tuples as \var{suffix}]{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{expandtabs}{\optional{tabsize}}
+\begin{methoddesc}[str]{expandtabs}{\optional{tabsize}}
 Return a copy of the string where all tab characters are expanded
 using spaces.  If \var{tabsize} is not given, a tab size of \code{8}
 characters is assumed.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{find}{sub\optional{, start\optional{, end}}}
+\begin{methoddesc}[str]{find}{sub\optional{, start\optional{, end}}}
 Return the lowest index in the string where substring \var{sub} is
 found, such that \var{sub} is contained in the range [\var{start},
 \var{end}].  Optional arguments \var{start} and \var{end} are
@@ -627,47 +627,47 @@
 not found.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{index}{sub\optional{, start\optional{, end}}}
+\begin{methoddesc}[str]{index}{sub\optional{, start\optional{, end}}}
 Like \method{find()}, but raise \exception{ValueError} when the
 substring is not found.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{isalnum}{}
+\begin{methoddesc}[str]{isalnum}{}
 Return true if all characters in the string are alphanumeric and there
 is at least one character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{isalpha}{}
+\begin{methoddesc}[str]{isalpha}{}
 Return true if all characters in the string are alphabetic and there
 is at least one character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{isdigit}{}
+\begin{methoddesc}[str]{isdigit}{}
 Return true if all characters in the string are digits and there
 is at least one character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{islower}{}
+\begin{methoddesc}[str]{islower}{}
 Return true if all cased characters in the string are lowercase and
 there is at least one cased character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{isspace}{}
+\begin{methoddesc}[str]{isspace}{}
 Return true if there are only whitespace characters in the string and
 there is at least one character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{istitle}{}
+\begin{methoddesc}[str]{istitle}{}
 Return true if the string is a titlecased string and there is at least one
 character, for example uppercase characters may only follow uncased
 characters and lowercase characters only cased ones.  Return false
@@ -676,20 +676,20 @@
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{isupper}{}
+\begin{methoddesc}[str]{isupper}{}
 Return true if all cased characters in the string are uppercase and
 there is at least one cased character, false otherwise.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{join}{seq}
+\begin{methoddesc}[str]{join}{seq}
 Return a string which is the concatenation of the strings in the
 sequence \var{seq}.  The separator between elements is the string
 providing this method.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{ljust}{width\optional{, fillchar}}
+\begin{methoddesc}[str]{ljust}{width\optional{, fillchar}}
 Return the string left justified in a string of length \var{width}.
 Padding is done using the specified \var{fillchar} (default is a
 space).  The original string is returned if
@@ -697,13 +697,13 @@
 \versionchanged[Support for the \var{fillchar} argument]{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{lower}{}
+\begin{methoddesc}[str]{lower}{}
 Return a copy of the string converted to lowercase.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{lstrip}{\optional{chars}}
+\begin{methoddesc}[str]{lstrip}{\optional{chars}}
 Return a copy of the string with leading characters removed.  The
 \var{chars} argument is a string specifying the set of characters
 to be removed.  If omitted or \code{None}, the \var{chars} argument
@@ -718,7 +718,7 @@
 \versionchanged[Support for the \var{chars} argument]{2.2.2}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{partition}{sep}
+\begin{methoddesc}[str]{partition}{sep}
 Split the string at the first occurrence of \var{sep}, and return
 a 3-tuple containing the part before the separator, the separator
 itself, and the part after the separator.  If the separator is not
@@ -727,26 +727,26 @@
 \versionadded{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{replace}{old, new\optional{, count}}
+\begin{methoddesc}[str]{replace}{old, new\optional{, count}}
 Return a copy of the string with all occurrences of substring
 \var{old} replaced by \var{new}.  If the optional argument
 \var{count} is given, only the first \var{count} occurrences are
 replaced.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rfind}{sub \optional{,start \optional{,end}}}
+\begin{methoddesc}[str]{rfind}{sub \optional{,start \optional{,end}}}
 Return the highest index in the string where substring \var{sub} is
 found, such that \var{sub} is contained within s[start,end].  Optional
 arguments \var{start} and \var{end} are interpreted as in slice
 notation.  Return \code{-1} on failure.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rindex}{sub\optional{, start\optional{, end}}}
+\begin{methoddesc}[str]{rindex}{sub\optional{, start\optional{, end}}}
 Like \method{rfind()} but raises \exception{ValueError} when the
 substring \var{sub} is not found.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rjust}{width\optional{, fillchar}}
+\begin{methoddesc}[str]{rjust}{width\optional{, fillchar}}
 Return the string right justified in a string of length \var{width}.
 Padding is done using the specified \var{fillchar} (default is a space).
 The original string is returned if
@@ -754,7 +754,7 @@
 \versionchanged[Support for the \var{fillchar} argument]{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rpartition}{sep}
+\begin{methoddesc}[str]{rpartition}{sep}
 Split the string at the last occurrence of \var{sep}, and return
 a 3-tuple containing the part before the separator, the separator
 itself, and the part after the separator.  If the separator is not
@@ -763,7 +763,7 @@
 \versionadded{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rsplit}{\optional{sep \optional{,maxsplit}}}
+\begin{methoddesc}[str]{rsplit}{\optional{sep \optional{,maxsplit}}}
 Return a list of the words in the string, using \var{sep} as the
 delimiter string.  If \var{maxsplit} is given, at most \var{maxsplit}
 splits are done, the \emph{rightmost} ones.  If \var{sep} is not specified
@@ -773,7 +773,7 @@
 \versionadded{2.4}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rstrip}{\optional{chars}}
+\begin{methoddesc}[str]{rstrip}{\optional{chars}}
 Return a copy of the string with trailing characters removed.  The
 \var{chars} argument is a string specifying the set of characters
 to be removed.  If omitted or \code{None}, the \var{chars} argument
@@ -788,7 +788,7 @@
 \versionchanged[Support for the \var{chars} argument]{2.2.2}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{split}{\optional{sep \optional{,maxsplit}}}
+\begin{methoddesc}[str]{split}{\optional{sep \optional{,maxsplit}}}
 Return a list of the words in the string, using \var{sep} as the
 delimiter string.  If \var{maxsplit} is given, at most \var{maxsplit}
 splits are done. (thus, the list will have at most \code{\var{maxsplit}+1}
@@ -811,13 +811,13 @@
 returns an empty list.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{splitlines}{\optional{keepends}}
+\begin{methoddesc}[str]{splitlines}{\optional{keepends}}
 Return a list of the lines in the string, breaking at line
 boundaries.  Line breaks are not included in the resulting list unless
 \var{keepends} is given and true.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{startswith}{prefix\optional{,
+\begin{methoddesc}[str]{startswith}{prefix\optional{,
                                        start\optional{, end}}}
 Return \code{True} if string starts with the \var{prefix}, otherwise
 return \code{False}.  \var{prefix} can also be a tuple of
@@ -828,7 +828,7 @@
 \versionchanged[Accept tuples as \var{prefix}]{2.5}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{strip}{\optional{chars}}
+\begin{methoddesc}[str]{strip}{\optional{chars}}
 Return a copy of the string with the leading and trailing characters
 removed.  The \var{chars} argument is a string specifying the set of
 characters to be removed.  If omitted or \code{None}, the \var{chars}
@@ -843,21 +843,21 @@
 \versionchanged[Support for the \var{chars} argument]{2.2.2}
 \end{methoddesc}
 
-\begin{methoddesc}[string]{swapcase}{}
+\begin{methoddesc}[str]{swapcase}{}
 Return a copy of the string with uppercase characters converted to
 lowercase and vice versa.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{title}{}
+\begin{methoddesc}[str]{title}{}
 Return a titlecased version of the string: words start with uppercase
 characters, all remaining cased characters are lowercase.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{translate}{table\optional{, deletechars}}
+\begin{methoddesc}[str]{translate}{table\optional{, deletechars}}
 Return a copy of the string where all characters occurring in the
 optional argument \var{deletechars} are removed, and the remaining
 characters have been mapped through the given translation table, which
@@ -865,6 +865,13 @@
 
 You can use the \function{maketrans()} helper function in the
 \refmodule{string} module to create a translation table.
+For string objects, set the \var{table} argument to \code{None}
+for translations that only delete characters:
+\begin{verbatim}
+    >>> 'read this short text'.translate(None, 'aeiou')
+    'rd ths shrt txt'
+\end{verbatim}
+\versionadded[Support for a \code{None} \var{table} argument]{2.6}
 
 For Unicode objects, the \method{translate()} method does not
 accept the optional \var{deletechars} argument.  Instead, it
@@ -877,13 +884,13 @@
 \module{encodings.cp1251} for an example).      
 \end{methoddesc}
 
-\begin{methoddesc}[string]{upper}{}
+\begin{methoddesc}[str]{upper}{}
 Return a copy of the string converted to uppercase.
 
 For 8-bit strings, this method is locale-dependent.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{zfill}{width}
+\begin{methoddesc}[str]{zfill}{width}
 Return the numeric string left filled with zeros in a string
 of length \var{width}. The original string is returned if
 \var{width} is less than \code{len(\var{s})}.
@@ -1592,14 +1599,15 @@
 iterator, typically in a \keyword{for} loop (for example,
 \code{for line in f: print line}), the \method{__next__()} method is
 called repeatedly.  This method returns the next input line, or raises
-\exception{StopIteration} when \EOF{} is hit.  In order to make a
-\keyword{for} loop the most efficient way of looping over the lines of
-a file (a very common operation), the \method{__next__()} method uses a
-hidden read-ahead buffer.  As a consequence of using a read-ahead
-buffer, combining \method{__next__()} with other file methods (like
-\method{readline()}) does not work right.  However, using
-\method{seek()} to reposition the file to an absolute position will
-flush the read-ahead buffer.
+\exception{StopIteration} when \EOF{} is hit when the file is open for
+reading (behavior is undefined when the file is open for writing).  In
+order to make a \keyword{for} loop the most efficient way of looping
+over the lines of a file (a very common operation), the
+\method{__next__()} method uses a hidden read-ahead buffer.  As a
+consequence of using a read-ahead buffer, combining \method{__next__()}
+with other file methods (like \method{readline()}) does not work
+right.  However, using \method{seek()} to reposition the file to an
+absolute position will flush the read-ahead buffer.
 \versionadded{2.3}
 \end{methoddesc}
 

Modified: python/branches/p3yk/Doc/lib/libstring.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libstring.tex	(original)
+++ python/branches/p3yk/Doc/lib/libstring.tex	Fri Apr 27 21:54:29 2007
@@ -419,7 +419,8 @@
   Delete all characters from \var{s} that are in \var{deletechars} (if 
   present), and then translate the characters using \var{table}, which 
   must be a 256-character string giving the translation for each
-  character value, indexed by its ordinal.
+  character value, indexed by its ordinal.  If \var{table} is \code{None},
+  then only the character deletion step is performed.
 \end{funcdesc}
 
 \begin{funcdesc}{upper}{s}

Modified: python/branches/p3yk/Doc/lib/libsubprocess.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsubprocess.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsubprocess.tex	Fri Apr 27 21:54:29 2007
@@ -176,16 +176,16 @@
 
 Instances of the \class{Popen} class have the following methods:
 
-\begin{methoddesc}{poll}{}
+\begin{methoddesc}[Popen]{poll}{}
 Check if child process has terminated.  Returns returncode
 attribute.
 \end{methoddesc}
 
-\begin{methoddesc}{wait}{}
+\begin{methoddesc}[Popen]{wait}{}
 Wait for child process to terminate.  Returns returncode attribute.
 \end{methoddesc}
 
-\begin{methoddesc}{communicate}{input=None}
+\begin{methoddesc}[Popen]{communicate}{input=None}
 Interact with process: Send data to stdin.  Read data from stdout and
 stderr, until end-of-file is reached.  Wait for process to terminate.
 The optional \var{input} argument should be a string to be sent to the
@@ -199,29 +199,29 @@
 
 The following attributes are also available:
 
-\begin{memberdesc}{stdin}
+\begin{memberdesc}[Popen]{stdin}
 If the \var{stdin} argument is \code{PIPE}, this attribute is a file
 object that provides input to the child process.  Otherwise, it is
 \code{None}.
 \end{memberdesc}
 
-\begin{memberdesc}{stdout}
+\begin{memberdesc}[Popen]{stdout}
 If the \var{stdout} argument is \code{PIPE}, this attribute is a file
 object that provides output from the child process.  Otherwise, it is
 \code{None}.
 \end{memberdesc}
 
-\begin{memberdesc}{stderr}
+\begin{memberdesc}[Popen]{stderr}
 If the \var{stderr} argument is \code{PIPE}, this attribute is file
 object that provides error output from the child process.  Otherwise,
 it is \code{None}.
 \end{memberdesc}
 
-\begin{memberdesc}{pid}
+\begin{memberdesc}[Popen]{pid}
 The process ID of the child process.
 \end{memberdesc}
 
-\begin{memberdesc}{returncode}
+\begin{memberdesc}[Popen]{returncode}
 The child return code.  A \code{None} value indicates that the process
 hasn't terminated yet.  A negative value -N indicates that the child
 was terminated by signal N (\UNIX{} only).

Modified: python/branches/p3yk/Doc/lib/libsun.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsun.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsun.tex	Fri Apr 27 21:54:29 2007
@@ -3,3 +3,5 @@
 
 The modules described in this chapter provide interfaces to features
 that are unique to SunOS 5 (also known as Solaris version 2).
+
+\localmoduletable

Modified: python/branches/p3yk/Doc/lib/libsys.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libsys.tex	(original)
+++ python/branches/p3yk/Doc/lib/libsys.tex	Fri Apr 27 21:54:29 2007
@@ -15,8 +15,8 @@
   whether this is a full pathname or not).  If the command was
   executed using the \programopt{-c} command line option to the
   interpreter, \code{argv[0]} is set to the string \code{'-c'}.  If no
-  script name was passed to the Python interpreter, \code{argv} has
-  zero length.
+  script name was passed to the Python interpreter, \code{argv[0]} is
+  the empty string.
 \end{datadesc}
 
 \begin{datadesc}{byteorder}

Modified: python/branches/p3yk/Doc/lib/libtarfile.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtarfile.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtarfile.tex	Fri Apr 27 21:54:29 2007
@@ -12,21 +12,24 @@
 
 \begin{itemize}
 \item reads and writes \module{gzip} and \module{bzip2} compressed archives.
-\item creates \POSIX{} 1003.1-1990 compliant or GNU tar compatible archives.
-\item reads GNU tar extensions \emph{longname}, \emph{longlink} and
-      \emph{sparse}.
-\item stores pathnames of unlimited length using GNU tar extensions.
+\item read/write support for the \POSIX{}.1-1988 (ustar) format.
+\item read/write support for the GNU tar format including \emph{longname} and
+      \emph{longlink} extensions, read-only support for the \emph{sparse}
+      extension.
+\item read/write support for the \POSIX{}.1-2001 (pax) format.
+      \versionadded{2.6}
 \item handles directories, regular files, hardlinks, symbolic links, fifos,
       character devices and block devices and is able to acquire and
       restore file information like timestamp, access permissions and owner.
 \item can handle tape devices.
 \end{itemize}
 
-\begin{funcdesc}{open}{\optional{name\optional{, mode
-                       \optional{, fileobj\optional{, bufsize}}}}}
+\begin{funcdesc}{open}{name\optional{, mode\optional{,
+        fileobj\optional{, bufsize}}}, **kwargs}
     Return a \class{TarFile} object for the pathname \var{name}.
-    For detailed information on \class{TarFile} objects,
-    see \citetitle{TarFile Objects} (section \ref{tarfile-objects}).
+    For detailed information on \class{TarFile} objects and the keyword
+    arguments that are allowed, see \citetitle{TarFile Objects}
+    (section \ref{tarfile-objects}).
 
     \var{mode} has to be a string of the form \code{'filemode[:compression]'},
     it defaults to \code{'r'}. Here is a full list of mode combinations:
@@ -130,6 +133,31 @@
     \versionadded{2.6}
 \end{excdesc}
 
+\begin{datadesc}{USTAR_FORMAT}
+    \POSIX{}.1-1988 (ustar) format. It supports filenames up to a length of
+    at best 256 characters and linknames up to 100 characters. The maximum
+    file size is 8 gigabytes. This is an old and limited but widely
+    supported format.
+\end{datadesc}
+
+\begin{datadesc}{GNU_FORMAT}
+    GNU tar format. It supports arbitrarily long filenames and linknames and
+    files bigger than 8 gigabytes. It is the defacto standard on GNU/Linux
+    systems.
+\end{datadesc}
+
+\begin{datadesc}{PAX_FORMAT}
+    \POSIX{}.1-2001 (pax) format. It is the most flexible format with
+    virtually no limits. It supports long filenames and linknames, large files
+    and stores pathnames in a portable way.  However, not all tar
+    implementations today are able to handle pax archives properly.
+\end{datadesc}
+
+\begin{datadesc}{DEFAULT_FORMAT}
+    The default format for creating archives. This is currently
+    \constant{GNU_FORMAT}.
+\end{datadesc}
+
 \begin{seealso}
     \seemodule{zipfile}{Documentation of the \refmodule{zipfile}
     standard module.}
@@ -152,12 +180,21 @@
 \class{TarInfo} object, see \citetitle{TarInfo Objects} (section
 \ref{tarinfo-objects}) for details.
 
-\begin{classdesc}{TarFile}{\optional{name
-                           \optional{, mode\optional{, fileobj}}}}
-    Open an \emph{(uncompressed)} tar archive \var{name}.
+\begin{classdesc}{TarFile}{name=None, mode='r', fileobj=None,
+        format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False,
+        ignore_zeros=False, encoding=None, pax_headers=None, debug=0,
+        errorlevel=0}
+
+    All following arguments are optional and can be accessed as instance
+    attributes as well.
+
+    \var{name} is the pathname of the archive. It can be omitted if
+    \var{fileobj} is given. In this case, the file object's \member{name}
+    attribute is used if it exists.
+
     \var{mode} is either \code{'r'} to read from an existing archive,
     \code{'a'} to append data to an existing file or \code{'w'} to create a new
-    file overwriting an existing one. \var{mode} defaults to \code{'r'}.
+    file overwriting an existing one.
 
     If \var{fileobj} is given, it is used for reading or writing data.
     If it can be determined, \var{mode} is overridden by \var{fileobj}'s mode.
@@ -165,6 +202,48 @@
     \begin{notice}
         \var{fileobj} is not closed, when \class{TarFile} is closed.
     \end{notice}
+
+    \var{format} controls the archive format. It must be one of the constants
+    \constant{USTAR_FORMAT}, \constant{GNU_FORMAT} or \constant{PAX_FORMAT}
+    that are defined at module level.
+    \versionadded{2.6}
+
+    The \var{tarinfo} argument can be used to replace the default
+    \class{TarInfo} class with a different one.
+    \versionadded{2.6}
+
+    If \var{dereference} is \code{False}, add symbolic and hard links to the
+    archive. If it is \code{True}, add the content of the target files to the
+    archive. This has no effect on systems that do not support symbolic links.
+
+    If \var{ignore_zeros} is \code{False}, treat an empty block as the end of
+    the archive. If it is \var{True}, skip empty (and invalid) blocks and try
+    to get as many members as possible. This is only useful for reading
+    concatenated or damaged archives.
+
+    \var{debug} can be set from \code{0} (no debug messages) up to \code{3}
+    (all debug messages). The messages are written to \code{sys.stderr}.
+
+    If \var{errorlevel} is \code{0}, all errors are ignored when using
+    \method{extract()}.  Nevertheless, they appear as error messages in the
+    debug output, when debugging is enabled.  If \code{1}, all \emph{fatal}
+    errors are raised as \exception{OSError} or \exception{IOError} exceptions.
+    If \code{2}, all \emph{non-fatal} errors are raised as \exception{TarError}
+    exceptions as well.
+
+    The \var{encoding} argument defines the local character encoding. It
+    defaults to the value from \function{sys.getfilesystemencoding()} or if
+    that is \code{None} to \code{"ascii"}. \var{encoding} is used only in
+    connection with the pax format which stores text data in \emph{UTF-8}. If
+    it is not set correctly, character conversion will fail with a
+    \exception{UnicodeError}.
+    \versionadded{2.6}
+
+    The \var{pax_headers} argument must be a dictionary whose elements are
+    either unicode objects, numbers or strings that can be decoded to unicode
+    using \var{encoding}. This information will be added to the archive as a
+    pax global header.
+    \versionadded{2.6}
 \end{classdesc}
 
 \begin{methoddesc}{open}{...}
@@ -279,43 +358,11 @@
 \end{methoddesc}
 
 \begin{memberdesc}{posix}
-    If true, create a \POSIX{} 1003.1-1990 compliant archive. GNU
-    extensions are not used, because they are not part of the \POSIX{}
-    standard.  This limits the length of filenames to at most 256,
-    link names to 100 characters and the maximum file size to 8
-    gigabytes. A \exception{ValueError} is raised if a file exceeds
-    this limit.  If false, create a GNU tar compatible archive.  It
-    will not be \POSIX{} compliant, but can store files without any
-    of the above restrictions. 
+    Setting this to \constant{True} is equivalent to setting the
+    \member{format} attribute to \constant{USTAR_FORMAT},
+    \constant{False} is equivalent to \constant{GNU_FORMAT}.
     \versionchanged[\var{posix} defaults to \constant{False}]{2.4}
-\end{memberdesc}
-
-\begin{memberdesc}{dereference}
-    If false, add symbolic and hard links to archive. If true, add the
-    content of the target files to the archive.  This has no effect on
-    systems that do not support symbolic links.
-\end{memberdesc}
-
-\begin{memberdesc}{ignore_zeros}
-    If false, treat an empty block as the end of the archive. If true,
-    skip empty (and invalid) blocks and try to get as many members as
-    possible. This is only useful for concatenated or damaged
-    archives.
-\end{memberdesc}
-
-\begin{memberdesc}{debug=0}
-    To be set from \code{0} (no debug messages; the default) up to
-    \code{3} (all debug messages). The messages are written to
-    \code{sys.stderr}.
-\end{memberdesc}
-
-\begin{memberdesc}{errorlevel}
-    If \code{0} (the default), all errors are ignored when using
-    \method{extract()}.  Nevertheless, they appear as error messages
-    in the debug output, when debugging is enabled.  If \code{1}, all
-    \emph{fatal} errors are raised as \exception{OSError} or
-    \exception{IOError} exceptions.  If \code{2}, all \emph{non-fatal}
-    errors are raised as \exception{TarError} exceptions as well.
+    \deprecated{2.6}{Use the \member{format} attribute instead.}
 \end{memberdesc}
 
 %-----------------
@@ -343,12 +390,16 @@
     invalid.]{2.6}
 \end{methoddesc}
 
-\begin{methoddesc}{tobuf}{posix}
-    Create a string buffer from a \class{TarInfo} object.
-    See \class{TarFile}'s \member{posix} attribute for information
-    on the \var{posix} argument. It defaults to \constant{False}.
+\begin{methoddesc}{fromtarfile}{tarfile}
+    Read the next member from the \class{TarFile} object \var{tarfile} and
+    return it as a \class{TarInfo} object.
+    \versionadded{2.6}
+\end{methoddesc}
 
-    \versionadded[The \var{posix} parameter]{2.5}
+\begin{methoddesc}{tobuf}{\optional{format}}
+    Create a string buffer from a \class{TarInfo} object.  See
+    \class{TarFile}'s \member{format} argument for information.
+    \versionchanged[The \var{format} parameter]{2.6}
 \end{methoddesc}
 
 A \code{TarInfo} object has the following public data attributes:

Modified: python/branches/p3yk/Doc/lib/libtelnetlib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtelnetlib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtelnetlib.tex	Fri Apr 27 21:54:29 2007
@@ -23,13 +23,16 @@
 SB (Subnegotiation Begin).
 
 
-\begin{classdesc}{Telnet}{\optional{host\optional{, port}}}
+\begin{classdesc}{Telnet}{\optional{host\optional{, port\optional{, timeout}}}}
 \class{Telnet} represents a connection to a Telnet server. The
 instance is initially not connected by default; the \method{open()}
 method must be used to establish a connection.  Alternatively, the
 host name and optional port number can be passed to the constructor,
 to, in which case the connection to the server will be established
 before the constructor returns.
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if not specified, or passed as None, the global default
+timeout setting will be used).
 
 Do not reopen an already connected instance.
 
@@ -52,7 +55,7 @@
 \class{Telnet} instances have the following methods:
 
 
-\begin{methoddesc}{read_until}{expected\optional{, timeout}}
+\begin{methoddesc}[Telnet]{read_until}{expected\optional{, timeout}}
 Read until a given string, \var{expected}, is encountered or until
 \var{timeout} seconds have passed.
 
@@ -61,17 +64,17 @@
 is closed and no cooked data is available.
 \end{methoddesc}
 
-\begin{methoddesc}{read_all}{}
+\begin{methoddesc}[Telnet]{read_all}{}
 Read all data until \EOF; block until connection closed.
 \end{methoddesc}
 
-\begin{methoddesc}{read_some}{}
+\begin{methoddesc}[Telnet]{read_some}{}
 Read at least one byte of cooked data unless \EOF{} is hit.
 Return \code{''} if \EOF{} is hit.  Block if no data is immediately
 available.
 \end{methoddesc}
 
-\begin{methoddesc}{read_very_eager}{}
+\begin{methoddesc}[Telnet]{read_very_eager}{}
 Read everything that can be without blocking in I/O (eager).
 
 Raise \exception{EOFError} if connection closed and no cooked data
@@ -79,7 +82,7 @@
 Do not block unless in the midst of an IAC sequence.
 \end{methoddesc}
 
-\begin{methoddesc}{read_eager}{}
+\begin{methoddesc}[Telnet]{read_eager}{}
 Read readily available data.
 
 Raise \exception{EOFError} if connection closed and no cooked data
@@ -87,7 +90,7 @@
 Do not block unless in the midst of an IAC sequence.
 \end{methoddesc}
 
-\begin{methoddesc}{read_lazy}{}
+\begin{methoddesc}[Telnet]{read_lazy}{}
 Process and return data already in the queues (lazy).
 
 Raise \exception{EOFError} if connection closed and no data available.
@@ -95,7 +98,7 @@
 unless in the midst of an IAC sequence.
 \end{methoddesc}
 
-\begin{methoddesc}{read_very_lazy}{}
+\begin{methoddesc}[Telnet]{read_very_lazy}{}
 Return any data available in the cooked queue (very lazy).
 
 Raise \exception{EOFError} if connection closed and no data available.
@@ -103,7 +106,7 @@
 never blocks.
 \end{methoddesc}
 
-\begin{methoddesc}{read_sb_data}{}
+\begin{methoddesc}[Telnet]{read_sb_data}{}
 Return the data collected between a SB/SE pair (suboption begin/end).
 The callback should access these data when it was invoked with a
 \code{SE} command. This method never blocks.
@@ -111,52 +114,55 @@
 \versionadded{2.3}
 \end{methoddesc}
 
-\begin{methoddesc}{open}{host\optional{, port}}
+\begin{methoddesc}[Telnet]{open}{host\optional{, port\optional{, timeout}}}
 Connect to a host.
 The optional second argument is the port number, which
 defaults to the standard Telnet port (23).
+The optional \var{timeout} parameter specifies a timeout in seconds for the
+connection attempt (if not specified, or passed as None, the global default
+timeout setting will be used).
 
 Do not try to reopen an already connected instance.
 \end{methoddesc}
 
-\begin{methoddesc}{msg}{msg\optional{, *args}}
+\begin{methoddesc}[Telnet]{msg}{msg\optional{, *args}}
 Print a debug message when the debug level is \code{>} 0.
 If extra arguments are present, they are substituted in the
 message using the standard string formatting operator.
 \end{methoddesc}
 
-\begin{methoddesc}{set_debuglevel}{debuglevel}
+\begin{methoddesc}[Telnet]{set_debuglevel}{debuglevel}
 Set the debug level.  The higher the value of \var{debuglevel}, the
 more debug output you get (on \code{sys.stdout}).
 \end{methoddesc}
 
-\begin{methoddesc}{close}{}
+\begin{methoddesc}[Telnet]{close}{}
 Close the connection.
 \end{methoddesc}
 
-\begin{methoddesc}{get_socket}{}
+\begin{methoddesc}[Telnet]{get_socket}{}
 Return the socket object used internally.
 \end{methoddesc}
 
-\begin{methoddesc}{fileno}{}
+\begin{methoddesc}[Telnet]{fileno}{}
 Return the file descriptor of the socket object used internally.
 \end{methoddesc}
 
-\begin{methoddesc}{write}{buffer}
+\begin{methoddesc}[Telnet]{write}{buffer}
 Write a string to the socket, doubling any IAC characters.
 This can block if the connection is blocked.  May raise
 \exception{socket.error} if the connection is closed.
 \end{methoddesc}
 
-\begin{methoddesc}{interact}{}
+\begin{methoddesc}[Telnet]{interact}{}
 Interaction function, emulates a very dumb Telnet client.
 \end{methoddesc}
 
-\begin{methoddesc}{mt_interact}{}
+\begin{methoddesc}[Telnet]{mt_interact}{}
 Multithreaded version of \method{interact()}.
 \end{methoddesc}
 
-\begin{methoddesc}{expect}{list\optional{, timeout}}
+\begin{methoddesc}[Telnet]{expect}{list\optional{, timeout}}
 Read until one from a list of a regular expressions matches.
 
 The first argument is a list of regular expressions, either
@@ -178,7 +184,7 @@
 results are indeterministic, and may depend on the I/O timing.
 \end{methoddesc}
 
-\begin{methoddesc}{set_option_negotiation_callback}{callback}
+\begin{methoddesc}[Telnet]{set_option_negotiation_callback}{callback}
 Each time a telnet option is read on the input flow, this
 \var{callback} (if set) is called with the following parameters :
 callback(telnet socket, command (DO/DONT/WILL/WONT), option).  No other

Modified: python/branches/p3yk/Doc/lib/libtempfile.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtempfile.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtempfile.tex	Fri Apr 27 21:54:29 2007
@@ -53,7 +53,7 @@
 \begin{funcdesc}{NamedTemporaryFile}{\optional{mode=\code{'w+b'}\optional{,
                                      bufsize=\code{-1}\optional{,
                                      suffix\optional{, prefix\optional{,
-                                     dir}}}}}}
+                                     dir\optional{, delete}}}}}}}
 This function operates exactly as \function{TemporaryFile()} does,
 except that the file is guaranteed to have a visible name in the file
 system (on \UNIX, the directory entry is not unlinked).  That name can
@@ -61,7 +61,27 @@
 the name can be used to open the file a second time, while the
 named temporary file is still open, varies across platforms (it can
 be so used on \UNIX; it cannot on Windows NT or later).
+If \var{delete} is true (the default), the file is deleted as soon as
+it is closed.
 \versionadded{2.3}
+\versionadded[The \var{delete} parameter]{2.6}
+\end{funcdesc}
+
+\begin{funcdesc}{SpooledTemporaryFile}{\optional{max\_size=\code{0},
+                                \optional{mode=\code{'w+b'}\optional{,
+                                bufsize=\code{-1}\optional{,
+                                suffix\optional{, prefix\optional{,
+                                dir}}}}}}}
+This function operates exactly as \function{TemporaryFile()} does,
+except that data is spooled in memory until the file size exceeds
+\var{max_size}, or until the file's \function{fileno()} method is
+called, at which point the contents are written to disk and operation
+proceeds as with \function{TemporaryFile()}.
+
+The resulting file has one additional method, \function{rollover()},
+which causes the file to roll over to an on-disk file regardless of
+its size.
+\versionadded{2.6}
 \end{funcdesc}
 
 \begin{funcdesc}{mkstemp}{\optional{suffix\optional{,

Modified: python/branches/p3yk/Doc/lib/libtest.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtest.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtest.tex	Fri Apr 27 21:54:29 2007
@@ -14,11 +14,11 @@
 
 Each module in the \module{test} package whose name starts with
 \samp{test_} is a testing suite for a specific module or feature.
-All new tests should be written using the \refmodule{unittest} module;
-using \refmodule{unittest} is not required but makes the tests more
-flexible and maintenance of the tests easier.  Some older tests are
-written to use \refmodule{doctest} and a ``traditional'' testing
-style; these styles of tests will not be covered.
+All new tests should be written using the \refmodule{unittest} or
+\refmodule{doctest} module.  Some older tests are
+written using a ``traditional'' testing style that compares output
+printed to \code{sys.stdout}; this style of test is considered
+deprecated.
 
 \begin{seealso}
 \seemodule{unittest}{Writing PyUnit regression tests.}
@@ -29,8 +29,8 @@
 \subsection{Writing Unit Tests for the \module{test} package%
             \label{writing-tests}}
 
-It is preferred that tests for the \module{test} package use the
-\refmodule{unittest} module and follow a few guidelines.
+It is preferred that tests that use the \refmodule{unittest} module
+follow a few guidelines.
 One is to name the test module by starting it with \samp{test_} and end it with
 the name of the module being tested.
 The test methods in the test module should start with \samp{test_} and end with
@@ -196,7 +196,9 @@
 This module defines the following exceptions:
 
 \begin{excdesc}{TestFailed}
-Exception to be raised when a test fails.
+Exception to be raised when a test fails. This is deprecated in favor
+of \module{unittest}-based tests and \class{unittest.TestCase}'s
+assertion methods.
 \end{excdesc}
 
 \begin{excdesc}{TestSkipped}
@@ -273,18 +275,30 @@
 Execute \class{unittest.TestCase} subclasses passed to the function.
 The function scans the classes for methods starting with the prefix
 \samp{test_} and executes the tests individually.
-This is the preferred way to execute tests.
-\end{funcdesc}
 
-\begin{funcdesc}{run_suite}{suite\optional{, testclass}}
-Execute the \class{unittest.TestSuite} instance \var{suite}.
-The optional argument \var{testclass} accepts one of the test classes in the
-suite so as to print out more detailed information on where the testing suite
-originated from.
+It is also legal to pass strings as parameters; these should be keys in
+\code{sys.modules}. Each associated module will be scanned by
+\code{unittest.TestLoader.loadTestsFromModule()}. This is usually seen in
+the following \function{test_main()} function:
+
+\begin{verbatim}
+def test_main():
+    test_support.run_unittest(__name__)
+\end{verbatim}
+
+This will run all tests defined in the named module.
 \end{funcdesc}
 
 The \module{test.test_support} module defines the following classes:
 
+\begin{classdesc}{TransientResource}{exc\optional{, **kwargs}}
+Create a context manager that raises \class{ResourceDenied} if the specified
+exception type is raised.  Any keyword arguments are treated as name/value
+pairs to be compared against any exception raised with the \code{with}
+statement.  Only if all pairs match is \class{ResourceDenied} raised.
+\versionadded{2.6}
+\end{classdesc}
+
 \begin{classdesc}{EnvironmentVarGuard}{}
 Class used to temporarily set or unset environment variables.  Instances can be
 used as a context manager.

Modified: python/branches/p3yk/Doc/lib/libtextwrap.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtextwrap.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtextwrap.tex	Fri Apr 27 21:54:29 2007
@@ -54,7 +54,7 @@
 in indented form.
 
 Note that tabs and spaces are both treated as whitespace, but they are
-not equal: the lines \code{" {} hello"} and \code{"\textbackslash{}thello"}
+not equal: the lines \code{" {} hello"} and \code{"\e thello"}
 are considered to have no common leading whitespace.  (This behaviour is
 new in Python 2.5; older versions of this module incorrectly expanded
 tabs before searching for common leading whitespace.)
@@ -115,6 +115,13 @@
 expansion.}
 \end{memberdesc}
 
+\begin{memberdesc}{drop_whitespace}
+(default: \code{True}) If true, whitespace that, after wrapping, happens
+to end up at the beginning or end of a line is dropped (leading whitespace
+in the first line is always preserved, though).
+\versionadded[Whitespace was always dropped in earlier versions]{2.6}
+\end{memberdesc}
+
 \begin{memberdesc}{initial_indent}
 (default: \code{''}) String that will be prepended to the first line
 of wrapped output.  Counts towards the length of the first line.

Modified: python/branches/p3yk/Doc/lib/libthreading.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libthreading.tex	(original)
+++ python/branches/p3yk/Doc/lib/libthreading.tex	Fri Apr 27 21:54:29 2007
@@ -15,17 +15,16 @@
 This module defines the following functions and objects:
 
 \begin{funcdesc}{activeCount}{}
-Return the number of currently active \class{Thread} objects.
-The returned count is equal to the length of the list returned by
+Return the number of \class{Thread} objects currently alive.  The
+returned count is equal to the length of the list returned by
 \function{enumerate()}.
-A function that returns the number of currently active threads.
 \end{funcdesc}
 
-\begin{funcdesc}{Condition}{}
+\begin{funcdescni}{Condition}{}
 A factory function that returns a new condition variable object.
 A condition variable allows one or more threads to wait until they
 are notified by another thread.
-\end{funcdesc}
+\end{funcdescni}
 
 \begin{funcdesc}{currentThread}{}
 Return the current \class{Thread} object, corresponding to the
@@ -36,18 +35,18 @@
 \end{funcdesc}
 
 \begin{funcdesc}{enumerate}{}
-Return a list of all currently active \class{Thread} objects.
-The list includes daemonic threads, dummy thread objects created
-by \function{currentThread()}, and the main thread.  It excludes terminated
-threads and threads that have not yet been started.
+Return a list of all \class{Thread} objects currently alive.  The list
+includes daemonic threads, dummy thread objects created by
+\function{currentThread()}, and the main thread.  It excludes
+terminated threads and threads that have not yet been started.
 \end{funcdesc}
 
-\begin{funcdesc}{Event}{}
+\begin{funcdescni}{Event}{}
 A factory function that returns a new event object.  An event manages
 a flag that can be set to true with the \method{set()} method and
 reset to false with the \method{clear()} method.  The \method{wait()}
 method blocks until the flag is true.
-\end{funcdesc}
+\end{funcdescni}
 
 \begin{classdesc*}{local}{}
 A class that represents thread-local data.  Thread-local data are data
@@ -82,14 +81,14 @@
 for each time it has acquired it.
 \end{funcdesc}
 
-\begin{funcdesc}{Semaphore}{\optional{value}}
+\begin{funcdescni}{Semaphore}{\optional{value}}
 A factory function that returns a new semaphore object.  A
 semaphore manages a counter representing the number of \method{release()}
 calls minus the number of \method{acquire()} calls, plus an initial value.
 The \method{acquire()} method blocks if necessary until it can return
 without making the counter negative.  If not given, \var{value} defaults to
 1. 
-\end{funcdesc}
+\end{funcdescni}
 
 \begin{funcdesc}{BoundedSemaphore}{\optional{value}}
 A factory function that returns a new bounded semaphore object.  A bounded
@@ -100,12 +99,12 @@
 \var{value} defaults to 1. 
 \end{funcdesc}
 
-\begin{classdesc*}{Thread}{}
+\begin{classdesc*}{Thread}
 A class that represents a thread of control.  This class can be safely
 subclassed in a limited fashion.
 \end{classdesc*}
 
-\begin{classdesc*}{Timer}{}
+\begin{classdesc*}{Timer}
 A thread that executes a function after a specified interval has passed.
 \end{classdesc*}
 
@@ -183,7 +182,7 @@
 
 All methods are executed atomically.
 
-\begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}}
+\begin{methoddesc}[Lock]{acquire}{\optional{blocking\code{ = 1}}}
 Acquire a lock, blocking or non-blocking.
 
 When invoked without arguments, block until the lock is
@@ -198,7 +197,7 @@
 without arguments, and return true.
 \end{methoddesc}
 
-\begin{methoddesc}{release}{}
+\begin{methoddesc}[Lock]{release}{}
 Release a lock.
 
 When the lock is locked, reset it to unlocked, and return.  If
@@ -228,7 +227,7 @@
 pair) resets the lock to unlocked and allows another thread blocked in
 \method{acquire()} to proceed.
 
-\begin{methoddesc}{acquire}{\optional{blocking\code{ = 1}}}
+\begin{methoddesc}[RLock]{acquire}{\optional{blocking\code{ = 1}}}
 Acquire a lock, blocking or non-blocking.
 
 When invoked without arguments: if this thread already owns
@@ -250,7 +249,7 @@
 without arguments, and return true.
 \end{methoddesc}
 
-\begin{methoddesc}{release}{}
+\begin{methoddesc}[RLock]{release}{}
 Release a lock, decrementing the recursion level.  If after the
 decrement it is zero, reset the lock to unlocked (not owned by any
 thread), and if any other threads are blocked waiting for the lock to
@@ -526,12 +525,9 @@
 \method{run()} method in a separate thread of control.
 
 Once the thread's activity is started, the thread is considered
-'alive' and 'active' (these concepts are almost, but not quite
-exactly, the same; their definition is intentionally somewhat
-vague).  It stops being alive and active when its \method{run()}
-method terminates -- either normally, or by raising an unhandled
-exception.  The \method{isAlive()} method tests whether the thread is
-alive.
+'alive'. It stops being alive when its \method{run()} method terminates
+-- either normally, or by raising an unhandled exception.  The
+\method{isAlive()} method tests whether the thread is alive.
 
 Other threads can call a thread's \method{join()} method.  This blocks
 the calling thread until the thread whose \method{join()} method is
@@ -551,14 +547,13 @@
 initial thread of control in the Python program.  It is not a
 daemon thread.
 
-There is the possibility that ``dummy thread objects'' are
-created.  These are thread objects corresponding to ``alien
-threads''.  These are threads of control started outside the
-threading module, such as directly from C code.  Dummy thread objects
-have limited functionality; they are always considered alive,
-active, and daemonic, and cannot be \method{join()}ed.  They are never 
-deleted, since it is impossible to detect the termination of alien
-threads.
+There is the possibility that ``dummy thread objects'' are created.
+These are thread objects corresponding to ``alien threads'', which
+are threads of control started outside the threading module, such as
+directly from C code.  Dummy thread objects have limited
+functionality; they are always considered alive and daemonic, and
+cannot be \method{join()}ed.  They are never deleted, since it is
+impossible to detect the termination of alien threads.
 
 
 \begin{classdesc}{Thread}{group=None, target=None, name=None,
@@ -646,7 +641,8 @@
 Return whether the thread is alive.
 
 Roughly, a thread is alive from the moment the \method{start()} method
-returns until its \method{run()} method terminates.
+returns until its \method{run()} method terminates. The module
+function \function{enumerate()} returns a list of all alive threads.
 \end{methoddesc}
 
 \begin{methoddesc}{isDaemon}{}
@@ -659,8 +655,8 @@
 
 The initial value is inherited from the creating thread.
 
-The entire Python program exits when no active non-daemon
-threads are left.
+The entire Python program exits when no alive non-daemon threads are
+left.
 \end{methoddesc}
 
 

Modified: python/branches/p3yk/Doc/lib/libtimeit.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libtimeit.tex	(original)
+++ python/branches/p3yk/Doc/lib/libtimeit.tex	Fri Apr 27 21:54:29 2007
@@ -31,6 +31,13 @@
 \method{timeit()} method.  The \method{repeat()} method is a
 convenience to call \method{timeit()} multiple times and return a list
 of results.
+
+\versionchanged[The \var{stmt} and \var{setup} parameters can now also
+                take objects that are callable without arguments. This
+		will embed calls to them in a timer function that will
+		then be executed by \method{timeit()}.  Note that the timing
+		overhead is a little larger in this case because of the
+		extra function calls]{2.6}
 \end{classdesc}
 
 \begin{methoddesc}{print_exc}{\optional{file=\constant{None}}}
@@ -97,12 +104,30 @@
 \end{methoddesc}
 
 
+Starting with version 2.6, the module also defines two convenience functions:
+
+\begin{funcdesc}{repeat}{stmt\optional{, setup\optional{, timer\optional{,
+                         repeat\code{=3} \optional{, number\code{=1000000}}}}}}
+Create a \class{Timer} instance with the given statement, setup code and timer
+function and run its \method{repeat} method with the given repeat count and
+\var{number} executions.
+\versionadded{2.6}
+\end{funcdesc}
+
+\begin{funcdesc}{timeit}{stmt\optional{, setup\optional{, timer\optional{,
+                         number\code{=1000000}}}}}
+Create a \class{Timer} instance with the given statement, setup code and timer
+function and run its \method{timeit} method with \var{number} executions.
+\versionadded{2.6}
+\end{funcdesc}
+
+
 \subsection{Command Line Interface}
 
 When called as a program from the command line, the following form is used:
 
 \begin{verbatim}
-python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]
+python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]
 \end{verbatim}
 
 where the following options are understood:

Modified: python/branches/p3yk/Doc/lib/libturtle.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libturtle.tex	(original)
+++ python/branches/p3yk/Doc/lib/libturtle.tex	Fri Apr 27 21:54:29 2007
@@ -261,7 +261,7 @@
 \function{degrees()}, which takes an optional argument letting 
 you specify the number of units corresponding to a full circle:
 
-\begin{methoddesc}{degrees}{\optional{fullcircle}}
+\begin{methoddesc}[Turtle]{degrees}{\optional{fullcircle}}
 \var{fullcircle} is by default 360. This can cause the pen to have any
 angular units whatever: give \var{fullcircle} 2*$\pi$ for radians, or
 400 for gradians.

Modified: python/branches/p3yk/Doc/lib/libunittest.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libunittest.tex	(original)
+++ python/branches/p3yk/Doc/lib/libunittest.tex	Fri Apr 27 21:54:29 2007
@@ -91,7 +91,7 @@
 \end{seealso}
 
 
-\subsection{Basic example \label{minimal-example}}
+\subsection{Basic example \label{unittest-minimal-example}}
 
 The \module{unittest} module provides a rich set of tools for
 constructing and running tests.  This section demonstrates that a
@@ -290,6 +290,7 @@
 we would end up subclassing \class{SimpleWidgetTestCase} into many
 small one-method classes such as
 \class{DefaultWidgetSizeTestCase}.  This is time-consuming and
+
 discouraging, so in the same vein as JUnit, \module{unittest} provides
 a simpler mechanism:
 
@@ -540,7 +541,7 @@
 
 \begin{funcdesc}{main}{\optional{module\optional{,
                  defaultTest\optional{, argv\optional{,
-                 testRunner\optional{, testRunner}}}}}}
+                 testRunner\optional{, testLoader}}}}}}
   A command-line program that runs a set of tests; this is primarily
   for making test modules conveniently executable.  The simplest use
   for this function is to include the following line at the end of a
@@ -550,6 +551,9 @@
 if __name__ == '__main__':
     unittest.main()
 \end{verbatim}
+
+  The \var{testRunner} argument can either be a test runner class or
+  an already created instance of it.
 \end{funcdesc}
 
 In some cases, the existing tests may have been written using the
@@ -615,14 +619,14 @@
 report failures.
 
 \begin{methoddesc}[TestCase]{assert_}{expr\optional{, msg}}
-\methodline{failUnless}{expr\optional{, msg}}
+\methodline[TestCase]{failUnless}{expr\optional{, msg}}
   Signal a test failure if \var{expr} is false; the explanation for
   the error will be \var{msg} if given, otherwise it will be
   \constant{None}.
 \end{methoddesc}
 
 \begin{methoddesc}[TestCase]{assertEqual}{first, second\optional{, msg}}
-\methodline{failUnlessEqual}{first, second\optional{, msg}}
+\methodline[TestCase]{failUnlessEqual}{first, second\optional{, msg}}
   Test that \var{first} and \var{second} are equal.  If the values do
   not compare equal, the test will fail with the explanation given by
   \var{msg}, or \constant{None}.  Note that using \method{failUnlessEqual()}
@@ -633,7 +637,7 @@
 \end{methoddesc}
 
 \begin{methoddesc}[TestCase]{assertNotEqual}{first, second\optional{, msg}}
-\methodline{failIfEqual}{first, second\optional{, msg}}
+\methodline[TestCase]{failIfEqual}{first, second\optional{, msg}}
   Test that \var{first} and \var{second} are not equal.  If the values
   do compare equal, the test will fail with the explanation given by
   \var{msg}, or \constant{None}.  Note that using \method{failIfEqual()}
@@ -645,7 +649,7 @@
 
 \begin{methoddesc}[TestCase]{assertAlmostEqual}{first, second\optional{,
 						places\optional{, msg}}}
-\methodline{failUnlessAlmostEqual}{first, second\optional{,
+\methodline[TestCase]{failUnlessAlmostEqual}{first, second\optional{,
 						places\optional{, msg}}}
   Test that \var{first} and \var{second} are approximately equal
   by computing the difference, rounding to the given number of \var{places},
@@ -657,7 +661,7 @@
 
 \begin{methoddesc}[TestCase]{assertNotAlmostEqual}{first, second\optional{,
 						places\optional{, msg}}}
-\methodline{failIfAlmostEqual}{first, second\optional{,
+\methodline[TestCase]{failIfAlmostEqual}{first, second\optional{,
 						places\optional{, msg}}}
   Test that \var{first} and \var{second} are not approximately equal
   by computing the difference, rounding to the given number of \var{places},
@@ -668,7 +672,7 @@
 \end{methoddesc}
 
 \begin{methoddesc}[TestCase]{assertRaises}{exception, callable, \moreargs}
-\methodline{failUnlessRaises}{exception, callable, \moreargs}
+\methodline[TestCase]{failUnlessRaises}{exception, callable, \moreargs}
   Test that an exception is raised when \var{callable} is called with
   any positional or keyword arguments that are also passed to
   \method{assertRaises()}.  The test passes if \var{exception} is

Modified: python/branches/p3yk/Doc/lib/liburllib2.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/liburllib2.tex	(original)
+++ python/branches/p3yk/Doc/lib/liburllib2.tex	Fri Apr 27 21:54:29 2007
@@ -588,7 +588,7 @@
 
 \class{HTTPCookieProcessor} instances have one attribute:
 
-\begin{memberdesc}{cookiejar}
+\begin{memberdesc}[HTTPCookieProcessor]{cookiejar}
 The \class{cookielib.CookieJar} in which cookies are stored.
 \end{memberdesc}
 
@@ -817,7 +817,10 @@
 import urllib2
 # Create an OpenerDirector with support for Basic HTTP Authentication...
 auth_handler = urllib2.HTTPBasicAuthHandler()
-auth_handler.add_password('realm', 'host', 'username', 'password')
+auth_handler.add_password(realm='PDQ Application',
+                          uri='https://mahler:8092/site-updates.py',
+                          user='klem',
+                          passwd='kadidd!ehopper')
 opener = urllib2.build_opener(auth_handler)
 # ...and install it globally so it can be used with urlopen.
 urllib2.install_opener(opener)

Modified: python/branches/p3yk/Doc/lib/liburlparse.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/liburlparse.tex	(original)
+++ python/branches/p3yk/Doc/lib/liburlparse.tex	Fri Apr 27 21:54:29 2007
@@ -157,7 +157,7 @@
 for \function{urlparse()}.
 
 \note{If \var{url} is an absolute URL (that is, starting with \code{//}
-      or \code{scheme://}, the \var{url}'s host name and/or scheme
+      or \code{scheme://}), the \var{url}'s host name and/or scheme
       will be present in the result.  For example:}
 
 \begin{verbatim}

Modified: python/branches/p3yk/Doc/lib/libwebbrowser.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libwebbrowser.tex	(original)
+++ python/branches/p3yk/Doc/lib/libwebbrowser.tex	Fri Apr 27 21:54:29 2007
@@ -154,20 +154,20 @@
 Browser controllers provide two methods which parallel two of the
 module-level convenience functions:
 
-\begin{funcdesc}{open}{url\optional{, new\optional{, autoraise=1}}}
+\begin{methoddesc}[controller]{open}{url\optional{, new\optional{, autoraise=1}}}
   Display \var{url} using the browser handled by this controller.
   If \var{new} is 1, a new browser window is opened if possible.
   If \var{new} is 2, a new browser page ("tab") is opened if possible.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{open_new}{url}
+\begin{methoddesc}[controller]{open_new}{url}
   Open \var{url} in a new window of the browser handled by this
   controller, if possible, otherwise, open \var{url} in the only
   browser window.  Alias \function{open_new}.
-\end{funcdesc}
+\end{methoddesc}
 
-\begin{funcdesc}{open_new_tab}{url}
+\begin{methoddesc}[controller]{open_new_tab}{url}
   Open \var{url} in a new page ("tab") of the browser handled by this
   controller, if possible, otherwise equivalent to \function{open_new}.
 \versionadded{2.5}
-\end{funcdesc}
+\end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libwinreg.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libwinreg.tex	(original)
+++ python/branches/p3yk/Doc/lib/libwinreg.tex	Fri Apr 27 21:54:29 2007
@@ -151,7 +151,7 @@
  An application should only call \function{FlushKey()} if it requires absolute 
  certainty that registry changes are on disk.
  
- \emph{If you don't know whether a \function{FlushKey()} call is required, it 
+ \note{If you don't know whether a \function{FlushKey()} call is required, it 
  probably isn't.}
  
 \end{funcdesc}
@@ -393,14 +393,14 @@
  \method{Detach()} method to return the integer handle, and
  also disconnect the Windows handle from the handle object.
 
-\begin{methoddesc}{Close}{}
+\begin{methoddesc}[PyHKEY]{Close}{}
   Closes the underlying Windows handle.
 
   If the handle is already closed, no error is raised.
 \end{methoddesc}
 
 
-\begin{methoddesc}{Detach}{}
+\begin{methoddesc}[PyHKEY]{Detach}{}
   Detaches the Windows handle from the handle object.
 
  The result is an integer (or long on 64 bit Windows) that holds

Modified: python/branches/p3yk/Doc/lib/libxmlrpclib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libxmlrpclib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libxmlrpclib.tex	Fri Apr 27 21:54:29 2007
@@ -134,12 +134,12 @@
 Servers that support the XML introspection API support some common
 methods grouped under the reserved \member{system} member:
 
-\begin{methoddesc}{system.listMethods}{}
+\begin{methoddesc}[ServerProxy]{system.listMethods}{}
 This method returns a list of strings, one for each (non-system)
 method supported by the XML-RPC server.
 \end{methoddesc}
 
-\begin{methoddesc}{system.methodSignature}{name}
+\begin{methoddesc}[ServerProxy]{system.methodSignature}{name}
 This method takes one parameter, the name of a method implemented by
 the XML-RPC server.It returns an array of possible signatures for this
 method. A signature is an array of types. The first of these types is
@@ -159,7 +159,7 @@
 value will be something other that list.
 \end{methoddesc}
 
-\begin{methoddesc}{system.methodHelp}{name}
+\begin{methoddesc}[ServerProxy]{system.methodHelp}{name}
 This method takes one parameter, the name of a method implemented by
 the XML-RPC server.  It returns a documentation string describing the
 use of that method. If no such string is available, an empty string is
@@ -184,7 +184,7 @@
 It also has the following method, supported mainly for internal use by
 the unmarshalling code:
 
-\begin{methoddesc}{encode}{out}
+\begin{methoddesc}[Boolean]{encode}{out}
 Write the XML-RPC encoding of this Boolean item to the out stream object.
 \end{methoddesc}
 
@@ -197,11 +197,11 @@
 instance.  It has the following methods, supported mainly for internal use
 by the marshalling/unmarshalling code:
 
-\begin{methoddesc}{decode}{string}
+\begin{methoddesc}[DateTime]{decode}{string}
 Accept a string as the instance's new time value.
 \end{methoddesc}
 
-\begin{methoddesc}{encode}{out}
+\begin{methoddesc}[DateTime]{encode}{out}
 Write the XML-RPC encoding of this \class{DateTime} item to the
 \var{out} stream object.
 \end{methoddesc}
@@ -242,11 +242,11 @@
 A \class{Fault} object encapsulates the content of an XML-RPC fault tag.
 Fault objects have the following members:
 
-\begin{memberdesc}{faultCode}
+\begin{memberdesc}[Fault]{faultCode}
 A string indicating the fault type.
 \end{memberdesc}
 
-\begin{memberdesc}{faultString}
+\begin{memberdesc}[Fault]{faultString}
 A string containing a diagnostic message associated with the fault.
 \end{memberdesc}
 
@@ -258,19 +258,19 @@
 server named by the URI does not exist).  It has the following
 members:
 
-\begin{memberdesc}{url}
+\begin{memberdesc}[ProtocolError]{url}
 The URI or URL that triggered the error.
 \end{memberdesc}
 
-\begin{memberdesc}{errcode}
+\begin{memberdesc}[ProtocolError]{errcode}
 The error code.
 \end{memberdesc}
 
-\begin{memberdesc}{errmsg}
+\begin{memberdesc}[ProtocolError]{errmsg}
 The error message or diagnostic string.
 \end{memberdesc}
 
-\begin{memberdesc}{headers}
+\begin{memberdesc}[ProtocolError]{headers}
 A string containing the headers of the HTTP/HTTPS request that
 triggered the error.
 \end{memberdesc}

Modified: python/branches/p3yk/Doc/lib/libzipfile.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libzipfile.tex	(original)
+++ python/branches/p3yk/Doc/lib/libzipfile.tex	Fri Apr 27 21:54:29 2007
@@ -141,6 +141,34 @@
   Return a list of archive members by name.
 \end{methoddesc}
 
+\begin{methoddesc}{open}{name\optional{, mode\optional{, pwd}}}
+    Extract a member from the archive as a file-like object (ZipExtFile).
+    \var{name} is the name of the file in the archive. The \var{mode}
+    parameter, if included, must be one of the following: \code{'r'} (the 
+    default), \code{'U'}, or \code{'rU'}. Choosing \code{'U'} or 
+    \code{'rU'} will enable universal newline support in the read-only
+    object. \var{pwd} is the password used for encrypted files.
+    \begin{notice}
+        The file-like object is read-only and provides the following methods:
+        \method{read()}, \method{readline()}, \method{readlines()},
+        \method{__iter__()}, \method{next()}. 
+    \end{notice}
+    \begin{notice}
+        If the ZipFile was created by passing in a file-like object as the 
+        first argument to the constructor, then the object returned by
+        \method{open()} shares the ZipFile's file pointer.  Under these 
+        circumstances, the object returned by \method{open()} should not 
+        be used after any additional operations are performed on the 
+        ZipFile object.  If the ZipFile was created by passing in a string
+        (the filename) as the first argument to the constructor, then 
+        \method{open()} will create a new file object that will be held
+        by the ZipExtFile, allowing it to operate independently of the 
+        ZipFile.
+    \end{notice}
+
+    \versionadded{2.6}
+\end{methoddesc}
+
 \begin{methoddesc}{printdir}{}
   Print a table of contents for the archive to \code{sys.stdout}.
 \end{methoddesc}

Modified: python/branches/p3yk/Doc/lib/libzlib.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libzlib.tex	(original)
+++ python/branches/p3yk/Doc/lib/libzlib.tex	Fri Apr 27 21:54:29 2007
@@ -131,7 +131,7 @@
 
 Decompression objects support the following methods, and two attributes:
 
-\begin{memberdesc}{unused_data}
+\begin{memberdesc}[Decompress]{unused_data}
 A string which contains any bytes past the end of the compressed data.
 That is, this remains \code{""} until the last byte that contains
 compression data is available.  If the whole string turned out to
@@ -145,7 +145,7 @@
 \member{unused_data} attribute is no longer the empty string.
 \end{memberdesc}
 
-\begin{memberdesc}{unconsumed_tail}
+\begin{memberdesc}[Decompress]{unconsumed_tail}
 A string that contains any data that was not consumed by the last
 \method{decompress} call because it exceeded the limit for the
 uncompressed data buffer.  This data has not yet been seen by the zlib

Modified: python/branches/p3yk/Doc/mac/libframework.tex
==============================================================================
--- python/branches/p3yk/Doc/mac/libframework.tex	(original)
+++ python/branches/p3yk/Doc/mac/libframework.tex	Fri Apr 27 21:54:29 2007
@@ -189,8 +189,6 @@
 
 Window objects have the following methods, among others:
 
-\setindexsubitem{(Window method)}
-
 \begin{methoddesc}[Window]{open}{}
 Override this method to open a window. Store the MacOS window-id in
 \member{self.wid} and call the \method{do_postopen()} method to
@@ -218,7 +216,7 @@
 An update event for the window was received. Redraw the window.
 \end{methoddesc}
 
-\begin{methoddesc}{do_activate}{activate, event}
+\begin{methoddesc}[Window]{do_activate}{activate, event}
 The window was activated (\code{\var{activate} == 1}) or deactivated
 (\code{\var{activate} == 0}). Handle things like focus highlighting,
 etc.

Modified: python/branches/p3yk/Doc/mac/libmacic.tex
==============================================================================
--- python/branches/p3yk/Doc/mac/libmacic.tex	(original)
+++ python/branches/p3yk/Doc/mac/libmacic.tex	Fri Apr 27 21:54:29 2007
@@ -68,14 +68,14 @@
 following methods:
 
 
-\begin{methoddesc}{launchurl}{url\optional{, hint}}
+\begin{methoddesc}[IC]{launchurl}{url\optional{, hint}}
 Parse the given URL, launch the correct application and pass it the
 URL. The optional \var{hint} can be a scheme name such as
 \code{'mailto:'}, in which case incomplete URLs are completed with this
 scheme.  If \var{hint} is not provided, incomplete URLs are invalid.
 \end{methoddesc}
 
-\begin{methoddesc}{parseurl}{data\optional{, start\optional{, end\optional{, hint}}}}
+\begin{methoddesc}[IC]{parseurl}{data\optional{, start\optional{, end\optional{, hint}}}}
 Find an URL somewhere in \var{data} and return start position, end
 position and the URL. The optional \var{start} and \var{end} can be
 used to limit the search, so for instance if a user clicks in a long
@@ -85,7 +85,7 @@
 complete incomplete URLs.
 \end{methoddesc}
 
-\begin{methoddesc}{mapfile}{file}
+\begin{methoddesc}[IC]{mapfile}{file}
 Return the mapping entry for the given \var{file}, which can be passed
 as either a filename or an \function{FSSpec()} result, and which
 need not exist.
@@ -106,7 +106,7 @@
 file and \var{entryname} is the name of this entry.
 \end{methoddesc}
 
-\begin{methoddesc}{maptypecreator}{type, creator\optional{, filename}}
+\begin{methoddesc}[IC]{maptypecreator}{type, creator\optional{, filename}}
 Return the mapping entry for files with given 4-character \var{type} and
 \var{creator} codes. The optional \var{filename} may be specified to
 further help finding the correct entry (if the creator code is
@@ -115,7 +115,7 @@
 The mapping entry is returned in the same format as for \var{mapfile}.
 \end{methoddesc}
 
-\begin{methoddesc}{settypecreator}{file}
+\begin{methoddesc}[IC]{settypecreator}{file}
 Given an existing \var{file}, specified either as a filename or as an
 \function{FSSpec()} result, set its creator and type correctly based
 on its extension.  The finder is told about the change, so the finder

Modified: python/branches/p3yk/Doc/mac/undoc.tex
==============================================================================
--- python/branches/p3yk/Doc/mac/undoc.tex	(original)
+++ python/branches/p3yk/Doc/mac/undoc.tex	Fri Apr 27 21:54:29 2007
@@ -21,7 +21,7 @@
 \modulesynopsis{Helper module for BuildApplet, BuildApplication and
                 macfreeze.}
 
-\deprecated{2.4}
+\deprecated{2.4}{}
 
 \section{\module{cfmfile} --- Code Fragment Resource module}
 \declaremodule{standard}{cfmfile}
@@ -33,7 +33,7 @@
 used by BuildApplication to combine all plugin modules to a single
 executable.
 
-\deprecated{2.4}
+\deprecated{2.4}{}
 
 \section{\module{icopen} --- Internet Config replacement for \method{open()}}
 \declaremodule{standard}{icopen}

Modified: python/branches/p3yk/Doc/mac/using.tex
==============================================================================
--- python/branches/p3yk/Doc/mac/using.tex	(original)
+++ python/branches/p3yk/Doc/mac/using.tex	Fri Apr 27 21:54:29 2007
@@ -2,7 +2,7 @@
 \sectionauthor{Bob Savage}{bobsavage at mac.com}
 
 Python on a Macintosh running Mac OS X is in principle very similar to
-Python on any other \UNIX platform, but there are a number of additional
+Python on any other \UNIX{} platform, but there are a number of additional
 features such as the IDE and the Package Manager that are worth pointing out.
 
 Python on Mac OS 9 or earlier can be quite different from Python on
@@ -13,206 +13,166 @@
 
 \section{Getting and Installing MacPython \label{getting-OSX}}
 
-Mac OS X 10.3 comes with Python 2.3 pre-installed by Apple.
-This installation does not come with the IDE and other additions, however,
-so to get these you need to install the \program{MacPython for Panther additions}
-from the MacPython website, \url{http://www.cwi.nl/\textasciitilde jack/macpython}.
-
-For MacPython 2.4, or for any MacPython on earlier releases of Mac OS X,
-you need to install a full distribution from the same website.
+Mac OS X 10.4 comes with Python 2.3 pre-installed by Apple. However, you are
+encouraged to install the most recent version of Python from the Python website
+(\url{http://www.python.org}). A ``universal binary'' build of Python 2.5, which
+runs natively on the Mac's new Intel and legacy PPC CPU's, is available there.
 
 What you get after installing is a number of things:
 
 \begin{itemize}
-    \item A \file{MacPython-2.3} folder in your \file{Applications}
-    folder. In here you find the PythonIDE Integrated Development Environment;
-    PythonLauncher, which handles double-clicking Python scripts from
-    the Finder; and the Package Manager.
-    
-    \item A fairly standard \UNIX{} commandline Python interpreter in
-    \file{/usr/local/bin/python}, but without the usual
-    \file{/usr/local/lib/python}.
-    
-    \item A framework \file{/Library/Frameworks/Python.framework}, where
-    all the action really is, but which you usually do not have to be aware of.
+\item A \file{MacPython 2.5} folder in your \file{Applications} folder. In here
+  you find IDLE, the development environment that is a standard part of official
+  Python distributions; PythonLauncher, which handles double-clicking Python
+  scripts from the Finder; and the ``Build Applet'' tool, which allows you to
+  package Python scripts as standalone applications on your system.
+
+\item A framework \file{/Library/Frameworks/Python.framework}, which includes
+  the Python executable and libraries. The installer adds this location to your
+  shell path. To uninstall MacPython, you can simply remove these three
+  things. A symlink to the Python executable is placed in /usr/local/bin/.
 \end{itemize}
 
-To uninstall MacPython you can simply remove these three things.
+The Apple-provided build of Python is installed in
+\file{/System/Library/Frameworks/Python.framework} and \file{/usr/bin/python},
+respectively. You should never modify or delete these, as they are
+Apple-controlled and are used by Apple- or third-party software.
+
+IDLE includes a help menu that allows you to access Python documentation. If you
+are completely new to Python you should start reading the tutorial introduction
+in that document.
 
-If you use the ``additions'' installer to install on top of an existing
-Apple-Python you will not get the framework and the commandline interpreter,
-as they have been installed by Apple already, in
-\file{/System/Library/Frameworks/Python.framework} and
-\file{/usr/bin/python}, respectively. You should in principle never modify
-or delete these, as they are Apple-controlled and may be used by Apple- or
-third-party software.
-
-PythonIDE contains an Apple Help Viewer book called "MacPython Help"
-which you can access through its help menu. If you are completely new to
-Python you should start reading the IDE introduction in that document.
+If you are familiar with Python on other \UNIX{} platforms you should read the
+section on running Python scripts from the \UNIX{} shell.
 
-If you are familiar with Python on other \UNIX{} platforms you should
-read the section on running Python scripts from the \UNIX{} shell.
 
 \subsection{How to run a Python script}
 
-Your best way to get started with Python on Mac OS X is through the PythonIDE
-integrated development environment, see section \ref{IDE} and use the Help
-menu when the IDE is running.
-
-If you want to run Python scripts from the Terminal window command line
-or from the Finder you first need an editor to create your script.
-Mac OS X comes with a number of standard \UNIX{} command line editors,
-\program{vim} and \program{emacs} among them. If you want a more Mac-like
-editor \program{BBEdit} or \program{TextWrangler} from Bare Bones Software
-(see \url{http://www.barebones.com/products/bbedit/index.shtml}) are
-good choices.  \program{AppleWorks} or any other
-word processor that can save files in ASCII is also a possibility, including
-\program{TextEdit} which is included with OS X.
+Your best way to get started with Python on Mac OS X is through the IDLE
+integrated development environment, see section \ref{IDE} and use the Help menu
+when the IDE is running.
+
+If you want to run Python scripts from the Terminal window command line or from
+the Finder you first need an editor to create your script. Mac OS X comes with a
+number of standard \UNIX{} command line editors, \program{vim} and
+\program{emacs} among them. If you want a more Mac-like editor, \program{BBEdit}
+or \program{TextWrangler} from Bare Bones Software (see
+\url{http://www.barebones.com/products/bbedit/index.shtml}) are good choices, as
+is \program{TextMate} (see \url{http://macromates.com/}). Other editors include
+\program{Gvim} (\url{http://macvim.org}) and \program{Aquamacs}
+(\url{http://aquamacs.org}).
 
 To run your script from the Terminal window you must make sure that
-\file{/usr/local/bin} is in your shell search path. 
+\file{/usr/local/bin} is in your shell search path.
 
 To run your script from the Finder you have two options:
+
 \begin{itemize}
-    \item Drag it to \program{PythonLauncher}
-    \item Select \program{PythonLauncher} as the default application
-    to open your script (or any .py script) through the finder Info window
-    and double-click it.
+\item Drag it to \program{PythonLauncher}
+\item Select \program{PythonLauncher} as the default application to open your
+  script (or any .py script) through the finder Info window and double-click it.
+  \program{PythonLauncher} has various preferences to control how your script is
+  launched. Option-dragging allows you to change these for one invocation, or
+  use its Preferences menu to change things globally.
 \end{itemize}
 
-PythonLauncher has various preferences to control how your script is launched.
-Option-dragging allows you to change these for one invocation, or use its
-Preferences menu to change things globally.
 
 \subsection{Running scripts with a GUI \label{osx-gui-scripts}}
 
-There is one Mac OS X quirk that you need to be aware of: programs
-that talk to the Aqua window manager (in other words, anything that has a GUI)
-need to be run in a special way. Use \program{pythonw} instead of \program{python}
-to start such scripts.
-
-\subsection{configuration}
-
-MacPython honours all standard \UNIX{} environment variables such as
-\envvar{PYTHONPATH}, but setting these variables for programs started
-from the Finder is non-standard
-as the Finder does not read your \file{.profile} or \file{.cshrc} at startup.
-You need to create a file \file{\textasciitilde /.MacOSX/environment.plist}.
-See Apple's Technical Document QA1067 for details.
+With older versions of Python, there is one Mac OS X quirk that you need to be
+aware of: programs that talk to the Aqua window manager (in other words,
+anything that has a GUI) need to be run in a special way. Use \program{pythonw}
+instead of \program{python} to start such scripts.
+
+With Python 2.5, you can use either \program{python} or \program{pythonw}.
+
+\subsection{Configuration}
+
+Python on OS X honors all standard \UNIX{} environment variables such as
+\envvar{PYTHONPATH}, but setting these variables for programs started from the
+Finder is non-standard as the Finder does not read your \file{.profile} or
+\file{.cshrc} at startup. You need to create a file \file{\textasciitilde
+  /.MacOSX/environment.plist}. See Apple's Technical Document QA1067 for
+details.
 
-Installing additional Python packages is most easily done through the
-Package Manager, see the MacPython Help Book for details.
+For more information on installation Python packages in MacPython, see section
+\ref{mac-package-manager}, ``Installing Additional Python Packages.''
 
 
 \section{The IDE\label{IDE}}
 
-The \program{Python IDE} (Integrated Development Environment) is a
-separate application that acts as a text editor for your Python code,
-a class browser, a graphical debugger, and more.
-
-The online Python Help contains a quick walkthrough of the IDE that
-shows the major features and how to use them.
-
-\subsection{Using the ``Python Interactive'' window}
-
-Use this window like you would use a normal \UNIX{} command line
-interpreter.
-
-\subsection{Writing a Python Script \label{IDEwrite}}
-
-In addition to using the \program{Python IDE} interactively, you can
-also type out a complete Python program, saving it incrementally, and
-execute it or smaller selections of it.
-
-You can create a new script, open a previously saved script, and save
-your currently open script by selecting the appropriate item in the
-``File'' menu. Dropping a Python script onto the
-\program{Python IDE} will open it for editing.
-
-When the \program{Python IDE} saves a script, it uses the creator code
-settings which are available by clicking on the small black triangle
-on the top right of the document window, and selecting ``save
-options''. The default is to save the file with the \program{Python
-IDE} as the creator, this means that you can open the file for editing
-by simply double-clicking on its icon. You might want to change this
-behaviour so that it will be opened by the
-\program{PythonLauncher}, and run. To do this simply choose
-``PythonLauncher'' from the ``save options''. Note that these
-options are associated with the \emph{file} not the application.
-
-
-\subsection{Executing a script from within the IDE
-            \label{IDEexecution}}
-
-You can run the script in the frontmost window of the \program{Python
-IDE} by hitting the run all button.  You should be aware, however that
-if you use the Python convention \samp{if __name__ == "__main__":} the
-script will \emph{not} be ``__main__'' by default. To get that
-behaviour you must select the ``Run as __main__'' option from the
-small black triangle on the top right of the document window.  Note
-that this option is associated with the \emph{file} not the
-application. It \emph{will} stay active after a save, however; to shut
-this feature off simply select it again.
- 
-
-\subsection{``Save as'' versus ``Save as Applet''
-            \label{IDEapplet}}
-
-When you are done writing your Python script you have the option of
-saving it as an ``applet'' (by selecting ``Save as applet'' from the
-``File'' menu). This has a significant advantage in that you can drop
-files or folders onto it, to pass them to the applet the way
-command-line users would type them onto the command-line to pass them
-as arguments to the script. However, you should make sure to save the
-applet as a separate file, do not overwrite the script you are
-writing, because you will not be able to edit it again.
-
-Accessing the items passed to the applet via ``drag-and-drop'' is done
-using the standard \member{sys.argv} mechanism. See the general
-documentation for more
-% need to link to the appropriate place in non-Mac docs
-
-Note that saving a script as an applet will not make it runnable on a
-system without a Python installation.
-
-%\subsection{Debugger}
-% **NEED INFO HERE**
- 
-%\subsection{Module Browser}
-% **NEED INFO HERE**
- 
-%\subsection{Profiler}
-% **NEED INFO HERE**
-% end IDE
-
-%\subsection{The ``Scripts'' menu}
-% **NEED INFO HERE**
-
-\section{The Package Manager}
-
-Historically MacPython came with a number of useful extension packages
-included, because most Macintosh users do not have access to a development
-environment and C compiler. For Mac OS X that bundling is no longer done,
-but a new mechanism has been made available to allow easy access to
-extension packages.
-
-The Python Package Manager helps you installing additional packages
-that enhance Python. It determines the exact MacOS version  and Python
-version you have and uses that information to download  a database that
-has packages that are tested and tried on that combination. In other
-words: if something is in your Package Manager  window but does not work
-you are free to blame the database maintainer.
-
-PackageManager then checks which of the packages you have installed  and
-which ones are not. This should also work when you have installed packages 
-outside of PackageManager.  You can select packages and install them,
-and PackageManager will work out the requirements and install these too.
-
-Often PackageManager will list a package in two flavors: binary  and
-source. Binary should always work, source will only work if  you have
-installed the Apple Developer Tools. PackageManager will warn  you about
-this, and also about other external dependencies.
+MacPython ships with the standard IDLE development environment. A good
+introduction to using IDLE can be found at
+\url{http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html}.
+
+
+\section{Installing Additional Python Packages \label{mac-package-manager}}
+
+There are several methods to install additional Python packages:
+
+\begin{itemize}
+\item \url{http://pythonmac.org/packages/} contains selected compiled packages
+  for Python 2.5, 2.4, and 2.3.
+\item Packages can be installed via the standard Python distutils mode
+  (\samp{python setup.py install}).
+\item Many packages can also be installed via the \program{setuptools}
+  extension.
+\end{itemize}
+
+
+\section{GUI Programming on the Mac}
+
+There are several options for building GUI applications on the Mac with Python.
+
+\emph{PyObjC} is a Python binding to Apple's Objective-C/Cocoa framework, which
+is the foundation of most modern Mac development. Information on PyObjC is
+available from \url{http://pybojc.sourceforge.net}.
+
+The standard Python GUI toolkit is \module{Tkinter}, based on the cross-platform
+Tk toolkit (\url{http://www.tcl.tk}). An Aqua-native version of Tk is bundled
+with OS X by Apple, and the latest version can be downloaded and installed from
+\url{http://www.activestate.com}; it can also be built from source.
+
+\emph{wxPython} is another popular cross-platform GUI toolkit that runs natively
+on Mac OS X. Packages and documentation are available from
+\url{http://www.wxpython.org}.
+
+\emph{PyQt} is another popular cross-platform GUI toolkit that runs natively on
+Mac OS X. More information can be found at
+\url{http://www.riverbankcomputing.co.uk/pyqt/}.
+
+
+\section{Distributing Python Applications on the Mac}
+
+The ``Build Applet'' tool that is placed in the MacPython 2.5 folder is fine for
+packaging small Python scripts on your own machine to run as a standard Mac
+application. This tool, however, is not robust enough to distribute Python
+applications to other users.
+
+The standard tool for deploying standalone Python applications on the Mac is
+\program{py2app}. More information on installing and using py2app can be found
+at \url{http://undefined.org/python/\#py2app}.
+
+\section{Application Scripting}
+
+Python can also be used to script other Mac applications via Apple's Open
+Scripting Architecture (OSA); see
+\url{http://appscript.sourceforge.net}. Appscript is a high-level, user-friendly
+Apple event bridge that allows you to control scriptable Mac OS X applications
+using ordinary Python scripts. Appscript makes Python a serious alternative to
+Apple's own \emph{AppleScript} language for automating your Mac. A related
+package, \emph{PyOSA}, is an OSA language component for the Python scripting
+language, allowing Python code to be executed by any OSA-enabled application
+(Script Editor, Mail, iTunes, etc.). PyOSA makes Python a full peer to
+AppleScript.
+
+\section{Other Resources}
+
+The MacPython mailing list is an excellent support resource for Python users and
+developers on the Mac:
+
+\url{http://www.python.org/community/sigs/current/pythonmac-sig/}
+
+Another useful resource is the MacPython wiki:
 
-PackageManager is available as a separate application and also  as a
-function of the IDE, through the File->Package Manager menu  entry.
+\url{http://wiki.python.org/moin/MacPython}

Modified: python/branches/p3yk/Doc/ref/ref1.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref1.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref1.tex	Fri Apr 27 21:54:29 2007
@@ -93,7 +93,7 @@
 \index{syntax}
 \index{notation}
 
-\begin{productionlist}
+\begin{productionlist}[*]
   \production{name}{\token{lc_letter} (\token{lc_letter} | "_")*}
   \production{lc_letter}{"a"..."z"}
 \end{productionlist}

Modified: python/branches/p3yk/Doc/ref/ref3.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref3.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref3.tex	Fri Apr 27 21:54:29 2007
@@ -218,7 +218,7 @@
 \indexii{integer}{representation}
 
 \item[Floating point numbers]
-These represent machine-level double precision floating point numbers.  
+These represent machine-level double precision floating point numbers.
 You are at the mercy of the underlying machine architecture (and
 C or Java implementation) for the accepted range and handling of overflow.
 Python does not support single-precision floating point numbers; the
@@ -470,7 +470,7 @@
 \obindex{function}
 \obindex{user-defined function}
 
-Special attributes: 
+Special attributes:
 
 \begin{tableiii}{lll}{member}{Attribute}{Meaning}{}
   \lineiii{__doc__}{The function's documentation string, or
@@ -860,12 +860,12 @@
 \begin{description}
 
 \item[Code objects]
-Code objects represent \emph{byte-compiled} executable Python code, or 
+Code objects represent \emph{byte-compiled} executable Python code, or
 \emph{bytecode}.
 The difference between a code
 object and a function object is that the function object contains an
 explicit reference to the function's globals (the module in which it
-was defined), while a code object contains no context; 
+was defined), while a code object contains no context;
 also the default argument values are stored in the function object,
 not in the code object (because they represent values calculated at
 run-time).  Unlike function objects, code objects are immutable and
@@ -1069,7 +1069,7 @@
 %=========================================================================
 \section{New-style and classic classes}
 
-Classes and instances come in two flavors: old-style or classic, and new-style.  
+Classes and instances come in two flavors: old-style or classic, and new-style.
 
 Up to Python 2.1, old-style classes were the only flavour available to the
 user.  The concept of (old-style) class is unrelated to the concept of type: if
@@ -1244,7 +1244,7 @@
 string object.
 If a class defines \method{__repr__()} but not \method{__str__()},
 then \method{__repr__()} is also used when an ``informal'' string
-representation of instances of that class is required.		     
+representation of instances of that class is required.
 
 This is typically used for debugging, so it is important that the
 representation is information-rich and unambiguous.
@@ -1280,10 +1280,14 @@
 \code{\var{x}!=\var{y}} calls \code{\var{x}.__ne__(\var{y})},
 \code{\var{x}>\var{y}} calls \code{\var{x}.__gt__(\var{y})}, and
 \code{\var{x}>=\var{y}} calls \code{\var{x}.__ge__(\var{y})}.
-These methods can return any value, but if the comparison operator is
-used in a Boolean context, the return value should be interpretable as
-a Boolean value, else a \exception{TypeError} will be raised.
-By convention, \code{False} is used for false and \code{True} for true.
+
+A rich comparison method may return the singleton \code{NotImplemented} if it
+does not implement the operation for a given pair of arguments.
+By convention, \code{False} and \code{True} are returned for a successful
+comparison. However, these methods can return any value, so if the
+comparison operator is used in a Boolean context (e.g., in the condition
+of an \code{if} statement), Python will call \function{bool()} on the
+value to determine if the result is true or false.
 
 There are no implied relationships among the comparison operators.
 The truth of \code{\var{x}==\var{y}} does not imply that \code{\var{x}!=\var{y}}
@@ -1297,9 +1301,7 @@
 \method{__ge__()} are each other's reflection, and \method{__eq__()}
 and \method{__ne__()} are their own reflection.
 
-Arguments to rich comparison methods are never coerced.  A rich
-comparison method may return \code{NotImplemented} if it does not
-implement the operation for a given pair of arguments.
+Arguments to rich comparison methods are never coerced.
 \end{methoddesc}
 
 \begin{methoddesc}[object]{__cmp__}{self, other}
@@ -1399,7 +1401,7 @@
 dictionary).  \var{name} is the attribute name, \var{value} is the
 value to be assigned to it.
 
-If \method{__setattr__()} wants to assign to an instance attribute, it 
+If \method{__setattr__()} wants to assign to an instance attribute, it
 should not simply execute \samp{self.\var{name} = value} --- this
 would cause a recursive call to itself.  Instead, it should insert the
 value in the dictionary of instance attributes, e.g.,
@@ -1422,8 +1424,8 @@
 
 \begin{methoddesc}[object]{__getattribute__}{self, name}
 Called unconditionally to implement attribute accesses for instances
-of the class. If the class also defines \method{__getattr__()}, the latter 
-will not be called unless \method{__getattribute__()} either calls it 
+of the class. If the class also defines \method{__getattr__()}, the latter
+will not be called unless \method{__getattribute__()} either calls it
 explicitly or raises an \exception{AttributeError}.
 This method should return the (computed) attribute
 value or raise an \exception{AttributeError} exception.
@@ -1475,7 +1477,7 @@
 The default behavior for attribute access is to get, set, or delete the
 attribute from an object's dictionary. For instance, \code{a.x} has a
 lookup chain starting with \code{a.__dict__['x']}, then
-\code{type(a).__dict__['x']}, and continuing 
+\code{type(a).__dict__['x']}, and continuing
 through the base classes of \code{type(a)} excluding metaclasses.
 
 However, if the looked-up value is an object defining one of the descriptor
@@ -1489,14 +1491,14 @@
 How the arguments are assembled depends on \code{a}:
 
 \begin{itemize}
-                      
+
   \item[Direct Call] The simplest and least common call is when user code
     directly invokes a descriptor method:    \code{x.__get__(a)}.
 
   \item[Instance Binding]  If binding to a new-style object instance,
     \code{a.x} is transformed into the call:
     \code{type(a).__dict__['x'].__get__(a, type(a))}.
-                     
+
   \item[Class Binding]  If binding to a new-style class, \code{A.x}
     is transformed into the call: \code{A.__dict__['x'].__get__(None, A)}.
 
@@ -1505,7 +1507,7 @@
     \code{obj.__class__.__mro__} for the base class \code{A} immediately
     preceding \code{B} and then invokes the descriptor with the call:
     \code{A.__dict__['m'].__get__(obj, A)}.
-                     
+
 \end{itemize}
 
 For instance bindings, the precedence of descriptor invocation depends
@@ -1518,7 +1520,7 @@
 Python methods (including \function{staticmethod()} and \function{classmethod()})
 are implemented as non-data descriptors.  Accordingly, instances can
 redefine and override methods.  This allows individual instances to acquire
-behaviors that differ from other instances of the same class.                     
+behaviors that differ from other instances of the same class.
 
 The \function{property()} function is implemented as a data descriptor.
 Accordingly, instances cannot override the behavior of a property.
@@ -1536,14 +1538,14 @@
 variables and reserves just enough space in each instance to hold a value
 for each variable.  Space is saved because \var{__dict__} is not created for
 each instance.
-    
+
 \begin{datadesc}{__slots__}
 This class variable can be assigned a string, iterable, or sequence of strings
 with variable names used by instances.  If defined in a new-style class,
 \var{__slots__} reserves space for the declared variables
 and prevents the automatic creation of \var{__dict__} and \var{__weakref__}
 for each instance.
-\versionadded{2.2}                     
+\versionadded{2.2}
 \end{datadesc}
 
 \noindent
@@ -1555,23 +1557,23 @@
 variables not listed in the \var{__slots__} definition.  Attempts to assign
 to an unlisted variable name raises \exception{AttributeError}. If dynamic
 assignment of new variables is desired, then add \code{'__dict__'} to the
-sequence of strings in the \var{__slots__} declaration.                                     
+sequence of strings in the \var{__slots__} declaration.
 \versionchanged[Previously, adding \code{'__dict__'} to the \var{__slots__}
 declaration would not enable the assignment of new attributes not
-specifically listed in the sequence of instance variable names]{2.3}                     
+specifically listed in the sequence of instance variable names]{2.3}
 
 \item Without a \var{__weakref__} variable for each instance, classes
 defining \var{__slots__} do not support weak references to its instances.
 If weak reference support is needed, then add \code{'__weakref__'} to the
-sequence of strings in the \var{__slots__} declaration.                    
+sequence of strings in the \var{__slots__} declaration.
 \versionchanged[Previously, adding \code{'__weakref__'} to the \var{__slots__}
-declaration would not enable support for weak references]{2.3}                                            
+declaration would not enable support for weak references]{2.3}
 
 \item \var{__slots__} are implemented at the class level by creating
 descriptors (\ref{descriptors}) for each variable name.  As a result,
 class attributes cannot be used to set default values for instance
 variables defined by \var{__slots__}; otherwise, the class attribute would
-overwrite the descriptor assignment. 
+overwrite the descriptor assignment.
 
 \item If a class defines a slot also defined in a base class, the instance
 variable defined by the base class slot is inaccessible (except by retrieving
@@ -1580,14 +1582,19 @@
 
 \item The action of a \var{__slots__} declaration is limited to the class
 where it is defined.  As a result, subclasses will have a \var{__dict__}
-unless they also define  \var{__slots__}.                     
+unless they also define  \var{__slots__}.
 
 \item \var{__slots__} do not work for classes derived from ``variable-length''
-built-in types such as \class{long}, \class{str} and \class{tuple}. 
+built-in types such as \class{long}, \class{str} and \class{tuple}.
 
 \item Any non-string iterable may be assigned to \var{__slots__}.
 Mappings may also be used; however, in the future, special meaning may
-be assigned to the values corresponding to each key.                      
+be assigned to the values corresponding to each key.
+
+\item \var{__class__} assignment works only if both classes have the
+same \var{__slots__}.
+\versionchanged[Previously, \var{__class__} assignment raised an error
+if either new or old class had \var{__slots__}]{2.6}
 
 \end{itemize}
 
@@ -1613,7 +1620,7 @@
 This variable can be any callable accepting arguments for \code{name},
 \code{bases}, and \code{dict}.  Upon class creation, the callable is
 used instead of the built-in \function{type()}.
-\versionadded{2.2}                     
+\versionadded{2.2}
 \end{datadesc}
 
 The appropriate metaclass is determined by the following precedence rules:
@@ -1630,7 +1637,7 @@
 
 \item Otherwise, the old-style, classic metaclass (types.ClassType) is used.
 
-\end{itemize}      
+\end{itemize}
 
 The potential uses for metaclasses are boundless. Some ideas that have
 been explored including logging, interface checking, automatic delegation,
@@ -1663,15 +1670,15 @@
 that mappings provide the methods \method{keys()}, \method{values()},
 \method{items()}, \method{has_key()}, \method{get()}, \method{clear()},
 \method{setdefault()}, \method{iterkeys()}, \method{itervalues()},
-\method{iteritems()}, \method{pop()}, \method{popitem()},		     
+\method{iteritems()}, \method{pop()}, \method{popitem()},
 \method{copy()}, and \method{update()} behaving similar to those for
 Python's standard dictionary objects.  The \module{UserDict} module
 provides a \class{DictMixin} class to help create those methods
 from a base set of \method{__getitem__()}, \method{__setitem__()},
-\method{__delitem__()}, and \method{keys()}.		     
+\method{__delitem__()}, and \method{keys()}.
 Mutable sequences should provide
 methods \method{append()}, \method{count()}, \method{index()},
-\method{extend()},		     
+\method{extend()},
 \method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()}
 and \method{sort()}, like Python standard list objects.  Finally,
 sequence types should implement addition (meaning concatenation) and
@@ -1694,12 +1701,12 @@
   \ttindex{items()}
   \ttindex{iterkeys()}
   \ttindex{itervalues()}
-  \ttindex{iteritems()}    
+  \ttindex{iteritems()}
   \ttindex{has_key()}
   \ttindex{get()}
   \ttindex{setdefault()}
-  \ttindex{pop()}      
-  \ttindex{popitem()}    
+  \ttindex{pop()}
+  \ttindex{popitem()}
   \ttindex{clear()}
   \ttindex{copy()}
   \ttindex{update()}
@@ -1707,7 +1714,7 @@
 \withsubitem{(sequence object method)}{
   \ttindex{append()}
   \ttindex{count()}
-  \ttindex{extend()}    
+  \ttindex{extend()}
   \ttindex{index()}
   \ttindex{insert()}
   \ttindex{pop()}
@@ -1721,7 +1728,7 @@
   \ttindex{__rmul__()}
   \ttindex{__imul__()}
   \ttindex{__contains__()}
-  \ttindex{__iter__()}}		     
+  \ttindex{__iter__()}}
 \withsubitem{(numeric object method)}
 
 \begin{methoddesc}[container object]{__len__}{self}
@@ -1744,7 +1751,7 @@
 (after any special interpretation of negative values),
 \exception{IndexError} should be raised.
 For mapping types, if \var{key} is missing (not in the container),
-\exception{KeyError} should be raised.                     
+\exception{KeyError} should be raised.
 \note{\keyword{for} loops expect that an
 \exception{IndexError} will be raised for illegal indexes to allow
 proper detection of the end of the sequence.}
@@ -1943,7 +1950,7 @@
 \methodline[numeric object]{__rmul__}{self, other}
 \methodline[numeric object]{__rdiv__}{self, other}
 \methodline[numeric object]{__rtruediv__}{self, other}
-\methodline[numeric object]{__rfloordiv__}{self, other}	     
+\methodline[numeric object]{__rfloordiv__}{self, other}
 \methodline[numeric object]{__rmod__}{self, other}
 \methodline[numeric object]{__rdivmod__}{self, other}
 \methodline[numeric object]{__rpow__}{self, other}
@@ -1964,7 +1971,7 @@
     For operands of the same type, it is assumed that if the
     non-reflected method (such as \method{__add__()}) fails the
     operation is not supported, which is why the reflected method
-    is not called.} 
+    is not called.}
 For instance, to evaluate the expression \var{x}\code{-}\var{y},
 where \var{y} is an instance of a class that has an
 \method{__rsub__()} method, \code{\var{y}.__rsub__(\var{x})}
@@ -1989,7 +1996,7 @@
 \methodline[numeric object]{__idiv__}{self, other}
 \methodline[numeric object]{__itruediv__}{self, other}
 \methodline[numeric object]{__ifloordiv__}{self, other}
-\methodline[numeric object]{__imod__}{self, other}		     
+\methodline[numeric object]{__imod__}{self, other}
 \methodline[numeric object]{__ipow__}{self, other\optional{, modulo}}
 \methodline[numeric object]{__ilshift__}{self, other}
 \methodline[numeric object]{__irshift__}{self, other}

Modified: python/branches/p3yk/Doc/ref/ref5.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref5.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref5.tex	Fri Apr 27 21:54:29 2007
@@ -56,7 +56,7 @@
   \production{enclosure}
              {\token{parenth_form} | \token{list_display}}
   \productioncont{| \token{generator_expression} | \token{dict_display}}
-  \productioncont{| \token{string_conversion}}
+  \productioncont{| \token{string_conversion} | \token{yield_atom}}
 \end{productionlist}
 
 
@@ -65,6 +65,7 @@
 \index{identifier}
 
 An identifier occurring as an atom is a name.  See
+section \ref{identifiers} for lexical definition and
 section~\ref{naming} for documentation of naming and binding.
 
 When the name is bound to an object, evaluation of the atom yields
@@ -154,22 +155,20 @@
 square brackets:
 
 \begin{productionlist}
-  \production{test}
-             {\token{or_test} | \token{lambda_form}}
-  \production{testlist}
-             {\token{test} ( "," \token{test} )* [ "," ]}
   \production{list_display}
-             {"[" [\token{listmaker}] "]"}
-  \production{listmaker}
-             {\token{expression} ( \token{list_for}
-              | ( "," \token{expression} )* [","] )}
-  \production{list_iter}
-             {\token{list_for} | \token{list_if}}
+             {"[" [\token{expression_list} | \token{list_comprehension}] "]"}
+  \production{list_comprehension}
+             {\token{expression} \token{list_for}}
   \production{list_for}
-             {"for" \token{expression_list} "in" \token{testlist}
+             {"for" \token{target_list} "in" \token{old_expression_list}
               [\token{list_iter}]}
+  \production{old_expression_list}
+             {\token{old_expression}
+              [("," \token{old_expression})+ [","]]}
+  \production{list_iter}
+             {\token{list_for} | \token{list_if}}
   \production{list_if}
-             {"if" \token{test} [\token{list_iter}]}
+             {"if" \token{old_expression} [\token{list_iter}]}
 \end{productionlist}
 
 A list display yields a new list object.  Its contents are specified
@@ -200,19 +199,18 @@
 
 \begin{productionlist}
   \production{generator_expression}
-             {"(" \token{test} \token{genexpr_for} ")"}
+             {"(" \token{expression} \token{genexpr_for} ")"}
   \production{genexpr_for}
-             {"for" \token{expression_list} "in" \token{test}
+             {"for" \token{target_list} "in" \token{or_test}
               [\token{genexpr_iter}]}
   \production{genexpr_iter}
              {\token{genexpr_for} | \token{genexpr_if}}
   \production{genexpr_if}
-             {"if" \token{test} [\token{genexpr_iter}]}
+             {"if" \token{old_expression} [\token{genexpr_iter}]}
 \end{productionlist}
 
 A generator expression yields a new generator object.
 \obindex{generator}
-\obindex{generator expression}
 It consists of a single expression followed by at least one
 \keyword{for} clause and zero or more \keyword{for} or \keyword{if}
 clauses.  The iterating values of the new generator are those that
@@ -268,6 +266,142 @@
 \indexii{immutable}{object}
 
 
+\subsection{Yield expressions\label{yieldexpr}}
+\kwindex{yield}
+\indexii{yield}{expression}
+\indexii{generator}{function}
+
+\begin{productionlist}
+  \production{yield_atom}
+             {"(" \token{yield_expression} ")"}
+  \production{yield_expression}
+             {"yield" [\token{expression_list}]}
+\end{productionlist}
+
+\versionadded{2.5}
+
+The \keyword{yield} expression is only used when defining a generator
+function, and can only be used in the body of a function definition.
+Using a \keyword{yield} expression in a function definition is
+sufficient to cause that definition to create a generator function
+instead of a normal function.
+
+When a generator function is called, it returns an iterator known as a
+generator.  That generator then controls the execution of a generator
+function.  The execution starts when one of the generator's methods is
+called.  At that time, the execution proceeds to the first
+\keyword{yield} expression, where it is suspended again, returning the
+value of \grammartoken{expression_list} to generator's caller.  By
+suspended we mean that all local state is retained, including the
+current bindings of local variables, the instruction pointer, and the
+internal evaluation stack.  When the execution is resumed by calling
+one of the generator's methods, the function can proceed exactly as
+if the \keyword{yield} expression was just another external call.
+The value of the \keyword{yield} expression after resuming depends on
+the method which resumed the execution.
+
+\index{coroutine}
+
+All of this makes generator functions quite similar to coroutines; they
+yield multiple times, they have more than one entry point and their
+execution can be suspended.  The only difference is that a generator
+function cannot control where should the execution continue after it
+yields; the control is always transfered to the generator's caller.
+
+\obindex{generator}
+
+The following generator's methods can be used to control the execution
+of a generator function:
+
+\exindex{StopIteration}
+
+\begin{methoddesc}[generator]{next}{}
+  Starts the execution of a generator function or resumes it at the
+  last executed \keyword{yield} expression.  When a generator function
+  is resumed with a \method{next()} method, the current \keyword{yield}
+  expression always evaluates to \constant{None}.  The execution then
+  continues to the next \keyword{yield} expression, where the generator
+  is suspended again, and the value of the
+  \grammartoken{expression_list} is returned to \method{next()}'s
+  caller. If the generator exits without yielding another value, a
+  \exception{StopIteration} exception is raised.
+\end{methoddesc}
+
+\begin{methoddesc}[generator]{send}{value}
+  Resumes the execution and ``sends'' a value into the generator
+  function.  The \code{value} argument becomes the result of the
+  current \keyword{yield} expression.  The \method{send()} method
+  returns the next value yielded by the generator, or raises
+  \exception{StopIteration} if the generator exits without yielding
+  another value.
+  When \method{send()} is called to start the generator, it must be
+  called with \constant{None} as the argument, because there is no
+  \keyword{yield} expression that could receieve the value.
+\end{methoddesc}
+
+\begin{methoddesc}[generator]{throw}
+                  {type\optional{, value\optional{, traceback}}}
+  Raises an exception of type \code{type} at the point where generator
+  was paused, and returns the next value yielded by the generator
+  function.  If the generator exits without yielding another value, a
+  \exception{StopIteration} exception is raised.  If the generator
+  function does not catch the passed-in exception, or raises a
+  different exception, then that exception propagates to the caller.
+\end{methoddesc}
+
+\exindex{GeneratorExit}
+
+\begin{methoddesc}[generator]{close}{}
+  Raises a \exception{GeneratorExit} at the point where the generator
+  function was paused.  If the generator function then raises
+  \exception{StopIteration} (by exiting normally, or due to already
+  being closed) or \exception{GeneratorExit} (by not catching the
+  exception), close returns to its caller.  If the generator yields a
+  value, a \exception{RuntimeError} is raised.  If the generator raises
+  any other exception, it is propagated to the caller.  \method{close}
+  does nothing if the generator has already exited due to an exception
+  or normal exit.
+\end{methoddesc}
+
+Here is a simple example that demonstrates the behavior of generators
+and generator functions:
+
+\begin{verbatim}
+>>> def echo(value=None):
+...     print "Execution starts when 'next()' is called for the first time."
+...     try:
+...         while True:
+...             try:
+...                 value = (yield value)
+...             except GeneratorExit:
+...                 # never catch GeneratorExit
+...                 raise
+...             except Exception, e:
+...                 value = e
+...     finally:
+...         print "Don't forget to clean up when 'close()' is called."
+...
+>>> generator = echo(1)
+>>> print generator.next()
+Execution starts when 'next()' is called for the first time.
+1
+>>> print generator.next()
+None
+>>> print generator.send(2)
+2
+>>> generator.throw(TypeError, "spam")
+TypeError('spam',)
+>>> generator.close()
+Don't forget to clean up when 'close()' is called.
+\end{verbatim}
+
+\begin{seealso}
+  \seepep{0342}{Coroutines via Enhanced Generators}
+         {The proposal to enhance the API and syntax of generators,
+          making them usable as simple coroutines.}
+\end{seealso}
+
+
 \section{Primaries\label{primaries}}
 \index{primary}
 
@@ -430,9 +564,8 @@
 
 \begin{productionlist}
   \production{call}
-             {\token{primary} "(" [\token{argument_list} [","]] ")"}
-             {\token{primary} "(" [\token{argument_list} [","] |
-	      \token{test} \token{genexpr_for} ] ")"}                                                   
+             {\token{primary} "(" [\token{argument_list} [","]}
+  \productioncont{            | \token{expression} \token{genexpr_for}] ")"}
   \production{argument_list}
              {\token{positional_arguments} ["," \token{keyword_arguments}]}
   \productioncont{                     ["," "*" \token{expression}]}
@@ -765,10 +898,9 @@
 operations:
 
 \begin{productionlist}
-  % The empty groups below prevent conversion to guillemets.
   \production{shift_expr}
              {\token{a_expr}
-              | \token{shift_expr} ( "<{}<" | ">{}>" ) \token{a_expr}}
+              | \token{shift_expr} ( "<<" | ">>" ) \token{a_expr}}
 \end{productionlist}
 
 These operators accept plain or long integers as arguments.  The
@@ -966,14 +1098,18 @@
 
 
 \section{Boolean operations\label{Booleans}}
+\indexii{Conditional}{expression}
 \indexii{Boolean}{operation}
 
 Boolean operations have the lowest priority of all Python operations:
 
 \begin{productionlist}
   \production{expression}
-             {\token{or_test} [\token{if} \token{or_test} \token{else}
-              \token{test}] | \token{lambda_form}}
+             {\token{conditional_expression} | \token{lambda_form}}
+  \production{old_expression}
+             {\token{or_test} | \token{old_lambda_form}}
+  \production{conditional_expression}
+             {\token{or_test} ["if" \token{or_test} "else" \token{expression}]}
   \production{or_test}
              {\token{and_test} | \token{or_test} "or" \token{and_test}}
   \production{and_test}
@@ -1025,6 +1161,8 @@
 \begin{productionlist}
   \production{lambda_form}
              {"lambda" [\token{parameter_list}]: \token{expression}}
+  \production{old_lambda_form}
+             {"lambda" [\token{parameter_list}]: \token{old_expression}}
 \end{productionlist}
 
 Lambda forms (lambda expressions) have the same syntactic position as

Modified: python/branches/p3yk/Doc/ref/ref6.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref6.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref6.tex	Fri Apr 27 21:54:29 2007
@@ -106,7 +106,8 @@
 
 \begin{productionlist}
   \production{assignment_stmt}
-             {(\token{target_list} "=")+ \token{expression_list}}
+             {(\token{target_list} "=")+
+              (\token{expression_list} | \token{yield_expression})}
   \production{target_list}
              {\token{target} ("," \token{target})* [","]}
   \production{target}
@@ -271,11 +272,11 @@
 
 \begin{productionlist}
   \production{augmented_assignment_stmt}
-             {\token{target} \token{augop} \token{expression_list}}
+             {\token{target} \token{augop}
+              (\token{expression_list} | \token{yield_expression})}
   \production{augop}
              {"+=" | "-=" | "*=" | "/=" | "\%=" | "**="}
-  % The empty groups below prevent conversion to guillemets.
-  \productioncont{| ">{}>=" | "<{}<=" | "\&=" | "\textasciicircum=" | "|="}
+  \productioncont{| ">>=" | "<<=" | "\&=" | "\textasciicircum=" | "|="}
 \end{productionlist}
 
 (See section~\ref{primaries} for the syntax definitions for the last
@@ -404,7 +405,7 @@
 
 \begin{productionlist}
   \production{yield_stmt}
-             {"yield" \token{expression_list}}
+             {\token{yield_expression}}
 \end{productionlist}
 
 \index{generator!function}
@@ -573,15 +574,19 @@
   \production{import_stmt}
              {"import" \token{module} ["as" \token{name}]
                 ( "," \token{module} ["as" \token{name}] )*}
-  \productioncont{| "from" \token{module} "import" \token{identifier}
+  \productioncont{| "from" \token{relative_module} "import" \token{identifier}
                     ["as" \token{name}]}
   \productioncont{  ( "," \token{identifier} ["as" \token{name}] )*}
-  \productioncont{| "from" \token{module} "import" "(" \token{identifier}
-                    ["as" \token{name}]}
+  \productioncont{| "from" \token{relative_module} "import" "("
+                    \token{identifier} ["as" \token{name}]}
   \productioncont{  ( "," \token{identifier} ["as" \token{name}] )* [","] ")"}
   \productioncont{| "from" \token{module} "import" "*"}
   \production{module}
              {(\token{identifier} ".")* \token{identifier}}
+  \production{relative_module}
+             {"."* \token{module} | "."+}
+  \production{name}
+             {\token{identifier}}
 \end{productionlist}
 
 Import statements are executed in two steps: (1) find a module, and
@@ -700,8 +705,10 @@
 
 \begin{productionlist}[*]
   \production{future_statement}
-             {"from" "__future__" "import" feature ["as" name] ("," feature ["as" name])*}
-  \productioncont{| "from" "__future__" "import" "(" feature ["as" name] ("," feature ["as" name])* [","] ")"}
+             {"from" "__future__" "import" feature ["as" name]}
+  \productioncont{  ("," feature ["as" name])*}
+  \productioncont{| "from" "__future__" "import" "(" feature ["as" name]}
+  \productioncont{  ("," feature ["as" name])* [","] ")"}
   \production{feature}{identifier}
   \production{name}{identifier}
 \end{productionlist}
@@ -718,9 +725,10 @@
 
 \end{itemize}
 
-The features recognized by Python 2.3 are \samp{generators},
-\samp{division} and \samp{nested_scopes}.  \samp{generators} and
-\samp{nested_scopes} are redundant in 2.3 because they are always
+The features recognized by Python 2.5 are \samp{absolute_import},
+\samp{division}, \samp{generators}, \samp{nested_scopes} and
+\samp{with_statement}.  \samp{generators} and \samp{nested_scopes} 
+are redundant in Python version 2.3 and above because they are always
 enabled. 
 
 A future statement is recognized and treated specially at compile

Modified: python/branches/p3yk/Doc/ref/ref7.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref7.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref7.tex	Fri Apr 27 21:54:29 2007
@@ -313,7 +313,7 @@
 
 \begin{productionlist}
   \production{with_stmt}
-  {"with" \token{expression} ["as" target] ":" \token{suite}}
+  {"with" \token{expression} ["as" \token{target}] ":" \token{suite}}
 \end{productionlist}
 
 The execution of the \keyword{with} statement proceeds as follows:

Modified: python/branches/p3yk/Doc/texinputs/python.sty
==============================================================================
--- python/branches/p3yk/Doc/texinputs/python.sty	(original)
+++ python/branches/p3yk/Doc/texinputs/python.sty	Fri Apr 27 21:54:29 2007
@@ -612,7 +612,7 @@
 \newenvironment{cfuncdesc}[4][\py at badkey]{
   \begin{fulllineitems}
     \cfuncline{#2}{#3}{#4}
-    \ifx#1\@undefined\else%
+    \ifx\@undefined#1\relax\else%
       \emph{Return value: \textbf{#1}.}\\
     \fi
 }{\end{fulllineitems}}
@@ -629,7 +629,7 @@
 \newenvironment{ctypedesc}[2][\py at badkey]{
   \begin{fulllineitems}
     \item[\bfcode{#2}%
-    \ifx#1\@undefined%
+    \ifx\@undefined#1\relax%
       \index{#2@{\py at idxcode{#2}} (C type)}
     \else%
       \index{#2@{\py at idxcode{#1}} (C type)}
@@ -712,7 +712,7 @@
 % \begin{methoddesc}[classname]{methodname}{args}
 \newcommand{\methodline}[3][\@undefined]{
   \methodlineni{#2}{#3}
-  \ifx#1\@undefined
+  \ifx\@undefined#1\relax
     \index{#2@{\py at idxcode{#2()}} (\py at thisclass\ method)}
   \else
     \index{#2@{\py at idxcode{#2()}} (#1 method)}
@@ -720,7 +720,7 @@
 }
 \newenvironment{methoddesc}[3][\@undefined]{
   \begin{fulllineitems}
-    \ifx#1\@undefined
+    \ifx\@undefined#1\relax
       \methodline{#2}{#3}
     \else
       \def\py at thisclass{#1}
@@ -740,7 +740,7 @@
 % object data attribute --------------------------------------------------
 % \begin{memberdesc}[classname]{membername}
 \newcommand{\memberline}[2][\py at classbadkey]{%
-  \ifx#1\@undefined
+  \ifx\@undefined#1\relax
     \memberlineni{#2}
     \index{#2@{\py at idxcode{#2}} (\py at thisclass\ attribute)}
   \else
@@ -750,7 +750,7 @@
 }
 \newenvironment{memberdesc}[2][\py at classbadkey]{
   \begin{fulllineitems}
-    \ifx#1\@undefined
+    \ifx\@undefined#1\relax
       \memberline{#2}
     \else
       \def\py at thisclass{#1}
@@ -1046,14 +1046,14 @@
 %  \versionchanged[short explanation]{2.0}
 %
 \newcommand{\versionadded}[2][\py at badkey]{%
-  \ifx#1\@undefined%
+  \ifx\@undefined#1\relax%
     {  New in version #2.  }%
   \else%
     {  New in version #2:\ #1.  }%
   \fi%
 }
 \newcommand{\versionchanged}[2][\py at badkey]{%
-  \ifx#1\@undefined%
+  \ifx\@undefined#1\relax%
     {  Changed in version #2.  }%
   \else%
     {  Changed in version #2:\ #1.  }%

Modified: python/branches/p3yk/Doc/tut/tut.tex
==============================================================================
--- python/branches/p3yk/Doc/tut/tut.tex	(original)
+++ python/branches/p3yk/Doc/tut/tut.tex	Fri Apr 27 21:54:29 2007
@@ -813,7 +813,7 @@
 IndexError: string index out of range
 \end{verbatim}
 
-The best way to remember how slices work is to think of the indices as
+One way to remember how slices work is to think of the indices as
 pointing \emph{between} characters, with the left edge of the first
 character numbered 0.  Then the right edge of the last character of a
 string of \var{n} characters has index \var{n}, for example:
@@ -4312,8 +4312,7 @@
     <statement-N>
 \end{verbatim}
 
-The only rule necessary to explain the semantics is the resolution
-rule used for class attribute references.  This is depth-first,
+For old-style classes, the only rule is depth-first,
 left-to-right.  Thus, if an attribute is not found in
 \class{DerivedClassName}, it is searched in \class{Base1}, then
 (recursively) in the base classes of \class{Base1}, and only if it is
@@ -4328,16 +4327,26 @@
 rule makes no differences between direct and inherited attributes of
 \class{Base1}.)
 
-It is clear that indiscriminate use of multiple inheritance is a
-maintenance nightmare, given the reliance in Python on conventions to
-avoid accidental name conflicts.  A well-known problem with multiple
-inheritance is a class derived from two classes that happen to have a
-common base class.  While it is easy enough to figure out what happens
-in this case (the instance will have a single copy of ``instance
-variables'' or data attributes used by the common base class), it is
-not clear that these semantics are in any way useful.
+For new-style classes, the method resolution order changes dynamically
+to support cooperative calls to \function{super()}.  This approach
+is known in some other multiple-inheritance languages as call-next-method
+and is more powerful than the super call found in single-inheritance languages.
+
+With new-style classes, dynamic ordering is necessary because all 
+cases of multiple inheritance exhibit one or more diamond relationships
+(where one at least one of the parent classes can be accessed through
+multiple paths from the bottommost class).  For example, all new-style
+classes inherit from \class{object}, so any case of multiple inheritance
+provides more than one path to reach \class{object}.  To keep the
+base classes from being accessed more than once, the dynamic algorithm
+linearizes the search order in a way that preserves the left-to-right
+ordering specified in each class, that calls each parent only once, and
+that is monotonic (meaning that a class can be subclassed without affecting
+the precedence order of its parents).  Taken together, these properties
+make it possible to design reliable and extensible classes with
+multiple inheritance.  For more detail, see 
+\url{http://www.python.org/download/releases/2.3/mro/}.
 
-%% XXX Add rules for new-style MRO?
 
 \section{Private Variables \label{private}}
 

Modified: python/branches/p3yk/Doc/whatsnew/whatsnew23.tex
==============================================================================
--- python/branches/p3yk/Doc/whatsnew/whatsnew23.tex	(original)
+++ python/branches/p3yk/Doc/whatsnew/whatsnew23.tex	Fri Apr 27 21:54:29 2007
@@ -896,7 +896,7 @@
 \end{seealso}
 
 %======================================================================
-\section{PEP 307: Pickle Enhancements \label{section-pep305}}
+\section{PEP 307: Pickle Enhancements \label{section-pep307}}
 
 The \module{pickle} and \module{cPickle} modules received some
 attention during the 2.3 development cycle.  In 2.2, new-style classes

Modified: python/branches/p3yk/Doc/whatsnew/whatsnew24.tex
==============================================================================
--- python/branches/p3yk/Doc/whatsnew/whatsnew24.tex	(original)
+++ python/branches/p3yk/Doc/whatsnew/whatsnew24.tex	Fri Apr 27 21:54:29 2007
@@ -1291,7 +1291,7 @@
 [1, 2, 3]
 >>> list(i2)               # Run the second iterator to exhaustion
 [1, 2, 3]
->\end{verbatim}
+\end{verbatim}
 
 Note that \function{tee()} has to keep copies of the values returned 
 by the iterator; in the worst case, it may need to keep all of them.  

Modified: python/branches/p3yk/Doc/whatsnew/whatsnew25.tex
==============================================================================
--- python/branches/p3yk/Doc/whatsnew/whatsnew25.tex	(original)
+++ python/branches/p3yk/Doc/whatsnew/whatsnew25.tex	Fri Apr 27 21:54:29 2007
@@ -1294,6 +1294,17 @@
 (Contributed by Alan McIntyre and committed at the NeedForSpeed sprint.)
 % Patch 1442927
 
+\item It's now illegal to mix iterating over a file 
+with \code{for line in \var{file}} and calling 
+the file object's \method{read()}/\method{readline()}/\method{readlines()}
+methods.  Iteration uses an internal buffer and the 
+\method{read*()} methods don't use that buffer.  
+Instead they would return the data following the buffer, causing the
+data to appear out of order.  Mixing iteration and these methods will
+now trigger a \exception{ValueError} from the \method{read*()} method.
+(Implemented by Thomas Wouters.)
+% Patch 1397960
+
 \item The \module{struct} module now compiles structure format 
 strings into an internal representation and caches this
 representation, yielding a 20\% speedup.  (Contributed by Bob Ippolito
@@ -1704,8 +1715,8 @@
 In Python code, netlink addresses are represented as a tuple of 2 integers, 
 \code{(\var{pid}, \var{group_mask})}.
 
-Two new methods on socket objects, \method{recv_buf(\var{buffer})} and
-\method{recvfrom_buf(\var{buffer})}, store the received data in an object 
+Two new methods on socket objects, \method{recv_into(\var{buffer})} and
+\method{recvfrom_into(\var{buffer})}, store the received data in an object 
 that supports the buffer protocol instead of returning the data as a
 string.  This means you can put the data directly into an array or a
 memory-mapped file.

Modified: python/branches/p3yk/Doc/whatsnew/whatsnew26.tex
==============================================================================
--- python/branches/p3yk/Doc/whatsnew/whatsnew26.tex	(original)
+++ python/branches/p3yk/Doc/whatsnew/whatsnew26.tex	Fri Apr 27 21:54:29 2007
@@ -2,6 +2,46 @@
 \usepackage{distutils}
 % $Id$
 
+% Rules for maintenance:
+% 
+%  * Anyone can add text to this document.  Do not spend very much time
+%    on the wording of your changes, because your text will probably
+%    get rewritten to some degree.
+%
+%  * The maintainer will go through Misc/NEWS periodically and add
+%    changes; it's therefore more important to add your changes to 
+%    Misc/NEWS than to this file.
+%
+%  * This is not a complete list of every single change; completeness
+%    is the purpose of Misc/NEWS.  Some changes I consider too small
+%    or esoteric to include.  If such a change is added to the text,
+%    I'll just remove it.  (This is another reason you shouldn't spend
+%    too much time on writing your addition.)
+%
+%  * If you want to draw your new text to the attention of the
+%    maintainer, add 'XXX' to the beginning of the paragraph or
+%    section.
+%
+%  * It's OK to just add a fragmentary note about a change.  For
+%    example: "XXX Describe the transmogrify() function added to the
+%    socket module."  The maintainer will research the change and
+%    write the necessary text.
+%
+%  * You can comment out your additions if you like, but it's not
+%    necessary (especially when a final release is some months away).
+%
+%  * Credit the author of a patch or bugfix.   Just the name is
+%    sufficient; the e-mail address isn't necessary.
+%
+%  * It's helpful to add the bug/patch number as a comment:
+%
+%       % Patch 12345
+%       XXX Describe the transmogrify() function added to the socket
+%       module.
+%       (Contributed by P.Y. Developer.)
+%
+%    This saves the maintainer the effort of going through the SVN log
+%    when researching a change.
 
 \title{What's New in Python 2.6}
 \release{0.0}
@@ -29,6 +69,9 @@
 
 % Large, PEP-level features and changes should be described here.
 
+% Should there be a new section here for 3k migration?
+% Or perhaps a more general section describing module changes/deprecation?
+% sets module deprecated
 
 %======================================================================
 \section{Other Language Changes}
@@ -37,7 +80,13 @@
 language.
 
 \begin{itemize}
-\item TBD
+
+% Bug 1569356
+\item An obscure change: when you use the the \function{locals()}
+function inside a \keyword{class} statement, the resulting dictionary
+no longer returns free variables.  (Free variables, in this case, are
+variables referred to in the \keyword{class} statement 
+that aren't attributes of the class.)
 
 \end{itemize}
 
@@ -47,7 +96,10 @@
 
 \begin{itemize}
 
-\item Optimizations should be described here.
+% Patch 1624059
+\item Internally, a bit is now set in type objects to indicate some of
+the standard built-in types.  This speeds up checking if an object is
+a subclass of one of these types.  (Contributed by Neal Norwitz.)
 
 \end{itemize}
 
@@ -67,6 +119,71 @@
 
 \begin{itemize}
 
+\item New data type in the \module{collections} module:
+\class{NamedTuple(\var{typename}, \var{fieldnames})} is a factory function that
+creates subclasses of the standard tuple whose fields are accessible
+by name as well as index.  For example:
+
+\begin{verbatim}
+var_type = collections.NamedTuple('variable', 
+             'id name type size')
+var = var_type(1, 'frequency', 'int', 4)
+
+print var[0], var.id		# Equivalent
+print var[2], var.type          # Equivalent
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item New method in the \module{curses} module:
+for a window, \method{chgat()} changes the display characters for a 
+certain number of characters on a single line.
+
+\begin{verbatim}
+# Boldface text starting at y=0,x=21 
+# and affecting the rest of the line.
+stdscr.chgat(0,21, curses.A_BOLD)  
+\end{verbatim}
+
+(Contributed by Fabian Kreutz.)
+
+\item New function in the \module{heapq} module:
+\function{merge(iter1, iter2, ...)} 
+takes any number of iterables that return data 
+\emph{in sorted order}, 
+and 
+returns a new iterator that returns the contents of
+all the iterators, also in sorted order.  For example:
+
+\begin{verbatim}
+heapq.merge([1, 3, 5, 9], [2, 8, 16]) ->
+  [1, 2, 3, 5, 8, 9, 16]
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+\item New function in the \module{itertools} module:
+\function{izip_longest(iter1, iter2, ...\optional{, fillvalue})}
+makes tuples from each of the elements; if some of the iterables
+are shorter than others, the missing values 
+are set to \var{fillvalue}.  For example:
+
+\begin{verbatim}
+itertools.izip_longest([1,2,3], [1,2,3,4,5]) ->
+  [(1, 1), (2, 2), (3, 3), (None, 4), (None, 5)]
+\end{verbatim}
+
+(Contributed by Raymond Hettinger.)
+
+% Patch #1490190
+\item New functions in the \module{posix} module: \function{chflags()}
+and \function{lchflags()} are wrappers for the corresponding system
+calls (where they're available).  Constants for the flag values are
+defined in the \module{stat} module; some possible values include
+\constant{UF_IMMUTABLE} to signal the file may not be changed and
+\constant{UF_APPEND} to indicate that data can only be appended to the
+file.  (Contributed by M. Levinson.)
+
 \item The \module{smtplib} module now supports SMTP over 
 SSL thanks to the addition of the \class{SMTP_SSL} class.
 This class supports an interface identical to the existing \class{SMTP} 

Modified: python/branches/p3yk/Include/fileobject.h
==============================================================================
--- python/branches/p3yk/Include/fileobject.h	(original)
+++ python/branches/p3yk/Include/fileobject.h	Fri Apr 27 21:54:29 2007
@@ -55,6 +55,11 @@
 char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
 size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
 
+/* A routine to do sanity checking on the file mode string.  returns
+   non-zero on if an exception occurred
+*/
+int _PyFile_SanitizeMode(char *mode);
+
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/p3yk/Include/pydebug.h
==============================================================================
--- python/branches/p3yk/Include/pydebug.h	(original)
+++ python/branches/p3yk/Include/pydebug.h	Fri Apr 27 21:54:29 2007
@@ -8,6 +8,7 @@
 PyAPI_DATA(int) Py_DebugFlag;
 PyAPI_DATA(int) Py_VerboseFlag;
 PyAPI_DATA(int) Py_InteractiveFlag;
+PyAPI_DATA(int) Py_InspectFlag;
 PyAPI_DATA(int) Py_OptimizeFlag;
 PyAPI_DATA(int) Py_NoSiteFlag;
 PyAPI_DATA(int) Py_UseClassExceptionsFlag;

Modified: python/branches/p3yk/Include/pystate.h
==============================================================================
--- python/branches/p3yk/Include/pystate.h	(original)
+++ python/branches/p3yk/Include/pystate.h	Fri Apr 27 21:54:29 2007
@@ -21,6 +21,7 @@
     PyObject *modules;
     PyObject *sysdict;
     PyObject *builtins;
+    PyObject *modules_reloading;
 
     PyObject *codec_search_path;
     PyObject *codec_search_cache;

Modified: python/branches/p3yk/Include/setobject.h
==============================================================================
--- python/branches/p3yk/Include/setobject.h	(original)
+++ python/branches/p3yk/Include/setobject.h	Fri Apr 27 21:54:29 2007
@@ -82,7 +82,8 @@
 PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
 PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
 PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
-PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **entry);
+PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key);
+PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
 

Modified: python/branches/p3yk/LICENSE
==============================================================================
--- python/branches/p3yk/LICENSE	(original)
+++ python/branches/p3yk/LICENSE	Fri Apr 27 21:54:29 2007
@@ -52,7 +52,9 @@
     2.4.1           2.4         2005        PSF         yes
     2.4.2           2.4.1       2005        PSF         yes
     2.4.3           2.4.2       2006        PSF         yes
+    2.4.4           2.4.3       2006        PSF         yes
     2.5             2.4         2006        PSF         yes
+    2.5.1           2.5         2007        PSF         yes
 
 Footnotes:
 

Modified: python/branches/p3yk/Lib/Bastion.py
==============================================================================
--- python/branches/p3yk/Lib/Bastion.py	(original)
+++ python/branches/p3yk/Lib/Bastion.py	Fri Apr 27 21:54:29 2007
@@ -97,7 +97,7 @@
 
     """
 
-    raise RuntimeError, "This code is not secure in Python 2.2 and 2.3"
+    raise RuntimeError, "This code is not secure in Python 2.2 and later"
 
     # Note: we define *two* ad-hoc functions here, get1 and get2.
     # Both are intended to be called in the same way: get(name).

Modified: python/branches/p3yk/Lib/CGIHTTPServer.py
==============================================================================
--- python/branches/p3yk/Lib/CGIHTTPServer.py	(original)
+++ python/branches/p3yk/Lib/CGIHTTPServer.py	Fri Apr 27 21:54:29 2007
@@ -197,6 +197,9 @@
         length = self.headers.getheader('content-length')
         if length:
             env['CONTENT_LENGTH'] = length
+        referer = self.headers.getheader('referer')
+        if referer:
+            env['HTTP_REFERER'] = referer
         accept = []
         for line in self.headers.getallmatchingheaders('accept'):
             if line[:1] in "\t\n\r ":
@@ -214,7 +217,7 @@
         # Since we're setting the env in the parent, provide empty
         # values to override previously set values
         for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
-                  'HTTP_USER_AGENT', 'HTTP_COOKIE'):
+                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
             env.setdefault(k, "")
         os.environ.update(env)
 

Modified: python/branches/p3yk/Lib/ConfigParser.py
==============================================================================
--- python/branches/p3yk/Lib/ConfigParser.py	(original)
+++ python/branches/p3yk/Lib/ConfigParser.py	Fri Apr 27 21:54:29 2007
@@ -594,7 +594,8 @@
         self._interpolate_some(option, L, rawval, section, vars, 1)
         return ''.join(L)
 
-    _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
+    _interpvar_re = re.compile(r"%\(([^)]+)\)s")
+    _badpercent_re = re.compile(r"%[^%]|%$")
 
     def _interpolate_some(self, option, accum, rest, section, map, depth):
         if depth > MAX_INTERPOLATION_DEPTH:
@@ -613,7 +614,7 @@
                 accum.append("%")
                 rest = rest[2:]
             elif c == "(":
-                m = self._interpvar_match(rest)
+                m = self._interpvar_re.match(rest)
                 if m is None:
                     raise InterpolationSyntaxError(option, section,
                         "bad interpolation variable reference %r" % rest)
@@ -638,4 +639,12 @@
         """Set an option.  Extend ConfigParser.set: check for string values."""
         if not isinstance(value, basestring):
             raise TypeError("option values must be strings")
+        # check for bad percent signs:
+        # first, replace all "good" interpolations
+        tmp_value = self._interpvar_re.sub('', value)
+        # then, check if there's a lone percent sign left
+        m = self._badpercent_re.search(tmp_value)
+        if m:
+            raise ValueError("invalid interpolation syntax in %r at "
+                             "position %d" % (value, m.start()))
         ConfigParser.set(self, section, option, value)

Modified: python/branches/p3yk/Lib/DocXMLRPCServer.py
==============================================================================
--- python/branches/p3yk/Lib/DocXMLRPCServer.py	(original)
+++ python/branches/p3yk/Lib/DocXMLRPCServer.py	Fri Apr 27 21:54:29 2007
@@ -252,8 +252,10 @@
     """
 
     def __init__(self, addr, requestHandler=DocXMLRPCRequestHandler,
-                 logRequests=1):
-        SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
+                 logRequests=1, allow_none=False, encoding=None,
+                 bind_and_activate=True):
+        SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests,
+                                    allow_none, encoding, bind_and_activate)
         XMLRPCDocGenerator.__init__(self)
 
 class DocCGIXMLRPCRequestHandler(   CGIXMLRPCRequestHandler,

Modified: python/branches/p3yk/Lib/HTMLParser.py
==============================================================================
--- python/branches/p3yk/Lib/HTMLParser.py	(original)
+++ python/branches/p3yk/Lib/HTMLParser.py	Fri Apr 27 21:54:29 2007
@@ -358,12 +358,30 @@
         self.error("unknown declaration: %r" % (data,))
 
     # Internal -- helper to remove special character quoting
+    entitydefs = None
     def unescape(self, s):
         if '&' not in s:
             return s
-        s = s.replace("&lt;", "<")
-        s = s.replace("&gt;", ">")
-        s = s.replace("&apos;", "'")
-        s = s.replace("&quot;", '"')
-        s = s.replace("&amp;", "&") # Must be last
-        return s
+        def replaceEntities(s):
+            s = s.groups()[0]
+            if s[0] == "#":
+                s = s[1:]
+                if s[0] in ['x','X']:
+                    c = int(s[1:], 16)
+                else:
+                    c = int(s)
+                return unichr(c)
+            else:
+                # Cannot use name2codepoint directly, because HTMLParser supports apos,
+                # which is not part of HTML 4
+                import htmlentitydefs
+                if HTMLParser.entitydefs is None:
+                    entitydefs = HTMLParser.entitydefs = {'apos':u"'"}
+                    for k, v in htmlentitydefs.name2codepoint.items():
+                        entitydefs[k] = unichr(v)
+                try:
+                    return self.entitydefs[s]
+                except KeyError:
+                    return '&'+s+';'
+
+        return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s)

Modified: python/branches/p3yk/Lib/SimpleXMLRPCServer.py
==============================================================================
--- python/branches/p3yk/Lib/SimpleXMLRPCServer.py	(original)
+++ python/branches/p3yk/Lib/SimpleXMLRPCServer.py	Fri Apr 27 21:54:29 2007
@@ -517,11 +517,11 @@
     allow_reuse_address = True
 
     def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
-                 logRequests=True, allow_none=False, encoding=None):
+                 logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
         self.logRequests = logRequests
 
         SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
-        SocketServer.TCPServer.__init__(self, addr, requestHandler)
+        SocketServer.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)
 
         # [Bug #1222790] If possible, set close-on-exec flag; if a
         # method spawns a subprocess, the subprocess shouldn't have

Modified: python/branches/p3yk/Lib/SocketServer.py
==============================================================================
--- python/branches/p3yk/Lib/SocketServer.py	(original)
+++ python/branches/p3yk/Lib/SocketServer.py	Fri Apr 27 21:54:29 2007
@@ -279,7 +279,7 @@
 
     Methods for the caller:
 
-    - __init__(server_address, RequestHandlerClass)
+    - __init__(server_address, RequestHandlerClass, bind_and_activate=True)
     - serve_forever()
     - handle_request()  # if you don't use serve_forever()
     - fileno() -> int   # for select()
@@ -322,13 +322,14 @@
 
     allow_reuse_address = False
 
-    def __init__(self, server_address, RequestHandlerClass):
+    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
         """Constructor.  May be extended, do not override."""
         BaseServer.__init__(self, server_address, RequestHandlerClass)
         self.socket = socket.socket(self.address_family,
                                     self.socket_type)
-        self.server_bind()
-        self.server_activate()
+        if bind_and_activate:
+            self.server_bind()
+            self.server_activate()
 
     def server_bind(self):
         """Called by constructor to bind the socket.
@@ -339,6 +340,7 @@
         if self.allow_reuse_address:
             self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         self.socket.bind(self.server_address)
+        self.server_address = self.socket.getsockname()
 
     def server_activate(self):
         """Called by constructor to activate the server.

Modified: python/branches/p3yk/Lib/_strptime.py
==============================================================================
--- python/branches/p3yk/Lib/_strptime.py	(original)
+++ python/branches/p3yk/Lib/_strptime.py	Fri Apr 27 21:54:29 2007
@@ -295,17 +295,16 @@
     """Return a time struct based on the input string and the format string."""
     global _TimeRE_cache, _regex_cache
     with _cache_lock:
-        time_re = _TimeRE_cache
-        locale_time = time_re.locale_time
-        if _getlang() != locale_time.lang:
+        if _getlang() != _TimeRE_cache.locale_time.lang:
             _TimeRE_cache = TimeRE()
-            _regex_cache = {}
+            _regex_cache.clear()
         if len(_regex_cache) > _CACHE_MAX_SIZE:
             _regex_cache.clear()
+        locale_time = _TimeRE_cache.locale_time
         format_regex = _regex_cache.get(format)
         if not format_regex:
             try:
-                format_regex = time_re.compile(format)
+                format_regex = _TimeRE_cache.compile(format)
             # KeyError raised when a bad format is found; can be specified as
             # \\, in which case it was a stray % but with a space after it
             except KeyError as err:

Modified: python/branches/p3yk/Lib/bisect.py
==============================================================================
--- python/branches/p3yk/Lib/bisect.py	(original)
+++ python/branches/p3yk/Lib/bisect.py	Fri Apr 27 21:54:29 2007
@@ -23,8 +23,8 @@
     """Return the index where to insert item x in list a, assuming a is sorted.
 
     The return value i is such that all e in a[:i] have e <= x, and all e in
-    a[i:] have e > x.  So if x already appears in the list, i points just
-    beyond the rightmost x already there.
+    a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
+    insert just after the rightmost x already there.
 
     Optional args lo (default 0) and hi (default len(a)) bound the
     slice of a to be searched.
@@ -62,8 +62,8 @@
     """Return the index where to insert item x in list a, assuming a is sorted.
 
     The return value i is such that all e in a[:i] have e < x, and all e in
-    a[i:] have e >= x.  So if x already appears in the list, i points just
-    before the leftmost x already there.
+    a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
+    insert just before the leftmost x already there.
 
     Optional args lo (default 0) and hi (default len(a)) bound the
     slice of a to be searched.

Modified: python/branches/p3yk/Lib/cmd.py
==============================================================================
--- python/branches/p3yk/Lib/cmd.py	(original)
+++ python/branches/p3yk/Lib/cmd.py	Fri Apr 27 21:54:29 2007
@@ -49,11 +49,6 @@
 PROMPT = '(Cmd) '
 IDENTCHARS = string.ascii_letters + string.digits + '_'
 
-def raw_input(prompt):
-    sys.stdout.write(prompt)
-    sys.stdout.flush()
-    return sys.stdin.readline()
-
 class Cmd:
     """A simple framework for writing line-oriented command interpreters.
 
@@ -129,7 +124,7 @@
                 else:
                     if self.use_rawinput:
                         try:
-                            line = raw_input(self.prompt)
+                            line = input(self.prompt)
                         except EOFError:
                             line = 'EOF'
                     else:

Copied: python/branches/p3yk/Lib/collections.py (from r54985, python/trunk/Lib/collections.py)
==============================================================================
--- python/trunk/Lib/collections.py	(original)
+++ python/branches/p3yk/Lib/collections.py	Fri Apr 27 21:54:29 2007
@@ -30,7 +30,7 @@
         if kwds:
             try:
                 args += tuple(kwds[name] for name in field_names[len(args):])
-            except KeyError, name:
+            except KeyError as name:
                 raise TypeError('%s missing required argument: %s' % (typename, name))
         if len(args) != nargs:
             raise TypeError('%s takes exactly %d arguments (%d given)' % (typename, nargs, len(args)))
@@ -59,4 +59,4 @@
 
     import doctest
     TestResults = NamedTuple('TestResults', 'failed attempted')
-    print TestResults(*doctest.testmod())
+    print(TestResults(*doctest.testmod()))

Modified: python/branches/p3yk/Lib/commands.py
==============================================================================
--- python/branches/p3yk/Lib/commands.py	(original)
+++ python/branches/p3yk/Lib/commands.py	Fri Apr 27 21:54:29 2007
@@ -32,6 +32,8 @@
 #
 def getstatus(file):
     """Return output of "ls -ld <file>" in a string."""
+    import warnings
+    warnings.warn("commands.getstatus() is deprecated", DeprecationWarning)
     return getoutput('ls -ld' + mkarg(file))
 
 

Modified: python/branches/p3yk/Lib/copy_reg.py
==============================================================================
--- python/branches/p3yk/Lib/copy_reg.py	(original)
+++ python/branches/p3yk/Lib/copy_reg.py	Fri Apr 27 21:54:29 2007
@@ -43,7 +43,8 @@
         obj = object.__new__(cls)
     else:
         obj = base.__new__(cls, state)
-        base.__init__(obj, state)
+        if base.__init__ != object.__init__:
+            base.__init__(obj, state)
     return obj
 
 _HEAPTYPE = 1<<9

Modified: python/branches/p3yk/Lib/csv.py
==============================================================================
--- python/branches/p3yk/Lib/csv.py	(original)
+++ python/branches/p3yk/Lib/csv.py	Fri Apr 27 21:54:29 2007
@@ -115,9 +115,10 @@
 
     def _dict_to_list(self, rowdict):
         if self.extrasaction == "raise":
-            for k in rowdict.keys():
-                if k not in self.fieldnames:
-                    raise ValueError, "dict contains fields not in fieldnames"
+            wrong_fields = [k for k in rowdict if k not in self.fieldnames]
+            if wrong_fields:
+                raise ValueError("dict contains fields not in fieldnames: " +
+                                 ", ".join(wrong_fields))
         return [rowdict.get(key, self.restval) for key in self.fieldnames]
 
     def writerow(self, rowdict):

Modified: python/branches/p3yk/Lib/ctypes/__init__.py
==============================================================================
--- python/branches/p3yk/Lib/ctypes/__init__.py	(original)
+++ python/branches/p3yk/Lib/ctypes/__init__.py	Fri Apr 27 21:54:29 2007
@@ -233,6 +233,9 @@
 c_voidp = c_void_p # backwards compatibility (to a bug)
 _check_size(c_void_p)
 
+class c_bool(_SimpleCData):
+    _type_ = "t"
+
 # This cache maps types to pointers to them.
 _pointer_type_cache = {}
 
@@ -480,7 +483,7 @@
     return _cast(obj, obj, typ)
 
 _string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
-def string_at(ptr, size=0):
+def string_at(ptr, size=-1):
     """string_at(addr[, size]) -> string
 
     Return the string at addr."""
@@ -492,7 +495,7 @@
     pass
 else:
     _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
-    def wstring_at(ptr, size=0):
+    def wstring_at(ptr, size=-1):
         """wstring_at(addr[, size]) -> string
 
         Return the string at addr."""

Modified: python/branches/p3yk/Lib/ctypes/test/test_functions.py
==============================================================================
--- python/branches/p3yk/Lib/ctypes/test/test_functions.py	(original)
+++ python/branches/p3yk/Lib/ctypes/test/test_functions.py	Fri Apr 27 21:54:29 2007
@@ -21,7 +21,9 @@
 
 class POINT(Structure):
     _fields_ = [("x", c_int), ("y", c_int)]
-
+class RECT(Structure):
+    _fields_ = [("left", c_int), ("top", c_int),
+                ("right", c_int), ("bottom", c_int)]
 class FunctionTestCase(unittest.TestCase):
 
     def test_mro(self):
@@ -379,5 +381,15 @@
             self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
                                  (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
 
+    def test_sf1651235(self):
+        # see http://www.python.org/sf/1651235
+
+        proto = CFUNCTYPE(c_int, RECT, POINT)
+        def callback(*args):
+            return 0
+
+        callback = proto(callback)
+        self.failUnlessRaises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT()))
+
 if __name__ == '__main__':
     unittest.main()

Modified: python/branches/p3yk/Lib/ctypes/test/test_memfunctions.py
==============================================================================
--- python/branches/p3yk/Lib/ctypes/test/test_memfunctions.py	(original)
+++ python/branches/p3yk/Lib/ctypes/test/test_memfunctions.py	Fri Apr 27 21:54:29 2007
@@ -14,6 +14,7 @@
         self.failUnlessEqual(string_at(result), "Hello, World")
         self.failUnlessEqual(string_at(result, 5), "Hello")
         self.failUnlessEqual(string_at(result, 16), "Hello, World\0\0\0\0")
+        self.failUnlessEqual(string_at(result, 0), "")
 
     def test_memset(self):
         a = create_string_buffer(1000000)
@@ -54,6 +55,7 @@
             self.failUnlessEqual(wstring_at(a), "Hello, World")
             self.failUnlessEqual(wstring_at(a, 5), "Hello")
             self.failUnlessEqual(wstring_at(a, 16), "Hello, World\0\0\0\0")
+            self.failUnlessEqual(wstring_at(a, 0), "")
 
 if __name__ == "__main__":
     unittest.main()

Modified: python/branches/p3yk/Lib/ctypes/test/test_numbers.py
==============================================================================
--- python/branches/p3yk/Lib/ctypes/test/test_numbers.py	(original)
+++ python/branches/p3yk/Lib/ctypes/test/test_numbers.py	Fri Apr 27 21:54:29 2007
@@ -24,6 +24,8 @@
 unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
 signed_types = [c_byte, c_short, c_int, c_long, c_longlong]
 
+bool_types = []
+
 float_types = [c_double, c_float]
 
 try:
@@ -35,8 +37,16 @@
     unsigned_types.append(c_ulonglong)
     signed_types.append(c_longlong)
 
+try:
+    c_bool
+except NameError:
+    pass
+else:
+    bool_types.append(c_bool)
+
 unsigned_ranges = valid_ranges(*unsigned_types)
 signed_ranges = valid_ranges(*signed_types)
+bool_values = [True, False, 0, 1, -1, 5000, 'test', [], [1]]
 
 ################################################################
 
@@ -60,6 +70,11 @@
             self.failUnlessEqual(t(l).value, l)
             self.failUnlessEqual(t(h).value, h)
 
+    def test_bool_values(self):
+        from operator import truth
+        for t, v in zip(bool_types, bool_values):
+            self.failUnlessEqual(t(v).value, truth(v))
+
     def test_typeerror(self):
         # Only numbers are allowed in the contructor,
         # otherwise TypeError is raised
@@ -82,7 +97,7 @@
 
     def test_byref(self):
         # calling byref returns also a PyCArgObject instance
-        for t in signed_types + unsigned_types + float_types:
+        for t in signed_types + unsigned_types + float_types + bool_types:
             parm = byref(t())
             self.failUnlessEqual(ArgType, type(parm))
 
@@ -101,7 +116,7 @@
             self.assertRaises(TypeError, t, 3.14)
 
     def test_sizes(self):
-        for t in signed_types + unsigned_types + float_types:
+        for t in signed_types + unsigned_types + float_types + bool_types:
             size = struct.calcsize(t._type_)
             # sizeof of the type...
             self.failUnlessEqual(sizeof(t), size)
@@ -164,6 +179,18 @@
         a[0] = '?'
         self.failUnlessEqual(v.value, a[0])
 
+    # array does not support c_bool / 't'
+    # def test_bool_from_address(self):
+    #     from ctypes import c_bool
+    #     from array import array
+    #     a = array(c_bool._type_, [True])
+    #     v = t.from_address(a.buffer_info()[0])
+    #     self.failUnlessEqual(v.value, a[0])
+    #     self.failUnlessEqual(type(v) is t)
+    #     a[0] = False
+    #     self.failUnlessEqual(v.value, a[0])
+    #     self.failUnlessEqual(type(v) is t)
+
     def test_init(self):
         # c_int() can be initialized from Python's int, and c_int.
         # Not from c_long or so, which seems strange, abd should

Modified: python/branches/p3yk/Lib/ctypes/test/test_repr.py
==============================================================================
--- python/branches/p3yk/Lib/ctypes/test/test_repr.py	(original)
+++ python/branches/p3yk/Lib/ctypes/test/test_repr.py	Fri Apr 27 21:54:29 2007
@@ -4,7 +4,7 @@
 subclasses = []
 for base in [c_byte, c_short, c_int, c_long, c_longlong,
         c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong,
-        c_float, c_double]:
+        c_float, c_double, c_bool]:
     class X(base):
         pass
     subclasses.append(X)

Modified: python/branches/p3yk/Lib/decimal.py
==============================================================================
--- python/branches/p3yk/Lib/decimal.py	(original)
+++ python/branches/p3yk/Lib/decimal.py	Fri Apr 27 21:54:29 2007
@@ -29,8 +29,8 @@
 
 Decimal floating point has finite precision with arbitrarily large bounds.
 
-The purpose of the module is to support arithmetic using familiar
-"schoolhouse" rules and to avoid the some of tricky representation
+The purpose of this module is to support arithmetic using familiar
+"schoolhouse" rules and to avoid some of the tricky representation
 issues associated with binary floating point.  The package is especially
 useful for financial applications or for contexts where users have
 expectations that are at odds with binary floating point (for instance,
@@ -136,7 +136,7 @@
 
 import copy as _copy
 
-#Rounding
+# Rounding
 ROUND_DOWN = 'ROUND_DOWN'
 ROUND_HALF_UP = 'ROUND_HALF_UP'
 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
@@ -145,11 +145,11 @@
 ROUND_UP = 'ROUND_UP'
 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
 
-#Rounding decision (not part of the public API)
+# Rounding decision (not part of the public API)
 NEVER_ROUND = 'NEVER_ROUND'    # Round in division (non-divmod), sqrt ONLY
 ALWAYS_ROUND = 'ALWAYS_ROUND'  # Every operation rounds at end.
 
-#Errors
+# Errors
 
 class DecimalException(ArithmeticError):
     """Base exception class.
@@ -179,9 +179,9 @@
 
     This occurs and signals clamped if the exponent of a result has been
     altered in order to fit the constraints of a specific concrete
-    representation. This may occur when the exponent of a zero result would
-    be outside the bounds of a representation, or  when a large normal
-    number would have an encoded exponent that cannot be represented. In
+    representation.  This may occur when the exponent of a zero result would
+    be outside the bounds of a representation, or when a large normal
+    number would have an encoded exponent that cannot be represented.  In
     this latter case, the exponent is reduced to fit and the corresponding
     number of zero digits are appended to the coefficient ("fold-down").
     """
@@ -194,8 +194,8 @@
 
     Something creates a signaling NaN
     -INF + INF
-     0 * (+-)INF
-     (+-)INF / (+-)INF
+    0 * (+-)INF
+    (+-)INF / (+-)INF
     x % 0
     (+-)INF % x
     x._rescale( non-integer )
@@ -207,7 +207,7 @@
     """
     def handle(self, context, *args):
         if args:
-            if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
+            if args[0] == 1:  # sNaN, must drop 's' but keep diagnostics
                 return Decimal( (args[1]._sign, args[1]._int, 'n') )
         return NaN
 
@@ -216,11 +216,11 @@
 
     This occurs and signals invalid-operation if an string is being
     converted to a number and it does not conform to the numeric string
-    syntax. The result is [0,qNaN].
+    syntax.  The result is [0,qNaN].
     """
 
     def handle(self, context, *args):
-        return (0, (0,), 'n') #Passed to something which uses a tuple.
+        return (0, (0,), 'n')  # Passed to something which uses a tuple.
 
 class DivisionByZero(DecimalException, ZeroDivisionError):
     """Division by 0.
@@ -245,7 +245,7 @@
 
     This occurs and signals invalid-operation if the integer result of a
     divide-integer or remainder operation had too many digits (would be
-    longer than precision). The result is [0,qNaN].
+    longer than precision).  The result is [0,qNaN].
     """
 
     def handle(self, context, *args):
@@ -256,12 +256,12 @@
 
     This occurs and signals invalid-operation if division by zero was
     attempted (during a divide-integer, divide, or remainder operation), and
-    the dividend is also zero. The result is [0,qNaN].
+    the dividend is also zero.  The result is [0,qNaN].
     """
 
     def handle(self, context, tup=None, *args):
         if tup is not None:
-            return (NaN, NaN) #for 0 %0, 0 // 0
+            return (NaN, NaN)  # for 0 %0, 0 // 0
         return NaN
 
 class Inexact(DecimalException):
@@ -269,7 +269,7 @@
 
     This occurs and signals inexact whenever the result of an operation is
     not exact (that is, it needed to be rounded and any discarded digits
-    were non-zero), or if an overflow or underflow condition occurs. The
+    were non-zero), or if an overflow or underflow condition occurs.  The
     result in all cases is unchanged.
 
     The inexact signal may be tested (or trapped) to determine if a given
@@ -281,11 +281,11 @@
     """Invalid context.  Unknown rounding, for example.
 
     This occurs and signals invalid-operation if an invalid context was
-    detected during an operation. This can occur if contexts are not checked
+    detected during an operation.  This can occur if contexts are not checked
     on creation and either the precision exceeds the capability of the
     underlying concrete representation or an unknown or unsupported rounding
-    was specified. These aspects of the context need only be checked when
-    the values are required to be used. The result is [0,qNaN].
+    was specified.  These aspects of the context need only be checked when
+    the values are required to be used.  The result is [0,qNaN].
     """
 
     def handle(self, context, *args):
@@ -296,7 +296,7 @@
 
     This occurs and signals rounded whenever the result of an operation is
     rounded (that is, some zero or non-zero digits were discarded from the
-    coefficient), or if an overflow or underflow condition occurs. The
+    coefficient), or if an overflow or underflow condition occurs.  The
     result in all cases is unchanged.
 
     The rounded signal may be tested (or trapped) to determine if a given
@@ -309,7 +309,7 @@
 
     This occurs and signals subnormal whenever the result of a conversion or
     operation is subnormal (that is, its adjusted exponent is less than
-    Emin, before any rounding). The result in all cases is unchanged.
+    Emin, before any rounding).  The result in all cases is unchanged.
 
     The subnormal signal may be tested (or trapped) to determine if a given
     or operation (or sequence of operations) yielded a subnormal result.
@@ -328,13 +328,13 @@
 
     For round-half-up and round-half-even (and for round-half-down and
     round-up, if implemented), the result of the operation is [sign,inf],
-    where sign is the sign of the intermediate result. For round-down, the
+    where sign is the sign of the intermediate result.  For round-down, the
     result is the largest finite number that can be represented in the
-    current precision, with the sign of the intermediate result. For
+    current precision, with the sign of the intermediate result.  For
     round-ceiling, the result is the same as for round-down if the sign of
-    the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
+    the intermediate result is 1, or is [0,inf] otherwise.  For round-floor,
     the result is the same as for round-down if the sign of the intermediate
-    result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
+    result is 0, or is [1,inf] otherwise.  In all cases, Inexact and Rounded
     will also be raised.
    """
 
@@ -360,10 +360,10 @@
     This occurs and signals underflow if a result is inexact and the
     adjusted exponent of the result would be smaller (more negative) than
     the smallest value that can be handled by the implementation (the value
-    Emin). That is, the result is both inexact and subnormal.
+    Emin).  That is, the result is both inexact and subnormal.
 
     The result after an underflow will be a subnormal number rounded, if
-    necessary, so that its exponent is not less than Etiny. This may result
+    necessary, so that its exponent is not less than Etiny.  This may result
     in 0 with the sign of the intermediate result and an exponent of Etiny.
 
     In all cases, Inexact, Rounded, and Subnormal will also be raised.
@@ -379,7 +379,7 @@
                   DivisionUndefined:InvalidOperation,
                   InvalidContext:InvalidOperation}
 
-##### Context Functions #######################################
+##### Context Functions ##################################################
 
 # The getcontext() and setcontext() function manage access to a thread-local
 # current context.  Py2.4 offers direct support for thread locals.  If that
@@ -392,7 +392,7 @@
 except ImportError:
     # Python was compiled without threads; create a mock object instead
     import sys
-    class MockThreading:
+    class MockThreading(object):
         def local(self, sys=sys):
             return sys.modules[__name__]
     threading = MockThreading()
@@ -403,8 +403,8 @@
 
 except AttributeError:
 
-    #To fix reloading, force it to create a new context
-    #Old contexts have different exceptions in their dicts, making problems.
+    # To fix reloading, force it to create a new context
+    # Old contexts have different exceptions in their dicts, making problems.
     if hasattr(threading.currentThread(), '__decimal_context__'):
         del threading.currentThread().__decimal_context__
 
@@ -469,14 +469,14 @@
                  ctx.prec += 2
                  # Rest of sin calculation algorithm
                  # uses a precision 2 greater than normal
-             return +s # Convert result to normal precision
+             return +s  # Convert result to normal precision
 
          def sin(x):
              with localcontext(ExtendedContext):
                  # Rest of sin calculation algorithm
                  # uses the Extended Context from the
                  # General Decimal Arithmetic Specification
-             return +s # Convert result to normal context
+             return +s  # Convert result to normal context
 
     """
     # The string below can't be included in the docstring until Python 2.6
@@ -489,11 +489,11 @@
     ...     ctx = getcontext()
     ...     ctx.prec += 2
     ...     print(ctx.prec)
-    ... 
+    ...
     30
     >>> with localcontext(ExtendedContext):
     ...     print(getcontext().prec)
-    ... 
+    ...
     9
     >>> print(getcontext().prec)
     28
@@ -502,7 +502,7 @@
     return _ContextManager(ctx)
 
 
-##### Decimal class ###########################################
+##### Decimal class #######################################################
 
 class Decimal(object):
     """Floating point class for decimal arithmetic."""
@@ -518,7 +518,7 @@
 
         >>> Decimal('3.14')              # string input
         Decimal("3.14")
-        >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
+        >>> Decimal((0, (3, 1, 4), -2))  # tuple (sign, digit_tuple, exponent)
         Decimal("3.14")
         >>> Decimal(314)                 # int or long
         Decimal("314")
@@ -557,13 +557,13 @@
         # tuple/list conversion (possibly from as_tuple())
         if isinstance(value, (list,tuple)):
             if len(value) != 3:
-                raise ValueError, 'Invalid arguments'
+                raise ValueError('Invalid arguments')
             if value[0] not in (0,1):
-                raise ValueError, 'Invalid sign'
+                raise ValueError('Invalid sign')
             for digit in value[1]:
                 if not isinstance(digit, (int,int)) or digit < 0:
-                    raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
-
+                    raise ValueError("The second value in the tuple must be"
+                                "composed of non negative integer elements.")
             self._sign = value[0]
             self._int  = tuple(value[1])
             if value[2] in ('F','n','N'):
@@ -596,22 +596,23 @@
             if _isnan(value):
                 sig, sign, diag = _isnan(value)
                 self._is_special = True
-                if len(diag) > context.prec: #Diagnostic info too long
+                if len(diag) > context.prec:  # Diagnostic info too long
                     self._sign, self._int, self._exp = \
                                 context._raise_error(ConversionSyntax)
                     return self
                 if sig == 1:
-                    self._exp = 'n' #qNaN
-                else: #sig == 2
-                    self._exp = 'N' #sNaN
+                    self._exp = 'n'  # qNaN
+                else:  # sig == 2
+                    self._exp = 'N'  # sNaN
                 self._sign = sign
-                self._int = tuple(map(int, diag)) #Diagnostic info
+                self._int = tuple(map(int, diag))  # Diagnostic info
                 return self
             try:
                 self._sign, self._int, self._exp = _string2exact(value)
             except ValueError:
                 self._is_special = True
-                self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
+                self._sign, self._int, self._exp = \
+                                        context._raise_error(ConversionSyntax)
             return self
 
         raise TypeError("Cannot convert %r to Decimal" % value)
@@ -694,15 +695,15 @@
         if self._is_special or other._is_special:
             ans = self._check_nans(other, context)
             if ans:
-                return 1 # Comparison involving NaN's always reports self > other
+                return 1  # Comparison involving NaN's always reports self > other
 
             # INF = INF
             return cmp(self._isinfinity(), other._isinfinity())
 
         if not self and not other:
-            return 0 #If both 0, sign comparison isn't certain.
+            return 0  # If both 0, sign comparison isn't certain.
 
-        #If different signs, neg one is less
+        # If different signs, neg one is less
         if other._sign < self._sign:
             return -1
         if self._sign < other._sign:
@@ -713,7 +714,7 @@
         if self_adjusted == other_adjusted and \
            self._int + (0,)*(self._exp - other._exp) == \
            other._int + (0,)*(other._exp - self._exp):
-            return 0 #equal, except in precision. ([0]*(-x) = [])
+            return 0  # equal, except in precision. ([0]*(-x) = [])
         elif self_adjusted > other_adjusted and self._int[0] != 0:
             return (-1)**self._sign
         elif self_adjusted < other_adjusted and other._int[0] != 0:
@@ -724,7 +725,7 @@
             context = getcontext()
 
         context = context._shallow_copy()
-        rounding = context._set_rounding(ROUND_UP) #round away from 0
+        rounding = context._set_rounding(ROUND_UP)  # round away from 0
 
         flags = context._ignore_all_flags()
         res = self.__sub__(other, context=context)
@@ -782,7 +783,7 @@
         if other is NotImplemented:
             return other
 
-        #compare(NaN, NaN) = NaN
+        # Compare(NaN, NaN) = NaN
         if (self._is_special or other and other._is_special):
             ans = self._check_nans(other, context)
             if ans:
@@ -843,11 +844,11 @@
         tmp = map(str, self._int)
         numdigits = len(self._int)
         leftdigits = self._exp + numdigits
-        if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
-            if self._exp < 0 and self._exp >= -6: #short, no need for e/E
+        if eng and not self:  # self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
+            if self._exp < 0 and self._exp >= -6:  # short, no need for e/E
                 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
                 return s
-            #exp is closest mult. of 3 >= self._exp
+            # exp is closest mult. of 3 >= self._exp
             exp = ((self._exp - 1)// 3 + 1) * 3
             if exp != self._exp:
                 s = '0.'+'0'*(exp - self._exp)
@@ -859,7 +860,7 @@
                 else:
                     s += 'e'
                 if exp > 0:
-                    s += '+' #0.0e+3, not 0.0e3
+                    s += '+'  # 0.0e+3, not 0.0e3
                 s += str(exp)
             s = '-'*self._sign + s
             return s
@@ -999,19 +1000,19 @@
                 return ans
 
             if self._isinfinity():
-                #If both INF, same sign => same as both, opposite => error.
+                # If both INF, same sign => same as both, opposite => error.
                 if self._sign != other._sign and other._isinfinity():
                     return context._raise_error(InvalidOperation, '-INF + INF')
                 return Decimal(self)
             if other._isinfinity():
-                return Decimal(other)  #Can't both be infinity here
+                return Decimal(other)  # Can't both be infinity here
 
         shouldround = context._rounding_decision == ALWAYS_ROUND
 
         exp = min(self._exp, other._exp)
         negativezero = 0
         if context.rounding == ROUND_FLOOR and self._sign != other._sign:
-            #If the answer is 0, the sign should be negative, in this case.
+            # If the answer is 0, the sign should be negative, in this case.
             negativezero = 1
 
         if not self and not other:
@@ -1046,19 +1047,19 @@
                 return Decimal((negativezero, (0,), exp))
             if op1.int < op2.int:
                 op1, op2 = op2, op1
-                #OK, now abs(op1) > abs(op2)
+                # OK, now abs(op1) > abs(op2)
             if op1.sign == 1:
                 result.sign = 1
                 op1.sign, op2.sign = op2.sign, op1.sign
             else:
                 result.sign = 0
-                #So we know the sign, and op1 > 0.
+                # So we know the sign, and op1 > 0.
         elif op1.sign == 1:
             result.sign = 1
             op1.sign, op2.sign = (0, 0)
         else:
             result.sign = 0
-        #Now, op1 > abs(op2) > 0
+        # Now, op1 > abs(op2) > 0
 
         if op2.sign == 0:
             result.int = op1.int + op2.int
@@ -1116,7 +1117,8 @@
             if ans:
                 return ans
 
-            return Decimal(self) # Must be infinite, and incrementing makes no difference
+            # Must be infinite, and incrementing makes no difference
+            return Decimal(self)
 
         L = list(self._int)
         L[-1] += 1
@@ -1172,7 +1174,7 @@
         if not self or not other:
             ans = Decimal((resultsign, (0,), resultexp))
             if shouldround:
-                #Fixing in case the exponent is out of bounds
+                # Fixing in case the exponent is out of bounds
                 ans = ans._fix(context)
             return ans
 
@@ -1191,7 +1193,7 @@
         op1 = _WorkRep(self)
         op2 = _WorkRep(other)
 
-        ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
+        ans = Decimal((resultsign, map(int, str(op1.int * op2.int)), resultexp))
         if shouldround:
             ans = ans._fix(context)
 
@@ -1283,12 +1285,11 @@
                                            sign, 1)
             return context._raise_error(DivisionByZero, 'x / 0', sign)
 
-        #OK, so neither = 0, INF or NaN
-
+        # OK, so neither = 0, INF or NaN
         shouldround = context._rounding_decision == ALWAYS_ROUND
 
-        #If we're dividing into ints, and self < other, stop.
-        #self.__abs__(0) does not round.
+        # If we're dividing into ints, and self < other, stop.
+        # self.__abs__(0) does not round.
         if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
 
             if divmod == 1 or divmod == 3:
@@ -1300,7 +1301,7 @@
                         ans2)
 
             elif divmod == 2:
-                #Don't round the mod part, if we don't need it.
+                # Don't round the mod part, if we don't need it.
                 return (Decimal( (sign, (0,), 0) ), Decimal(self))
 
         op1 = _WorkRep(self)
@@ -1349,7 +1350,7 @@
             op1.exp -= 1
 
             if res.exp == 0 and divmod and op2.int > op1.int:
-                #Solves an error in precision.  Same as a previous block.
+                # Solves an error in precision.  Same as a previous block.
 
                 if res.int >= prec_limit and shouldround:
                     return context._raise_error(DivisionImpossible)
@@ -1434,7 +1435,7 @@
         # ignored in the calling function.
         context = context._shallow_copy()
         flags = context._ignore_flags(Rounded, Inexact)
-        #keep DivisionImpossible flags
+        # Keep DivisionImpossible flags
         (side, r) = self.__divmod__(other, context=context)
 
         if r._isnan():
@@ -1457,7 +1458,7 @@
 
         if r < comparison:
             r._sign, comparison._sign = s1, s2
-            #Get flags now
+            # Get flags now
             self.__divmod__(other, context=context)
             return r._fix(context)
         r._sign, comparison._sign = s1, s2
@@ -1479,7 +1480,8 @@
         if r > comparison or decrease and r == comparison:
             r._sign, comparison._sign = s1, s2
             context.prec += 1
-            if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
+            numbsquant = len(side.__add__(Decimal(1), context=context)._int)
+            if numbsquant >= context.prec:
                 context.prec -= 1
                 return context._raise_error(DivisionImpossible)[1]
             context.prec -= 1
@@ -1514,7 +1516,7 @@
                 context = getcontext()
                 return context._raise_error(InvalidContext)
             elif self._isinfinity():
-                raise OverflowError, "Cannot convert infinity to long"
+                raise OverflowError("Cannot convert infinity to long")
         if self._exp >= 0:
             s = ''.join(map(str, self._int)) + '0'*self._exp
         else:
@@ -1568,13 +1570,13 @@
                     context._raise_error(Clamped)
                     return ans
                 ans = ans._rescale(Etiny, context=context)
-                #It isn't zero, and exp < Emin => subnormal
+                # It isn't zero, and exp < Emin => subnormal
                 context._raise_error(Subnormal)
                 if context.flags[Inexact]:
                     context._raise_error(Underflow)
             else:
                 if ans:
-                    #Only raise subnormal if non-zero.
+                    # Only raise subnormal if non-zero.
                     context._raise_error(Subnormal)
         else:
             Etop = context.Etop()
@@ -1591,7 +1593,8 @@
                         return ans
                     context._raise_error(Inexact)
                     context._raise_error(Rounded)
-                    return context._raise_error(Overflow, 'above Emax', ans._sign)
+                    c = context._raise_error(Overflow, 'above Emax', ans._sign)
+                    return c
         return ans
 
     def _round(self, prec=None, rounding=None, context=None):
@@ -1651,18 +1654,18 @@
             ans =  Decimal( (temp._sign, tmp, temp._exp - expdiff))
             return ans
 
-        #OK, but maybe all the lost digits are 0.
+        # OK, but maybe all the lost digits are 0.
         lostdigits = self._int[expdiff:]
         if lostdigits == (0,) * len(lostdigits):
             ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
-            #Rounded, but not Inexact
+            # Rounded, but not Inexact
             context._raise_error(Rounded)
             return ans
 
         # Okay, let's round and lose data
 
         this_function = getattr(temp, self._pick_rounding_function[rounding])
-        #Now we've got the rounding function
+        # Now we've got the rounding function
 
         if prec != context.prec:
             context = context._shallow_copy()
@@ -1758,7 +1761,7 @@
             context = getcontext()
 
         if self._is_special or n._is_special or n.adjusted() > 8:
-            #Because the spot << doesn't work with really big exponents
+            # Because the spot << doesn't work with really big exponents
             if n._isinfinity() or n.adjusted() > 8:
                 return context._raise_error(InvalidOperation, 'x ** INF')
 
@@ -1788,9 +1791,10 @@
                 return Infsign[sign]
             return Decimal( (sign, (0,), 0) )
 
-        #with ludicrously large exponent, just raise an overflow and return inf.
-        if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
-           and self:
+        # With ludicrously large exponent, just raise an overflow
+        # and return inf.
+        if not modulo and n > 0 and \
+           (self._exp + len(self._int) - 1) * n > context.Emax and self:
 
             tmp = Decimal('inf')
             tmp._sign = sign
@@ -1810,7 +1814,7 @@
         context = context._shallow_copy()
         context.prec = firstprec + elength + 1
         if n < 0:
-            #n is a long now, not Decimal instance
+            # n is a long now, not Decimal instance
             n = -n
             mul = Decimal(1).__truediv__(mul, context=context)
 
@@ -1819,7 +1823,7 @@
             spot <<= 1
 
         spot >>= 1
-        #Spot is the highest power of 2 less than n
+        # spot is the highest power of 2 less than n
         while spot:
             val = val.__mul__(val, context=context)
             if val._isinfinity():
@@ -1877,7 +1881,7 @@
 
             if exp._isinfinity() or self._isinfinity():
                 if exp._isinfinity() and self._isinfinity():
-                    return self  #if both are inf, it is OK
+                    return self  # if both are inf, it is OK
                 if context is None:
                     context = getcontext()
                 return context._raise_error(InvalidOperation,
@@ -1982,13 +1986,13 @@
                 return Decimal(self)
 
         if not self:
-            #exponent = self._exp / 2, using round_down.
-            #if self._exp < 0:
+            # exponent = self._exp / 2, using round_down.
+            # if self._exp < 0:
             #    exp = (self._exp+1) // 2
-            #else:
+            # else:
             exp = (self._exp) // 2
             if self._sign == 1:
-                #sqrt(-0) = -0
+                # sqrt(-0) = -0
                 return Decimal( (1, (0,), exp))
             else:
                 return Decimal( (0, (0,), exp))
@@ -2023,8 +2027,7 @@
                                           context=context), context=context)
             ans._exp -= 1 + tmp.adjusted()  // 2
 
-        #ans is now a linear approximation.
-
+        # ans is now a linear approximation.
         Emax, Emin = context.Emax, context.Emin
         context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
 
@@ -2039,12 +2042,12 @@
             if context.prec == maxp:
                 break
 
-        #round to the answer's precision-- the only error can be 1 ulp.
+        # Round to the answer's precision-- the only error can be 1 ulp.
         context.prec = firstprec
         prevexp = ans.adjusted()
         ans = ans._round(context=context)
 
-        #Now, check if the other last digits are better.
+        # Now, check if the other last digits are better.
         context.prec = firstprec + 1
         # In case we rounded up another digit and we should actually go lower.
         if prevexp != ans.adjusted():
@@ -2076,10 +2079,10 @@
             context._raise_error(Rounded)
             context._raise_error(Inexact)
         else:
-            #Exact answer, so let's set the exponent right.
-            #if self._exp < 0:
+            # Exact answer, so let's set the exponent right.
+            # if self._exp < 0:
             #    exp = (self._exp +1)// 2
-            #else:
+            # else:
             exp = self._exp // 2
             context.prec += ans._exp - exp
             ans = ans._rescale(exp, context=context)
@@ -2100,7 +2103,7 @@
             return other
 
         if self._is_special or other._is_special:
-            # if one operand is a quiet NaN and the other is number, then the
+            # If one operand is a quiet NaN and the other is number, then the
             # number is always returned
             sn = self._isnan()
             on = other._isnan()
@@ -2114,13 +2117,13 @@
         ans = self
         c = self.__cmp__(other)
         if c == 0:
-            # if both operands are finite and equal in numerical value
+            # If both operands are finite and equal in numerical value
             # then an ordering is applied:
             #
-            # if the signs differ then max returns the operand with the
+            # If the signs differ then max returns the operand with the
             # positive sign and min returns the operand with the negative sign
             #
-            # if the signs are the same then the exponent is used to select
+            # If the signs are the same then the exponent is used to select
             # the result.
             if self._sign != other._sign:
                 if self._sign:
@@ -2141,7 +2144,7 @@
     def min(self, other, context=None):
         """Returns the smaller value.
 
-        like min(self, other) except if one is not a number, returns
+        Like min(self, other) except if one is not a number, returns
         NaN (and signals if one is sNaN).  Also rounds.
         """
         other = _convert_other(other)
@@ -2149,7 +2152,7 @@
             return other
 
         if self._is_special or other._is_special:
-            # if one operand is a quiet NaN and the other is number, then the
+            # If one operand is a quiet NaN and the other is number, then the
             # number is always returned
             sn = self._isnan()
             on = other._isnan()
@@ -2163,13 +2166,13 @@
         ans = self
         c = self.__cmp__(other)
         if c == 0:
-            # if both operands are finite and equal in numerical value
+            # If both operands are finite and equal in numerical value
             # then an ordering is applied:
             #
-            # if the signs differ then max returns the operand with the
+            # If the signs differ then max returns the operand with the
             # positive sign and min returns the operand with the negative sign
             #
-            # if the signs are the same then the exponent is used to select
+            # If the signs are the same then the exponent is used to select
             # the result.
             if self._sign != other._sign:
                 if other._sign:
@@ -2204,11 +2207,11 @@
         """Return the adjusted exponent of self"""
         try:
             return self._exp + len(self._int) - 1
-        #If NaN or Infinity, self._exp is string
+        # If NaN or Infinity, self._exp is string
         except TypeError:
             return 0
 
-    # support for pickling, copy, and deepcopy
+    # Support for pickling, copy, and deepcopy
     def __reduce__(self):
         return (self.__class__, (str(self),))
 
@@ -2222,13 +2225,14 @@
             return self     # My components are also immutable
         return self.__class__(str(self))
 
-##### Context class ###########################################
+##### Context class #######################################################
 
 
 # get rounding method function:
-rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
+rounding_functions = [name for name in Decimal.__dict__.keys()
+                                    if name.startswith('_round_')]
 for name in rounding_functions:
-    #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
+    # name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
     globalname = name[1:].upper()
     val = globals()[globalname]
     Decimal._pick_rounding_function[val] = name
@@ -2255,7 +2259,7 @@
 
     Contains:
     prec - precision (for use in rounding, division, square roots..)
-    rounding - rounding type. (how you round)
+    rounding - rounding type (how you round)
     _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
     traps - If traps[exception] = 1, then the exception is
                     raised when it is caused.  Otherwise, a value is
@@ -2294,9 +2298,13 @@
     def __repr__(self):
         """Show the current context."""
         s = []
-        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
-        s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
-        s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
+        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, '
+                 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d'
+                 % vars(self))
+        names = [f.__name__ for f, v in self.flags.items() if v]
+        s.append('flags=[' + ', '.join(names) + ']')
+        names = [t.__name__ for t, v in self.traps.items() if v]
+        s.append('traps=[' + ', '.join(names) + ']')
         return ', '.join(s) + ')'
 
     def clear_flags(self):
@@ -2313,9 +2321,9 @@
 
     def copy(self):
         """Returns a deep copy from self."""
-        nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
-                         self._rounding_decision, self.Emin, self.Emax,
-                         self.capitals, self._clamp, self._ignored_flags)
+        nc = Context(self.prec, self.rounding, self.traps.copy(),
+                self.flags.copy(), self._rounding_decision, self.Emin,
+                self.Emax, self.capitals, self._clamp, self._ignored_flags)
         return nc
     __copy__ = copy
 
@@ -2329,16 +2337,16 @@
         """
         error = _condition_map.get(condition, condition)
         if error in self._ignored_flags:
-            #Don't touch the flag
+            # Don't touch the flag
             return error().handle(self, *args)
 
         self.flags[error] += 1
         if not self.traps[error]:
-            #The errors define how to handle themselves.
+            # The errors define how to handle themselves.
             return condition().handle(self, *args)
 
         # Errors should only be risked on copies of the context
-        #self._ignored_flags = []
+        # self._ignored_flags = []
         raise error, explanation
 
     def _ignore_all_flags(self):
@@ -2362,7 +2370,7 @@
     def __hash__(self):
         """A Context cannot be hashed."""
         # We inherit object.__hash__, so we must deny this explicitly
-        raise TypeError, "Cannot hash a Context."
+        raise TypeError("Cannot hash a Context.")
 
     def Etiny(self):
         """Returns Etiny (= Emin - prec + 1)"""
@@ -2417,12 +2425,12 @@
         d = Decimal(num, context=self)
         return d._fix(self)
 
-    #Methods
+    # Methods
     def abs(self, a):
         """Returns the absolute value of the operand.
 
         If the operand is negative, the result is the same as using the minus
-        operation on the operand. Otherwise, the result is the same as using
+        operation on the operand.  Otherwise, the result is the same as using
         the plus operation on the operand.
 
         >>> ExtendedContext.abs(Decimal('2.1'))
@@ -2524,8 +2532,8 @@
 
         If either operand is a NaN then the general rules apply.
         Otherwise, the operands are compared as as though by the compare
-        operation. If they are numerically equal then the left-hand operand
-        is chosen as the result. Otherwise the maximum (closer to positive
+        operation.  If they are numerically equal then the left-hand operand
+        is chosen as the result.  Otherwise the maximum (closer to positive
         infinity) of the two operands is chosen as the result.
 
         >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
@@ -2544,8 +2552,8 @@
 
         If either operand is a NaN then the general rules apply.
         Otherwise, the operands are compared as as though by the compare
-        operation. If they are numerically equal then the left-hand operand
-        is chosen as the result. Otherwise the minimum (closer to negative
+        operation.  If they are numerically equal then the left-hand operand
+        is chosen as the result.  Otherwise the minimum (closer to negative
         infinity) of the two operands is chosen as the result.
 
         >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
@@ -2634,14 +2642,14 @@
 
         The right-hand operand must be a whole number whose integer part (after
         any exponent has been applied) has no more than 9 digits and whose
-        fractional part (if any) is all zeros before any rounding. The operand
+        fractional part (if any) is all zeros before any rounding.  The operand
         may be positive, negative, or zero; if negative, the absolute value of
         the power is used, and the left-hand operand is inverted (divided into
         1) before use.
 
         If the increased precision needed for the intermediate calculations
-        exceeds the capabilities of the implementation then an Invalid operation
-        condition is raised.
+        exceeds the capabilities of the implementation then an Invalid
+        operation condition is raised.
 
         If, when raising to a negative power, an underflow occurs during the
         division into 1, the operation is not halted at that point but
@@ -2679,18 +2687,18 @@
         return a.__pow__(b, modulo, context=self)
 
     def quantize(self, a, b):
-        """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
+        """Returns a value equal to 'a' (rounded), having the exponent of 'b'.
 
         The coefficient of the result is derived from that of the left-hand
-        operand. It may be rounded using the current rounding setting (if the
+        operand.  It may be rounded using the current rounding setting (if the
         exponent is being increased), multiplied by a positive power of ten (if
         the exponent is being decreased), or is unchanged (if the exponent is
         already equal to that of the right-hand operand).
 
         Unlike other operations, if the length of the coefficient after the
         quantize operation would be greater than precision then an Invalid
-        operation condition is raised. This guarantees that, unless there is an
-        error condition, the exponent of the result of a quantize is always
+        operation condition is raised.  This guarantees that, unless there is
+        an error condition, the exponent of the result of a quantize is always
         equal to that of the right-hand operand.
 
         Also unlike other operations, quantize will never raise Underflow, even
@@ -2733,9 +2741,9 @@
         """Returns the remainder from integer division.
 
         The result is the residue of the dividend after the operation of
-        calculating integer division as described for divide-integer, rounded to
-        precision digits if necessary. The sign of the result, if non-zero, is
-        the same as that of the original dividend.
+        calculating integer division as described for divide-integer, rounded
+        to precision digits if necessary.  The sign of the result, if
+        non-zero, is the same as that of the original dividend.
 
         This operation will fail under the same conditions as integer division
         (that is, if integer division on the same two operands would fail, the
@@ -2759,7 +2767,7 @@
     def remainder_near(self, a, b):
         """Returns to be "a - b * n", where n is the integer nearest the exact
         value of "x / b" (if two integers are equally near then the even one
-        is chosen). If the result is equal to 0 then its sign will be the
+        is chosen).  If the result is equal to 0 then its sign will be the
         sign of a.
 
         This operation will fail under the same conditions as integer division
@@ -2801,7 +2809,7 @@
         return a.same_quantum(b)
 
     def sqrt(self, a):
-        """Returns the square root of a non-negative number to context precision.
+        """Square root of a non-negative number to context precision.
 
         If the result must be inexact, it is rounded using the round-half-even
         algorithm.
@@ -2862,7 +2870,7 @@
         as using the quantize() operation using the given operand as the
         left-hand-operand, 1E+0 as the right-hand-operand, and the precision
         of the operand as the precision setting, except that no flags will
-        be set. The rounding mode is taken from the context.
+        be set.  The rounding mode is taken from the context.
 
         >>> ExtendedContext.to_integral(Decimal('2.1'))
         Decimal("2")
@@ -2937,8 +2945,9 @@
         other_len = len(str(other.int))
         if numdigits > (other_len + prec + 1 - tmp_len):
             # If the difference in adjusted exps is > prec+1, we know
-            # other is insignificant, so might as well put a 1 after the precision.
-            # (since this is only for addition.)  Also stops use of massive longs.
+            # other is insignificant, so might as well put a 1 after the
+            # precision (since this is only for addition).  Also stops
+            # use of massive longs.
 
             extend = prec + 2 - tmp_len
             if extend <= 0:
@@ -2961,13 +2970,13 @@
     Used on _WorkRep instances during division.
     """
     adjust = 0
-    #If op1 is smaller, make it larger
+    # If op1 is smaller, make it larger
     while op2.int > op1.int:
         op1.int *= 10
         op1.exp -= 1
         adjust += 1
 
-    #If op2 is too small, make it larger
+    # If op2 is too small, make it larger
     while op1.int >= (10 * op2.int):
         op2.int *= 10
         op2.exp -= 1
@@ -2975,7 +2984,7 @@
 
     return op1, op2, adjust
 
-##### Helper Functions ########################################
+##### Helper Functions ####################################################
 
 def _convert_other(other):
     """Convert other to Decimal.
@@ -3016,16 +3025,16 @@
     if not num:
         return 0
 
-    #get the sign, get rid of trailing [+-]
+    # Get the sign, get rid of trailing [+-]
     sign = 0
     if num[0] == '+':
         num = num[1:]
-    elif num[0] == '-':  #elif avoids '+-nan'
+    elif num[0] == '-':  # elif avoids '+-nan'
         num = num[1:]
         sign = 1
 
     if num.startswith('nan'):
-        if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
+        if len(num) > 3 and not num[3:].isdigit():  # diagnostic info
             return 0
         return (1, sign, num[3:].lstrip('0'))
     if num.startswith('snan'):
@@ -3035,7 +3044,7 @@
     return 0
 
 
-##### Setup Specific Contexts ################################
+##### Setup Specific Contexts ############################################
 
 # The default context prototype used by Context()
 # Is mutable, so that new contexts can have different default values
@@ -3068,19 +3077,19 @@
 )
 
 
-##### Useful Constants (internal use only) ####################
+##### Useful Constants (internal use only) ################################
 
-#Reusable defaults
+# Reusable defaults
 Inf = Decimal('Inf')
 negInf = Decimal('-Inf')
 
-#Infsign[sign] is infinity w/ that sign
+# Infsign[sign] is infinity w/ that sign
 Infsign = (Inf, negInf)
 
 NaN = Decimal('NaN')
 
 
-##### crud for parsing strings #################################
+##### crud for parsing strings #############################################
 import re
 
 # There's an optional sign at the start, and an optional exponent
@@ -3100,13 +3109,15 @@
     ([eE](?P<exp>[-+]? \d+))?
 #    \s*
     $
-""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
+""", re.VERBOSE).match  # Uncomment the \s* to allow leading or trailing spaces.
 
 del re
 
-# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
-
 def _string2exact(s):
+    """Return sign, n, p s.t.
+
+    Float string value == -1**sign * n * 10**p exactly
+    """
     m = _parser(s)
     if m is None:
         raise ValueError("invalid literal for Decimal: %r" % s)

Modified: python/branches/p3yk/Lib/difflib.py
==============================================================================
--- python/branches/p3yk/Lib/difflib.py	(original)
+++ python/branches/p3yk/Lib/difflib.py	Fri Apr 27 21:54:29 2007
@@ -1946,8 +1946,7 @@
         fromlist,tolist,flaglist,next_href,next_id = self._convert_flags(
             fromlist,tolist,flaglist,context,numlines)
 
-        import cStringIO
-        s = cStringIO.StringIO()
+        s = []
         fmt = '            <tr><td class="diff_next"%s>%s</td>%s' + \
               '<td class="diff_next">%s</td>%s</tr>\n'
         for i in range(len(flaglist)):
@@ -1955,9 +1954,9 @@
                 # mdiff yields None on separator lines skip the bogus ones
                 # generated for the first line
                 if i > 0:
-                    s.write('        </tbody>        \n        <tbody>\n')
+                    s.append('        </tbody>        \n        <tbody>\n')
             else:
-                s.write( fmt % (next_id[i],next_href[i],fromlist[i],
+                s.append( fmt % (next_id[i],next_href[i],fromlist[i],
                                            next_href[i],tolist[i]))
         if fromdesc or todesc:
             header_row = '<thead><tr>%s%s%s%s</tr></thead>' % (
@@ -1969,7 +1968,7 @@
             header_row = ''
 
         table = self._table_template % dict(
-            data_rows=s.getvalue(),
+            data_rows=''.join(s),
             header_row=header_row,
             prefix=self._prefix[1])
 

Modified: python/branches/p3yk/Lib/distutils/__init__.py
==============================================================================
--- python/branches/p3yk/Lib/distutils/__init__.py	(original)
+++ python/branches/p3yk/Lib/distutils/__init__.py	Fri Apr 27 21:54:29 2007
@@ -20,4 +20,4 @@
 # In general, major and minor version should loosely follow the Python
 # version number the distutils code was shipped with.
 #
-__version__ = "2.5.0"
+__version__ = "2.5.1"

Modified: python/branches/p3yk/Lib/distutils/command/build_ext.py
==============================================================================
--- python/branches/p3yk/Lib/distutils/command/build_ext.py	(original)
+++ python/branches/p3yk/Lib/distutils/command/build_ext.py	Fri Apr 27 21:54:29 2007
@@ -186,7 +186,7 @@
         # for extensions under Cygwin and AtheOS Python's library directory must be
         # appended to library_dirs
         if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos':
-            if sys.executable.find(sys.exec_prefix) != -1:
+            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
                 # building third party extensions
                 self.library_dirs.append(os.path.join(sys.prefix, "lib",
                                                       "python" + get_python_version(),
@@ -199,7 +199,7 @@
         # Python's library directory must be appended to library_dirs
         if (sys.platform.startswith('linux') or sys.platform.startswith('gnu')) \
                 and sysconfig.get_config_var('Py_ENABLE_SHARED'):
-            if sys.executable.find(sys.exec_prefix) != -1:
+            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
                 # building third party extensions
                 self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
             else:
@@ -533,7 +533,8 @@
         if self.swig_cpp:
             log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
 
-        if self.swig_cpp or ('-c++' in self.swig_opts):
+        if self.swig_cpp or ('-c++' in self.swig_opts) or \
+           ('-c++' in extension.swig_opts):
             target_ext = '.cpp'
         else:
             target_ext = '.c'

Modified: python/branches/p3yk/Lib/distutils/msvccompiler.py
==============================================================================
--- python/branches/p3yk/Lib/distutils/msvccompiler.py	(original)
+++ python/branches/p3yk/Lib/distutils/msvccompiler.py	Fri Apr 27 21:54:29 2007
@@ -187,6 +187,19 @@
     j = sys.version.find(")", i)
     return sys.version[i+len(prefix):j]
 
+def normalize_and_reduce_paths(paths):
+    """Return a list of normalized paths with duplicates removed.
+
+    The current order of paths is maintained.
+    """
+    # Paths are normalized so things like:  /a and /a/ aren't both preserved.
+    reduced_paths = []
+    for p in paths:
+        np = os.path.normpath(p)
+        # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
+        if np not in reduced_paths:
+            reduced_paths.append(np)
+    return reduced_paths
 
 
 class MSVCCompiler (CCompiler) :
@@ -270,7 +283,8 @@
                 self.__paths.append(p)
         except KeyError:
             pass
-        os.environ['path'] = ';'.join(self.__paths)
+        self.__paths = normalize_and_reduce_paths(self.__paths)
+        os.environ['path'] = ";".join(self.__paths)
 
         self.preprocess_options = None
         if self.__arch == "Intel":

Modified: python/branches/p3yk/Lib/doctest.py
==============================================================================
--- python/branches/p3yk/Lib/doctest.py	(original)
+++ python/branches/p3yk/Lib/doctest.py	Fri Apr 27 21:54:29 2007
@@ -2625,8 +2625,23 @@
            }
 
 def _test():
-    r = unittest.TextTestRunner()
-    r.run(DocTestSuite())
+    testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-']
+    if testfiles:
+        for filename in testfiles:
+            if filename.endswith(".py"):
+                # It is a module -- insert its dir into sys.path and try to
+                # import it. If it is part of a package, that possibly won't work
+                # because of package imports.
+                dirname, filename = os.path.split(filename)
+                sys.path.insert(0, dirname)
+                m = __import__(filename[:-3])
+                del sys.path[0]
+                testmod(m)
+            else:
+                testfile(filename, module_relative=False)
+    else:
+        r = unittest.TextTestRunner()
+        r.run(DocTestSuite())
 
 if __name__ == "__main__":
     _test()

Modified: python/branches/p3yk/Lib/email/_parseaddr.py
==============================================================================
--- python/branches/p3yk/Lib/email/_parseaddr.py	(original)
+++ python/branches/p3yk/Lib/email/_parseaddr.py	Fri Apr 27 21:54:29 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2006 Python Software Foundation
+# Copyright (C) 2002-2007 Python Software Foundation
 # Contact: email-sig at python.org
 
 """Email address parsing code.
@@ -172,6 +172,7 @@
         self.pos = 0
         self.LWS = ' \t'
         self.CR = '\r\n'
+        self.FWS = self.LWS + self.CR
         self.atomends = self.specials + self.LWS + self.CR
         # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it
         # is obsolete syntax.  RFC 2822 requires that we recognize obsolete
@@ -418,7 +419,7 @@
         plist = []
 
         while self.pos < len(self.field):
-            if self.field[self.pos] in self.LWS:
+            if self.field[self.pos] in self.FWS:
                 self.pos += 1
             elif self.field[self.pos] == '"':
                 plist.append(self.getquote())

Modified: python/branches/p3yk/Lib/email/header.py
==============================================================================
--- python/branches/p3yk/Lib/email/header.py	(original)
+++ python/branches/p3yk/Lib/email/header.py	Fri Apr 27 21:54:29 2007
@@ -39,7 +39,8 @@
   \?                    # literal ?
   (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string
   \?=                   # literal ?=
-  ''', re.VERBOSE | re.IGNORECASE)
+  (?=[ \t]|$)           # whitespace or the end of the string
+  ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE)
 
 # Field name regexp, including trailing colon, but not separating whitespace,
 # according to RFC 2822.  Character range is from tilde to exclamation mark.

Modified: python/branches/p3yk/Lib/email/message.py
==============================================================================
--- python/branches/p3yk/Lib/email/message.py	(original)
+++ python/branches/p3yk/Lib/email/message.py	Fri Apr 27 21:54:29 2007
@@ -238,7 +238,7 @@
             self.del_param('charset')
             self._charset = None
             return
-        if isinstance(charset, str):
+        if isinstance(charset, basestring):
             charset = email.charset.Charset(charset)
         if not isinstance(charset, email.charset.Charset):
             raise TypeError(charset)
@@ -756,7 +756,9 @@
                 charset = charset[2]
         # charset character must be in us-ascii range
         try:
-            charset = unicode(charset, 'us-ascii').encode('us-ascii')
+            if isinstance(charset, str):
+                charset = unicode(charset, 'us-ascii')
+            charset = charset.encode('us-ascii')
         except UnicodeError:
             return failobj
         # RFC 2046, $4.1.2 says charsets are not case sensitive

Modified: python/branches/p3yk/Lib/email/test/test_email.py
==============================================================================
--- python/branches/p3yk/Lib/email/test/test_email.py	(original)
+++ python/branches/p3yk/Lib/email/test/test_email.py	Fri Apr 27 21:54:29 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2006 Python Software Foundation
+# Copyright (C) 2001-2007 Python Software Foundation
 # Contact: email-sig at python.org
 # email package unit tests
 
@@ -501,6 +501,13 @@
         msg.set_payload(x)
         self.assertEqual(msg.get_payload(decode=True), x)
 
+    def test_get_content_charset(self):
+        msg = Message()
+        msg.set_charset('us-ascii')
+        self.assertEqual('us-ascii', msg.get_content_charset())
+        msg.set_charset(u'us-ascii')
+        self.assertEqual('us-ascii', msg.get_content_charset())
+
 
 
 # Test the email.Encoders module
@@ -1519,6 +1526,18 @@
         hu = make_header(dh).__unicode__()
         eq(hu, u'The quick brown fox jumped over the lazy dog')
 
+    def test_rfc2047_without_whitespace(self):
+        s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [(s, None)])
+
+    def test_rfc2047_with_whitespace(self):
+        s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'),
+                              ('rg', None), ('\xe5', 'iso-8859-1'),
+                              ('sbord', None)])
+
 
 
 # Test the MIMEMessage class
@@ -2164,6 +2183,12 @@
         # formataddr() quotes the name if there's a dot in it
         self.assertEqual(Utils.formataddr((a, b)), y)
 
+    def test_multiline_from_comment(self):
+        x = """\
+Foo
+\tBar <foo at example.com>"""
+        self.assertEqual(Utils.parseaddr(x), ('Foo Bar', 'foo at example.com'))
+
     def test_quote_dump(self):
         self.assertEqual(
             Utils.formataddr(('A Silly; Person', 'person at dom.ain')),

Modified: python/branches/p3yk/Lib/email/test/test_email_renamed.py
==============================================================================
--- python/branches/p3yk/Lib/email/test/test_email_renamed.py	(original)
+++ python/branches/p3yk/Lib/email/test/test_email_renamed.py	Fri Apr 27 21:54:29 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2006 Python Software Foundation
+# Copyright (C) 2001-2007 Python Software Foundation
 # Contact: email-sig at python.org
 # email package unit tests
 
@@ -1524,6 +1524,18 @@
         hu = make_header(dh).__unicode__()
         eq(hu, u'The quick brown fox jumped over the lazy dog')
 
+    def test_rfc2047_missing_whitespace(self):
+        s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [(s, None)])
+
+    def test_rfc2047_with_whitespace(self):
+        s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord'
+        dh = decode_header(s)
+        self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'),
+                              ('rg', None), ('\xe5', 'iso-8859-1'),
+                              ('sbord', None)])
+
 
 
 # Test the MIMEMessage class
@@ -2170,6 +2182,12 @@
         # formataddr() quotes the name if there's a dot in it
         self.assertEqual(utils.formataddr((a, b)), y)
 
+    def test_multiline_from_comment(self):
+        x = """\
+Foo
+\tBar <foo at example.com>"""
+        self.assertEqual(utils.parseaddr(x), ('Foo Bar', 'foo at example.com'))
+
     def test_quote_dump(self):
         self.assertEqual(
             utils.formataddr(('A Silly; Person', 'person at dom.ain')),

Modified: python/branches/p3yk/Lib/ftplib.py
==============================================================================
--- python/branches/p3yk/Lib/ftplib.py	(original)
+++ python/branches/p3yk/Lib/ftplib.py	Fri Apr 27 21:54:29 2007
@@ -76,9 +76,15 @@
 
     '''An FTP client class.
 
-    To create a connection, call the class using these argument:
-            host, user, passwd, acct
-    These are all strings, and have default value ''.
+    To create a connection, call the class using these arguments:
+            host, user, passwd, acct, timeout
+
+    The first four arguments are all strings, and have default value ''.
+    timeout must be numeric and defaults to None if not passed,
+    meaning that no timeout will be set on any ftp socket(s)
+    If a timeout is passed, then this is now the default timeout for all ftp
+    socket operations for this instance.
+
     Then use self.connect() with optional host and port argument.
 
     To download a file, use ftp.retrlines('RETR ' + filename),
@@ -102,33 +108,26 @@
     # Initialize host to localhost, port to standard ftp port
     # Optional arguments are host (for connect()),
     # and user, passwd, acct (for login())
-    def __init__(self, host='', user='', passwd='', acct=''):
+    def __init__(self, host='', user='', passwd='', acct='', timeout=None):
+        self.timeout = timeout
         if host:
             self.connect(host)
-            if user: self.login(user, passwd, acct)
+            if user:
+                self.login(user, passwd, acct)
 
-    def connect(self, host = '', port = 0):
+    def connect(self, host='', port=0, timeout=None):
         '''Connect to host.  Arguments are:
-        - host: hostname to connect to (string, default previous host)
-        - port: port to connect to (integer, default previous port)'''
-        if host: self.host = host
-        if port: self.port = port
-        msg = "getaddrinfo returns an empty list"
-        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
-            try:
-                self.sock = socket.socket(af, socktype, proto)
-                self.sock.connect(sa)
-            except socket.error as err:
-                msg = err
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
-        self.af = af
+         - host: hostname to connect to (string, default previous host)
+         - port: port to connect to (integer, default previous port)
+        '''
+        if host != '':
+            self.host = host
+        if port > 0:
+            self.port = port
+        if timeout is not None:
+            self.timeout = timeout
+        self.sock = socket.create_connection((self.host, self.port), self.timeout)
+        self.af = self.sock.family
         self.file = self.sock.makefile('rb')
         self.welcome = self.getresp()
         return self.welcome

Modified: python/branches/p3yk/Lib/genericpath.py
==============================================================================
--- python/branches/p3yk/Lib/genericpath.py	(original)
+++ python/branches/p3yk/Lib/genericpath.py	Fri Apr 27 21:54:29 2007
@@ -75,3 +75,32 @@
         if s1[i] != s2[i]:
             return s1[:i]
     return s1[:n]
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+# Generic implementation of splitext, to be parametrized with
+# the separators
+def _splitext(p, sep, altsep, extsep):
+    """Split the extension from a pathname.
+
+    Extension is everything from the last dot to the end, ignoring
+    leading dots.  Returns "(root, ext)"; ext may be empty."""
+
+    sepIndex = p.rfind(sep)
+    if altsep:
+        altsepIndex = p.rfind(altsep)
+        sepIndex = max(sepIndex, altsepIndex)
+
+    dotIndex = p.rfind(extsep)
+    if dotIndex > sepIndex:
+        # skip all leading dots
+        filenameIndex = sepIndex + 1
+        while filenameIndex < dotIndex:
+            if p[filenameIndex] != extsep:
+                return p[:dotIndex], p[dotIndex:]
+            filenameIndex += 1
+
+    return p, ''

Modified: python/branches/p3yk/Lib/glob.py
==============================================================================
--- python/branches/p3yk/Lib/glob.py	(original)
+++ python/branches/p3yk/Lib/glob.py	Fri Apr 27 21:54:29 2007
@@ -1,8 +1,9 @@
 """Filename globbing utility."""
 
+import sys
 import os
-import fnmatch
 import re
+import fnmatch
 
 __all__ = ["glob", "iglob"]
 
@@ -48,13 +49,16 @@
 def glob1(dirname, pattern):
     if not dirname:
         dirname = os.curdir
+    if isinstance(pattern, unicode) and not isinstance(dirname, unicode):
+        dirname = unicode(dirname, sys.getfilesystemencoding() or
+                                   sys.getdefaultencoding())
     try:
         names = os.listdir(dirname)
     except os.error:
         return []
-    if pattern[0]!='.':
-        names=filter(lambda x: x[0]!='.',names)
-    return fnmatch.filter(names,pattern)
+    if pattern[0] != '.':
+        names = filter(lambda x: x[0] != '.', names)
+    return fnmatch.filter(names, pattern)
 
 def glob0(dirname, basename):
     if basename == '':

Modified: python/branches/p3yk/Lib/heapq.py
==============================================================================
--- python/branches/p3yk/Lib/heapq.py	(original)
+++ python/branches/p3yk/Lib/heapq.py	Fri Apr 27 21:54:29 2007
@@ -311,7 +311,7 @@
 def merge(*iterables):
     '''Merge multiple sorted inputs into a single sorted output.
 
-    Similar to sorted(itertools.chain(*iterables)) but returns an iterable,
+    Similar to sorted(itertools.chain(*iterables)) but returns a generator,
     does not pull the data into memory all at once, and assumes that each of
     the input streams is already sorted (smallest to largest).
 

Modified: python/branches/p3yk/Lib/httplib.py
==============================================================================
--- python/branches/p3yk/Lib/httplib.py	(original)
+++ python/branches/p3yk/Lib/httplib.py	Fri Apr 27 21:54:29 2007
@@ -625,7 +625,8 @@
     debuglevel = 0
     strict = 0
 
-    def __init__(self, host, port=None, strict=None):
+    def __init__(self, host, port=None, strict=None, timeout=None):
+        self.timeout = timeout
         self.sock = None
         self._buffer = []
         self.__response = None
@@ -658,25 +659,8 @@
 
     def connect(self):
         """Connect to the host and port specified in __init__."""
-        msg = "getaddrinfo returns an empty list"
-        for res in socket.getaddrinfo(self.host, self.port, 0,
-                                      socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
-            try:
-                self.sock = socket.socket(af, socktype, proto)
-                if self.debuglevel > 0:
-                    print("connect: (%s, %s)" % (self.host, self.port))
-                self.sock.connect(sa)
-            except socket.error as msg:
-                if self.debuglevel > 0:
-                    print('connect fail:', (self.host, self.port))
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
+        self.sock = socket.create_connection((self.host,self.port),
+                                             self.timeout)
 
     def close(self):
         """Close the connection to the HTTP server."""
@@ -948,8 +932,8 @@
         self.__state = _CS_IDLE
 
         if response.will_close:
-            # Pass the socket to the response
-            self.sock = None
+            # this effectively passes the connection to the response
+            self.close()
         else:
             # remember this, so we can tell when it is complete
             self.__response = response

Modified: python/branches/p3yk/Lib/idlelib/MultiCall.py
==============================================================================
--- python/branches/p3yk/Lib/idlelib/MultiCall.py	(original)
+++ python/branches/p3yk/Lib/idlelib/MultiCall.py	Fri Apr 27 21:54:29 2007
@@ -350,6 +350,8 @@
                     triplets.append(triplet)
 
         def event_delete(self, virtual, *sequences):
+            if virtual not in self.__eventinfo:
+                return
             func, triplets = self.__eventinfo[virtual]
             for seq in sequences:
                 triplet = _parse_sequence(seq)

Modified: python/branches/p3yk/Lib/imaplib.py
==============================================================================
--- python/branches/p3yk/Lib/imaplib.py	(original)
+++ python/branches/p3yk/Lib/imaplib.py	Fri Apr 27 21:54:29 2007
@@ -746,8 +746,10 @@
         if not command in Commands:
             raise self.error("Unknown IMAP4 UID command: %s" % command)
         if self.state not in Commands[command]:
-            raise self.error('command %s illegal in state %s'
-                                    % (command, self.state))
+            raise self.error("command %s illegal in state %s, "
+                             "only allowed in states %s" %
+                             (command, self.state,
+                              ', '.join(Commands[command])))
         name = 'UID'
         typ, dat = self._simple_command(name, command, *args)
         if command in ('SEARCH', 'SORT'):
@@ -811,8 +813,10 @@
 
         if self.state not in Commands[name]:
             self.literal = None
-            raise self.error(
-            'command %s illegal in state %s' % (name, self.state))
+            raise self.error("command %s illegal in state %s, "
+                             "only allowed in states %s" %
+                             (name, self.state,
+                              ', '.join(Commands[name])))
 
         for typ in ('OK', 'NO', 'BAD'):
             if typ in self.untagged_responses:

Modified: python/branches/p3yk/Lib/logging/handlers.py
==============================================================================
--- python/branches/p3yk/Lib/logging/handlers.py	(original)
+++ python/branches/p3yk/Lib/logging/handlers.py	Fri Apr 27 21:54:29 2007
@@ -365,12 +365,14 @@
         self.retryMax = 30.0
         self.retryFactor = 2.0
 
-    def makeSocket(self):
+    def makeSocket(self, timeout=1):
         """
         A factory method which allows subclasses to define the precise
         type of socket they want.
         """
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        if hasattr(s, 'settimeout'):
+            s.settimeout(timeout)
         s.connect((self.host, self.port))
         return s
 

Modified: python/branches/p3yk/Lib/macpath.py
==============================================================================
--- python/branches/p3yk/Lib/macpath.py	(original)
+++ python/branches/p3yk/Lib/macpath.py	Fri Apr 27 21:54:29 2007
@@ -2,6 +2,7 @@
 
 import os
 from stat import *
+import genericpath
 from genericpath import *
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
@@ -69,17 +70,8 @@
 
 
 def splitext(p):
-    """Split a path into root and extension.
-    The extension is everything starting at the last dot in the last
-    pathname component; the root is everything before that.
-    It is always true that root + ext == p."""
-
-    i = p.rfind('.')
-    if i<=p.rfind(':'):
-        return p, ''
-    else:
-        return p[:i], p[i:]
-
+    return genericpath._splitext(p, sep, altsep, extsep)
+splitext.__doc__ = genericpath._splitext.__doc__
 
 def splitdrive(p):
     """Split a pathname into a drive specification and the rest of the

Modified: python/branches/p3yk/Lib/ntpath.py
==============================================================================
--- python/branches/p3yk/Lib/ntpath.py	(original)
+++ python/branches/p3yk/Lib/ntpath.py	Fri Apr 27 21:54:29 2007
@@ -8,6 +8,7 @@
 import os
 import stat
 import sys
+import genericpath
 from genericpath import *
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
@@ -15,7 +16,7 @@
            "getatime","getctime", "islink","exists","lexists","isdir","isfile",
            "ismount","walk","expanduser","expandvars","normpath","abspath",
            "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
-           "extsep","devnull","realpath","supports_unicode_filenames"]
+           "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
 
 # strings representing various path-related bits and pieces
 curdir = '.'
@@ -182,16 +183,8 @@
 # It is always true that root + ext == p.
 
 def splitext(p):
-    """Split the extension from a pathname.
-
-    Extension is everything from the last dot to the end.
-    Return (root, ext), either part may be empty."""
-
-    i = p.rfind('.')
-    if i<=max(p.rfind('/'), p.rfind('\\')):
-        return p, ''
-    else:
-        return p[:i], p[i:]
+    return genericpath._splitext(p, sep, altsep, extsep)
+splitext.__doc__ = genericpath._splitext.__doc__
 
 
 # Return the tail (basename) part of a path.
@@ -285,36 +278,44 @@
     i, n = 1, len(path)
     while i < n and path[i] not in '/\\':
         i = i + 1
-    if i == 1:
-        if 'HOME' in os.environ:
-            userhome = os.environ['HOME']
-        elif not 'HOMEPATH' in os.environ:
-            return path
-        else:
-            try:
-                drive = os.environ['HOMEDRIVE']
-            except KeyError:
-                drive = ''
-            userhome = join(drive, os.environ['HOMEPATH'])
-    else:
+
+    if 'HOME' in os.environ:
+        userhome = os.environ['HOME']
+    elif 'USERPROFILE' in os.environ:
+        userhome = os.environ['USERPROFILE']
+    elif not 'HOMEPATH' in os.environ:
         return path
+    else:
+        try:
+            drive = os.environ['HOMEDRIVE']
+        except KeyError:
+            drive = ''
+        userhome = join(drive, os.environ['HOMEPATH'])
+
+    if i != 1: #~user
+        userhome = join(dirname(userhome), path[1:i])
+
     return userhome + path[i:]
 
 
 # Expand paths containing shell variable substitutions.
 # The following rules apply:
 #       - no expansion within single quotes
-#       - no escape character, except for '$$' which is translated into '$'
+#       - '$$' is translated into '$'
+#       - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
 #       - ${varname} is accepted.
-#       - varnames can be made out of letters, digits and the character '_'
+#       - $varname is accepted.
+#       - %varname% is accepted.
+#       - varnames can be made out of letters, digits and the characters '_-'
+#         (though is not verifed in the ${varname} and %varname% cases)
 # XXX With COMMAND.COM you can use any characters in a variable name,
 # XXX except '^|<>='.
 
 def expandvars(path):
-    """Expand shell variables of form $var and ${var}.
+    """Expand shell variables of the forms $var, ${var} and %var%.
 
     Unknown variables are left unchanged."""
-    if '$' not in path:
+    if '$' not in path and '%' not in path:
         return path
     import string
     varchars = string.ascii_letters + string.digits + '_-'
@@ -332,6 +333,24 @@
             except ValueError:
                 res = res + path
                 index = pathlen - 1
+        elif c == '%':  # variable or '%'
+            if path[index + 1:index + 2] == '%':
+                res = res + c
+                index = index + 1
+            else:
+                path = path[index+1:]
+                pathlen = len(path)
+                try:
+                    index = path.index('%')
+                except ValueError:
+                    res = res + '%' + path
+                    index = pathlen - 1
+                else:
+                    var = path[:index]
+                    if var in os.environ:
+                        res = res + os.environ[var]
+                    else:
+                        res = res + '%' + var + '%'
         elif c == '$':  # variable or '$$'
             if path[index + 1:index + 2] == '$':
                 res = res + c
@@ -446,3 +465,29 @@
 # Win9x family and earlier have no Unicode filename support.
 supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
                               sys.getwindowsversion()[3] >= 2)
+
+def relpath(path, start=curdir):
+    """Return a relative version of a path"""
+
+    if not path:
+        raise ValueError("no path specified")
+    start_list = abspath(start).split(sep)
+    path_list = abspath(path).split(sep)
+    if start_list[0].lower() != path_list[0].lower():
+        unc_path, rest = splitunc(path)
+        unc_start, rest = splitunc(start)
+        if bool(unc_path) ^ bool(unc_start):
+            raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+                                                                % (path, start))
+        else:
+            raise ValueError("path is on drive %s, start on drive %s"
+                                                % (path_list[0], start_list[0]))
+    # Work out how much of the filepath is shared by start and path.
+    for i in range(min(len(start_list), len(path_list))):
+        if start_list[i].lower() != path_list[i].lower():
+            break
+    else:
+        i += 1
+
+    rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
+    return join(*rel_list)

Modified: python/branches/p3yk/Lib/os.py
==============================================================================
--- python/branches/p3yk/Lib/os.py	(original)
+++ python/branches/p3yk/Lib/os.py	Fri Apr 27 21:54:29 2007
@@ -221,7 +221,7 @@
 
 __all__.extend(["makedirs", "removedirs", "renames"])
 
-def walk(top, topdown=True, onerror=None):
+def walk(top, topdown=True, onerror=None, followlinks=False):
     """Directory tree generator.
 
     For each directory in the directory tree rooted at top (including top
@@ -257,6 +257,10 @@
     to abort the walk.  Note that the filename is available as the
     filename attribute of the exception object.
 
+    By default, os.walk does not follow symbolic links to subdirectories on
+    systems that support them.  In order to get this functionality, set the
+    optional argument 'followlinks' to true.
+
     Caution:  if you pass a relative pathname for top, don't change the
     current working directory between resumptions of walk.  walk never
     changes the current directory, and assumes that the client doesn't
@@ -300,8 +304,8 @@
         yield top, dirs, nondirs
     for name in dirs:
         path = join(top, name)
-        if not islink(path):
-            for x in walk(path, topdown, onerror):
+        if followlinks or not islink(path):
+            for x in walk(path, topdown, onerror, followlinks):
                 yield x
     if not topdown:
         yield top, dirs, nondirs

Modified: python/branches/p3yk/Lib/pdb.doc
==============================================================================
--- python/branches/p3yk/Lib/pdb.doc	(original)
+++ python/branches/p3yk/Lib/pdb.doc	Fri Apr 27 21:54:29 2007
@@ -131,6 +131,12 @@
 r(eturn)
         Continue execution until the current function returns.
 
+run [args...]
+        Restart the debugged python program. If a string is supplied it is
+        splitted with "shlex", and the result is used as the new sys.argv.
+	History, breakpoints, actions and debugger options are preserved.
+	"restart" is an alias for "run".
+
 c(ont(inue))
         Continue execution, only stop when a breakpoint is encountered.
 

Modified: python/branches/p3yk/Lib/pdb.py
==============================================================================
--- python/branches/p3yk/Lib/pdb.py	(original)
+++ python/branches/p3yk/Lib/pdb.py	Fri Apr 27 21:54:29 2007
@@ -13,6 +13,12 @@
 import re
 import pprint
 import traceback
+
+
+class Restart(Exception):
+    """Causes a debugger to be restarted for the debugged python program."""
+    pass
+
 # Create a custom safe Repr instance and increase its maxstring.
 # The default of 30 truncates error messages too easily.
 _repr = Repr()
@@ -484,11 +490,16 @@
         except ValueError:
             # something went wrong
             print('Breakpoint index %r is not a number' % args[0], file=self.stdout)
+            return
         try:
             cond = args[1]
         except:
             cond = None
-        bp = bdb.Breakpoint.bpbynumber[bpnum]
+        try:
+            bp = bdb.Breakpoint.bpbynumber[bpnum]
+        except IndexError:
+            print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
+            return
         if bp:
             bp.cond = cond
             if not cond:
@@ -503,11 +514,16 @@
         except ValueError:
             # something went wrong
             print('Breakpoint index %r is not a number' % args[0], file=self.stdout)
+            return
         try:
             count = int(args[1].strip())
         except:
             count = 0
-        bp = bdb.Breakpoint.bpbynumber[bpnum]
+        try:
+            bp = bdb.Breakpoint.bpbynumber[bpnum]
+        except IndexError:
+            print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
+            return
         if bp:
             bp.ignore = count
             if count > 0:
@@ -601,6 +617,18 @@
         return 1
     do_n = do_next
 
+    def do_run(self, arg):
+        """Restart program by raising an exception to be caught in the main debugger
+        loop. If arguments were given, set them in sys.argv."""
+        if arg:
+            import shlex
+            argv0 = sys.argv[0:1]
+            sys.argv = shlex.split(arg)
+            sys.argv[:0] = argv0
+        raise Restart
+
+    do_restart = do_run
+
     def do_return(self, arg):
         self.set_return(self.curframe)
         return 1
@@ -1005,6 +1033,15 @@
 (Pdb) global list_options; list_options = ['-l']
 (Pdb)""", file=self.stdout)
 
+    def help_run(self):
+        print("""run [args...]
+Restart the debugged python program. If a string is supplied, it is
+splitted with "shlex" and the result is used as the new sys.argv.
+History, breakpoints, actions and debugger options are preserved.
+"restart" is an alias for "run".""")
+
+    help_restart = help_run
+
     def help_quit(self):
         self.help_q()
 
@@ -1113,11 +1150,17 @@
         return None
 
     def _runscript(self, filename):
-        # Start with fresh empty copy of globals and locals and tell the script
-        # that it's being run as __main__ to avoid scripts being able to access
-        # the pdb.py namespace.
-        globals_ = {"__name__" : "__main__"}
-        locals_ = globals_
+        # The script has to run in __main__ namespace (or imports from
+        # __main__ will break).
+        #
+        # So we clear up the __main__ and set several special variables
+        # (this gets rid of pdb's globals and cleans old variables on restarts).
+        import __main__
+        __main__.__dict__.clear()
+        __main__.__dict__.update({"__name__"    : "__main__",
+                                  "__file__"    : filename,
+                                  "__builtins__": __builtins__,
+                                 })
 
         # When bdb sets tracing, a number of call and line events happens
         # BEFORE debugger even reaches user's code (and the exact sequence of
@@ -1128,7 +1171,7 @@
         self.mainpyfile = self.canonic(filename)
         self._user_requested_quit = 0
         statement = 'execfile( "%s")' % filename
-        self.run(statement, globals=globals_, locals=locals_)
+        self.run(statement)
 
 # Simplified interface
 
@@ -1197,9 +1240,8 @@
 
     # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
     # modified by the script being debugged. It's a bad idea when it was
-    # changed by the user from the command line. The best approach would be to
-    # have a "restart" command which would allow explicit specification of
-    # command line arguments.
+    # changed by the user from the command line. There is a "restart" command which
+    # allows explicit specification of command line arguments.
     pdb = Pdb()
     while 1:
         try:
@@ -1207,6 +1249,9 @@
             if pdb._user_requested_quit:
                 break
             print("The program finished and will be restarted")
+        except Restart:
+            print("Restarting", mainpyfile, "with arguments:")
+            print("\t" + " ".join(sys.argv[1:]))
         except SystemExit:
             # In most cases SystemExit does not warrant a post-mortem session.
             print("The program exited via sys.exit(). Exit status: ", end=' ')
@@ -1223,5 +1268,6 @@
 
 
 # When invoked as main program, invoke the debugger on a script
-if __name__=='__main__':
-    main()
+if __name__ == '__main__':
+    import pdb
+    pdb.main()

Modified: python/branches/p3yk/Lib/popen2.py
==============================================================================
--- python/branches/p3yk/Lib/popen2.py	(original)
+++ python/branches/p3yk/Lib/popen2.py	Fri Apr 27 21:54:29 2007
@@ -200,45 +200,3 @@
         return inst.fromchild, inst.tochild
 
     __all__.extend(["Popen3", "Popen4"])
-
-def _test():
-    # When the test runs, there shouldn't be any open pipes
-    _cleanup()
-    assert not _active, "Active pipes when test starts " + repr([c.cmd for c in _active])
-    cmd  = "cat"
-    teststr = "ab cd\n"
-    if os.name == "nt":
-        cmd = "more"
-    # "more" doesn't act the same way across Windows flavors,
-    # sometimes adding an extra newline at the start or the
-    # end.  So we strip whitespace off both ends for comparison.
-    expected = teststr.strip()
-    print("testing popen2...")
-    r, w = popen2(cmd)
-    w.write(teststr)
-    w.close()
-    got = r.read()
-    if got.strip() != expected:
-        raise ValueError("wrote %r read %r" % (teststr, got))
-    print("testing popen3...")
-    try:
-        r, w, e = popen3([cmd])
-    except:
-        r, w, e = popen3(cmd)
-    w.write(teststr)
-    w.close()
-    got = r.read()
-    if got.strip() != expected:
-        raise ValueError("wrote %r read %r" % (teststr, got))
-    got = e.read()
-    if got:
-        raise ValueError("unexpected %r on stderr" % (got,))
-    for inst in _active[:]:
-        inst.wait()
-    _cleanup()
-    if _active:
-        raise ValueError("_active not empty")
-    print("All OK")
-
-if __name__ == '__main__':
-    _test()

Modified: python/branches/p3yk/Lib/poplib.py
==============================================================================
--- python/branches/p3yk/Lib/poplib.py	(original)
+++ python/branches/p3yk/Lib/poplib.py	Fri Apr 27 21:54:29 2007
@@ -76,24 +76,10 @@
     """
 
 
-    def __init__(self, host, port = POP3_PORT):
+    def __init__(self, host, port=POP3_PORT, timeout=None):
         self.host = host
         self.port = port
-        msg = "getaddrinfo returns an empty list"
-        self.sock = None
-        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
-            try:
-                self.sock = socket.socket(af, socktype, proto)
-                self.sock.connect(sa)
-            except socket.error as msg:
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
+        self.sock = socket.create_connection((host, port), timeout)
         self.file = self.sock.makefile('rb')
         self._debugging = 0
         self.welcome = self._getresp()

Modified: python/branches/p3yk/Lib/posixpath.py
==============================================================================
--- python/branches/p3yk/Lib/posixpath.py	(original)
+++ python/branches/p3yk/Lib/posixpath.py	Fri Apr 27 21:54:29 2007
@@ -12,6 +12,7 @@
 
 import os
 import stat
+import genericpath
 from genericpath import *
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
@@ -20,7 +21,7 @@
            "ismount","walk","expanduser","expandvars","normpath","abspath",
            "samefile","sameopenfile","samestat",
            "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
-           "devnull","realpath","supports_unicode_filenames"]
+           "devnull","realpath","supports_unicode_filenames","relpath"]
 
 # strings representing various path-related bits and pieces
 curdir = '.'
@@ -88,14 +89,8 @@
 # It is always true that root + ext == p.
 
 def splitext(p):
-    """Split the extension from a pathname.  Extension is everything from the
-    last dot to the end.  Returns "(root, ext)", either part may be empty."""
-    i = p.rfind('.')
-    if i<=p.rfind('/'):
-        return p, ''
-    else:
-        return p[:i], p[i:]
-
+    return genericpath._splitext(p, sep, altsep, extsep)
+splitext.__doc__ = genericpath._splitext.__doc__
 
 # Split a pathname into a drive specification and the rest of the
 # path.  Useful on DOS/Windows/NT; on Unix, the drive is always empty.
@@ -387,3 +382,18 @@
     return path
 
 supports_unicode_filenames = False
+
+def relpath(path, start=curdir):
+    """Return a relative version of a path"""
+
+    if not path:
+        raise ValueError("no path specified")
+
+    start_list = abspath(start).split(sep)
+    path_list = abspath(path).split(sep)
+
+    # Work out how much of the filepath is shared by start and path.
+    i = len(commonprefix([start_list, path_list]))
+
+    rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
+    return join(*rel_list)

Modified: python/branches/p3yk/Lib/pydoc.py
==============================================================================
--- python/branches/p3yk/Lib/pydoc.py	(original)
+++ python/branches/p3yk/Lib/pydoc.py	Fri Apr 27 21:54:29 2007
@@ -854,7 +854,7 @@
                 if imclass is not cl:
                     note = ' from ' + self.classlink(imclass, mod)
             else:
-                if object.im_self:
+                if object.im_self is not None:
                     note = ' method of %s instance' % self.classlink(
                         object.im_self.__class__, mod)
                 else:
@@ -1232,7 +1232,7 @@
                 if imclass is not cl:
                     note = ' from ' + classname(imclass, mod)
             else:
-                if object.im_self:
+                if object.im_self is not None:
                     note = ' method of %s instance' % classname(
                         object.im_self.__class__, mod)
                 else:
@@ -1468,6 +1468,27 @@
     else:
         return thing, getattr(thing, '__name__', None)
 
+def render_doc(thing, title='Python Library Documentation: %s', forceload=0):
+    """Render text documentation, given an object or a path to an object."""
+    object, name = resolve(thing, forceload)
+    desc = describe(object)
+    module = inspect.getmodule(object)
+    if name and '.' in name:
+        desc += ' in ' + name[:name.rfind('.')]
+    elif module and module is not object:
+        desc += ' in module ' + module.__name__
+    elif not (inspect.ismodule(object) or
+              inspect.isclass(object) or
+              inspect.isroutine(object) or
+              inspect.isgetsetdescriptor(object) or
+              inspect.ismemberdescriptor(object) or
+              isinstance(object, property)):
+        # If the passed object is a piece of data or an instance,
+        # document its available methods instead of its value.
+        object = type(object)
+        desc += ' object'
+    return title % desc + '\n\n' + text.document(object, name)
+
 def doc(thing, title='Python Library Documentation: %s', forceload=0):
     """Display text documentation, given an object or a path to an object."""
     try:
@@ -1488,7 +1509,7 @@
             # document its available methods instead of its value.
             object = type(object)
             desc += ' object'
-        pager(title % desc + '\n\n' + text.document(object, name))
+        pager(render_doc(thing, title, forceload))
     except (ImportError, ErrorDuringImport) as value:
         print(value)
 
@@ -1519,6 +1540,7 @@
 class Helper:
     keywords = {
         'and': 'BOOLEAN',
+        'as': 'with',
         'assert': ('ref/assert', ''),
         'break': ('ref/break', 'while for'),
         'class': ('ref/class', 'CLASSES SPECIALMETHODS'),
@@ -1546,6 +1568,7 @@
         'return': ('ref/return', 'FUNCTIONS'),
         'try': ('ref/try', 'EXCEPTIONS'),
         'while': ('ref/while', 'break continue if TRUTHVALUE'),
+        'with': ('ref/with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
         'yield': ('ref/yield', ''),
     }
 
@@ -1626,6 +1649,7 @@
         'LOOPING': ('ref/compound', 'for while break continue'),
         'TRUTHVALUE': ('lib/truth', 'if while and or not BASICMETHODS'),
         'DEBUGGING': ('lib/module-pdb', 'pdb'),
+        'CONTEXTMANAGERS': ('ref/context-managers', 'with'),
     }
 
     def __init__(self, input, output):
@@ -1634,16 +1658,21 @@
         self.docdir = None
         execdir = os.path.dirname(sys.executable)
         homedir = os.environ.get('PYTHONHOME')
+        join = os.path.join
         for dir in [os.environ.get('PYTHONDOCS'),
                     homedir and os.path.join(homedir, 'doc'),
-                    os.path.join(execdir, 'doc'),
-                    '/usr/doc/python-docs-' + sys.version.split()[0],
-                    '/usr/doc/python-' + sys.version.split()[0],
-                    '/usr/doc/python-docs-' + sys.version[:3],
-                    '/usr/doc/python-' + sys.version[:3],
-                    os.path.join(sys.prefix, 'Resources/English.lproj/Documentation')]:
-            if dir and os.path.isdir(os.path.join(dir, 'lib')):
+                    join(execdir, 'doc'), # for Windows
+                    join(sys.prefix, 'doc/python-docs-' + sys.version.split()[0]),
+                    join(sys.prefix, 'doc/python-' + sys.version.split()[0]),
+                    join(sys.prefix, 'doc/python-docs-' + sys.version[:3]),
+                    join(sys.prefix, 'doc/python-' + sys.version[:3]),
+                    join(sys.prefix, 'Resources/English.lproj/Documentation')]:
+            if dir and os.path.isdir(join(dir, 'lib')):
                 self.docdir = dir
+                break
+            if dir and os.path.isdir(join(dir, 'html', 'lib')):
+                self.docdir = join(dir, 'html')
+                break
 
     def __repr__(self):
         if inspect.stack()[1][3] == '?':

Modified: python/branches/p3yk/Lib/rexec.py
==============================================================================
--- python/branches/p3yk/Lib/rexec.py	(original)
+++ python/branches/p3yk/Lib/rexec.py	Fri Apr 27 21:54:29 2007
@@ -29,7 +29,7 @@
 class FileBase:
 
     ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
-            'readlines', 'seek', 'tell', 'write', 'writelines', 
+            'readlines', 'seek', 'tell', 'write', 'writelines',
             '__iter__')
 
 
@@ -181,7 +181,7 @@
 
         """
 
-        raise RuntimeError, "This code is not secure in Python 2.2 and 2.3"
+        raise RuntimeError, "This code is not secure in Python 2.2 and later"
 
         ihooks._Verbose.__init__(self, verbose)
         # XXX There's a circular reference here:

Modified: python/branches/p3yk/Lib/robotparser.py
==============================================================================
--- python/branches/p3yk/Lib/robotparser.py	(original)
+++ python/branches/p3yk/Lib/robotparser.py	Fri Apr 27 21:54:29 2007
@@ -65,7 +65,7 @@
             lines.append(line.strip())
             line = f.readline()
         self.errcode = opener.errcode
-        if self.errcode == 401 or self.errcode == 403:
+        if self.errcode in (401, 403):
             self.disallow_all = True
             _debug("disallow all")
         elif self.errcode >= 400:
@@ -168,10 +168,7 @@
 
 
     def __str__(self):
-        ret = ""
-        for entry in self.entries:
-            ret = ret + str(entry) + "\n"
-        return ret
+        return ''.join([str(entry) + "\n" for entry in self.entries])
 
 
 class RuleLine:
@@ -198,12 +195,12 @@
         self.rulelines = []
 
     def __str__(self):
-        ret = ""
+        ret = []
         for agent in self.useragents:
-            ret = ret + "User-agent: "+agent+"\n"
+            ret.extend(["User-agent: ", agent, "\n"])
         for line in self.rulelines:
-            ret = ret + str(line) + "\n"
-        return ret
+            ret.extend([str(line), "\n"])
+        return ''.join(ret)
 
     def applies_to(self, useragent):
         """check if this entry applies to the specified agent"""

Modified: python/branches/p3yk/Lib/sched.py
==============================================================================
--- python/branches/p3yk/Lib/sched.py	(original)
+++ python/branches/p3yk/Lib/sched.py	Fri Apr 27 21:54:29 2007
@@ -72,7 +72,7 @@
 
     def empty(self):
         """Check whether the queue is empty."""
-        return not not self.queue
+        return not self.queue
 
     def run(self):
         """Execute events until the queue is empty.

Modified: python/branches/p3yk/Lib/site.py
==============================================================================
--- python/branches/p3yk/Lib/site.py	(original)
+++ python/branches/p3yk/Lib/site.py	Fri Apr 27 21:54:29 2007
@@ -134,7 +134,7 @@
         for line in f:
             if line.startswith("#"):
                 continue
-            if line.startswith("import"):
+            if line.startswith("import ") or line.startswith("import\t"):
                 exec(line)
                 continue
             line = line.rstrip()

Modified: python/branches/p3yk/Lib/smtplib.py
==============================================================================
--- python/branches/p3yk/Lib/smtplib.py	(original)
+++ python/branches/p3yk/Lib/smtplib.py	Fri Apr 27 21:54:29 2007
@@ -226,10 +226,11 @@
     debuglevel = 0
     file = None
     helo_resp = None
+    ehlo_msg = "ehlo"
     ehlo_resp = None
     does_esmtp = 0
 
-    def __init__(self, host = '', port = 0, local_hostname = None):
+    def __init__(self, host='', port=0, local_hostname=None, timeout=None):
         """Initialize a new instance.
 
         If specified, `host' is the name of the remote host to which to
@@ -240,6 +241,7 @@
         the local hostname is found using socket.getfqdn().
 
         """
+        self.timeout = timeout
         self.esmtp_features = {}
         self.default_port = SMTP_PORT
         if host:
@@ -273,12 +275,11 @@
         """
         self.debuglevel = debuglevel
 
-    def _get_socket(self,af, socktype, proto,sa):
+    def _get_socket(self, port, host, timeout):
         # This makes it simpler for SMTP_SSL to use the SMTP connect code
         # and just alter the socket connection bit.
-        self.sock = socket.socket(af, socktype, proto)
         if self.debuglevel > 0: print('connect:', (host, port), file=stderr)
-        self.sock.connect(sa)
+        return socket.create_connection((port, host), timeout)
 
     def connect(self, host='localhost', port = 0):
         """Connect to a host on a given port.
@@ -297,24 +298,10 @@
                 host, port = host[:i], host[i+1:]
                 try: port = int(port)
                 except ValueError:
-                    raise socket.error, "nonnumeric port"
+                    raise socket.error("nonnumeric port")
         if not port: port = self.default_port
         if self.debuglevel > 0: print('connect:', (host, port), file=stderr)
-        msg = "getaddrinfo returns an empty list"
-        self.sock = None
-        for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
-            try:
-                self._get_socket(af,socktype,proto,sa)
-            except socket.error as msg:
-                if self.debuglevel > 0: print('connect fail:', msg, file=stderr)
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
+        self.sock = self._get_socket(host, port, self.timeout)
         (code, msg) = self.getreply()
         if self.debuglevel > 0: print("connect:", msg, file=stderr)
         return (code, msg)
@@ -401,7 +388,7 @@
         host.
         """
         self.esmtp_features = {}
-        self.putcmd("ehlo", name or self.local_hostname)
+        self.putcmd(self.ehlo_msg, name or self.local_hostname)
         (code,msg)=self.getreply()
         # According to RFC1869 some (badly written)
         # MTA's will disconnect on an ehlo. Toss an exception if
@@ -731,21 +718,64 @@
     are also optional - they can contain a PEM formatted private key and
     certificate chain file for the SSL connection.
     """
-    def __init__(self, host = '', port = 0, local_hostname = None,
-                 keyfile = None, certfile = None):
+    def __init__(self, host='', port=0, local_hostname=None,
+                 keyfile=None, certfile=None, timeout=None):
         self.keyfile = keyfile
         self.certfile = certfile
-        SMTP.__init__(self,host,port,local_hostname)
+        SMTP.__init__(self, host, port, local_hostname, timeout)
         self.default_port = SMTP_SSL_PORT
 
-    def _get_socket(self,af, socktype, proto,sa):
-        self.sock = socket.socket(af, socktype, proto)
+    def _get_socket(self, host, port, timeout):
         if self.debuglevel > 0: print('connect:', (host, port), file=stderr)
-        self.sock.connect(sa)
+        self.sock = socket.create_connection((host, port), timeout)
         sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
         self.sock = SSLFakeSocket(self.sock, sslobj)
         self.file = SSLFakeFile(sslobj)
 
+#
+# LMTP extension
+#
+LMTP_PORT = 2003
+
+class LMTP(SMTP):
+    """LMTP - Local Mail Transfer Protocol
+
+    The LMTP protocol, which is very similar to ESMTP, is heavily based
+    on the standard SMTP client. It's common to use Unix sockets for LMTP,
+    so our connect() method must support that as well as a regular
+    host:port server. To specify a Unix socket, you must use an absolute
+    path as the host, starting with a '/'.
+
+    Authentication is supported, using the regular SMTP mechanism. When
+    using a Unix socket, LMTP generally don't support or require any
+    authentication, but your mileage might vary."""
+
+    ehlo_msg = "lhlo"
+
+    def __init__(self, host = '', port = LMTP_PORT, local_hostname = None):
+        """Initialize a new instance."""
+        SMTP.__init__(self, host, port, local_hostname)
+
+    def connect(self, host = 'localhost', port = 0):
+        """Connect to the LMTP daemon, on either a Unix or a TCP socket."""
+        if host[0] != '/':
+            return SMTP.connect(self, host, port)
+
+        # Handle Unix-domain sockets.
+        try:
+            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            self.sock.connect(host)
+        except socket.error as msg:
+            if self.debuglevel > 0: print>>stderr, 'connect fail:', host
+            if self.sock:
+                self.sock.close()
+            self.sock = None
+            raise socket.error(msg)
+        (code, msg) = self.getreply()
+        if self.debuglevel > 0: print>>stderr, "connect:", msg
+        return (code, msg)
+
+
 # Test the sendmail method, which tests most of the others.
 # Note: This always sends to localhost.
 if __name__ == '__main__':

Modified: python/branches/p3yk/Lib/socket.py
==============================================================================
--- python/branches/p3yk/Lib/socket.py	(original)
+++ python/branches/p3yk/Lib/socket.py	Fri Apr 27 21:54:29 2007
@@ -24,6 +24,7 @@
 ssl() -- secure socket layer support (only available if configured)
 socket.getdefaulttimeout() -- get the default timeout value
 socket.setdefaulttimeout() -- set the default timeout value
+create_connection() -- connects to an address, with an optional timeout
 
  [*] not available on all platforms!
 
@@ -139,8 +140,6 @@
     __slots__ = []
     def _dummy(*args):
         raise error(EBADF, 'Bad file descriptor')
-    def close(self):
-        pass
     # All _delegate_methods must also be initialized here.
     send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
     __getattr__ = _dummy
@@ -159,7 +158,6 @@
             setattr(self, method, getattr(_sock, method))
 
     def close(self):
-        self._sock.close()
         self._sock = _closedsocket()
         dummy = self._sock._dummy
         for method in _delegate_methods:
@@ -414,3 +412,32 @@
         if not line:
             raise StopIteration
         return line
+
+
+def create_connection(address, timeout=None):
+    """Connect to address (host, port) with an optional timeout.
+
+    Provides access to socketobject timeout for higher-level
+    protocols.  Passing a timeout will set the timeout on the
+    socket instance (if not present, or passed as None, the
+    default global timeout setting will be used).
+    """
+
+    msg = "getaddrinfo returns an empty list"
+    host, port = address
+    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
+        af, socktype, proto, canonname, sa = res
+        sock = None
+        try:
+            sock = socket(af, socktype, proto)
+            if timeout is not None:
+                sock.settimeout(timeout)
+            sock.connect(sa)
+            return sock
+
+        except error as err:
+            msg = err
+            if sock is not None:
+                sock.close()
+
+    raise error(msg)

Modified: python/branches/p3yk/Lib/sre.py
==============================================================================
--- python/branches/p3yk/Lib/sre.py	(original)
+++ python/branches/p3yk/Lib/sre.py	Fri Apr 27 21:54:29 2007
@@ -8,3 +8,6 @@
 
 from re import *
 from re import __all__
+
+# old pickles expect the _compile() reconstructor in this module
+from re import _compile

Modified: python/branches/p3yk/Lib/subprocess.py
==============================================================================
--- python/branches/p3yk/Lib/subprocess.py	(original)
+++ python/branches/p3yk/Lib/subprocess.py	Fri Apr 27 21:54:29 2007
@@ -597,7 +597,7 @@
         # either have to redirect all three or none. If the subprocess
         # user has only redirected one or two handles, we are
         # automatically creating PIPEs for the rest. We should close
-        # these after the process is started. See bug #1124861. 
+        # these after the process is started. See bug #1124861.
         if mswindows:
             if stdin is None and p2cwrite is not None:
                 os.close(p2cwrite)
@@ -629,7 +629,7 @@
         return data
 
 
-    def __del__(self):
+    def __del__(self, sys=sys):
         if not self._child_created:
             # We didn't get to successfully create a child process.
             return

Modified: python/branches/p3yk/Lib/tarfile.py
==============================================================================
--- python/branches/p3yk/Lib/tarfile.py	(original)
+++ python/branches/p3yk/Lib/tarfile.py	Fri Apr 27 21:54:29 2007
@@ -33,7 +33,7 @@
 __version__ = "$Revision$"
 # $Source$
 
-version     = "0.8.0"
+version     = "0.9.0"
 __author__  = "Lars Gustäbel (lars at gustaebel.de)"
 __date__    = "$Date$"
 __cvsid__   = "$Id$"
@@ -50,6 +50,7 @@
 import time
 import struct
 import copy
+import re
 
 if sys.platform == 'mac':
     # This module needs work for MacOS9, especially in the area of pathname
@@ -71,42 +72,60 @@
 #---------------------------------------------------------
 # tar constants
 #---------------------------------------------------------
-NUL        = "\0"               # the null character
-BLOCKSIZE  = 512                # length of processing blocks
+NUL = "\0"                      # the null character
+BLOCKSIZE = 512                 # length of processing blocks
 RECORDSIZE = BLOCKSIZE * 20     # length of records
-MAGIC      = "ustar"            # magic tar string
-VERSION    = "00"               # version number
+GNU_MAGIC = "ustar  \0"         # magic gnu tar string
+POSIX_MAGIC = "ustar\x0000"     # magic posix tar string
 
-LENGTH_NAME    = 100            # maximum length of a filename
-LENGTH_LINK    = 100            # maximum length of a linkname
-LENGTH_PREFIX  = 155            # maximum length of the prefix field
-MAXSIZE_MEMBER = 077777777777  # maximum size of a file (11 octal digits)
+LENGTH_NAME = 100               # maximum length of a filename
+LENGTH_LINK = 100               # maximum length of a linkname
+LENGTH_PREFIX = 155             # maximum length of the prefix field
 
-REGTYPE  = "0"                  # regular file
+REGTYPE = "0"                   # regular file
 AREGTYPE = "\0"                 # regular file
-LNKTYPE  = "1"                  # link (inside tarfile)
-SYMTYPE  = "2"                  # symbolic link
-CHRTYPE  = "3"                  # character special device
-BLKTYPE  = "4"                  # block special device
-DIRTYPE  = "5"                  # directory
+LNKTYPE = "1"                   # link (inside tarfile)
+SYMTYPE = "2"                   # symbolic link
+CHRTYPE = "3"                   # character special device
+BLKTYPE = "4"                   # block special device
+DIRTYPE = "5"                   # directory
 FIFOTYPE = "6"                  # fifo special device
 CONTTYPE = "7"                  # contiguous file
 
-GNUTYPE_LONGNAME = "L"          # GNU tar extension for longnames
-GNUTYPE_LONGLINK = "K"          # GNU tar extension for longlink
-GNUTYPE_SPARSE   = "S"          # GNU tar extension for sparse file
+GNUTYPE_LONGNAME = "L"          # GNU tar longname
+GNUTYPE_LONGLINK = "K"          # GNU tar longlink
+GNUTYPE_SPARSE = "S"            # GNU tar sparse file
+
+XHDTYPE = "x"                   # POSIX.1-2001 extended header
+XGLTYPE = "g"                   # POSIX.1-2001 global header
+SOLARIS_XHDTYPE = "X"           # Solaris extended header
+
+USTAR_FORMAT = 0                # POSIX.1-1988 (ustar) format
+GNU_FORMAT = 1                  # GNU tar format
+PAX_FORMAT = 2                  # POSIX.1-2001 (pax) format
+DEFAULT_FORMAT = GNU_FORMAT
 
 #---------------------------------------------------------
 # tarfile constants
 #---------------------------------------------------------
-SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,  # file types that tarfile
-                   SYMTYPE, DIRTYPE, FIFOTYPE,  # can cope with.
+# File types that tarfile supports:
+SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,
+                   SYMTYPE, DIRTYPE, FIFOTYPE,
                    CONTTYPE, CHRTYPE, BLKTYPE,
                    GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
                    GNUTYPE_SPARSE)
 
-REGULAR_TYPES = (REGTYPE, AREGTYPE,             # file types that somehow
-                 CONTTYPE, GNUTYPE_SPARSE)      # represent regular files
+# File types that will be treated as a regular file.
+REGULAR_TYPES = (REGTYPE, AREGTYPE,
+                 CONTTYPE, GNUTYPE_SPARSE)
+
+# File types that are part of the GNU tar format.
+GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
+             GNUTYPE_SPARSE)
+
+# Fields from a pax header that override a TarInfo attribute.
+PAX_FIELDS = ("path", "linkpath", "size", "mtime",
+              "uid", "gid", "uname", "gname")
 
 #---------------------------------------------------------
 # Bits used in the mode field, values in octal.
@@ -133,6 +152,13 @@
 TOEXEC  = 0001           # execute/search by other
 
 #---------------------------------------------------------
+# initialization
+#---------------------------------------------------------
+ENCODING = sys.getfilesystemencoding()
+if ENCODING is None:
+    ENCODING = "ascii"
+
+#---------------------------------------------------------
 # Some useful functions
 #---------------------------------------------------------
 
@@ -141,6 +167,15 @@
     """
     return s[:length] + (length - len(s)) * NUL
 
+def nts(s):
+    """Convert a null-terminated string field to a python string.
+    """
+    # Use the string up to the first null char.
+    p = s.find("\0")
+    if p == -1:
+        return s
+    return s[:p]
+
 def nti(s):
     """Convert a number field to a python number.
     """
@@ -148,7 +183,7 @@
     # itn() below.
     if s[0] != chr(0200):
         try:
-            n = int(s.rstrip(NUL + " ") or "0", 8)
+            n = int(nts(s) or "0", 8)
         except ValueError:
             raise HeaderError("invalid header")
     else:
@@ -158,7 +193,7 @@
             n += ord(s[i + 1])
     return n
 
-def itn(n, digits=8, posix=False):
+def itn(n, digits=8, format=DEFAULT_FORMAT):
     """Convert a python number to a number field.
     """
     # POSIX 1003.1-1988 requires numbers to be encoded as a string of
@@ -170,7 +205,7 @@
     if 0 <= n < 8 ** (digits - 1):
         s = "%0*o" % (digits - 1, n) + NUL
     else:
-        if posix:
+        if format != GNU_FORMAT or n >= 256 ** (digits - 1):
             raise ValueError("overflow in number field")
 
         if n < 0:
@@ -516,7 +551,10 @@
             buf = self.__read(self.bufsize)
             if not buf:
                 break
-            buf = self.cmp.decompress(buf)
+            try:
+                buf = self.cmp.decompress(buf)
+            except IOError:
+                raise ReadError("invalid compressed data")
             t.append(buf)
             c += len(buf)
         t = "".join(t)
@@ -577,6 +615,7 @@
     def __init__(self, fileobj, mode):
         self.fileobj = fileobj
         self.mode = mode
+        self.name = getattr(self.fileobj, "name", None)
         self.init()
 
     def init(self):
@@ -849,8 +888,8 @@
         """Construct a TarInfo object. name is the optional name
            of the member.
         """
-        self.name = name        # member name (dirnames must end with '/')
-        self.mode = 0666        # file permissions
+        self.name = name        # member name
+        self.mode = 0644        # file permissions
         self.uid = 0            # user id
         self.gid = 0            # group id
         self.size = 0           # file size
@@ -858,17 +897,274 @@
         self.chksum = 0         # header checksum
         self.type = REGTYPE     # member type
         self.linkname = ""      # link name
-        self.uname = "user"     # user name
-        self.gname = "group"    # group name
+        self.uname = "root"     # user name
+        self.gname = "root"     # group name
         self.devmajor = 0       # device major number
         self.devminor = 0       # device minor number
 
         self.offset = 0         # the tar header starts here
         self.offset_data = 0    # the file's data starts here
 
+        self.pax_headers = {}   # pax header information
+
+    # In pax headers the "name" and "linkname" field are called
+    # "path" and "linkpath".
+    def _getpath(self):
+        return self.name
+    def _setpath(self, name):
+        self.name = name
+    path = property(_getpath, _setpath)
+
+    def _getlinkpath(self):
+        return self.linkname
+    def _setlinkpath(self, linkname):
+        self.linkname = linkname
+    linkpath = property(_getlinkpath, _setlinkpath)
+
     def __repr__(self):
         return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
 
+    def get_info(self):
+        """Return the TarInfo's attributes as a dictionary.
+        """
+        info = {
+            "name":     normpath(self.name),
+            "mode":     self.mode & 07777,
+            "uid":      self.uid,
+            "gid":      self.gid,
+            "size":     self.size,
+            "mtime":    self.mtime,
+            "chksum":   self.chksum,
+            "type":     self.type,
+            "linkname": normpath(self.linkname) if self.linkname else "",
+            "uname":    self.uname,
+            "gname":    self.gname,
+            "devmajor": self.devmajor,
+            "devminor": self.devminor
+        }
+
+        if info["type"] == DIRTYPE and not info["name"].endswith("/"):
+            info["name"] += "/"
+
+        return info
+
+    def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING):
+        """Return a tar header as a string of 512 byte blocks.
+        """
+        if format == USTAR_FORMAT:
+            return self.create_ustar_header()
+        elif format == GNU_FORMAT:
+            return self.create_gnu_header()
+        elif format == PAX_FORMAT:
+            return self.create_pax_header(encoding)
+        else:
+            raise ValueError("invalid format")
+
+    def create_ustar_header(self):
+        """Return the object as a ustar header block.
+        """
+        info = self.get_info()
+        info["magic"] = POSIX_MAGIC
+
+        if len(info["linkname"]) > LENGTH_LINK:
+            raise ValueError("linkname is too long")
+
+        if len(info["name"]) > LENGTH_NAME:
+            info["prefix"], info["name"] = self._posix_split_name(info["name"])
+
+        return self._create_header(info, USTAR_FORMAT)
+
+    def create_gnu_header(self):
+        """Return the object as a GNU header block sequence.
+        """
+        info = self.get_info()
+        info["magic"] = GNU_MAGIC
+
+        buf = ""
+        if len(info["linkname"]) > LENGTH_LINK:
+            buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK)
+
+        if len(info["name"]) > LENGTH_NAME:
+            buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME)
+
+        return buf + self._create_header(info, GNU_FORMAT)
+
+    def create_pax_header(self, encoding):
+        """Return the object as a ustar header block. If it cannot be
+           represented this way, prepend a pax extended header sequence
+           with supplement information.
+        """
+        info = self.get_info()
+        info["magic"] = POSIX_MAGIC
+        pax_headers = self.pax_headers.copy()
+
+        # Test string fields for values that exceed the field length or cannot
+        # be represented in ASCII encoding.
+        for name, hname, length in (
+                ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK),
+                ("uname", "uname", 32), ("gname", "gname", 32)):
+
+            val = info[name].decode(encoding)
+
+            # Try to encode the string as ASCII.
+            try:
+                val.encode("ascii")
+            except UnicodeEncodeError:
+                pax_headers[hname] = val
+                continue
+
+            if len(val) > length:
+                if name == "name":
+                    # Try to squeeze a longname in the prefix and name fields as in
+                    # ustar format.
+                    try:
+                        info["prefix"], info["name"] = self._posix_split_name(info["name"])
+                    except ValueError:
+                        pax_headers[hname] = val
+                    else:
+                        continue
+                else:
+                    pax_headers[hname] = val
+
+        # Test number fields for values that exceed the field limit or values
+        # that like to be stored as float.
+        for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
+            val = info[name]
+            if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
+                pax_headers[name] = unicode(val)
+                info[name] = 0
+
+        if pax_headers:
+            buf = self._create_pax_generic_header(pax_headers)
+        else:
+            buf = ""
+
+        return buf + self._create_header(info, USTAR_FORMAT)
+
+    @classmethod
+    def create_pax_global_header(cls, pax_headers, encoding):
+        """Return the object as a pax global header block sequence.
+        """
+        new_headers = {}
+        for key, val in pax_headers.items():
+            key = cls._to_unicode(key, encoding)
+            val = cls._to_unicode(val, encoding)
+            new_headers[key] = val
+        return cls._create_pax_generic_header(new_headers, type=XGLTYPE)
+
+    @staticmethod
+    def _to_unicode(value, encoding):
+        if isinstance(value, unicode):
+            return value
+        elif isinstance(value, (int, float)):
+            return unicode(value)
+        elif isinstance(value, str):
+            return unicode(value, encoding)
+        else:
+            raise ValueError("unable to convert to unicode: %r" % value)
+
+    def _posix_split_name(self, name):
+        """Split a name longer than 100 chars into a prefix
+           and a name part.
+        """
+        prefix = name[:LENGTH_PREFIX + 1]
+        while prefix and prefix[-1] != "/":
+            prefix = prefix[:-1]
+
+        name = name[len(prefix):]
+        prefix = prefix[:-1]
+
+        if not prefix or len(name) > LENGTH_NAME:
+            raise ValueError("name is too long")
+        return prefix, name
+
+    @staticmethod
+    def _create_header(info, format):
+        """Return a header block. info is a dictionary with file
+           information, format must be one of the *_FORMAT constants.
+        """
+        parts = [
+            stn(info.get("name", ""), 100),
+            itn(info.get("mode", 0) & 07777, 8, format),
+            itn(info.get("uid", 0), 8, format),
+            itn(info.get("gid", 0), 8, format),
+            itn(info.get("size", 0), 12, format),
+            itn(info.get("mtime", 0), 12, format),
+            "        ", # checksum field
+            info.get("type", REGTYPE),
+            stn(info.get("linkname", ""), 100),
+            stn(info.get("magic", ""), 8),
+            stn(info.get("uname", ""), 32),
+            stn(info.get("gname", ""), 32),
+            itn(info.get("devmajor", 0), 8, format),
+            itn(info.get("devminor", 0), 8, format),
+            stn(info.get("prefix", ""), 155)
+        ]
+
+        buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
+        chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
+        buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
+        return buf
+
+    @staticmethod
+    def _create_payload(payload):
+        """Return the string payload filled with zero bytes
+           up to the next 512 byte border.
+        """
+        blocks, remainder = divmod(len(payload), BLOCKSIZE)
+        if remainder > 0:
+            payload += (BLOCKSIZE - remainder) * NUL
+        return payload
+
+    @classmethod
+    def _create_gnu_long_header(cls, name, type):
+        """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence
+           for name.
+        """
+        name += NUL
+
+        info = {}
+        info["name"] = "././@LongLink"
+        info["type"] = type
+        info["size"] = len(name)
+        info["magic"] = GNU_MAGIC
+
+        # create extended header + name blocks.
+        return cls._create_header(info, USTAR_FORMAT) + \
+                cls._create_payload(name)
+
+    @classmethod
+    def _create_pax_generic_header(cls, pax_headers, type=XHDTYPE):
+        """Return a POSIX.1-2001 extended or global header sequence
+           that contains a list of keyword, value pairs. The values
+           must be unicode objects.
+        """
+        records = []
+        for keyword, value in pax_headers.items():
+            keyword = keyword.encode("utf8")
+            value = value.encode("utf8")
+            l = len(keyword) + len(value) + 3   # ' ' + '=' + '\n'
+            n = p = 0
+            while True:
+                n = l + len(str(p))
+                if n == p:
+                    break
+                p = n
+            records.append("%d %s=%s\n" % (p, keyword, value))
+        records = "".join(records)
+
+        # We use a hardcoded "././@PaxHeader" name like star does
+        # instead of the one that POSIX recommends.
+        info = {}
+        info["name"] = "././@PaxHeader"
+        info["type"] = type
+        info["size"] = len(records)
+        info["magic"] = POSIX_MAGIC
+
+        # Create pax header + record blocks.
+        return cls._create_header(info, USTAR_FORMAT) + \
+                cls._create_payload(records)
+
     @classmethod
     def frombuf(cls, buf):
         """Construct a TarInfo object from a 512 byte string buffer.
@@ -882,125 +1178,251 @@
         if chksum not in calc_chksums(buf):
             raise HeaderError("bad checksum")
 
-        tarinfo = cls()
-        tarinfo.buf = buf
-        tarinfo.name = buf[0:100].rstrip(NUL)
-        tarinfo.mode = nti(buf[100:108])
-        tarinfo.uid = nti(buf[108:116])
-        tarinfo.gid = nti(buf[116:124])
-        tarinfo.size = nti(buf[124:136])
-        tarinfo.mtime = nti(buf[136:148])
-        tarinfo.chksum = chksum
-        tarinfo.type = buf[156:157]
-        tarinfo.linkname = buf[157:257].rstrip(NUL)
-        tarinfo.uname = buf[265:297].rstrip(NUL)
-        tarinfo.gname = buf[297:329].rstrip(NUL)
-        tarinfo.devmajor = nti(buf[329:337])
-        tarinfo.devminor = nti(buf[337:345])
-        prefix = buf[345:500].rstrip(NUL)
+        obj = cls()
+        obj.buf = buf
+        obj.name = nts(buf[0:100])
+        obj.mode = nti(buf[100:108])
+        obj.uid = nti(buf[108:116])
+        obj.gid = nti(buf[116:124])
+        obj.size = nti(buf[124:136])
+        obj.mtime = nti(buf[136:148])
+        obj.chksum = chksum
+        obj.type = buf[156:157]
+        obj.linkname = nts(buf[157:257])
+        obj.uname = nts(buf[265:297])
+        obj.gname = nts(buf[297:329])
+        obj.devmajor = nti(buf[329:337])
+        obj.devminor = nti(buf[337:345])
+        prefix = nts(buf[345:500])
 
-        if prefix and not tarinfo.issparse():
-            tarinfo.name = prefix + "/" + tarinfo.name
+        # Old V7 tar format represents a directory as a regular
+        # file with a trailing slash.
+        if obj.type == AREGTYPE and obj.name.endswith("/"):
+            obj.type = DIRTYPE
 
-        return tarinfo
+        # Remove redundant slashes from directories.
+        if obj.isdir():
+            obj.name = obj.name.rstrip("/")
+
+        # Reconstruct a ustar longname.
+        if prefix and obj.type not in GNU_TYPES:
+            obj.name = prefix + "/" + obj.name
+        return obj
 
-    def tobuf(self, posix=False):
-        """Return a tar header as a string of 512 byte blocks.
+    @classmethod
+    def fromtarfile(cls, tarfile):
+        """Return the next TarInfo object from TarFile object
+           tarfile.
         """
-        buf = ""
-        type = self.type
-        prefix = ""
+        buf = tarfile.fileobj.read(BLOCKSIZE)
+        if not buf:
+            return
+        obj = cls.frombuf(buf)
+        obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
+        return obj._proc_member(tarfile)
 
-        if self.name.endswith("/"):
-            type = DIRTYPE
+    #--------------------------------------------------------------------------
+    # The following are methods that are called depending on the type of a
+    # member. The entry point is _proc_member() which can be overridden in a
+    # subclass to add custom _proc_*() methods. A _proc_*() method MUST
+    # implement the following
+    # operations:
+    # 1. Set self.offset_data to the position where the data blocks begin,
+    #    if there is data that follows.
+    # 2. Set tarfile.offset to the position where the next member's header will
+    #    begin.
+    # 3. Return self or another valid TarInfo object.
+    def _proc_member(self, tarfile):
+        """Choose the right processing method depending on
+           the type and call it.
+        """
+        if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
+            return self._proc_gnulong(tarfile)
+        elif self.type == GNUTYPE_SPARSE:
+            return self._proc_sparse(tarfile)
+        elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE):
+            return self._proc_pax(tarfile)
+        else:
+            return self._proc_builtin(tarfile)
+
+    def _proc_builtin(self, tarfile):
+        """Process a builtin type or an unknown type which
+           will be treated as a regular file.
+        """
+        self.offset_data = tarfile.fileobj.tell()
+        offset = self.offset_data
+        if self.isreg() or self.type not in SUPPORTED_TYPES:
+            # Skip the following data blocks.
+            offset += self._block(self.size)
+        tarfile.offset = offset
 
-        if type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
-            # Prevent "././@LongLink" from being normalized.
-            name = self.name
-        else:
-            name = normpath(self.name)
+        # Patch the TarInfo object with saved extended
+        # header information.
+        for keyword, value in tarfile.pax_headers.items():
+            if keyword in PAX_FIELDS:
+                setattr(self, keyword, value)
+            self.pax_headers[keyword] = value
 
-        if type == DIRTYPE:
-            # directories should end with '/'
-            name += "/"
+        return self
 
-        linkname = self.linkname
-        if linkname:
-            # if linkname is empty we end up with a '.'
-            linkname = normpath(linkname)
+    def _proc_gnulong(self, tarfile):
+        """Process the blocks that hold a GNU longname
+           or longlink member.
+        """
+        buf = tarfile.fileobj.read(self._block(self.size))
 
-        if posix:
-            if self.size > MAXSIZE_MEMBER:
-                raise ValueError("file is too large (>= 8 GB)")
+        # Fetch the next header and process it.
+        b = tarfile.fileobj.read(BLOCKSIZE)
+        t = self.frombuf(b)
+        t.offset = self.offset
+        next = t._proc_member(tarfile)
 
-            if len(self.linkname) > LENGTH_LINK:
-                raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
+        # Patch the TarInfo object from the next header with
+        # the longname information.
+        next.offset = self.offset
+        if self.type == GNUTYPE_LONGNAME:
+            next.name = buf.rstrip(NUL)
+        elif self.type == GNUTYPE_LONGLINK:
+            next.linkname = buf.rstrip(NUL)
 
-            if len(name) > LENGTH_NAME:
-                prefix = name[:LENGTH_PREFIX + 1]
-                while prefix and prefix[-1] != "/":
-                    prefix = prefix[:-1]
+        return next
 
-                name = name[len(prefix):]
-                prefix = prefix[:-1]
+    def _proc_sparse(self, tarfile):
+        """Process a GNU sparse header plus extra headers.
+        """
+        buf = self.buf
+        sp = _ringbuffer()
+        pos = 386
+        lastpos = 0
+        realpos = 0
+        # There are 4 possible sparse structs in the
+        # first header.
+        for i in xrange(4):
+            try:
+                offset = nti(buf[pos:pos + 12])
+                numbytes = nti(buf[pos + 12:pos + 24])
+            except ValueError:
+                break
+            if offset > lastpos:
+                sp.append(_hole(lastpos, offset - lastpos))
+            sp.append(_data(offset, numbytes, realpos))
+            realpos += numbytes
+            lastpos = offset + numbytes
+            pos += 24
 
-                if not prefix or len(name) > LENGTH_NAME:
-                    raise ValueError("name is too long")
+        isextended = ord(buf[482])
+        origsize = nti(buf[483:495])
 
-        else:
-            if len(self.linkname) > LENGTH_LINK:
-                buf += self._create_gnulong(self.linkname, GNUTYPE_LONGLINK)
+        # If the isextended flag is given,
+        # there are extra headers to process.
+        while isextended == 1:
+            buf = tarfile.fileobj.read(BLOCKSIZE)
+            pos = 0
+            for i in xrange(21):
+                try:
+                    offset = nti(buf[pos:pos + 12])
+                    numbytes = nti(buf[pos + 12:pos + 24])
+                except ValueError:
+                    break
+                if offset > lastpos:
+                    sp.append(_hole(lastpos, offset - lastpos))
+                sp.append(_data(offset, numbytes, realpos))
+                realpos += numbytes
+                lastpos = offset + numbytes
+                pos += 24
+            isextended = ord(buf[504])
 
-            if len(name) > LENGTH_NAME:
-                buf += self._create_gnulong(name, GNUTYPE_LONGNAME)
+        if lastpos < origsize:
+            sp.append(_hole(lastpos, origsize - lastpos))
 
-        parts = [
-            stn(name, 100),
-            itn(self.mode & 07777, 8, posix),
-            itn(self.uid, 8, posix),
-            itn(self.gid, 8, posix),
-            itn(self.size, 12, posix),
-            itn(self.mtime, 12, posix),
-            "        ", # checksum field
-            type,
-            stn(self.linkname, 100),
-            stn(MAGIC, 6),
-            stn(VERSION, 2),
-            stn(self.uname, 32),
-            stn(self.gname, 32),
-            itn(self.devmajor, 8, posix),
-            itn(self.devminor, 8, posix),
-            stn(prefix, 155)
-        ]
+        self.sparse = sp
 
-        buf += struct.pack("%ds" % BLOCKSIZE, "".join(parts))
-        chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
-        buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
-        self.buf = buf
-        return buf
+        self.offset_data = tarfile.fileobj.tell()
+        tarfile.offset = self.offset_data + self._block(self.size)
+        self.size = origsize
 
-    def _create_gnulong(self, name, type):
-        """Create a GNU longname/longlink header from name.
-           It consists of an extended tar header, with the length
-           of the longname as size, followed by data blocks,
-           which contain the longname as a null terminated string.
-        """
-        name += NUL
+        return self
 
-        tarinfo = self.__class__()
-        tarinfo.name = "././@LongLink"
-        tarinfo.type = type
-        tarinfo.mode = 0
-        tarinfo.size = len(name)
+    def _proc_pax(self, tarfile):
+        """Process an extended or global header as described in
+           POSIX.1-2001.
+        """
+        # Read the header information.
+        buf = tarfile.fileobj.read(self._block(self.size))
+
+        # A pax header stores supplemental information for either
+        # the following file (extended) or all following files
+        # (global).
+        if self.type == XGLTYPE:
+            pax_headers = tarfile.pax_headers
+        else:
+            pax_headers = tarfile.pax_headers.copy()
+
+        # Fields in POSIX.1-2001 that are numbers, all other fields
+        # are treated as UTF-8 strings.
+        type_mapping = {
+            "atime":        float,
+            "ctime":        float,
+            "mtime":        float,
+            "uid":          int,
+            "gid":          int,
+            "size":         int
+        }
+
+        # Parse pax header information. A record looks like that:
+        # "%d %s=%s\n" % (length, keyword, value). length is the size
+        # of the complete record including the length field itself and
+        # the newline.
+        regex = re.compile(r"(\d+) ([^=]+)=", re.U)
+        pos = 0
+        while True:
+            match = regex.match(buf, pos)
+            if not match:
+                break
 
-        # create extended header
-        buf = tarinfo.tobuf()
-        # create name blocks
-        buf += name
-        blocks, remainder = divmod(len(name), BLOCKSIZE)
-        if remainder > 0:
-            buf += (BLOCKSIZE - remainder) * NUL
-        return buf
+            length, keyword = match.groups()
+            length = int(length)
+            value = buf[match.end(2) + 1:match.start(1) + length - 1]
+
+            keyword = keyword.decode("utf8")
+            keyword = keyword.encode(tarfile.encoding)
+
+            value = value.decode("utf8")
+            if keyword in type_mapping:
+                try:
+                    value = type_mapping[keyword](value)
+                except ValueError:
+                    value = 0
+            else:
+                value = value.encode(tarfile.encoding)
+
+            pax_headers[keyword] = value
+            pos += length
+
+        # Fetch the next header that will be patched with the
+        # supplement information from the pax header (extended
+        # only).
+        t = self.fromtarfile(tarfile)
+
+        if self.type != XGLTYPE and t is not None:
+            # Patch the TarInfo object from the next header with
+            # the pax header's information.
+            for keyword, value in pax_headers.items():
+                if keyword in PAX_FIELDS:
+                    setattr(t, keyword, value)
+                pax_headers[keyword] = value
+            t.pax_headers = pax_headers.copy()
+
+        return t
+
+    def _block(self, count):
+        """Round up a byte count by BLOCKSIZE and return it,
+           e.g. _block(834) => 1024.
+        """
+        blocks, remainder = divmod(count, BLOCKSIZE)
+        if remainder:
+            blocks += 1
+        return blocks * BLOCKSIZE
 
     def isreg(self):
         return self.type in REGULAR_TYPES
@@ -1040,12 +1462,18 @@
                                 # messages (if debug >= 0). If > 0, errors
                                 # are passed to the caller as exceptions.
 
-    posix = False               # If True, generates POSIX.1-1990-compliant
-                                # archives (no GNU extensions!)
+    format = DEFAULT_FORMAT     # The format to use when creating an archive.
 
-    fileobject = ExFileObject
+    encoding = ENCODING         # Transfer UTF-8 strings from POSIX.1-2001
+                                # headers to this encoding.
 
-    def __init__(self, name=None, mode="r", fileobj=None):
+    tarinfo = TarInfo           # The default TarInfo class to use.
+
+    fileobject = ExFileObject   # The default ExFileObject class to use.
+
+    def __init__(self, name=None, mode="r", fileobj=None, format=None,
+            tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
+            pax_headers=None, debug=None, errorlevel=None):
         """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
            read from an existing archive, 'a' to append data to an existing
            file or 'w' to create a new file overwriting an existing one. `mode'
@@ -1054,58 +1482,86 @@
            can be determined, `mode' is overridden by `fileobj's mode.
            `fileobj' is not closed, when TarFile is closed.
         """
-        self.name = os.path.abspath(name)
-
         if len(mode) > 1 or mode not in "raw":
             raise ValueError("mode must be 'r', 'a' or 'w'")
-        self._mode = mode
-        self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
+        self.mode = mode
+        self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
 
         if not fileobj:
-            if self._mode == "a" and not os.path.exists(self.name):
+            if self.mode == "a" and not os.path.exists(name):
                 # Create nonexistent files in append mode.
-                self._mode = "w"
-                self.mode = "wb"
-            fileobj = _open(self.name, self.mode)
+                self.mode = "w"
+                self._mode = "wb"
+            fileobj = _open(name, self._mode)
             self._extfileobj = False
         else:
-            if self.name is None and hasattr(fileobj, "name"):
-                self.name = os.path.abspath(fileobj.name)
+            if name is None and hasattr(fileobj, "name"):
+                name = fileobj.name
             if hasattr(fileobj, "mode"):
-                self.mode = fileobj.mode
+                self._mode = fileobj.mode
             self._extfileobj = True
+        self.name = os.path.abspath(name)
         self.fileobj = fileobj
 
-        # Init datastructures
+        # Init attributes.
+        if format is not None:
+            self.format = format
+        if tarinfo is not None:
+            self.tarinfo = tarinfo
+        if dereference is not None:
+            self.dereference = dereference
+        if ignore_zeros is not None:
+            self.ignore_zeros = ignore_zeros
+        if encoding is not None:
+            self.encoding = encoding
+        if debug is not None:
+            self.debug = debug
+        if errorlevel is not None:
+            self.errorlevel = errorlevel
+
+        # Init datastructures.
         self.closed = False
         self.members = []       # list of members as TarInfo objects
         self._loaded = False    # flag if all members have been read
         self.offset = 0        # current position in the archive file
         self.inodes = {}        # dictionary caching the inodes of
                                 # archive members already added
+        self.pax_headers = {}   # save contents of global pax headers
 
-        if self._mode == "r":
+        if self.mode == "r":
             self.firstmember = None
             self.firstmember = self.next()
 
-        if self._mode == "a":
+        if self.mode == "a":
             # Move to the end of the archive,
             # before the first empty block.
             self.firstmember = None
             while True:
-                try:
-                    tarinfo = self.next()
-                except ReadError:
-                    self.fileobj.seek(0)
-                    break
-                if tarinfo is None:
+                if self.next() is None:
                     if self.offset > 0:
                         self.fileobj.seek(- BLOCKSIZE, 1)
                     break
 
-        if self._mode in "aw":
+        if self.mode in "aw":
             self._loaded = True
 
+            if pax_headers:
+                buf = self.tarinfo.create_pax_global_header(
+                        pax_headers.copy(), self.encoding)
+                self.fileobj.write(buf)
+                self.offset += len(buf)
+
+    def _getposix(self):
+        return self.format == USTAR_FORMAT
+    def _setposix(self, value):
+        import warnings
+        warnings.warn("use the format attribute instead", DeprecationWarning)
+        if value:
+            self.format = USTAR_FORMAT
+        else:
+            self.format = GNU_FORMAT
+    posix = property(_getposix, _setposix)
+
     #--------------------------------------------------------------------------
     # Below are the classmethods which act as alternate constructors to the
     # TarFile class. The open() method is the only one that is needed for
@@ -1118,7 +1574,7 @@
     # by adding it to the mapping in OPEN_METH.
 
     @classmethod
-    def open(cls, name=None, mode="r", fileobj=None, bufsize=20*512):
+    def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
         """Open a tar archive for reading, writing or appending. Return
            an appropriate TarFile class.
 
@@ -1151,8 +1607,8 @@
                 if fileobj is not None:
                     saved_pos = fileobj.tell()
                 try:
-                    return func(name, "r", fileobj)
-                except (ReadError, CompressionError):
+                    return func(name, "r", fileobj, **kwargs)
+                except (ReadError, CompressionError) as e:
                     if fileobj is not None:
                         fileobj.seek(saved_pos)
                     continue
@@ -1169,7 +1625,7 @@
                 func = getattr(cls, cls.OPEN_METH[comptype])
             else:
                 raise CompressionError("unknown compression type %r" % comptype)
-            return func(name, filemode, fileobj)
+            return func(name, filemode, fileobj, **kwargs)
 
         elif "|" in mode:
             filemode, comptype = mode.split("|", 1)
@@ -1180,25 +1636,26 @@
                 raise ValueError("mode must be 'r' or 'w'")
 
             t = cls(name, filemode,
-                    _Stream(name, filemode, comptype, fileobj, bufsize))
+                    _Stream(name, filemode, comptype, fileobj, bufsize),
+                    **kwargs)
             t._extfileobj = False
             return t
 
         elif mode in "aw":
-            return cls.taropen(name, mode, fileobj)
+            return cls.taropen(name, mode, fileobj, **kwargs)
 
         raise ValueError("undiscernible mode")
 
     @classmethod
-    def taropen(cls, name, mode="r", fileobj=None):
+    def taropen(cls, name, mode="r", fileobj=None, **kwargs):
         """Open uncompressed tar archive name for reading or writing.
         """
         if len(mode) > 1 or mode not in "raw":
             raise ValueError("mode must be 'r', 'a' or 'w'")
-        return cls(name, mode, fileobj)
+        return cls(name, mode, fileobj, **kwargs)
 
     @classmethod
-    def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9):
+    def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
         """Open gzip compressed tar archive name for reading or writing.
            Appending is not allowed.
         """
@@ -1216,14 +1673,15 @@
 
         try:
             t = cls.taropen(name, mode,
-                gzip.GzipFile(name, mode, compresslevel, fileobj))
+                gzip.GzipFile(name, mode, compresslevel, fileobj),
+                **kwargs)
         except IOError:
             raise ReadError("not a gzip file")
         t._extfileobj = False
         return t
 
     @classmethod
-    def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9):
+    def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
         """Open bzip2 compressed tar archive name for reading or writing.
            Appending is not allowed.
         """
@@ -1241,7 +1699,7 @@
             fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
 
         try:
-            t = cls.taropen(name, mode, fileobj)
+            t = cls.taropen(name, mode, fileobj, **kwargs)
         except IOError:
             raise ReadError("not a bzip2 file")
         t._extfileobj = False
@@ -1264,7 +1722,7 @@
         if self.closed:
             return
 
-        if self._mode in "aw":
+        if self.mode in "aw":
             self.fileobj.write(NUL * (BLOCKSIZE * 2))
             self.offset += (BLOCKSIZE * 2)
             # fill up the end with zero-blocks
@@ -1330,7 +1788,8 @@
 
         # Now, fill the TarInfo object with
         # information specific for the file.
-        tarinfo = TarInfo()
+        tarinfo = self.tarinfo()
+        tarinfo.tarfile = self
 
         # Use os.stat or os.lstat, depending on platform
         # and if symlinks shall be resolved.
@@ -1346,8 +1805,8 @@
         stmd = statres.st_mode
         if stat.S_ISREG(stmd):
             inode = (statres.st_ino, statres.st_dev)
-            if not self.dereference and \
-                    statres.st_nlink > 1 and inode in self.inodes:
+            if not self.dereference and statres.st_nlink > 1 and \
+                    inode in self.inodes and arcname != self.inodes[inode]:
                 # Is it a hardlink to an already
                 # archived file?
                 type = LNKTYPE
@@ -1424,7 +1883,7 @@
                 print("%d-%02d-%02d %02d:%02d:%02d" \
                       % time.localtime(tarinfo.mtime)[:6], end=' ')
 
-            print(tarinfo.name, end=' ')
+            print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ')
 
             if verbose:
                 if tarinfo.issym():
@@ -1456,7 +1915,7 @@
             if recursive:
                 if arcname == ".":
                     arcname = ""
-                for f in os.listdir("."):
+                for f in os.listdir(name):
                     self.add(f, os.path.join(arcname, f))
             return
 
@@ -1495,7 +1954,7 @@
 
         tarinfo = copy.copy(tarinfo)
 
-        buf = tarinfo.tobuf(self.posix)
+        buf = tarinfo.tobuf(self.format, self.encoding)
         self.fileobj.write(buf)
         self.offset += len(buf)
 
@@ -1527,7 +1986,7 @@
                 # Extract directory with a safe mode, so that
                 # all files below can be extracted as well.
                 try:
-                    os.makedirs(os.path.join(path, tarinfo.name), 0777)
+                    os.makedirs(os.path.join(path, tarinfo.name), 0700)
                 except EnvironmentError:
                     pass
                 directories.append(tarinfo)
@@ -1559,10 +2018,10 @@
         """
         self._check("r")
 
-        if isinstance(member, TarInfo):
-            tarinfo = member
-        else:
+        if isinstance(member, basestring):
             tarinfo = self.getmember(member)
+        else:
+            tarinfo = member
 
         # Prepare the link target for makelink().
         if tarinfo.islnk():
@@ -1595,10 +2054,10 @@
         """
         self._check("r")
 
-        if isinstance(member, TarInfo):
-            tarinfo = member
-        else:
+        if isinstance(member, basestring):
             tarinfo = self.getmember(member)
+        else:
+            tarinfo = member
 
         if tarinfo.isreg():
             return self.fileobject(self, tarinfo)
@@ -1811,20 +2270,11 @@
         # Read the next block.
         self.fileobj.seek(self.offset)
         while True:
-            buf = self.fileobj.read(BLOCKSIZE)
-            if not buf:
-                return None
-
             try:
-                tarinfo = TarInfo.frombuf(buf)
-
-                # Set the TarInfo object's offset to the current position of the
-                # TarFile and set self.offset to the position where the data blocks
-                # should begin.
-                tarinfo.offset = self.offset
-                self.offset += BLOCKSIZE
-
-                tarinfo = self.proc_member(tarinfo)
+                tarinfo = self.tarinfo.fromtarfile(self)
+                if tarinfo is None:
+                    return
+                self.members.append(tarinfo)
 
             except HeaderError as e:
                 if self.ignore_zeros:
@@ -1837,149 +2287,11 @@
                     return None
             break
 
-        # Some old tar programs represent a directory as a regular
-        # file with a trailing slash.
-        if tarinfo.isreg() and tarinfo.name.endswith("/"):
-            tarinfo.type = DIRTYPE
-
-        # Directory names should have a '/' at the end.
-        if tarinfo.isdir():
-            tarinfo.name += "/"
-
-        self.members.append(tarinfo)
-        return tarinfo
-
-    #--------------------------------------------------------------------------
-    # The following are methods that are called depending on the type of a
-    # member. The entry point is proc_member() which is called with a TarInfo
-    # object created from the header block from the current offset. The
-    # proc_member() method can be overridden in a subclass to add custom
-    # proc_*() methods. A proc_*() method MUST implement the following
-    # operations:
-    # 1. Set tarinfo.offset_data to the position where the data blocks begin,
-    #    if there is data that follows.
-    # 2. Set self.offset to the position where the next member's header will
-    #    begin.
-    # 3. Return tarinfo or another valid TarInfo object.
-    def proc_member(self, tarinfo):
-        """Choose the right processing method for tarinfo depending
-           on its type and call it.
-        """
-        if tarinfo.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
-            return self.proc_gnulong(tarinfo)
-        elif tarinfo.type == GNUTYPE_SPARSE:
-            return self.proc_sparse(tarinfo)
-        else:
-            return self.proc_builtin(tarinfo)
-
-    def proc_builtin(self, tarinfo):
-        """Process a builtin type member or an unknown member
-           which will be treated as a regular file.
-        """
-        tarinfo.offset_data = self.offset
-        if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
-            # Skip the following data blocks.
-            self.offset += self._block(tarinfo.size)
-        return tarinfo
-
-    def proc_gnulong(self, tarinfo):
-        """Process the blocks that hold a GNU longname
-           or longlink member.
-        """
-        buf = ""
-        count = tarinfo.size
-        while count > 0:
-            block = self.fileobj.read(BLOCKSIZE)
-            buf += block
-            self.offset += BLOCKSIZE
-            count -= BLOCKSIZE
-
-        # Fetch the next header and process it.
-        b = self.fileobj.read(BLOCKSIZE)
-        t = TarInfo.frombuf(b)
-        t.offset = self.offset
-        self.offset += BLOCKSIZE
-        next = self.proc_member(t)
-
-        # Patch the TarInfo object from the next header with
-        # the longname information.
-        next.offset = tarinfo.offset
-        if tarinfo.type == GNUTYPE_LONGNAME:
-            next.name = buf.rstrip(NUL)
-        elif tarinfo.type == GNUTYPE_LONGLINK:
-            next.linkname = buf.rstrip(NUL)
-
-        return next
-
-    def proc_sparse(self, tarinfo):
-        """Process a GNU sparse header plus extra headers.
-        """
-        buf = tarinfo.buf
-        sp = _ringbuffer()
-        pos = 386
-        lastpos = 0
-        realpos = 0
-        # There are 4 possible sparse structs in the
-        # first header.
-        for i in xrange(4):
-            try:
-                offset = nti(buf[pos:pos + 12])
-                numbytes = nti(buf[pos + 12:pos + 24])
-            except ValueError:
-                break
-            if offset > lastpos:
-                sp.append(_hole(lastpos, offset - lastpos))
-            sp.append(_data(offset, numbytes, realpos))
-            realpos += numbytes
-            lastpos = offset + numbytes
-            pos += 24
-
-        isextended = ord(buf[482])
-        origsize = nti(buf[483:495])
-
-        # If the isextended flag is given,
-        # there are extra headers to process.
-        while isextended == 1:
-            buf = self.fileobj.read(BLOCKSIZE)
-            self.offset += BLOCKSIZE
-            pos = 0
-            for i in xrange(21):
-                try:
-                    offset = nti(buf[pos:pos + 12])
-                    numbytes = nti(buf[pos + 12:pos + 24])
-                except ValueError:
-                    break
-                if offset > lastpos:
-                    sp.append(_hole(lastpos, offset - lastpos))
-                sp.append(_data(offset, numbytes, realpos))
-                realpos += numbytes
-                lastpos = offset + numbytes
-                pos += 24
-            isextended = ord(buf[504])
-
-        if lastpos < origsize:
-            sp.append(_hole(lastpos, origsize - lastpos))
-
-        tarinfo.sparse = sp
-
-        tarinfo.offset_data = self.offset
-        self.offset += self._block(tarinfo.size)
-        tarinfo.size = origsize
-
         return tarinfo
 
     #--------------------------------------------------------------------------
     # Little helper methods:
 
-    def _block(self, count):
-        """Round up a byte count by BLOCKSIZE and return it,
-           e.g. _block(834) => 1024.
-        """
-        blocks, remainder = divmod(count, BLOCKSIZE)
-        if remainder:
-            blocks += 1
-        return blocks * BLOCKSIZE
-
     def _getmember(self, name, tarinfo=None):
         """Find an archive member by name from bottom to top.
            If tarinfo is given, it is used as the starting point.
@@ -2012,8 +2324,8 @@
         """
         if self.closed:
             raise IOError("%s is closed" % self.__class__.__name__)
-        if mode is not None and self._mode not in mode:
-            raise IOError("bad operation for mode %r" % self._mode)
+        if mode is not None and self.mode not in mode:
+            raise IOError("bad operation for mode %r" % self.mode)
 
     def __iter__(self):
         """Provide an iterator object.

Modified: python/branches/p3yk/Lib/telnetlib.py
==============================================================================
--- python/branches/p3yk/Lib/telnetlib.py	(original)
+++ python/branches/p3yk/Lib/telnetlib.py	Fri Apr 27 21:54:29 2007
@@ -184,7 +184,7 @@
 
     """
 
-    def __init__(self, host=None, port=0):
+    def __init__(self, host=None, port=0, timeout=None):
         """Constructor.
 
         When called without arguments, create an unconnected instance.
@@ -195,6 +195,7 @@
         self.debuglevel = DEBUGLEVEL
         self.host = host
         self.port = port
+        self.timeout = timeout
         self.sock = None
         self.rawq = ''
         self.irawq = 0
@@ -205,9 +206,9 @@
         self.sbdataq = ''
         self.option_callback = None
         if host is not None:
-            self.open(host, port)
+            self.open(host, port, timeout)
 
-    def open(self, host, port=0):
+    def open(self, host, port=0, timeout=None):
         """Connect to a host.
 
         The optional second argument is the port number, which
@@ -221,20 +222,9 @@
             port = TELNET_PORT
         self.host = host
         self.port = port
-        msg = "getaddrinfo returns an empty list"
-        for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
-            try:
-                self.sock = socket.socket(af, socktype, proto)
-                self.sock.connect(sa)
-            except socket.error as msg:
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
+        if timeout is not None:
+            self.timeout = timeout
+        self.sock = socket.create_connection((host, port), self.timeout)
 
     def __del__(self):
         """Destructor -- close the connection."""
@@ -661,7 +651,7 @@
             port = socket.getservbyname(portstr, 'tcp')
     tn = Telnet()
     tn.set_debuglevel(debuglevel)
-    tn.open(host, port)
+    tn.open(host, port, timeout=0.5)
     tn.interact()
     tn.close()
 

Modified: python/branches/p3yk/Lib/tempfile.py
==============================================================================
--- python/branches/p3yk/Lib/tempfile.py	(original)
+++ python/branches/p3yk/Lib/tempfile.py	Fri Apr 27 21:54:29 2007
@@ -19,6 +19,7 @@
 
 __all__ = [
     "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
+    "SpooledTemporaryFile",
     "mkstemp", "mkdtemp",                  # low level safe interfaces
     "mktemp",                              # deprecated unsafe interface
     "TMP_MAX", "gettempprefix",            # constants
@@ -37,6 +38,11 @@
     import Carbon.Folders as _Folders
 
 try:
+    from cStringIO import StringIO as _StringIO
+except:
+    from StringIO import StringIO as _StringIO
+
+try:
     import fcntl as _fcntl
 except ImportError:
     def _set_cloexec(fd):
@@ -114,7 +120,7 @@
 
     characters = ("abcdefghijklmnopqrstuvwxyz" +
                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
-                  "0123456789-_")
+                  "0123456789_")
 
     def __init__(self):
         self.mutex = _allocate_lock()
@@ -372,10 +378,11 @@
     remove the file when it is no longer needed.
     """
 
-    def __init__(self, file, name):
+    def __init__(self, file, name, delete=True):
         self.file = file
         self.name = name
         self.close_called = False
+        self.delete = delete
 
     def __getattr__(self, name):
         file = self.__dict__['file']
@@ -400,23 +407,25 @@
             if not self.close_called:
                 self.close_called = True
                 self.file.close()
-                self.unlink(self.name)
+                if self.delete:
+                    self.unlink(self.name)
 
         def __del__(self):
             self.close()
 
 def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
-                       prefix=template, dir=None):
+                       prefix=template, dir=None, delete=True):
     """Create and return a temporary file.
     Arguments:
     'prefix', 'suffix', 'dir' -- as for mkstemp.
     'mode' -- the mode argument to os.fdopen (default "w+b").
     'bufsize' -- the buffer size argument to os.fdopen (default -1).
+    'delete' -- whether the file is deleted on close (default True).
     The file is created as mkstemp() would do it.
 
     Returns an object with a file-like interface; the name of the file
     is accessible as file.name.  The file will be automatically deleted
-    when it is closed.
+    when it is closed unless the 'delete' argument is set to False.
     """
 
     if dir is None:
@@ -429,12 +438,12 @@
 
     # Setting O_TEMPORARY in the flags causes the OS to delete
     # the file when it is closed.  This is only supported by Windows.
-    if _os.name == 'nt':
+    if _os.name == 'nt' and delete:
         flags |= _os.O_TEMPORARY
 
     (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
     file = _os.fdopen(fd, mode, bufsize)
-    return _TemporaryFileWrapper(file, name)
+    return _TemporaryFileWrapper(file, name, delete)
 
 if _os.name != 'posix' or _os.sys.platform == 'cygwin':
     # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
@@ -470,3 +479,111 @@
         except:
             _os.close(fd)
             raise
+
+class SpooledTemporaryFile:
+    """Temporary file wrapper, specialized to switch from
+    StringIO to a real file when it exceeds a certain size or
+    when a fileno is needed.
+    """
+    _rolled = False
+
+    def __init__(self, max_size=0, mode='w+b', bufsize=-1,
+                 suffix="", prefix=template, dir=None):
+        self._file = _StringIO()
+        self._max_size = max_size
+        self._rolled = False
+        self._TemporaryFileArgs = (mode, bufsize, suffix, prefix, dir)
+
+    def _check(self, file):
+        if self._rolled: return
+        max_size = self._max_size
+        if max_size and file.tell() > max_size:
+            self.rollover()
+
+    def rollover(self):
+        if self._rolled: return
+        file = self._file
+        newfile = self._file = TemporaryFile(*self._TemporaryFileArgs)
+        del self._TemporaryFileArgs
+
+        newfile.write(file.getvalue())
+        newfile.seek(file.tell(), 0)
+
+        self._rolled = True
+
+    # file protocol
+    def __iter__(self):
+        return self._file.__iter__()
+
+    def close(self):
+        self._file.close()
+
+    @property
+    def closed(self):
+        return self._file.closed
+
+    @property
+    def encoding(self):
+        return self._file.encoding
+
+    def fileno(self):
+        self.rollover()
+        return self._file.fileno()
+
+    def flush(self):
+        self._file.flush()
+
+    def isatty(self):
+        return self._file.isatty()
+
+    @property
+    def mode(self):
+        return self._file.mode
+
+    @property
+    def name(self):
+        return self._file.name
+
+    @property
+    def newlines(self):
+        return self._file.newlines
+
+    def next(self):
+        return self._file.next
+
+    def read(self, *args):
+        return self._file.read(*args)
+
+    def readline(self, *args):
+        return self._file.readline(*args)
+
+    def readlines(self, *args):
+        return self._file.readlines(*args)
+
+    def seek(self, *args):
+        self._file.seek(*args)
+
+    @property
+    def softspace(self):
+        return self._file.softspace
+
+    def tell(self):
+        return self._file.tell()
+
+    def truncate(self):
+        self._file.truncate()
+
+    def write(self, s):
+        file = self._file
+        rv = file.write(s)
+        self._check(file)
+        return rv
+
+    def writelines(self, iterable):
+        file = self._file
+        rv = file.writelines(iterable)
+        self._check(file)
+        return rv
+
+    def xreadlines(self, *args):
+        return self._file.xreadlines(*args)

Modified: python/branches/p3yk/Lib/test/README
==============================================================================
--- python/branches/p3yk/Lib/test/README	(original)
+++ python/branches/p3yk/Lib/test/README	Fri Apr 27 21:54:29 2007
@@ -15,7 +15,7 @@
 one of these options.  Each option requires writing a test module using the
 conventions of the selected option:
 
-    - PyUnit_ based tests
+    - unittest_ based tests
     - doctest_ based tests
     - "traditional" Python test modules
 
@@ -28,31 +28,34 @@
 able to refer to the C and Python code in the CVS repository when writing
 your regression test cases.
 
-.. _PyUnit:
 .. _unittest: http://www.python.org/doc/current/lib/module-unittest.html
 .. _doctest: http://www.python.org/doc/current/lib/module-doctest.html
 
-PyUnit based tests
+unittest-based tests
 ------------------
-The PyUnit_ framework is based on the ideas of unit testing as espoused
+The unittest_ framework is based on the ideas of unit testing as espoused
 by Kent Beck and the `Extreme Programming`_ (XP) movement.  The specific
 interface provided by the framework is tightly based on the JUnit_
 Java implementation of Beck's original SmallTalk test framework.  Please
 see the documentation of the unittest_ module for detailed information on
-the interface and general guidelines on writing PyUnit based tests.
+the interface and general guidelines on writing unittest-based tests.
 
-The test_support helper module provides two functions for use by
-PyUnit based tests in the Python regression testing framework:
-
-- ``run_unittest()`` takes a ``unittest.TestCase`` derived class as a
-  parameter and runs the tests defined in that class
-   
-- ``run_suite()`` takes a populated ``TestSuite`` instance and runs the
-  tests
+The test_support helper module provides a function for use by
+unittest-based tests in the Python regression testing framework,
+``run_unittest()``. This is the primary way of running tests in the
+standard library. You can pass it any number of the following:
+
+- classes derived from or instances of ``unittest.TestCase`` or
+  ``unittest.TestSuite``. These will be handed off to unittest for
+  converting into a proper TestSuite instance.
+
+- a string; this must be a key in sys.modules. The module associated with
+  that string will be scanned by ``unittest.TestLoader.loadTestsFromModule``.
+  This is usually seen as ``test_support.run_unittest(__name__)`` in a test
+  module's ``test_main()`` function. This has the advantage of picking up
+  new tests automatically, without you having to add each new test case
+  manually.
    
-``run_suite()`` is preferred because unittest files typically grow multiple
-test classes, and you might as well be prepared.
-
 All test methods in the Python regression framework have names that
 start with "``test_``" and use lower-case names with words separated with
 underscores.
@@ -63,7 +66,7 @@
 latter information makes it easier to find the source for the test
 than the docstring.
 
-All PyUnit-based tests in the Python test suite use boilerplate that
+All unittest-based tests in the Python test suite use boilerplate that
 looks like this (with minor variations)::
 
     import unittest
@@ -97,11 +100,7 @@
     ...etc...
 
     def test_main():
-        suite = unittest.TestSuite()
-        suite.addTest(unittest.makeSuite(MyTestCase1))
-        suite.addTest(unittest.makeSuite(MyTestCase2))
-        ...add more suites...
-        test_support.run_suite(suite)
+        test_support.run_unittest(__name__)
 
     if __name__ == "__main__":
         test_main()
@@ -415,7 +414,7 @@
       This is rarely required with the "traditional" Python tests, and
       you shouldn't create a module global with name test_main unless
       you're specifically exploiting this gimmick.  This usage does
-      prove useful with PyUnit-based tests as well, however; defining
+      prove useful with unittest-based tests as well, however; defining
       a ``test_main()`` which is run by regrtest and a script-stub in the
       test module ("``if __name__ == '__main__': test_main()``") allows
       the test to be used like any other Python test and also work

Modified: python/branches/p3yk/Lib/test/crashers/modify_dict_attr.py
==============================================================================
--- python/branches/p3yk/Lib/test/crashers/modify_dict_attr.py	(original)
+++ python/branches/p3yk/Lib/test/crashers/modify_dict_attr.py	Fri Apr 27 21:54:29 2007
@@ -4,15 +4,16 @@
 class Y(object):
     pass
 
-class type_with_modifiable_dict(Y, type):
+class type_with_modifiable_dict(type, Y):
     pass
 
 class MyClass(object, metaclass=type_with_modifiable_dict):
-    """This class has its __dict__ attribute completely exposed:
-    user code can read, reassign and even delete it.
+    """This class has its __dict__ attribute indirectly
+    exposed via the __dict__ getter/setter of Y.
     """
 
 
 if __name__ == '__main__':
-    del MyClass.__dict__  # if we set tp_dict to NULL,
+    dictattr = Y.__dict__['__dict__']
+    dictattr.__delete__(MyClass)  # if we set tp_dict to NULL,
     print(MyClass)         # doing anything with MyClass segfaults

Deleted: /python/branches/p3yk/Lib/test/output/test_operations
==============================================================================
--- /python/branches/p3yk/Lib/test/output/test_operations	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,19 +0,0 @@
-test_operations
-3. Operations
-XXX Mostly not yet implemented
-3.1 Dictionary lookups fail if __cmp__() raises an exception
-raising error
-d[x2] = 2: caught the RuntimeError outside
-raising error
-z = d[x2]: caught the RuntimeError outside
-raising error
-x2 in d: caught the RuntimeError outside
-raising error
-d.get(x2): caught the RuntimeError outside
-raising error
-d.setdefault(x2, 42): caught the RuntimeError outside
-raising error
-d.pop(x2): caught the RuntimeError outside
-raising error
-d.update({x2: 2}): caught the RuntimeError outside
-resize bugs not triggered.

Deleted: /python/branches/p3yk/Lib/test/output/test_popen2
==============================================================================
--- /python/branches/p3yk/Lib/test/output/test_popen2	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,9 +0,0 @@
-test_popen2
-Test popen2 module:
-testing popen2...
-testing popen3...
-All OK
-Testing os module:
-testing popen2...
-testing popen3...
-All OK

Deleted: /python/branches/p3yk/Lib/test/output/test_pty
==============================================================================
--- /python/branches/p3yk/Lib/test/output/test_pty	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,3 +0,0 @@
-test_pty
-I wish to buy a fish license.
-For my pet fish, Eric.

Deleted: /python/branches/p3yk/Lib/test/output/test_pyexpat
==============================================================================
--- /python/branches/p3yk/Lib/test/output/test_pyexpat	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,110 +0,0 @@
-test_pyexpat
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-PI:
-	'xml-stylesheet' 'href="stylesheet.css"'
-Comment:
-	' comment data '
-Notation declared: ('notation', None, 'notation.jpeg', None)
-Unparsed entity decl:
-	('unparsed_entity', None, 'entity.file', None, 'notation')
-Start element:
-	'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
-NS decl:
-	'myns' 'http://www.python.org/namespace'
-Start element:
-	'http://www.python.org/namespace!subelement' {}
-Character data:
-	'Contents of subelements'
-End element:
-	'http://www.python.org/namespace!subelement'
-End of NS decl:
-	'myns'
-Start element:
-	'sub2' {}
-Start of CDATA section
-Character data:
-	'contents of CDATA section'
-End of CDATA section
-End element:
-	'sub2'
-External entity ref: (None, 'entity.file', None)
-End element:
-	'root'
-PI:
-	u'xml-stylesheet' u'href="stylesheet.css"'
-Comment:
-	u' comment data '
-Notation declared: (u'notation', None, u'notation.jpeg', None)
-Unparsed entity decl:
-	(u'unparsed_entity', None, u'entity.file', None, u'notation')
-Start element:
-	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
-NS decl:
-	u'myns' u'http://www.python.org/namespace'
-Start element:
-	u'http://www.python.org/namespace!subelement' {}
-Character data:
-	u'Contents of subelements'
-End element:
-	u'http://www.python.org/namespace!subelement'
-End of NS decl:
-	u'myns'
-Start element:
-	u'sub2' {}
-Start of CDATA section
-Character data:
-	u'contents of CDATA section'
-End of CDATA section
-End element:
-	u'sub2'
-External entity ref: (None, u'entity.file', None)
-End element:
-	u'root'
-PI:
-	u'xml-stylesheet' u'href="stylesheet.css"'
-Comment:
-	u' comment data '
-Notation declared: (u'notation', None, u'notation.jpeg', None)
-Unparsed entity decl:
-	(u'unparsed_entity', None, u'entity.file', None, u'notation')
-Start element:
-	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
-NS decl:
-	u'myns' u'http://www.python.org/namespace'
-Start element:
-	u'http://www.python.org/namespace!subelement' {}
-Character data:
-	u'Contents of subelements'
-End element:
-	u'http://www.python.org/namespace!subelement'
-End of NS decl:
-	u'myns'
-Start element:
-	u'sub2' {}
-Start of CDATA section
-Character data:
-	u'contents of CDATA section'
-End of CDATA section
-End element:
-	u'sub2'
-External entity ref: (None, u'entity.file', None)
-End element:
-	u'root'
-
-Testing constructor for proper handling of namespace_separator values:
-Legal values tested o.k.
-Caught expected TypeError:
-ParserCreate() argument 2 must be string or None, not int
-Caught expected ValueError:
-namespace_separator must be at most one character, omitted, or None

Deleted: /python/branches/p3yk/Lib/test/output/test_threadedtempfile
==============================================================================
--- /python/branches/p3yk/Lib/test/output/test_threadedtempfile	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,5 +0,0 @@
-test_threadedtempfile
-Creating
-Starting
-Reaping
-Done: errors 0 ok 1000

Deleted: /python/branches/p3yk/Lib/test/output/xmltests
==============================================================================
--- /python/branches/p3yk/Lib/test/output/xmltests	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,364 +0,0 @@
-xmltests
-Passed testAAA
-Passed setAttribute() sets ownerDocument
-Passed setAttribute() sets ownerElement
-Test Succeeded testAAA
-Passed assertion: len(Node.allnodes) == 0
-Passed testAAB
-Test Succeeded testAAB
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Test Succeeded testAddAttr
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testAppendChild
-Passed assertion: len(Node.allnodes) == 0
-Passed appendChild(<fragment>)
-Test Succeeded testAppendChildFragment
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListItem
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListItemNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListItems
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListKeys
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListKeysNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListLength
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrListValues
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrList__getitem__
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testAttrList__setitem__
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testAttributeRepr
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Passed Test
-Test Succeeded testChangeAttr
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testChildNodes
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCloneAttributeDeep
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCloneAttributeShallow
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCloneDocumentDeep
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCloneDocumentShallow
-Passed assertion: len(Node.allnodes) == 0
-Passed clone of element has same attribute keys
-Passed clone of attribute node has proper attribute values
-Passed clone of attribute node correctly owned
-Passed testCloneElementDeep
-Test Succeeded testCloneElementDeep
-Passed assertion: len(Node.allnodes) == 0
-Passed clone of element has same attribute keys
-Passed clone of attribute node has proper attribute values
-Passed clone of attribute node correctly owned
-Passed testCloneElementShallow
-Test Succeeded testCloneElementShallow
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testClonePIDeep
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testClonePIShallow
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testComment
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCreateAttributeNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testCreateElementNS
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Passed Test
-Test Succeeded testDeleteAttr
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testDocumentElement
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Test Succeeded testElement
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Test Succeeded testElementReprAndStr
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testFirstChild
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttrLength
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttrList
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttrValues
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttribute
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttributeNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetAttributeNode
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Test Succeeded testGetElementsByTagName
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Test Succeeded testGetElementsByTagNameNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testGetEmptyNodeListFromElementsByTagNameNS
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testHasChildNodes
-Passed assertion: len(Node.allnodes) == 0
-Passed testInsertBefore -- node properly placed in tree
-Passed testInsertBefore -- node properly placed in tree
-Passed testInsertBefore -- node properly placed in tree
-Test Succeeded testInsertBefore
-Passed assertion: len(Node.allnodes) == 0
-Passed insertBefore(<fragment>, None)
-Passed insertBefore(<fragment>, orig)
-Test Succeeded testInsertBeforeFragment
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testLegalChildren
-Passed assertion: len(Node.allnodes) == 0
-Passed NamedNodeMap.__setitem__() sets ownerDocument
-Passed NamedNodeMap.__setitem__() sets ownerElement
-Passed NamedNodeMap.__setitem__() sets value
-Passed NamedNodeMap.__setitem__() sets nodeValue
-Test Succeeded testNamedNodeMapSetItem
-Passed assertion: len(Node.allnodes) == 0
-Passed test NodeList.item()
-Test Succeeded testNodeListItem
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testNonZero
-Passed assertion: len(Node.allnodes) == 0
-Passed testNormalize -- preparation
-Passed testNormalize -- result
-Passed testNormalize -- single empty node removed
-Test Succeeded testNormalize
-Passed assertion: len(Node.allnodes) == 0
-Passed testParents
-Test Succeeded testParents
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParse
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseAttributeNamespaces
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseAttributes
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseElement
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseElementNamespaces
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Test Succeeded testParseFromFile
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseProcessingInstructions
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testParseString
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testProcessingInstruction
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testProcessingInstructionRepr
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testRemoveAttr
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testRemoveAttrNS
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testRemoveAttributeNode
-Passed assertion: len(Node.allnodes) == 0
-Passed replaceChild(<fragment>)
-Test Succeeded testReplaceChildFragment
-Passed assertion: len(Node.allnodes) == 0
-Passed testSAX2DOM - siblings
-Passed testSAX2DOM - parents
-Test Succeeded testSAX2DOM
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testSetAttrValueandNodeValue
-Passed assertion: len(Node.allnodes) == 0
-Passed testSiblings
-Test Succeeded testSiblings
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testTextNodeRepr
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testTextRepr
-Passed assertion: len(Node.allnodes) == 0
-Caught expected exception when adding extra document element.
-Test Succeeded testTooManyDocumentElements
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testUnlink
-Passed assertion: len(Node.allnodes) == 0
-Test Succeeded testWriteText
-Passed assertion: len(Node.allnodes) == 0
-Passed Test
-Passed Test
-Test Succeeded testWriteXML
-Passed assertion: len(Node.allnodes) == 0
-All tests succeeded
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-OK.
-PI:
-	'xml-stylesheet' 'href="stylesheet.css"'
-Comment:
-	' comment data '
-Notation declared: ('notation', None, 'notation.jpeg', None)
-Unparsed entity decl:
-	('unparsed_entity', None, 'entity.file', None, 'notation')
-Start element:
-	'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
-NS decl:
-	'myns' 'http://www.python.org/namespace'
-Start element:
-	'http://www.python.org/namespace!subelement' {}
-Character data:
-	'Contents of subelements'
-End element:
-	'http://www.python.org/namespace!subelement'
-End of NS decl:
-	'myns'
-Start element:
-	'sub2' {}
-Start of CDATA section
-Character data:
-	'contents of CDATA section'
-End of CDATA section
-End element:
-	'sub2'
-External entity ref: (None, 'entity.file', None)
-End element:
-	'root'
-PI:
-	u'xml-stylesheet' u'href="stylesheet.css"'
-Comment:
-	u' comment data '
-Notation declared: (u'notation', None, u'notation.jpeg', None)
-Unparsed entity decl:
-	(u'unparsed_entity', None, u'entity.file', None, u'notation')
-Start element:
-	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
-NS decl:
-	u'myns' u'http://www.python.org/namespace'
-Start element:
-	u'http://www.python.org/namespace!subelement' {}
-Character data:
-	u'Contents of subelements'
-End element:
-	u'http://www.python.org/namespace!subelement'
-End of NS decl:
-	u'myns'
-Start element:
-	u'sub2' {}
-Start of CDATA section
-Character data:
-	u'contents of CDATA section'
-End of CDATA section
-End element:
-	u'sub2'
-External entity ref: (None, u'entity.file', None)
-End element:
-	u'root'
-PI:
-	u'xml-stylesheet' u'href="stylesheet.css"'
-Comment:
-	u' comment data '
-Notation declared: (u'notation', None, u'notation.jpeg', None)
-Unparsed entity decl:
-	(u'unparsed_entity', None, u'entity.file', None, u'notation')
-Start element:
-	u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
-NS decl:
-	u'myns' u'http://www.python.org/namespace'
-Start element:
-	u'http://www.python.org/namespace!subelement' {}
-Character data:
-	u'Contents of subelements'
-End element:
-	u'http://www.python.org/namespace!subelement'
-End of NS decl:
-	u'myns'
-Start element:
-	u'sub2' {}
-Start of CDATA section
-Character data:
-	u'contents of CDATA section'
-End of CDATA section
-End element:
-	u'sub2'
-External entity ref: (None, u'entity.file', None)
-End element:
-	u'root'
-
-Testing constructor for proper handling of namespace_separator values:
-Legal values tested o.k.
-Caught expected TypeError:
-ParserCreate() argument 2 must be string or None, not int
-Caught expected ValueError:
-namespace_separator must be at most one character, omitted, or None
-Passed test_attrs_empty
-Passed test_attrs_wattr
-Passed test_double_quoteattr
-Passed test_escape_all
-Passed test_escape_basic
-Passed test_escape_extra
-Passed test_expat_attrs_empty
-Passed test_expat_attrs_wattr
-Passed test_expat_dtdhandler
-Passed test_expat_entityresolver
-Passed test_expat_file
-Passed test_expat_incomplete
-Passed test_expat_incremental
-Passed test_expat_incremental_reset
-Passed test_expat_inpsource_filename
-Passed test_expat_inpsource_location
-Passed test_expat_inpsource_stream
-Passed test_expat_inpsource_sysid
-Passed test_expat_locator_noinfo
-Passed test_expat_locator_withinfo
-Passed test_expat_nsattrs_empty
-Passed test_expat_nsattrs_wattr
-Passed test_filter_basic
-Passed test_make_parser
-Passed test_make_parser2
-Passed test_nsattrs_empty
-Passed test_nsattrs_wattr
-Passed test_quoteattr_basic
-Passed test_single_double_quoteattr
-Passed test_single_quoteattr
-Passed test_xmlgen_attr_escape
-Passed test_xmlgen_basic
-Passed test_xmlgen_content
-Passed test_xmlgen_content_escape
-Passed test_xmlgen_ignorable
-Passed test_xmlgen_ns
-Passed test_xmlgen_pi
-37 tests, 0 failures

Modified: python/branches/p3yk/Lib/test/outstanding_bugs.py
==============================================================================
--- python/branches/p3yk/Lib/test/outstanding_bugs.py	(original)
+++ python/branches/p3yk/Lib/test/outstanding_bugs.py	Fri Apr 27 21:54:29 2007
@@ -10,13 +10,44 @@
 from test import test_support
 
 #
-# No test cases for outstanding bugs at the moment.
+# One test case for outstanding bugs at the moment:
 #
 
+class TestDifflibLongestMatch(unittest.TestCase):
+    # From Patch #1678339:
+    # The find_longest_match method in the difflib's SequenceMatcher has a bug.
+
+    # The bug is in turn caused by a problem with creating a b2j mapping which
+    # should contain a list of indices for each of the list elements in b.
+    # However, when the b2j mapping is being created (this is being done in
+    # __chain_b method in the SequenceMatcher) the mapping becomes broken. The
+    # cause of this is that for the frequently used elements the list of indices
+    # is removed and the element is being enlisted in the populardict mapping.
+
+    # The test case tries to match two strings like:
+    # abbbbbb.... and ...bbbbbbc
+
+    # The number of b is equal and the find_longest_match should have returned
+    # the proper amount. However, in case the number of "b"s is large enough, the
+    # method reports that the length of the longest common substring is 0. It
+    # simply can't find it.
+
+    # A bug was raised some time ago on this matter. It's ID is 1528074.
+
+    def test_find_longest_match(self):
+        import difflib
+        for i in (190, 200, 210):
+            text1 = "a" + "b"*i
+            text2 = "b"*i + "c"
+            m = difflib.SequenceMatcher(None, text1, text2)
+            (aptr, bptr, l) = m.find_longest_match(0, len(text1), 0, len(text2))
+            self.assertEquals(i, l)
+            self.assertEquals(aptr, 1)
+            self.assertEquals(bptr, 0)
+
 
 def test_main():
-    #test_support.run_unittest()
-    pass
+    test_support.run_unittest(TestDifflibLongestMatch)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/pickletester.py
==============================================================================
--- python/branches/p3yk/Lib/test/pickletester.py	(original)
+++ python/branches/p3yk/Lib/test/pickletester.py	Fri Apr 27 21:54:29 2007
@@ -835,6 +835,24 @@
             y = self.loads(s)
             self.assertEqual(y._proto, None)
 
+    def test_reduce_ex_calls_base(self):
+        for proto in 0, 1, 2:
+            x = REX_four()
+            self.assertEqual(x._proto, None)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._proto, proto)
+            y = self.loads(s)
+            self.assertEqual(y._proto, proto)
+
+    def test_reduce_calls_base(self):
+        for proto in 0, 1, 2:
+            x = REX_five()
+            self.assertEqual(x._reduce_called, 0)
+            s = self.dumps(x, proto)
+            self.assertEqual(x._reduce_called, 1)
+            y = self.loads(s)
+            self.assertEqual(y._reduce_called, 1)
+
 # Test classes for reduce_ex
 
 class REX_one(object):
@@ -859,6 +877,20 @@
     def __reduce__(self):
         raise TestFailed, "This __reduce__ shouldn't be called"
 
+class REX_four(object):
+    _proto = None
+    def __reduce_ex__(self, proto):
+        self._proto = proto
+        return object.__reduce_ex__(self, proto)
+    # Calling base class method should succeed
+
+class REX_five(object):
+    _reduce_called = 0
+    def __reduce__(self):
+        self._reduce_called = 1
+        return object.__reduce__(self)
+    # This one used to fail with infinite recursion
+
 # Test classes for newobj
 
 class MyInt(int):

Modified: python/branches/p3yk/Lib/test/regrtest.py
==============================================================================
--- python/branches/p3yk/Lib/test/regrtest.py	(original)
+++ python/branches/p3yk/Lib/test/regrtest.py	Fri Apr 27 21:54:29 2007
@@ -474,7 +474,7 @@
 STDTESTS = [
     'test_grammar',
     'test_opcodes',
-    'test_operations',
+    'test_dict',
     'test_builtin',
     'test_exceptions',
     'test_types',

Modified: python/branches/p3yk/Lib/test/string_tests.py
==============================================================================
--- python/branches/p3yk/Lib/test/string_tests.py	(original)
+++ python/branches/p3yk/Lib/test/string_tests.py	Fri Apr 27 21:54:29 2007
@@ -1104,6 +1104,9 @@
         self.checkequal('Abc', 'abc', 'translate', table)
         self.checkequal('xyz', 'xyz', 'translate', table)
         self.checkequal('yz', 'xyz', 'translate', table, 'x')
+        self.checkequal('yx', 'zyzzx', 'translate', None, 'z')
+        self.checkequal('zyzzx', 'zyzzx', 'translate', None, '')
+        self.checkequal('zyzzx', 'zyzzx', 'translate', None)
         self.checkraises(ValueError, 'xyz', 'translate', 'too short', 'strip')
         self.checkraises(ValueError, 'xyz', 'translate', 'too short')
 

Modified: python/branches/p3yk/Lib/test/test___all__.py
==============================================================================
--- python/branches/p3yk/Lib/test/test___all__.py	(original)
+++ python/branches/p3yk/Lib/test/test___all__.py	Fri Apr 27 21:54:29 2007
@@ -1,7 +1,5 @@
 import unittest
-from test import test_support
-
-from test.test_support import verify, verbose
+from test.test_support import verbose, run_unittest
 import sys
 import warnings
 
@@ -20,15 +18,15 @@
             # Silent fail here seems the best route since some modules
             # may not be available in all environments.
             return
-        verify(hasattr(sys.modules[modname], "__all__"),
-               "%s has no __all__ attribute" % modname)
+        self.failUnless(hasattr(sys.modules[modname], "__all__"),
+                        "%s has no __all__ attribute" % modname)
         names = {}
         exec("from %s import *" % modname, names)
         if "__builtins__" in names:
             del names["__builtins__"]
         keys = set(names)
         all = set(sys.modules[modname].__all__)
-        verify(keys==all, "%s != %s" % (keys, all))
+        self.assertEqual(keys, all)
 
     def test_all(self):
         if not sys.platform.startswith('java'):
@@ -177,7 +175,7 @@
 
 
 def test_main():
-    test_support.run_unittest(AllTest)
+    run_unittest(AllTest)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_array.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_array.py	(original)
+++ python/branches/p3yk/Lib/test/test_array.py	Fri Apr 27 21:54:29 2007
@@ -111,6 +111,21 @@
             self.assertEqual(a.x, b.x)
             self.assertEqual(type(a), type(b))
 
+    def test_pickle_for_empty_array(self):
+        for protocol in (0, 1, 2):
+            a = array.array(self.typecode)
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+
+            a = ArraySubclass(self.typecode)
+            a.x = 10
+            b = loads(dumps(a, protocol))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+            self.assertEqual(a.x, b.x)
+            self.assertEqual(type(a), type(b))
+
     def test_insert(self):
         a = array.array(self.typecode, self.example)
         a.insert(0, self.example[0])
@@ -713,7 +728,6 @@
                 return array.array.__new__(cls, 'c', s)
 
             def __init__(self, s, color='blue'):
-                array.array.__init__(self, 'c', s)
                 self.color = color
 
             def strip(self):

Modified: python/branches/p3yk/Lib/test/test_atexit.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_atexit.py	(original)
+++ python/branches/p3yk/Lib/test/test_atexit.py	Fri Apr 27 21:54:29 2007
@@ -28,7 +28,7 @@
         self.stream = StringIO.StringIO()
         sys.stdout = sys.stderr = self.stream
         atexit._clear()
-        
+
     def tearDown(self):
         sys.stdout = sys.__stdout__
         sys.stderr = sys.__stderr__
@@ -50,63 +50,63 @@
         atexit.register(h2)
         atexit.register(h3)
         atexit._run_exitfuncs()
-            
+
         self.assertEqual(self.stream.getvalue(), "h3\nh2\nh1\n")
 
     def test_raise(self):
         # be sure raises are handled properly
         atexit.register(raise1)
         atexit.register(raise2)
-        
+
         self.assertRaises(TypeError, atexit._run_exitfuncs)
-        
+
     def test_stress(self):
         a = [0]
         def inc():
             a[0] += 1
-    
+
         for i in range(128):
             atexit.register(inc)
         atexit._run_exitfuncs()
-        
+
         self.assertEqual(a[0], 128)
-        
+
     def test_clear(self):
         a = [0]
         def inc():
             a[0] += 1
-            
+
         atexit.register(inc)
         atexit._clear()
         atexit._run_exitfuncs()
-        
+
         self.assertEqual(a[0], 0)
-        
+
     def test_unregister(self):
         a = [0]
         def inc():
             a[0] += 1
         def dec():
             a[0] -= 1
-        
-        for i in range(4):    
+
+        for i in range(4):
             atexit.register(inc)
         atexit.register(dec)
         atexit.unregister(inc)
         atexit._run_exitfuncs()
-        
+
         self.assertEqual(a[0], -1)
-        
+
     def test_bound_methods(self):
         l = []
         atexit.register(l.append, 5)
         atexit._run_exitfuncs()
         self.assertEqual(l, [5])
-        
+
         atexit.unregister(l.append)
         atexit._run_exitfuncs()
         self.assertEqual(l, [5])
-        
+
 
 def test_main():
     test_support.run_unittest(TestCase)

Modified: python/branches/p3yk/Lib/test/test_base64.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_base64.py	(original)
+++ python/branches/p3yk/Lib/test/test_base64.py	Fri Apr 27 21:54:29 2007
@@ -183,16 +183,8 @@
 
 
 
-def suite():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(LegacyBase64TestCase))
-    suite.addTest(unittest.makeSuite(BaseXYTestCase))
-    return suite
-
-
 def test_main():
-    test_support.run_suite(suite())
-
+    test_support.run_unittest(__name__)
 
 if __name__ == '__main__':
-    unittest.main(defaultTest='suite')
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_binascii.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_binascii.py	(original)
+++ python/branches/p3yk/Lib/test/test_binascii.py	Fri Apr 27 21:54:29 2007
@@ -148,6 +148,15 @@
             "0"*75+"=\r\n=FF\r\n=FF\r\n=FF"
         )
 
+        self.assertEqual(binascii.b2a_qp('\0\n'), '=00\n')
+        self.assertEqual(binascii.b2a_qp('\0\n', quotetabs=True), '=00\n')
+        self.assertEqual(binascii.b2a_qp('foo\tbar\t\n'), 'foo\tbar=09\n')
+        self.assertEqual(binascii.b2a_qp('foo\tbar\t\n', quotetabs=True), 'foo=09bar=09\n')
+
+        self.assertEqual(binascii.b2a_qp('.'), '=2E')
+        self.assertEqual(binascii.b2a_qp('.\n'), '=2E\n')
+        self.assertEqual(binascii.b2a_qp('a.\n'), 'a.\n')
+
     def test_empty_string(self):
         # A test for SF bug #1022953.  Make sure SystemError is not raised.
         for n in ['b2a_qp', 'a2b_hex', 'b2a_base64', 'a2b_uu', 'a2b_qp',

Modified: python/branches/p3yk/Lib/test/test_bool.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_bool.py	(original)
+++ python/branches/p3yk/Lib/test/test_bool.py	Fri Apr 27 21:54:29 2007
@@ -321,7 +321,7 @@
         self.assertEqual(pickle.dumps(False), "I00\n.")
         self.assertEqual(pickle.dumps(True, True), "I01\n.")
         self.assertEqual(pickle.dumps(False, True), "I00\n.")
- 
+
         try:
             import cPickle
         except ImportError:

Modified: python/branches/p3yk/Lib/test/test_bsddb3.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_bsddb3.py	(original)
+++ python/branches/p3yk/Lib/test/test_bsddb3.py	Fri Apr 27 21:54:29 2007
@@ -4,7 +4,7 @@
 """
 import sys
 import unittest
-from test.test_support import requires, verbose, run_suite, unlink
+from test.test_support import requires, verbose, run_unittest, unlink
 
 # When running as a script instead of within the regrtest framework, skip the
 # requires test, since it's obvious we want to run them.
@@ -58,9 +58,7 @@
 
 # For invocation through regrtest
 def test_main():
-    tests = suite()
-    run_suite(tests)
-
+    run_unittest(suite())
 
 # For invocation as a script
 if __name__ == '__main__':
@@ -73,4 +71,4 @@
     print('python version:        %s' % sys.version)
     print('-=' * 38)
 
-    unittest.main(defaultTest='suite')
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_builtin.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_builtin.py	(original)
+++ python/branches/p3yk/Lib/test/test_builtin.py	Fri Apr 27 21:54:29 2007
@@ -107,9 +107,12 @@
         __import__('sys')
         __import__('time')
         __import__('string')
+        __import__(name='sys')
+        __import__(name='time', level=0)
         self.assertRaises(ImportError, __import__, 'spamspam')
         self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
         self.assertRaises(ValueError, __import__, '')
+        self.assertRaises(TypeError, __import__, 'sys', name='sys')
 
     def test_abs(self):
         # int
@@ -207,15 +210,21 @@
         compile('print(1)\n', '', 'exec')
         bom = '\xef\xbb\xbf'
         compile(bom + 'print(1)\n', '', 'exec')
+        compile(source='pass', filename='?', mode='exec')
+        compile(dont_inherit=0, filename='tmp', source='0', mode='eval')
+        compile('pass', '?', dont_inherit=1, mode='exec')
         self.assertRaises(TypeError, compile)
         self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode')
         self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'single', 0xff)
         self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
+        self.assertRaises(TypeError, compile, 'pass', '?', 'exec',
+                          mode='eval', source='0', filename='tmp')
         if have_unicode:
             compile(unicode('print(u"\xc3\xa5")\n', 'utf8'), '', 'exec')
             self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
             self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad')
 
+
     def test_delattr(self):
         import sys
         sys.spam = 1
@@ -1035,6 +1044,11 @@
         self.assertRaises(ValueError, int, '53', 40)
         self.assertRaises(TypeError, int, 1, 12)
 
+        # SF patch #1638879: embedded NULs were not detected with
+        # explicit base
+        self.assertRaises(ValueError, int, '123\0', 10)
+        self.assertRaises(ValueError, int, '123\x00 245', 20)
+
         self.assertEqual(int('100000000000000000000000000000000', 2),
                          4294967296)
         self.assertEqual(int('102002022201221111211', 3), 4294967296)
@@ -1138,10 +1152,10 @@
 
         self.assertEqual(int(Foo0()), 42)
         self.assertEqual(int(Foo1()), 42)
-	# XXX invokes __int__ now
+        # XXX invokes __int__ now
         # self.assertEqual(long(Foo2()), 42L)
         self.assertEqual(int(Foo3()), 0)
-	# XXX likewise
+        # XXX likewise
         # self.assertEqual(long(Foo4()), 42)
         # self.assertRaises(TypeError, long, Foo5())
 

Modified: python/branches/p3yk/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_cfgparser.py	(original)
+++ python/branches/p3yk/Lib/test/test_cfgparser.py	Fri Apr 27 21:54:29 2007
@@ -417,6 +417,18 @@
         self.assertEqual(cf.get("section", "ok"), "xxx/%s")
         self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
 
+    def test_set_malformatted_interpolation(self):
+        cf = self.fromstring("[sect]\n"
+                             "option1=foo\n")
+
+        self.assertEqual(cf.get('sect', "option1"), "foo")
+
+        self.assertRaises(ValueError, cf.set, "sect", "option1", "%foo")
+        self.assertRaises(ValueError, cf.set, "sect", "option1", "foo%")
+        self.assertRaises(ValueError, cf.set, "sect", "option1", "f%oo")
+
+        self.assertEqual(cf.get('sect', "option1"), "foo")
+
     def test_set_nonstring_types(self):
         cf = self.fromstring("[sect]\n"
                              "option1=foo\n")

Modified: python/branches/p3yk/Lib/test/test_cmath.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_cmath.py	(original)
+++ python/branches/p3yk/Lib/test/test_cmath.py	Fri Apr 27 21:54:29 2007
@@ -1,52 +1,196 @@
-#! /usr/bin/env python
-""" Simple test script for cmathmodule.c
-    Roger E. Masse
-"""
+from test.test_support import run_unittest
+import unittest
 import cmath, math
-from test.test_support import verbose, verify, TestFailed
 
-verify(abs(cmath.log(10) - math.log(10)) < 1e-9)
-verify(abs(cmath.log(10,2) - math.log(10,2)) < 1e-9)
-try:
-    cmath.log('a')
-except TypeError:
-    pass
-else:
-    raise TestFailed
-
-try:
-    cmath.log(10, 'a')
-except TypeError:
-    pass
-else:
-    raise TestFailed
-
-
-testdict = {'acos' : 1.0,
-            'acosh' : 1.0,
-            'asin' : 1.0,
-            'asinh' : 1.0,
-            'atan' : 0.2,
-            'atanh' : 0.2,
-            'cos' : 1.0,
-            'cosh' : 1.0,
-            'exp' : 1.0,
-            'log' : 1.0,
-            'log10' : 1.0,
-            'sin' : 1.0,
-            'sinh' : 1.0,
-            'sqrt' : 1.0,
-            'tan' : 1.0,
-            'tanh' : 1.0}
-
-for func in testdict.keys():
-    f = getattr(cmath, func)
-    r = f(testdict[func])
-    if verbose:
-        print('Calling %s(%f) = %f' % (func, testdict[func], abs(r)))
-
-p = cmath.pi
-e = cmath.e
-if verbose:
-    print('PI = ', abs(p))
-    print('E = ', abs(e))
+class CMathTests(unittest.TestCase):
+    # list of all functions in cmath
+    test_functions = [getattr(cmath, fname) for fname in [
+            'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh',
+            'cos', 'cosh', 'exp', 'log', 'log10', 'sin', 'sinh',
+            'sqrt', 'tan', 'tanh']]
+    # test first and second arguments independently for 2-argument log
+    test_functions.append(lambda x : cmath.log(x, 1729. + 0j))
+    test_functions.append(lambda x : cmath.log(14.-27j, x))
+
+    def cAssertAlmostEqual(self, a, b, rel_eps = 1e-10, abs_eps = 1e-100):
+        """Check that two complex numbers are almost equal."""
+        # the two complex numbers are considered almost equal if
+        # either the relative error is <= rel_eps or the absolute error
+        # is tiny, <= abs_eps.
+        if a == b == 0:
+            return
+        absolute_error = abs(a-b)
+        relative_error = absolute_error/max(abs(a), abs(b))
+        if relative_error > rel_eps and absolute_error > abs_eps:
+            self.fail("%s and %s are not almost equal" % (a, b))
+
+    def test_constants(self):
+        e_expected = 2.71828182845904523536
+        pi_expected = 3.14159265358979323846
+        self.assertAlmostEqual(cmath.pi, pi_expected, 9,
+            "cmath.pi is %s; should be %s" % (cmath.pi, pi_expected))
+        self.assertAlmostEqual(cmath.e,  e_expected, 9,
+            "cmath.e is %s; should be %s" % (cmath.e, e_expected))
+
+    def test_user_object(self):
+        # Test automatic calling of __complex__ and __float__ by cmath
+        # functions
+
+        # some random values to use as test values; we avoid values
+        # for which any of the functions in cmath is undefined
+        # (i.e. 0., 1., -1., 1j, -1j) or would cause overflow
+        cx_arg = 4.419414439 + 1.497100113j
+        flt_arg = -6.131677725
+
+        # a variety of non-complex numbers, used to check that
+        # non-complex return values from __complex__ give an error
+        non_complexes = ["not complex", 1, 5, 2., None,
+                         object(), NotImplemented]
+
+        # Now we introduce a variety of classes whose instances might
+        # end up being passed to the cmath functions
+
+        # usual case: new-style class implementing __complex__
+        class MyComplex(object):
+            def __init__(self, value):
+                self.value = value
+            def __complex__(self):
+                return self.value
+
+        # old-style class implementing __complex__
+        class MyComplexOS:
+            def __init__(self, value):
+                self.value = value
+            def __complex__(self):
+                return self.value
+
+        # classes for which __complex__ raises an exception
+        class SomeException(Exception):
+            pass
+        class MyComplexException(object):
+            def __complex__(self):
+                raise SomeException
+        class MyComplexExceptionOS:
+            def __complex__(self):
+                raise SomeException
+
+        # some classes not providing __float__ or __complex__
+        class NeitherComplexNorFloat(object):
+            pass
+        class NeitherComplexNorFloatOS:
+            pass
+        class MyInt(object):
+            def __int__(self): return 2
+            def __long__(self): return 2
+            def __index__(self): return 2
+        class MyIntOS:
+            def __int__(self): return 2
+            def __long__(self): return 2
+            def __index__(self): return 2
+
+        # other possible combinations of __float__ and __complex__
+        # that should work
+        class FloatAndComplex(object):
+            def __float__(self):
+                return flt_arg
+            def __complex__(self):
+                return cx_arg
+        class FloatAndComplexOS:
+            def __float__(self):
+                return flt_arg
+            def __complex__(self):
+                return cx_arg
+        class JustFloat(object):
+            def __float__(self):
+                return flt_arg
+        class JustFloatOS:
+            def __float__(self):
+                return flt_arg
+
+        for f in self.test_functions:
+            # usual usage
+            self.cAssertAlmostEqual(f(MyComplex(cx_arg)), f(cx_arg))
+            self.cAssertAlmostEqual(f(MyComplexOS(cx_arg)), f(cx_arg))
+            # other combinations of __float__ and __complex__
+            self.cAssertAlmostEqual(f(FloatAndComplex()), f(cx_arg))
+            self.cAssertAlmostEqual(f(FloatAndComplexOS()), f(cx_arg))
+            self.cAssertAlmostEqual(f(JustFloat()), f(flt_arg))
+            self.cAssertAlmostEqual(f(JustFloatOS()), f(flt_arg))
+            # TypeError should be raised for classes not providing
+            # either __complex__ or __float__, even if they provide
+            # __int__, __long__ or __index__.  An old-style class
+            # currently raises AttributeError instead of a TypeError;
+            # this could be considered a bug.
+            self.assertRaises(TypeError, f, NeitherComplexNorFloat())
+            self.assertRaises(TypeError, f, MyInt())
+            self.assertRaises(Exception, f, NeitherComplexNorFloatOS())
+            self.assertRaises(Exception, f, MyIntOS())
+            # non-complex return value from __complex__ -> TypeError
+            for bad_complex in non_complexes:
+                self.assertRaises(TypeError, f, MyComplex(bad_complex))
+                self.assertRaises(TypeError, f, MyComplexOS(bad_complex))
+            # exceptions in __complex__ should be propagated correctly
+            self.assertRaises(SomeException, f, MyComplexException())
+            self.assertRaises(SomeException, f, MyComplexExceptionOS())
+
+    def test_input_type(self):
+        # ints and longs should be acceptable inputs to all cmath
+        # functions, by virtue of providing a __float__ method
+        for f in self.test_functions:
+            for arg in [2, 2.]:
+                self.cAssertAlmostEqual(f(arg), f(arg.__float__()))
+
+        # but strings should give a TypeError
+        for f in self.test_functions:
+            for arg in ["a", "long_string", "0", "1j", ""]:
+                self.assertRaises(TypeError, f, arg)
+
+    def test_cmath_matches_math(self):
+        # check that corresponding cmath and math functions are equal
+        # for floats in the appropriate range
+
+        # test_values in (0, 1)
+        test_values = [0.01, 0.1, 0.2, 0.5, 0.9, 0.99]
+
+        # test_values for functions defined on [-1., 1.]
+        unit_interval = test_values + [-x for x in test_values] + \
+            [0., 1., -1.]
+
+        # test_values for log, log10, sqrt
+        positive = test_values + [1.] + [1./x for x in test_values]
+        nonnegative = [0.] + positive
+
+        # test_values for functions defined on the whole real line
+        real_line = [0.] + positive + [-x for x in positive]
+
+        test_functions = {
+            'acos' : unit_interval,
+            'asin' : unit_interval,
+            'atan' : real_line,
+            'cos' : real_line,
+            'cosh' : real_line,
+            'exp' : real_line,
+            'log' : positive,
+            'log10' : positive,
+            'sin' : real_line,
+            'sinh' : real_line,
+            'sqrt' : nonnegative,
+            'tan' : real_line,
+            'tanh' : real_line}
+
+        for fn, values in test_functions.items():
+            float_fn = getattr(math, fn)
+            complex_fn = getattr(cmath, fn)
+            for v in values:
+                self.cAssertAlmostEqual(float_fn(v), complex_fn(v))
+
+        # test two-argument version of log with various bases
+        for base in [0.5, 2., 10.]:
+            for v in positive:
+                self.cAssertAlmostEqual(cmath.log(v, base), math.log(v, base))
+
+def test_main():
+    run_unittest(CMathTests)
+
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_cmd_line.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_cmd_line.py	(original)
+++ python/branches/p3yk/Lib/test/test_cmd_line.py	Fri Apr 27 21:54:29 2007
@@ -6,7 +6,7 @@
 
 class CmdLineTest(unittest.TestCase):
     def start_python(self, cmd_line):
-        outfp, infp = popen2.popen4('%s %s' % (sys.executable, cmd_line))
+        outfp, infp = popen2.popen4('"%s" %s' % (sys.executable, cmd_line))
         infp.close()
         data = outfp.read()
         outfp.close()

Modified: python/branches/p3yk/Lib/test/test_codecencodings_cn.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecencodings_cn.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecencodings_cn.py	Fri Apr 27 21:54:29 2007
@@ -51,11 +51,7 @@
     has_iso10646 = True
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_GB2312))
-    suite.addTest(unittest.makeSuite(Test_GBK))
-    suite.addTest(unittest.makeSuite(Test_GB18030))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecencodings_hk.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecencodings_hk.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecencodings_hk.py	Fri Apr 27 21:54:29 2007
@@ -21,9 +21,7 @@
     )
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_Big5HKSCS))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecencodings_jp.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecencodings_jp.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecencodings_jp.py	Fri Apr 27 21:54:29 2007
@@ -99,13 +99,7 @@
     )
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_CP932))
-    suite.addTest(unittest.makeSuite(Test_EUC_JISX0213))
-    suite.addTest(unittest.makeSuite(Test_EUC_JP_COMPAT))
-    suite.addTest(unittest.makeSuite(Test_SJIS_COMPAT))
-    suite.addTest(unittest.makeSuite(Test_SJISX0213))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecencodings_kr.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecencodings_kr.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecencodings_kr.py	Fri Apr 27 21:54:29 2007
@@ -45,11 +45,7 @@
     )
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_CP949))
-    suite.addTest(unittest.makeSuite(Test_EUCKR))
-    suite.addTest(unittest.makeSuite(Test_JOHAB))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecencodings_tw.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecencodings_tw.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecencodings_tw.py	Fri Apr 27 21:54:29 2007
@@ -21,9 +21,7 @@
     )
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_Big5))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecmaps_cn.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecmaps_cn.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecmaps_cn.py	Fri Apr 27 21:54:29 2007
@@ -20,10 +20,7 @@
                  'MICSFT/WINDOWS/CP936.TXT'
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestGB2312Map))
-    suite.addTest(unittest.makeSuite(TestGBKMap))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecmaps_hk.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecmaps_hk.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecmaps_hk.py	Fri Apr 27 21:54:29 2007
@@ -14,9 +14,7 @@
     mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS.TXT'
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestBig5HKSCSMap))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecmaps_jp.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecmaps_jp.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecmaps_jp.py	Fri Apr 27 21:54:29 2007
@@ -61,13 +61,7 @@
 
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestCP932Map))
-    suite.addTest(unittest.makeSuite(TestEUCJPCOMPATMap))
-    suite.addTest(unittest.makeSuite(TestSJISCOMPATMap))
-    suite.addTest(unittest.makeSuite(TestEUCJISX0213Map))
-    suite.addTest(unittest.makeSuite(TestSJISX0213Map))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecmaps_kr.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecmaps_kr.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecmaps_kr.py	Fri Apr 27 21:54:29 2007
@@ -34,11 +34,7 @@
     pass_dectest = [('\\', u'\u20a9')]
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestCP949Map))
-    suite.addTest(unittest.makeSuite(TestEUCKRMap))
-    suite.addTest(unittest.makeSuite(TestJOHABMap))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_codecmaps_tw.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_codecmaps_tw.py	(original)
+++ python/branches/p3yk/Lib/test/test_codecmaps_tw.py	Fri Apr 27 21:54:29 2007
@@ -25,10 +25,7 @@
     ]
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestBIG5Map))
-    suite.addTest(unittest.makeSuite(TestCP950Map))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_commands.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_commands.py	(original)
+++ python/branches/p3yk/Lib/test/test_commands.py	Fri Apr 27 21:54:29 2007
@@ -4,6 +4,10 @@
 '''
 import unittest
 import os, tempfile, re
+import warnings
+
+warnings.filterwarnings('ignore', r".*commands.getstatus.. is deprecated",
+                        DeprecationWarning)
 
 from test.test_support import TestSkipped, run_unittest, reap_children
 from commands import *

Modified: python/branches/p3yk/Lib/test/test_compile.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_compile.py	(original)
+++ python/branches/p3yk/Lib/test/test_compile.py	Fri Apr 27 21:54:29 2007
@@ -399,13 +399,26 @@
         # is the max. Ensure the result of too many annotations is a
         # SyntaxError.
         s = "def f((%s)): pass"
-        s %= ', '.join('a%d:%d' % (i,i) for i in xrange(65535))        
+        s %= ', '.join('a%d:%d' % (i,i) for i in xrange(65535))
         self.assertRaises(SyntaxError, compile, s, '?', 'exec')
         # Test that the max # of annotations compiles.
         s = "def f((%s)): pass"
         s %= ', '.join('a%d:%d' % (i,i) for i in xrange(65534))
         compile(s, '?', 'exec')
-        
+
+    def test_mangling(self):
+        class A:
+            def f():
+                __mangled = 1
+                __not_mangled__ = 2
+                import __mangled_mod
+                import __package__.module
+
+        self.assert_("_A__mangled" in A.f.__code__.co_varnames)
+        self.assert_("__not_mangled__" in A.f.__code__.co_varnames)
+        self.assert_("_A__mangled_mod" in A.f.__code__.co_varnames)
+        self.assert_("__package__" in A.f.__code__.co_varnames)
+
 def test_main():
     test_support.run_unittest(TestSpecifics)
 

Modified: python/branches/p3yk/Lib/test/test_compiler.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_compiler.py	(original)
+++ python/branches/p3yk/Lib/test/test_compiler.py	Fri Apr 27 21:54:29 2007
@@ -190,7 +190,7 @@
     def testBytesLiteral(self):
         c = compiler.compile("b'foo'", '<string>', 'eval')
         b = eval(c)
-        
+
         c = compiler.compile('def f(b=b"foo"):\n'
                              '    b[0] += 1\n'
                              '    return b\n'
@@ -200,7 +200,7 @@
         dct = {}
         exec(c, dct)
         self.assertEquals(dct.get('result'), b"ioo")
-        
+
         c = compiler.compile('def f():\n'
                              '    b = b"foo"\n'
                              '    b[0] += 1\n'

Modified: python/branches/p3yk/Lib/test/test_complex.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_complex.py	(original)
+++ python/branches/p3yk/Lib/test/test_complex.py	Fri Apr 27 21:54:29 2007
@@ -208,6 +208,8 @@
         self.assertAlmostEqual(complex(),  0)
         self.assertAlmostEqual(complex("-1"), -1)
         self.assertAlmostEqual(complex("+1"), +1)
+        self.assertAlmostEqual(complex("(1+2j)"), 1+2j)
+        self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j)
 
         class complex2(complex): pass
         self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
@@ -237,12 +239,17 @@
         self.assertRaises(ValueError, complex, "")
         self.assertRaises(TypeError, complex, None)
         self.assertRaises(ValueError, complex, "\0")
+        self.assertRaises(ValueError, complex, "3\09")
         self.assertRaises(TypeError, complex, "1", "2")
         self.assertRaises(TypeError, complex, "1", 42)
         self.assertRaises(TypeError, complex, 1, "2")
         self.assertRaises(ValueError, complex, "1+")
         self.assertRaises(ValueError, complex, "1+1j+1j")
         self.assertRaises(ValueError, complex, "--")
+        self.assertRaises(ValueError, complex, "(1+2j")
+        self.assertRaises(ValueError, complex, "1+2j)")
+        self.assertRaises(ValueError, complex, "1+(2j)")
+        self.assertRaises(ValueError, complex, "(1+2j)123")
         if test_support.have_unicode:
             self.assertRaises(ValueError, complex, unicode("1"*500))
             self.assertRaises(ValueError, complex, unicode("x"))
@@ -305,6 +312,11 @@
 
         self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
 
+        self.assertEqual(1-6j,complex(repr(1-6j)))
+        self.assertEqual(1+6j,complex(repr(1+6j)))
+        self.assertEqual(-6j,complex(repr(-6j)))
+        self.assertEqual(6j,complex(repr(6j)))
+
     def test_neg(self):
         self.assertEqual(-(1+6j), -1-6j)
 

Modified: python/branches/p3yk/Lib/test/test_contextlib.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_contextlib.py	(original)
+++ python/branches/p3yk/Lib/test/test_contextlib.py	Fri Apr 27 21:54:29 2007
@@ -9,7 +9,7 @@
 import unittest
 import threading
 from contextlib import *  # Tests __all__
-from test.test_support import run_suite
+from test import test_support
 
 class ContextManagerTestCase(unittest.TestCase):
 
@@ -332,9 +332,7 @@
 
 # This is needed to make the test actually run under regrtest.py!
 def test_main():
-    run_suite(
-        unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])
-    )
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_crypt.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_crypt.py	(original)
+++ python/branches/p3yk/Lib/test/test_crypt.py	Fri Apr 27 21:54:29 2007
@@ -3,7 +3,7 @@
    Roger E. Masse
 """
 
-from test.test_support import verify, verbose
+from test.test_support import verbose
 import crypt
 
 c = crypt.crypt('mypassword', 'ab')

Modified: python/branches/p3yk/Lib/test/test_csv.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_csv.py	(original)
+++ python/branches/p3yk/Lib/test/test_csv.py	Fri Apr 27 21:54:29 2007
@@ -484,12 +484,16 @@
         self.readerAssertEqual('a"b"c', [['a"b"c']])
 
     def test_quotes_and_more(self):
+        # Excel would never write a field containing '"a"b', but when
+        # reading one, it will return 'ab'.
         self.readerAssertEqual('"a"b', [['ab']])
 
     def test_lone_quote(self):
         self.readerAssertEqual('a"b', [['a"b']])
 
     def test_quote_and_quote(self):
+        # Excel would never write a field containing '"a" "b"', but when
+        # reading one, it will return 'a "b"'.
         self.readerAssertEqual('"a" "b"', [['a "b"']])
 
     def test_space_and_quote(self):

Modified: python/branches/p3yk/Lib/test/test_ctypes.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_ctypes.py	(original)
+++ python/branches/p3yk/Lib/test/test_ctypes.py	Fri Apr 27 21:54:29 2007
@@ -1,12 +1,12 @@
 import unittest
 
-from test.test_support import run_suite
+from test.test_support import run_unittest
 import ctypes.test
 
 def test_main():
     skipped, testcases = ctypes.test.get_tests(ctypes.test, "test_*.py", verbosity=0)
     suites = [unittest.makeSuite(t) for t in testcases]
-    run_suite(unittest.TestSuite(suites))
+    run_unittest(unittest.TestSuite(suites))
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_curses.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_curses.py	(original)
+++ python/branches/p3yk/Lib/test/test_curses.py	Fri Apr 27 21:54:29 2007
@@ -129,6 +129,12 @@
     stdscr.touchline(5,5,0)
     stdscr.vline('a', 3)
     stdscr.vline('a', 3, curses.A_STANDOUT)
+    stdscr.chgat(5, 2, 3, curses.A_BLINK)
+    stdscr.chgat(3, curses.A_BOLD)
+    stdscr.chgat(5, 8, curses.A_UNDERLINE)
+    stdscr.chgat(curses.A_BLINK)
+    stdscr.refresh()
+
     stdscr.vline(1,1, 'a', 3)
     stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
 
@@ -241,12 +247,21 @@
     except curses.panel.error:
         pass
 
+def test_resize_term(stdscr):
+    if hasattr(curses, 'resizeterm'):
+        lines, cols = curses.LINES, curses.COLS
+        curses.resizeterm(lines - 1, cols + 1)
+
+        if curses.LINES != lines - 1 or curses.COLS != cols + 1:
+            raise RuntimeError, "Expected resizeterm to update LINES and COLS"
+
 def main(stdscr):
     curses.savetty()
     try:
         module_funcs(stdscr)
         window_funcs(stdscr)
         test_userptr_without_set(stdscr)
+        test_resize_term(stdscr)
     finally:
         curses.resetty()
 

Modified: python/branches/p3yk/Lib/test/test_datetime.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_datetime.py	(original)
+++ python/branches/p3yk/Lib/test/test_datetime.py	Fri Apr 27 21:54:29 2007
@@ -3,6 +3,7 @@
 See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
 """
 
+import os
 import sys
 import pickle
 import unittest
@@ -135,7 +136,7 @@
 # Base clase for testing a particular aspect of timedelta, time, date and
 # datetime comparisons.
 
-class HarmlessMixedComparison(unittest.TestCase):
+class HarmlessMixedComparison:
     # Test that __eq__ and __ne__ don't complain for mixed-type comparisons.
 
     # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a
@@ -174,7 +175,7 @@
 #############################################################################
 # timedelta tests
 
-class TestTimeDelta(HarmlessMixedComparison):
+class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
 
     theclass = timedelta
 
@@ -521,7 +522,7 @@
 class SubclassDate(date):
     sub_var = 1
 
-class TestDate(HarmlessMixedComparison):
+class TestDate(HarmlessMixedComparison, unittest.TestCase):
     # Tests here should pass for both dates and datetimes, except for a
     # few tests that TestDateTime overrides.
 
@@ -1452,6 +1453,21 @@
             self.assertRaises(ValueError, self.theclass.utcfromtimestamp,
                               insane)
 
+    def test_negative_float_fromtimestamp(self):
+        # Windows doesn't accept negative timestamps
+        if os.name == "nt":
+            return
+        # The result is tz-dependent; at least test that this doesn't
+        # fail (like it did before bug 1646728 was fixed).
+        self.theclass.fromtimestamp(-1.05)
+
+    def test_negative_float_utcfromtimestamp(self):
+        # Windows doesn't accept negative timestamps
+        if os.name == "nt":
+            return
+        d = self.theclass.utcfromtimestamp(-1.05)
+        self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
+
     def test_utcnow(self):
         import time
 
@@ -1607,7 +1623,7 @@
 class SubclassTime(time):
     sub_var = 1
 
-class TestTime(HarmlessMixedComparison):
+class TestTime(HarmlessMixedComparison, unittest.TestCase):
 
     theclass = time
 
@@ -1890,7 +1906,7 @@
 # A mixin for classes with a tzinfo= argument.  Subclasses must define
 # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
 # must be legit (which is true for time and datetime).
-class TZInfoBase(unittest.TestCase):
+class TZInfoBase:
 
     def test_argument_passing(self):
         cls = self.theclass
@@ -2050,7 +2066,7 @@
 
 
 # Testing time objects with a non-None tzinfo.
-class TestTimeTZ(TestTime, TZInfoBase):
+class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
     theclass = time
 
     def test_empty(self):
@@ -2298,7 +2314,7 @@
 
 # Testing datetime objects with a non-None tzinfo.
 
-class TestDateTimeTZ(TestDateTime, TZInfoBase):
+class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
     theclass = datetime
 
     def test_trivial(self):
@@ -3259,45 +3275,8 @@
         self.assertEqual(as_datetime, datetime_sc)
         self.assertEqual(datetime_sc, as_datetime)
 
-def test_suite():
-    allsuites = [unittest.makeSuite(klass, 'test')
-                 for klass in (TestModule,
-                               TestTZInfo,
-                               TestTimeDelta,
-                               TestDateOnly,
-                               TestDate,
-                               TestDateTime,
-                               TestTime,
-                               TestTimeTZ,
-                               TestDateTimeTZ,
-                               TestTimezoneConversions,
-                               Oddballs,
-                              )
-                ]
-    return unittest.TestSuite(allsuites)
-
 def test_main():
-    import gc
-    import sys
-
-    thesuite = test_suite()
-    lastrc = None
-    while True:
-        test_support.run_suite(thesuite)
-        if 1:       # change to 0, under a debug build, for some leak detection
-            break
-        gc.collect()
-        if gc.garbage:
-            raise SystemError("gc.garbage not empty after test run: %r" %
-                              gc.garbage)
-        if hasattr(sys, 'gettotalrefcount'):
-            thisrc = sys.gettotalrefcount()
-            print('*' * 10, 'total refs:', thisrc, end=' ', file=sys.stderr)
-            if lastrc:
-                print('delta:', thisrc - lastrc, file=sys.stderr)
-            else:
-                print(file=sys.stderr)
-            lastrc = thisrc
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_defaultdict.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_defaultdict.py	(original)
+++ python/branches/p3yk/Lib/test/test_defaultdict.py	Fri Apr 27 21:54:29 2007
@@ -132,6 +132,15 @@
         self.assertEqual(d2.default_factory, list)
         self.assertEqual(d2, d1)
 
+    def test_keyerror_without_factory(self):
+        d1 = defaultdict()
+        try:
+            d1[(1,)]
+        except KeyError as err:
+            self.assertEqual(err.message, (1,))
+        else:
+            self.fail("expected KeyError")
+
 
 def test_main():
     test_support.run_unittest(TestDefaultDict)

Modified: python/branches/p3yk/Lib/test/test_deque.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_deque.py	(original)
+++ python/branches/p3yk/Lib/test/test_deque.py	Fri Apr 27 21:54:29 2007
@@ -575,7 +575,7 @@
 
 >>> for value in roundrobin('abc', 'd', 'efgh'):
 ...     print(value)
-... 
+...
 a
 d
 e

Modified: python/branches/p3yk/Lib/test/test_descr.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_descr.py	(original)
+++ python/branches/p3yk/Lib/test/test_descr.py	Fri Apr 27 21:54:29 2007
@@ -773,6 +773,22 @@
     except TypeError: pass
     else: raise TestFailed, "calling object w/o call method should raise TypeError"
 
+    # Testing code to find most derived baseclass
+    class A(type):
+        def __new__(*args, **kwargs):
+            return type.__new__(*args, **kwargs)
+
+    class B(object):
+        pass
+
+    class C(object, metaclass=A):
+        pass
+
+    # The most derived metaclass of D is A rather than type.
+    class D(B, C):
+        pass
+
+
 def pymods():
     if verbose: print("Testing Python subclass of module...")
     log = []
@@ -1072,6 +1088,45 @@
         raise TestFailed, "[''] slots not caught"
     class C(object):
         __slots__ = ["a", "a_b", "_a", "A0123456789Z"]
+    # XXX(nnorwitz): was there supposed to be something tested
+    # from the class above?
+
+    # Test a single string is not expanded as a sequence.
+    class C(object):
+        __slots__ = "abc"
+    c = C()
+    c.abc = 5
+    vereq(c.abc, 5)
+
+    # Test unicode slot names
+    try:
+        unicode
+    except NameError:
+        pass
+    else:
+        # Test a single unicode string is not expanded as a sequence.
+        class C(object):
+            __slots__ = unicode("abc")
+        c = C()
+        c.abc = 5
+        vereq(c.abc, 5)
+
+        # _unicode_to_string used to modify slots in certain circumstances
+        slots = (unicode("foo"), unicode("bar"))
+        class C(object):
+            __slots__ = slots
+        x = C()
+        x.foo = 5
+        vereq(x.foo, 5)
+        veris(type(slots[0]), unicode)
+        # this used to leak references
+        try:
+            class C(object):
+                __slots__ = [unichr(128)]
+        except (TypeError, UnicodeEncodeError):
+            pass
+        else:
+            raise TestFailed, "[unichr(128)] slots not caught"
 
     # Test leaks
     class Counted(object):
@@ -1318,6 +1373,22 @@
     else:
         verify(0, "__slots__ = [1] should be illegal")
 
+    class M1(type):
+        pass
+    class M2(type):
+        pass
+    class A1(object, metaclass=M1):
+        pass
+    class A2(object, metaclass=M2):
+        pass
+    try:
+        class B(A1, A2):
+            pass
+    except TypeError:
+        pass
+    else:
+        verify(0, "finding the most derived metaclass should have failed")
+
 def classmethods():
     if verbose: print("Testing class methods...")
     class C(object):
@@ -2092,7 +2163,6 @@
         __slots__ = ['prec']
         def __init__(self, value=0.0, prec=12):
             self.prec = int(prec)
-            float.__init__(self, value)
         def __repr__(self):
             return "%.*g" % (self.prec, self)
     vereq(repr(precfloat(1.1)), "1.1")
@@ -2644,6 +2714,51 @@
     cant(o, type(1))
     cant(o, type(None))
     del o
+    class G(object):
+        __slots__ = ["a", "b"]
+    class H(object):
+        __slots__ = ["b", "a"]
+    try:
+        unicode
+    except NameError:
+        class I(object):
+            __slots__ = ["a", "b"]
+    else:
+        class I(object):
+            __slots__ = [unicode("a"), unicode("b")]
+    class J(object):
+        __slots__ = ["c", "b"]
+    class K(object):
+        __slots__ = ["a", "b", "d"]
+    class L(H):
+        __slots__ = ["e"]
+    class M(I):
+        __slots__ = ["e"]
+    class N(J):
+        __slots__ = ["__weakref__"]
+    class P(J):
+        __slots__ = ["__dict__"]
+    class Q(J):
+        pass
+    class R(J):
+        __slots__ = ["__dict__", "__weakref__"]
+
+    for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)):
+        x = cls()
+        x.a = 1
+        x.__class__ = cls2
+        verify(x.__class__ is cls2,
+               "assigning %r as __class__ for %r silently failed" % (cls2, x))
+        vereq(x.a, 1)
+        x.__class__ = cls
+        verify(x.__class__ is cls,
+               "assigning %r as __class__ for %r silently failed" % (cls, x))
+        vereq(x.a, 1)
+    for cls in G, J, K, L, M, N, P, R, list, Int:
+        for cls2 in G, J, K, L, M, N, P, R, list, Int:
+            if cls is cls2:
+                continue
+            cant(cls(), cls2)
 
 def setdict():
     if verbose: print("Testing __dict__ assignment...")
@@ -3999,6 +4114,19 @@
                 check(iexpr, c, N1)
                 check(iexpr, c, N2)
 
+def test_assign_slice():
+    # ceval.c's assign_slice used to check for
+    # tp->tp_as_sequence->sq_slice instead of
+    # tp->tp_as_sequence->sq_ass_slice
+
+    class C(object):
+        def __setslice__(self, start, stop, value):
+            self.value = value
+
+    c = C()
+    c[1:2] = 3
+    vereq(c.value, 3)
+
 def test_main():
     weakref_segfault() # Must be first, somehow
     wrapper_segfault()
@@ -4094,6 +4222,7 @@
     test_init()
     methodwrapper()
     notimplemented()
+    test_assign_slice()
 
     if verbose: print("All OK")
 

Modified: python/branches/p3yk/Lib/test/test_descrtut.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_descrtut.py	(original)
+++ python/branches/p3yk/Lib/test/test_descrtut.py	Fri Apr 27 21:54:29 2007
@@ -243,7 +243,7 @@
 static methods in C++ or Java. Here's an example:
 
     >>> class C:
-    ... 
+    ...
     ...     @staticmethod
     ...     def foo(x, y):
     ...         print("staticmethod", x, y)

Modified: python/branches/p3yk/Lib/test/test_dict.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_dict.py	(original)
+++ python/branches/p3yk/Lib/test/test_dict.py	Fri Apr 27 21:54:29 2007
@@ -425,7 +425,7 @@
         except RuntimeError as err:
             self.assertEqual(err.args, (42,))
         else:
-            self.fail_("e[42] didn't raise RuntimeError")
+            self.fail("e[42] didn't raise RuntimeError")
         class F(dict):
             def __init__(self):
                 # An instance variable __missing__ should have no effect
@@ -436,7 +436,7 @@
         except KeyError as err:
             self.assertEqual(err.args, (42,))
         else:
-            self.fail_("f[42] didn't raise KeyError")
+            self.fail("f[42] didn't raise KeyError")
         class G(dict):
             pass
         g = G()
@@ -445,7 +445,7 @@
         except KeyError as err:
             self.assertEqual(err.args, (42,))
         else:
-            self.fail_("g[42] didn't raise KeyError")
+            self.fail("g[42] didn't raise KeyError")
 
     def test_tuple_keyerror(self):
         # SF #1576657
@@ -457,6 +457,76 @@
         else:
             self.fail("missing KeyError")
 
+    def test_bad_key(self):
+        # Dictionary lookups should fail if __cmp__() raises an exception.
+        class CustomException(Exception):
+            pass
+
+        class BadDictKey:
+            def __hash__(self):
+                return hash(self.__class__)
+
+            def __eq__(self, other):
+                if isinstance(other, self.__class__):
+                    raise CustomException
+                return other
+
+        d = {}
+        x1 = BadDictKey()
+        x2 = BadDictKey()
+        d[x1] = 1
+        for stmt in ['d[x2] = 2',
+                     'z = d[x2]',
+                     'x2 in d',
+                     'd.get(x2)',
+                     'd.setdefault(x2, 42)',
+                     'd.pop(x2)',
+                     'd.update({x2: 2})']:
+            try:
+                exec(stmt, locals())
+            except CustomException:
+                pass
+            else:
+                self.fail("Statement %r didn't raise exception" % stmt)
+
+    def test_resize1(self):
+        # Dict resizing bug, found by Jack Jansen in 2.2 CVS development.
+        # This version got an assert failure in debug build, infinite loop in
+        # release build.  Unfortunately, provoking this kind of stuff requires
+        # a mix of inserts and deletes hitting exactly the right hash codes in
+        # exactly the right order, and I can't think of a randomized approach
+        # that would be *likely* to hit a failing case in reasonable time.
+
+        d = {}
+        for i in range(5):
+            d[i] = i
+        for i in range(5):
+            del d[i]
+        for i in range(5, 9):  # i==8 was the problem
+            d[i] = i
+
+    def test_resize2(self):
+        # Another dict resizing bug (SF bug #1456209).
+        # This caused Segmentation faults or Illegal instructions.
+
+        class X(object):
+            def __hash__(self):
+                return 5
+            def __eq__(self, other):
+                if resizing:
+                    d.clear()
+                return False
+        d = {}
+        resizing = False
+        d[X()] = 1
+        d[X()] = 2
+        d[X()] = 3
+        d[X()] = 4
+        d[X()] = 5
+        # now trigger a resize
+        resizing = True
+        d[9] = 6
+
 
 from test import mapping_tests
 

Modified: python/branches/p3yk/Lib/test/test_dis.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_dis.py	(original)
+++ python/branches/p3yk/Lib/test/test_dis.py	Fri Apr 27 21:54:29 2007
@@ -1,11 +1,11 @@
-from test.test_support import verify, verbose, TestFailed, run_unittest
+# Minimal tests for dis module
+
+from test.test_support import verbose, run_unittest
+import unittest
 import sys
 import dis
 import StringIO
 
-# Minimal tests for dis module
-
-import unittest
 
 def _f(a):
     print(a)

Modified: python/branches/p3yk/Lib/test/test_doctest.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_doctest.py	(original)
+++ python/branches/p3yk/Lib/test/test_doctest.py	Fri Apr 27 21:54:29 2007
@@ -35,7 +35,7 @@
     >>> for i in range(10):
     ...     sc = sc.double()
     ...     print(sc.get(), end=' ')
-    6 12 24 48 96 192 384 768 1536 3072 
+    6 12 24 48 96 192 384 768 1536 3072
     """
     def __init__(self, val):
         """
@@ -571,7 +571,7 @@
     ...
     ...     >>> for x in range(10):
     ...     ...     print(x, end=' ')
-    ...     0 1 2 3 4 5 6 7 8 9 
+    ...     0 1 2 3 4 5 6 7 8 9
     ...     >>> x//2
     ...     6
     ...     '''
@@ -1461,11 +1461,11 @@
     >>> def f(x): r'''
     ...     >>> for x in range(10): # doctest: +ELLIPSIS
     ...     ...     print(x, end=' ')
-    ...     0 1 2 ... 9 
+    ...     0 1 2 ... 9
     ...
     ...     >>> for x in range(10):
     ...     ...     print(x, end=' ') # doctest: +ELLIPSIS
-    ...     0 1 2 ... 9 
+    ...     0 1 2 ... 9
     ...     '''
     >>> test = doctest.DocTestFinder().find(f)[0]
     >>> doctest.DocTestRunner(verbose=False).run(test)
@@ -1478,7 +1478,7 @@
     ...     Should fail (option directive not on the last line):
     ...         >>> for x in range(10): # doctest: +ELLIPSIS
     ...         ...     print(x, end=' ') # doctest: +NORMALIZE_WHITESPACE
-    ...         0  1    2...9 
+    ...         0  1    2...9
     ...     '''
     >>> test = doctest.DocTestFinder().find(f)[0]
     >>> doctest.DocTestRunner(verbose=False).run(test)

Modified: python/branches/p3yk/Lib/test/test_email.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_email.py	(original)
+++ python/branches/p3yk/Lib/test/test_email.py	Fri Apr 27 21:54:29 2007
@@ -4,10 +4,10 @@
 import unittest
 # The specific tests now live in Lib/email/test
 from email.test.test_email import suite
-from test.test_support import run_suite
+from test import test_support
 
 def test_main():
-    run_suite(suite())
+    test_support.run_unittest(suite())
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/p3yk/Lib/test/test_email_codecs.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_email_codecs.py	(original)
+++ python/branches/p3yk/Lib/test/test_email_codecs.py	Fri Apr 27 21:54:29 2007
@@ -9,7 +9,7 @@
 def test_main():
     suite = test_email_codecs.suite()
     suite.addTest(test_email_codecs_renamed.suite())
-    test_support.run_suite(suite)
+    test_support.run_unittest(suite)
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/p3yk/Lib/test/test_email_renamed.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_email_renamed.py	(original)
+++ python/branches/p3yk/Lib/test/test_email_renamed.py	Fri Apr 27 21:54:29 2007
@@ -4,10 +4,10 @@
 import unittest
 # The specific tests now live in Lib/email/test
 from email.test.test_email_renamed import suite
-from test.test_support import run_suite
+from test import test_support
 
 def test_main():
-    run_suite(suite())
+    test_support.run_unittest(suite())
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/p3yk/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_exceptions.py	(original)
+++ python/branches/p3yk/Lib/test/test_exceptions.py	Fri Apr 27 21:54:29 2007
@@ -229,6 +229,9 @@
             (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
                 {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
                  'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
+            (SyntaxError, (), {'message' : '', 'msg' : None, 'text' : None,
+                'filename' : None, 'lineno' : None, 'offset' : None,
+                'print_file_and_line' : None}),
             (SyntaxError, ('msgStr',),
                 {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
                  'print_file_and_line' : None, 'msg' : 'msgStr',
@@ -337,7 +340,7 @@
 
     def testExceptionCleanup(self):
         # Make sure "except V as N" exceptions are cleaned up properly
-        
+
         try:
             raise Exception()
         except Exception as e:

Modified: python/branches/p3yk/Lib/test/test_fileinput.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_fileinput.py	(original)
+++ python/branches/p3yk/Lib/test/test_fileinput.py	Fri Apr 27 21:54:29 2007
@@ -3,7 +3,9 @@
 Nick Mathewson
 '''
 
-from test.test_support import verify, verbose, TESTFN, TestFailed
+import unittest
+from test.test_support import verbose, TESTFN, run_unittest
+from test.test_support import unlink as safe_unlink
 import sys, os, re
 from StringIO import StringIO
 from fileinput import FileInput, hook_encoded
@@ -18,211 +20,206 @@
 def writeTmp(i, lines, mode='w'):  # opening in text mode is the default
     name = TESTFN + str(i)
     f = open(name, mode)
-    for line in lines:
-        f.write(line)
+    f.writelines(lines)
     f.close()
     return name
 
-pat = re.compile(r'LINE (\d+) OF FILE (\d+)')
-
 def remove_tempfiles(*names):
     for name in names:
-        try:
-            os.unlink(name)
-        except:
-            pass
+        safe_unlink(name)
 
-def runTests(t1, t2, t3, t4, bs=0, round=0):
-    start = 1 + round*6
-    if verbose:
-        print('%s. Simple iteration (bs=%s)' % (start+0, bs))
-    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
-    lines = list(fi)
-    fi.close()
-    verify(len(lines) == 31)
-    verify(lines[4] == 'Line 5 of file 1\n')
-    verify(lines[30] == 'Line 1 of file 4\n')
-    verify(fi.lineno() == 31)
-    verify(fi.filename() == t4)
-
-    if verbose:
-        print('%s. Status variables (bs=%s)' % (start+1, bs))
-    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
-    s = "x"
-    while s and s != 'Line 6 of file 2\n':
-        s = fi.readline()
-    verify(fi.filename() == t2)
-    verify(fi.lineno() == 21)
-    verify(fi.filelineno() == 6)
-    verify(not fi.isfirstline())
-    verify(not fi.isstdin())
-
-    if verbose:
-        print('%s. Nextfile (bs=%s)' % (start+2, bs))
-    fi.nextfile()
-    verify(fi.readline() == 'Line 1 of file 3\n')
-    verify(fi.lineno() == 22)
-    fi.close()
-
-    if verbose:
-        print('%s. Stdin (bs=%s)' % (start+3, bs))
-    fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs)
-    savestdin = sys.stdin
-    try:
-        sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n")
+class BufferSizesTests(unittest.TestCase):
+    def test_buffer_sizes(self):
+        # First, run the tests with default and teeny buffer size.
+        for round, bs in (0, 0), (1, 30):
+            try:
+                t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)])
+                t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)])
+                t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)])
+                t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)])
+                self.buffer_size_test(t1, t2, t3, t4, bs, round)
+            finally:
+                remove_tempfiles(t1, t2, t3, t4)
+
+    def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):
+        pat = re.compile(r'LINE (\d+) OF FILE (\d+)')
+
+        start = 1 + round*6
+        if verbose:
+            print('%s. Simple iteration (bs=%s)' % (start+0, bs))
+        fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
         lines = list(fi)
-        verify(len(lines) == 33)
-        verify(lines[32] == 'Line 2 of stdin\n')
-        verify(fi.filename() == '<stdin>')
+        fi.close()
+        self.assertEqual(len(lines), 31)
+        self.assertEqual(lines[4], 'Line 5 of file 1\n')
+        self.assertEqual(lines[30], 'Line 1 of file 4\n')
+        self.assertEqual(fi.lineno(), 31)
+        self.assertEqual(fi.filename(), t4)
+
+        if verbose:
+            print('%s. Status variables (bs=%s)' % (start+1, bs))
+        fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+        s = "x"
+        while s and s != 'Line 6 of file 2\n':
+            s = fi.readline()
+        self.assertEqual(fi.filename(), t2)
+        self.assertEqual(fi.lineno(), 21)
+        self.assertEqual(fi.filelineno(), 6)
+        self.failIf(fi.isfirstline())
+        self.failIf(fi.isstdin())
+
+        if verbose:
+            print('%s. Nextfile (bs=%s)' % (start+2, bs))
         fi.nextfile()
-    finally:
-        sys.stdin = savestdin
+        self.assertEqual(fi.readline(), 'Line 1 of file 3\n')
+        self.assertEqual(fi.lineno(), 22)
+        fi.close()
 
-    if verbose:
-        print('%s. Boundary conditions (bs=%s)' % (start+4, bs))
-    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
-    verify(fi.lineno() == 0)
-    verify(fi.filename() == None)
-    fi.nextfile()
-    verify(fi.lineno() == 0)
-    verify(fi.filename() == None)
-
-    if verbose:
-        print('%s. Inplace (bs=%s)' % (start+5, bs))
-    savestdout = sys.stdout
-    try:
-        fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs)
+        if verbose:
+            print('%s. Stdin (bs=%s)' % (start+3, bs))
+        fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs)
+        savestdin = sys.stdin
+        try:
+            sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n")
+            lines = list(fi)
+            self.assertEqual(len(lines), 33)
+            self.assertEqual(lines[32], 'Line 2 of stdin\n')
+            self.assertEqual(fi.filename(), '<stdin>')
+            fi.nextfile()
+        finally:
+            sys.stdin = savestdin
+
+        if verbose:
+            print('%s. Boundary conditions (bs=%s)' % (start+4, bs))
+        fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
+        self.assertEqual(fi.lineno(), 0)
+        self.assertEqual(fi.filename(), None)
+        fi.nextfile()
+        self.assertEqual(fi.lineno(), 0)
+        self.assertEqual(fi.filename(), None)
+
+        if verbose:
+            print('%s. Inplace (bs=%s)' % (start+5, bs))
+        savestdout = sys.stdout
+        try:
+            fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs)
+            for line in fi:
+                line = line[:-1].upper()
+                print(line)
+            fi.close()
+        finally:
+            sys.stdout = savestdout
+
+        fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
         for line in fi:
-            line = line[:-1].upper()
-            print(line)
+            self.assertEqual(line[-1], '\n')
+            m = pat.match(line[:-1])
+            self.assertNotEqual(m, None)
+            self.assertEqual(int(m.group(1)), fi.filelineno())
         fi.close()
-    finally:
-        sys.stdout = savestdout
 
-    fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
-    for line in fi:
-        verify(line[-1] == '\n')
-        m = pat.match(line[:-1])
-        verify(m != None)
-        verify(int(m.group(1)) == fi.filelineno())
-    fi.close()
-
-
-def writeFiles():
-    global t1, t2, t3, t4
-    t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)])
-    t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)])
-    t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)])
-    t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)])
-
-# First, run the tests with default and teeny buffer size.
-for round, bs in (0, 0), (1, 30):
-    try:
-        writeFiles()
-        runTests(t1, t2, t3, t4, bs, round)
-    finally:
-        remove_tempfiles(t1, t2, t3, t4)
-
-# Next, check for proper behavior with 0-byte files.
-if verbose:
-    print("13. 0-byte files")
-try:
-    t1 = writeTmp(1, [""])
-    t2 = writeTmp(2, [""])
-    t3 = writeTmp(3, ["The only line there is.\n"])
-    t4 = writeTmp(4, [""])
-    fi = FileInput(files=(t1, t2, t3, t4))
-    line = fi.readline()
-    verify(line == 'The only line there is.\n')
-    verify(fi.lineno() == 1)
-    verify(fi.filelineno() == 1)
-    verify(fi.filename() == t3)
-    line = fi.readline()
-    verify(not line)
-    verify(fi.lineno() == 1)
-    verify(fi.filelineno() == 0)
-    verify(fi.filename() == t4)
-    fi.close()
-finally:
-    remove_tempfiles(t1, t2, t3, t4)
-
-if verbose:
-    print("14. Files that don't end with newline")
-try:
-    t1 = writeTmp(1, ["A\nB\nC"])
-    t2 = writeTmp(2, ["D\nE\nF"])
-    fi = FileInput(files=(t1, t2))
-    lines = list(fi)
-    verify(lines == ["A\n", "B\n", "C", "D\n", "E\n", "F"])
-    verify(fi.filelineno() == 3)
-    verify(fi.lineno() == 6)
-finally:
-    remove_tempfiles(t1, t2)
-
-if verbose:
-    print("15. Unicode filenames")
-try:
-    t1 = writeTmp(1, ["A\nB"])
-    encoding = sys.getfilesystemencoding()
-    if encoding is None:
-        encoding = 'ascii'
-    fi = FileInput(files=unicode(t1, encoding))
-    lines = list(fi)
-    verify(lines == ["A\n", "B"])
-finally:
-    remove_tempfiles(t1)
-
-if verbose:
-    print("16. fileno()")
-try:
-    t1 = writeTmp(1, ["A\nB"])
-    t2 = writeTmp(2, ["C\nD"])
-    fi = FileInput(files=(t1, t2))
-    verify(fi.fileno() == -1)
-    line = next(fi)
-    verify(fi.fileno() != -1)
-    fi.nextfile()
-    verify(fi.fileno() == -1)
-    line = list(fi)
-    verify(fi.fileno() == -1)
-finally:
-    remove_tempfiles(t1, t2)
-
-if verbose:
-    print("17. Specify opening mode")
-try:
-    # invalid mode, should raise ValueError
-    fi = FileInput(mode="w")
-    raise TestFailed("FileInput should reject invalid mode argument")
-except ValueError:
-    pass
-try:
-    # try opening in universal newline mode
-    t1 = writeTmp(1, ["A\nB\r\nC\rD"], mode="wb")
-    fi = FileInput(files=t1, mode="U")
-    lines = list(fi)
-    verify(lines == ["A\n", "B\n", "C\n", "D"])
-finally:
-    remove_tempfiles(t1)
-
-if verbose:
-    print("18. Test file opening hook")
-try:
-    # cannot use openhook and inplace mode
-    fi = FileInput(inplace=1, openhook=lambda f,m: None)
-    raise TestFailed("FileInput should raise if both inplace "
-                     "and openhook arguments are given")
-except ValueError:
-    pass
-try:
-    fi = FileInput(openhook=1)
-    raise TestFailed("FileInput should check openhook for being callable")
-except ValueError:
-    pass
-try:
-    t1 = writeTmp(1, ["A\nB"], mode="wb")
-    fi = FileInput(files=t1, openhook=hook_encoded("rot13"))
-    lines = list(fi)
-    verify(lines == ["N\n", "O"])
-finally:
-    remove_tempfiles(t1)
+class FileInputTests(unittest.TestCase):
+    def test_zero_byte_files(self):
+        try:
+            t1 = writeTmp(1, [""])
+            t2 = writeTmp(2, [""])
+            t3 = writeTmp(3, ["The only line there is.\n"])
+            t4 = writeTmp(4, [""])
+            fi = FileInput(files=(t1, t2, t3, t4))
+
+            line = fi.readline()
+            self.assertEqual(line, 'The only line there is.\n')
+            self.assertEqual(fi.lineno(), 1)
+            self.assertEqual(fi.filelineno(), 1)
+            self.assertEqual(fi.filename(), t3)
+
+            line = fi.readline()
+            self.failIf(line)
+            self.assertEqual(fi.lineno(), 1)
+            self.assertEqual(fi.filelineno(), 0)
+            self.assertEqual(fi.filename(), t4)
+            fi.close()
+        finally:
+            remove_tempfiles(t1, t2, t3, t4)
+
+    def test_files_that_dont_end_with_newline(self):
+        try:
+            t1 = writeTmp(1, ["A\nB\nC"])
+            t2 = writeTmp(2, ["D\nE\nF"])
+            fi = FileInput(files=(t1, t2))
+            lines = list(fi)
+            self.assertEqual(lines, ["A\n", "B\n", "C", "D\n", "E\n", "F"])
+            self.assertEqual(fi.filelineno(), 3)
+            self.assertEqual(fi.lineno(), 6)
+        finally:
+            remove_tempfiles(t1, t2)
+
+    def test_unicode_filenames(self):
+        try:
+            t1 = writeTmp(1, ["A\nB"])
+            encoding = sys.getfilesystemencoding()
+            if encoding is None:
+                encoding = 'ascii'
+            fi = FileInput(files=unicode(t1, encoding))
+            lines = list(fi)
+            self.assertEqual(lines, ["A\n", "B"])
+        finally:
+            remove_tempfiles(t1)
+
+    def test_fileno(self):
+        try:
+            t1 = writeTmp(1, ["A\nB"])
+            t2 = writeTmp(2, ["C\nD"])
+            fi = FileInput(files=(t1, t2))
+            self.assertEqual(fi.fileno(), -1)
+            line =next( fi)
+            self.assertNotEqual(fi.fileno(), -1)
+            fi.nextfile()
+            self.assertEqual(fi.fileno(), -1)
+            line = list(fi)
+            self.assertEqual(fi.fileno(), -1)
+        finally:
+            remove_tempfiles(t1, t2)
+
+    def test_opening_mode(self):
+        try:
+            # invalid mode, should raise ValueError
+            fi = FileInput(mode="w")
+            self.fail("FileInput should reject invalid mode argument")
+        except ValueError:
+            pass
+        try:
+            # try opening in universal newline mode
+            t1 = writeTmp(1, ["A\nB\r\nC\rD"], mode="wb")
+            fi = FileInput(files=t1, mode="U")
+            lines = list(fi)
+            self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"])
+        finally:
+            remove_tempfiles(t1)
+
+    def test_file_opening_hook(self):
+        try:
+            # cannot use openhook and inplace mode
+            fi = FileInput(inplace=1, openhook=lambda f, m: None)
+            self.fail("FileInput should raise if both inplace "
+                             "and openhook arguments are given")
+        except ValueError:
+            pass
+        try:
+            fi = FileInput(openhook=1)
+            self.fail("FileInput should check openhook for being callable")
+        except ValueError:
+            pass
+        try:
+            t1 = writeTmp(1, ["A\nB"], mode="wb")
+            fi = FileInput(files=t1, openhook=hook_encoded("rot13"))
+            lines = list(fi)
+            self.assertEqual(lines, ["N\n", "O"])
+        finally:
+            remove_tempfiles(t1)
+
+def test_main():
+    run_unittest(BufferSizesTests, FileInputTests)
+
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_fileio.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_fileio.py	(original)
+++ python/branches/p3yk/Lib/test/test_fileio.py	Fri Apr 27 21:54:29 2007
@@ -110,13 +110,13 @@
             self.assertEquals(f.writable(), True)
             self.assertEquals(f.seekable(), True)
             f.close()
-            
+
             f = _fileio._FileIO(TESTFN, "r")
             self.assertEquals(f.readable(), True)
             self.assertEquals(f.writable(), False)
             self.assertEquals(f.seekable(), True)
             f.close()
-            
+
             f = _fileio._FileIO(TESTFN, "a+")
             self.assertEquals(f.readable(), True)
             self.assertEquals(f.writable(), True)

Modified: python/branches/p3yk/Lib/test/test_functools.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_functools.py	(original)
+++ python/branches/p3yk/Lib/test/test_functools.py	Fri Apr 27 21:54:29 2007
@@ -285,7 +285,7 @@
                     self.sofar.append(n*n)
                     n += 1
                 return self.sofar[i]
-    
+
         self.assertEqual(self.func(lambda x, y: x+y, ['a', 'b', 'c'], ''), 'abc')
         self.assertEqual(
             self.func(lambda x, y: x+y, [['a', 'c'], [], ['d', 'w']], []),
@@ -321,7 +321,7 @@
                     return i
                 else:
                     raise IndexError
-    
+
         from operator import add
         self.assertEqual(self.func(add, SequenceClass(5)), 10)
         self.assertEqual(self.func(add, SequenceClass(5), 42), 52)
@@ -333,7 +333,7 @@
         d = {"one": 1, "two": 2, "three": 3}
         self.assertEqual(self.func(add, d), "".join(d.keys()))
 
-    
+
 
 
 def test_main(verbose=None):

Modified: python/branches/p3yk/Lib/test/test_gc.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_gc.py	(original)
+++ python/branches/p3yk/Lib/test/test_gc.py	Fri Apr 27 21:54:29 2007
@@ -1,390 +1,11 @@
-from test.test_support import verify, verbose, TestFailed, vereq
+import unittest
+from test.test_support import verbose, run_unittest
 import sys
 import gc
 import weakref
 
-def expect(actual, expected, name):
-    if actual != expected:
-        raise TestFailed, "test_%s: actual %r, expected %r" % (
-            name, actual, expected)
-
-def expect_nonzero(actual, name):
-    if actual == 0:
-        raise TestFailed, "test_%s: unexpected zero" % name
-
-def run_test(name, thunk):
-    if verbose:
-        print("testing %s..." % name, end=' ')
-    thunk()
-    if verbose:
-        print("ok")
-
-def test_list():
-    l = []
-    l.append(l)
-    gc.collect()
-    del l
-    expect(gc.collect(), 1, "list")
-
-def test_dict():
-    d = {}
-    d[1] = d
-    gc.collect()
-    del d
-    expect(gc.collect(), 1, "dict")
-
-def test_tuple():
-    # since tuples are immutable we close the loop with a list
-    l = []
-    t = (l,)
-    l.append(t)
-    gc.collect()
-    del t
-    del l
-    expect(gc.collect(), 2, "tuple")
-
-def test_class():
-    class A:
-        pass
-    A.a = A
-    gc.collect()
-    del A
-    expect_nonzero(gc.collect(), "class")
-
-def test_newstyleclass():
-    class A(object):
-        pass
-    gc.collect()
-    del A
-    expect_nonzero(gc.collect(), "staticclass")
-
-def test_instance():
-    class A:
-        pass
-    a = A()
-    a.a = a
-    gc.collect()
-    del a
-    expect_nonzero(gc.collect(), "instance")
-
-def test_newinstance():
-    class A(object):
-        pass
-    a = A()
-    a.a = a
-    gc.collect()
-    del a
-    expect_nonzero(gc.collect(), "newinstance")
-    class B(list):
-        pass
-    class C(B, A):
-        pass
-    a = C()
-    a.a = a
-    gc.collect()
-    del a
-    expect_nonzero(gc.collect(), "newinstance(2)")
-    del B, C
-    expect_nonzero(gc.collect(), "newinstance(3)")
-    A.a = A()
-    del A
-    expect_nonzero(gc.collect(), "newinstance(4)")
-    expect(gc.collect(), 0, "newinstance(5)")
-
-def test_method():
-    # Tricky: self.__init__ is a bound method, it references the instance.
-    class A:
-        def __init__(self):
-            self.init = self.__init__
-    a = A()
-    gc.collect()
-    del a
-    expect_nonzero(gc.collect(), "method")
-
-def test_finalizer():
-    # A() is uncollectable if it is part of a cycle, make sure it shows up
-    # in gc.garbage.
-    class A:
-        def __del__(self): pass
-    class B:
-        pass
-    a = A()
-    a.a = a
-    id_a = id(a)
-    b = B()
-    b.b = b
-    gc.collect()
-    del a
-    del b
-    expect_nonzero(gc.collect(), "finalizer")
-    for obj in gc.garbage:
-        if id(obj) == id_a:
-            del obj.a
-            break
-    else:
-        raise TestFailed, "didn't find obj in garbage (finalizer)"
-    gc.garbage.remove(obj)
-
-def test_finalizer_newclass():
-    # A() is uncollectable if it is part of a cycle, make sure it shows up
-    # in gc.garbage.
-    class A(object):
-        def __del__(self): pass
-    class B(object):
-        pass
-    a = A()
-    a.a = a
-    id_a = id(a)
-    b = B()
-    b.b = b
-    gc.collect()
-    del a
-    del b
-    expect_nonzero(gc.collect(), "finalizer")
-    for obj in gc.garbage:
-        if id(obj) == id_a:
-            del obj.a
-            break
-    else:
-        raise TestFailed, "didn't find obj in garbage (finalizer)"
-    gc.garbage.remove(obj)
-
-def test_function():
-    # Tricky: f -> d -> f, code should call d.clear() after the exec to
-    # break the cycle.
-    d = {}
-    exec("def f(): pass\n", d)
-    gc.collect()
-    del d
-    expect(gc.collect(), 2, "function")
-
-def test_frame():
-    def f():
-        frame = sys._getframe()
-    gc.collect()
-    f()
-    expect(gc.collect(), 1, "frame")
-
-
-def test_saveall():
-    # Verify that cyclic garbage like lists show up in gc.garbage if the
-    # SAVEALL option is enabled.
-
-    # First make sure we don't save away other stuff that just happens to
-    # be waiting for collection.
-    gc.collect()
-    vereq(gc.garbage, []) # if this fails, someone else created immortal trash
-
-    L = []
-    L.append(L)
-    id_L = id(L)
-
-    debug = gc.get_debug()
-    gc.set_debug(debug | gc.DEBUG_SAVEALL)
-    del L
-    gc.collect()
-    gc.set_debug(debug)
-
-    vereq(len(gc.garbage), 1)
-    obj = gc.garbage.pop()
-    vereq(id(obj), id_L)
-
-def test_del():
-    # __del__ methods can trigger collection, make this to happen
-    thresholds = gc.get_threshold()
-    gc.enable()
-    gc.set_threshold(1)
-
-    class A:
-        def __del__(self):
-            dir(self)
-    a = A()
-    del a
-
-    gc.disable()
-    gc.set_threshold(*thresholds)
-
-def test_del_newclass():
-    # __del__ methods can trigger collection, make this to happen
-    thresholds = gc.get_threshold()
-    gc.enable()
-    gc.set_threshold(1)
-
-    class A(object):
-        def __del__(self):
-            dir(self)
-    a = A()
-    del a
-
-    gc.disable()
-    gc.set_threshold(*thresholds)
-
-def test_get_count():
-    gc.collect()
-    expect(gc.get_count(), (0, 0, 0), "get_count()")
-    a = dict()
-    expect(gc.get_count(), (1, 0, 0), "get_count()")
-
-def test_collect_generations():
-    gc.collect()
-    a = dict()
-    gc.collect(0)
-    expect(gc.get_count(), (0, 1, 0), "collect(0)")
-    gc.collect(1)
-    expect(gc.get_count(), (0, 0, 1), "collect(1)")
-    gc.collect(2)
-    expect(gc.get_count(), (0, 0, 0), "collect(1)")
-
-class Ouch:
-    n = 0
-    def __del__(self):
-        Ouch.n = Ouch.n + 1
-        if Ouch.n % 17 == 0:
-            gc.collect()
-
-def test_trashcan():
-    # "trashcan" is a hack to prevent stack overflow when deallocating
-    # very deeply nested tuples etc.  It works in part by abusing the
-    # type pointer and refcount fields, and that can yield horrible
-    # problems when gc tries to traverse the structures.
-    # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
-    # most likely die via segfault.
-
-    # Note:  In 2.3 the possibility for compiling without cyclic gc was
-    # removed, and that in turn allows the trashcan mechanism to work
-    # via much simpler means (e.g., it never abuses the type pointer or
-    # refcount fields anymore).  Since it's much less likely to cause a
-    # problem now, the various constants in this expensive (we force a lot
-    # of full collections) test are cut back from the 2.2 version.
-    gc.enable()
-    N = 150
-    for count in range(2):
-        t = []
-        for i in range(N):
-            t = [t, Ouch()]
-        u = []
-        for i in range(N):
-            u = [u, Ouch()]
-        v = {}
-        for i in range(N):
-            v = {1: v, 2: Ouch()}
-    gc.disable()
-
-class Boom:
-    def __getattr__(self, someattribute):
-        del self.attr
-        raise AttributeError
-
-def test_boom():
-    a = Boom()
-    b = Boom()
-    a.attr = b
-    b.attr = a
-
-    gc.collect()
-    garbagelen = len(gc.garbage)
-    del a, b
-    # a<->b are in a trash cycle now.  Collection will invoke Boom.__getattr__
-    # (to see whether a and b have __del__ methods), and __getattr__ deletes
-    # the internal "attr" attributes as a side effect.  That causes the
-    # trash cycle to get reclaimed via refcounts falling to 0, thus mutating
-    # the trash graph as a side effect of merely asking whether __del__
-    # exists.  This used to (before 2.3b1) crash Python.  Now __getattr__
-    # isn't called.
-    expect(gc.collect(), 4, "boom")
-    expect(len(gc.garbage), garbagelen, "boom")
-
-class Boom2:
-    def __init__(self):
-        self.x = 0
-
-    def __getattr__(self, someattribute):
-        self.x += 1
-        if self.x > 1:
-            del self.attr
-        raise AttributeError
-
-def test_boom2():
-    a = Boom2()
-    b = Boom2()
-    a.attr = b
-    b.attr = a
-
-    gc.collect()
-    garbagelen = len(gc.garbage)
-    del a, b
-    # Much like test_boom(), except that __getattr__ doesn't break the
-    # cycle until the second time gc checks for __del__.  As of 2.3b1,
-    # there isn't a second time, so this simply cleans up the trash cycle.
-    # We expect a, b, a.__dict__ and b.__dict__ (4 objects) to get reclaimed
-    # this way.
-    expect(gc.collect(), 4, "boom2")
-    expect(len(gc.garbage), garbagelen, "boom2")
-
-# boom__new and boom2_new are exactly like boom and boom2, except use
-# new-style classes.
-
-class Boom_New(object):
-    def __getattr__(self, someattribute):
-        del self.attr
-        raise AttributeError
-
-def test_boom_new():
-    a = Boom_New()
-    b = Boom_New()
-    a.attr = b
-    b.attr = a
-
-    gc.collect()
-    garbagelen = len(gc.garbage)
-    del a, b
-    expect(gc.collect(), 4, "boom_new")
-    expect(len(gc.garbage), garbagelen, "boom_new")
-
-class Boom2_New(object):
-    def __init__(self):
-        self.x = 0
-
-    def __getattr__(self, someattribute):
-        self.x += 1
-        if self.x > 1:
-            del self.attr
-        raise AttributeError
-
-def test_boom2_new():
-    a = Boom2_New()
-    b = Boom2_New()
-    a.attr = b
-    b.attr = a
-
-    gc.collect()
-    garbagelen = len(gc.garbage)
-    del a, b
-    expect(gc.collect(), 4, "boom2_new")
-    expect(len(gc.garbage), garbagelen, "boom2_new")
-
-def test_get_referents():
-    alist = [1, 3, 5]
-    got = gc.get_referents(alist)
-    got.sort()
-    expect(got, alist, "get_referents")
-
-    atuple = tuple(alist)
-    got = gc.get_referents(atuple)
-    got.sort()
-    expect(got, alist, "get_referents")
-
-    adict = {1: 3, 5: 7}
-    expected = [1, 3, 5, 7]
-    got = gc.get_referents(adict)
-    got.sort()
-    expect(got, expected, "get_referents")
-
-    got = gc.get_referents([1, 2], {3: 4}, (0, 0, 0))
-    got.sort()
-    expect(got, [0, 0] + range(5), "get_referents")
-
-    expect(gc.get_referents(1, 'a', 4j), [], "get_referents")
+### Support code
+###############################################################################
 
 # Bug 1055820 has several tests of longstanding bugs involving weakrefs and
 # cyclic gc.
@@ -410,217 +31,556 @@
         # gc collects it.
         self.wr = weakref.ref(C1055820(666), it_happened)
 
-def test_bug1055820b():
-    # Corresponds to temp2b.py in the bug report.
 
-    ouch = []
-    def callback(ignored):
-        ouch[:] = [wr() for wr in WRs]
-
-    Cs = [C1055820(i) for i in range(2)]
-    WRs = [weakref.ref(c, callback) for c in Cs]
-    c = None
-
-    gc.collect()
-    expect(len(ouch), 0, "bug1055820b")
-    # Make the two instances trash, and collect again.  The bug was that
-    # the callback materialized a strong reference to an instance, but gc
-    # cleared the instance's dict anyway.
-    Cs = None
-    gc.collect()
-    expect(len(ouch), 2, "bug1055820b")  # else the callbacks didn't run
-    for x in ouch:
-        # If the callback resurrected one of these guys, the instance
-        # would be damaged, with an empty __dict__.
-        expect(x, None, "bug1055820b")
-
-def test_bug1055820c():
-    # Corresponds to temp2c.py in the bug report.  This is pretty elaborate.
-
-    c0 = C1055820(0)
-    # Move c0 into generation 2.
-    gc.collect()
-
-    c1 = C1055820(1)
-    c1.keep_c0_alive = c0
-    del c0.loop # now only c1 keeps c0 alive
-
-    c2 = C1055820(2)
-    c2wr = weakref.ref(c2) # no callback!
-
-    ouch = []
-    def callback(ignored):
-        ouch[:] = [c2wr()]
-
-    # The callback gets associated with a wr on an object in generation 2.
-    c0wr = weakref.ref(c0, callback)
-
-    c0 = c1 = c2 = None
-
-    # What we've set up:  c0, c1, and c2 are all trash now.  c0 is in
-    # generation 2.  The only thing keeping it alive is that c1 points to it.
-    # c1 and c2 are in generation 0, and are in self-loops.  There's a global
-    # weakref to c2 (c2wr), but that weakref has no callback.  There's also
-    # a global weakref to c0 (c0wr), and that does have a callback, and that
-    # callback references c2 via c2wr().
-    #
-    #               c0 has a wr with callback, which references c2wr
-    #               ^
-    #               |
-    #               |     Generation 2 above dots
-    #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
-    #               |     Generation 0 below dots
-    #               |
-    #               |
-    #            ^->c1   ^->c2 has a wr but no callback
-    #            |  |    |  |
-    #            <--v    <--v
-    #
-    # So this is the nightmare:  when generation 0 gets collected, we see that
-    # c2 has a callback-free weakref, and c1 doesn't even have a weakref.
-    # Collecting generation 0 doesn't see c0 at all, and c0 is the only object
-    # that has a weakref with a callback.  gc clears c1 and c2.  Clearing c1
-    # has the side effect of dropping the refcount on c0 to 0, so c0 goes
-    # away (despite that it's in an older generation) and c0's wr callback
-    # triggers.  That in turn materializes a reference to c2 via c2wr(), but
-    # c2 gets cleared anyway by gc.
-
-    # We want to let gc happen "naturally", to preserve the distinction
-    # between generations.
-    junk = []
-    i = 0
-    detector = GC_Detector()
-    while not detector.gc_happened:
-        i += 1
-        if i > 10000:
-            raise TestFailed("gc didn't happen after 10000 iterations")
-        expect(len(ouch), 0, "bug1055820c")
-        junk.append([])  # this will eventually trigger gc
-
-    expect(len(ouch), 1, "bug1055820c")  # else the callback wasn't invoked
-    for x in ouch:
-        # If the callback resurrected c2, the instance would be damaged,
-        # with an empty __dict__.
-        expect(x, None, "bug1055820c")
-
-def test_bug1055820d():
-    # Corresponds to temp2d.py in the bug report.  This is very much like
-    # test_bug1055820c, but uses a __del__ method instead of a weakref
-    # callback to sneak in a resurrection of cyclic trash.
-
-    ouch = []
-    class D(C1055820):
-        def __del__(self):
-            ouch[:] = [c2wr()]
+### Tests
+###############################################################################
 
-    d0 = D(0)
-    # Move all the above into generation 2.
-    gc.collect()
-
-    c1 = C1055820(1)
-    c1.keep_d0_alive = d0
-    del d0.loop # now only c1 keeps d0 alive
-
-    c2 = C1055820(2)
-    c2wr = weakref.ref(c2) # no callback!
-
-    d0 = c1 = c2 = None
-
-    # What we've set up:  d0, c1, and c2 are all trash now.  d0 is in
-    # generation 2.  The only thing keeping it alive is that c1 points to it.
-    # c1 and c2 are in generation 0, and are in self-loops.  There's a global
-    # weakref to c2 (c2wr), but that weakref has no callback.  There are no
-    # other weakrefs.
-    #
-    #               d0 has a __del__ method that references c2wr
-    #               ^
-    #               |
-    #               |     Generation 2 above dots
-    #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
-    #               |     Generation 0 below dots
-    #               |
-    #               |
-    #            ^->c1   ^->c2 has a wr but no callback
-    #            |  |    |  |
-    #            <--v    <--v
-    #
-    # So this is the nightmare:  when generation 0 gets collected, we see that
-    # c2 has a callback-free weakref, and c1 doesn't even have a weakref.
-    # Collecting generation 0 doesn't see d0 at all.  gc clears c1 and c2.
-    # Clearing c1 has the side effect of dropping the refcount on d0 to 0, so
-    # d0 goes away (despite that it's in an older generation) and d0's __del__
-    # triggers.  That in turn materializes a reference to c2 via c2wr(), but
-    # c2 gets cleared anyway by gc.
-
-    # We want to let gc happen "naturally", to preserve the distinction
-    # between generations.
-    detector = GC_Detector()
-    junk = []
-    i = 0
-    while not detector.gc_happened:
-        i += 1
-        if i > 10000:
-            raise TestFailed("gc didn't happen after 10000 iterations")
-        expect(len(ouch), 0, "bug1055820d")
-        junk.append([])  # this will eventually trigger gc
-
-    expect(len(ouch), 1, "bug1055820d")  # else __del__ wasn't invoked
-    for x in ouch:
-        # If __del__ resurrected c2, the instance would be damaged, with an
-        # empty __dict__.
-        expect(x, None, "bug1055820d")
-
-
-def test_all():
-    gc.collect() # Delete 2nd generation garbage
-    run_test("lists", test_list)
-    run_test("dicts", test_dict)
-    run_test("tuples", test_tuple)
-    run_test("classes", test_class)
-    run_test("new style classes", test_newstyleclass)
-    run_test("instances", test_instance)
-    run_test("new instances", test_newinstance)
-    run_test("methods", test_method)
-    run_test("functions", test_function)
-    run_test("frames", test_frame)
-    run_test("finalizers", test_finalizer)
-    run_test("finalizers (new class)", test_finalizer_newclass)
-    run_test("__del__", test_del)
-    run_test("__del__ (new class)", test_del_newclass)
-    run_test("get_count()", test_get_count)
-    run_test("collect(n)", test_collect_generations)
-    run_test("saveall", test_saveall)
-    run_test("trashcan", test_trashcan)
-    run_test("boom", test_boom)
-    run_test("boom2", test_boom2)
-    run_test("boom_new", test_boom_new)
-    run_test("boom2_new", test_boom2_new)
-    run_test("get_referents", test_get_referents)
-    run_test("bug1055820b", test_bug1055820b)
+class GCTests(unittest.TestCase):
+    def test_list(self):
+        l = []
+        l.append(l)
+        gc.collect()
+        del l
+        self.assertEqual(gc.collect(), 1)
+
+    def test_dict(self):
+        d = {}
+        d[1] = d
+        gc.collect()
+        del d
+        self.assertEqual(gc.collect(), 1)
+
+    def test_tuple(self):
+        # since tuples are immutable we close the loop with a list
+        l = []
+        t = (l,)
+        l.append(t)
+        gc.collect()
+        del t
+        del l
+        self.assertEqual(gc.collect(), 2)
+
+    def test_class(self):
+        class A:
+            pass
+        A.a = A
+        gc.collect()
+        del A
+        self.assertNotEqual(gc.collect(), 0)
+
+    def test_newstyleclass(self):
+        class A(object):
+            pass
+        gc.collect()
+        del A
+        self.assertNotEqual(gc.collect(), 0)
+
+    def test_instance(self):
+        class A:
+            pass
+        a = A()
+        a.a = a
+        gc.collect()
+        del a
+        self.assertNotEqual(gc.collect(), 0)
+
+    def test_newinstance(self):
+        class A(object):
+            pass
+        a = A()
+        a.a = a
+        gc.collect()
+        del a
+        self.assertNotEqual(gc.collect(), 0)
+        class B(list):
+            pass
+        class C(B, A):
+            pass
+        a = C()
+        a.a = a
+        gc.collect()
+        del a
+        self.assertNotEqual(gc.collect(), 0)
+        del B, C
+        self.assertNotEqual(gc.collect(), 0)
+        A.a = A()
+        del A
+        self.assertNotEqual(gc.collect(), 0)
+        self.assertEqual(gc.collect(), 0)
+
+    def test_method(self):
+        # Tricky: self.__init__ is a bound method, it references the instance.
+        class A:
+            def __init__(self):
+                self.init = self.__init__
+        a = A()
+        gc.collect()
+        del a
+        self.assertNotEqual(gc.collect(), 0)
+
+    def test_finalizer(self):
+        # A() is uncollectable if it is part of a cycle, make sure it shows up
+        # in gc.garbage.
+        class A:
+            def __del__(self): pass
+        class B:
+            pass
+        a = A()
+        a.a = a
+        id_a = id(a)
+        b = B()
+        b.b = b
+        gc.collect()
+        del a
+        del b
+        self.assertNotEqual(gc.collect(), 0)
+        for obj in gc.garbage:
+            if id(obj) == id_a:
+                del obj.a
+                break
+        else:
+            self.fail("didn't find obj in garbage (finalizer)")
+        gc.garbage.remove(obj)
+
+    def test_finalizer_newclass(self):
+        # A() is uncollectable if it is part of a cycle, make sure it shows up
+        # in gc.garbage.
+        class A(object):
+            def __del__(self): pass
+        class B(object):
+            pass
+        a = A()
+        a.a = a
+        id_a = id(a)
+        b = B()
+        b.b = b
+        gc.collect()
+        del a
+        del b
+        self.assertNotEqual(gc.collect(), 0)
+        for obj in gc.garbage:
+            if id(obj) == id_a:
+                del obj.a
+                break
+        else:
+            self.fail("didn't find obj in garbage (finalizer)")
+        gc.garbage.remove(obj)
+
+    def test_function(self):
+        # Tricky: f -> d -> f, code should call d.clear() after the exec to
+        # break the cycle.
+        d = {}
+        exec("def f(): pass\n", d)
+        gc.collect()
+        del d
+        self.assertEqual(gc.collect(), 2)
+
+    def test_frame(self):
+        def f():
+            frame = sys._getframe()
+        gc.collect()
+        f()
+        self.assertEqual(gc.collect(), 1)
+
+    def test_saveall(self):
+        # Verify that cyclic garbage like lists show up in gc.garbage if the
+        # SAVEALL option is enabled.
+
+        # First make sure we don't save away other stuff that just happens to
+        # be waiting for collection.
+        gc.collect()
+        # if this fails, someone else created immortal trash
+        self.assertEqual(gc.garbage, [])
+
+        L = []
+        L.append(L)
+        id_L = id(L)
+
+        debug = gc.get_debug()
+        gc.set_debug(debug | gc.DEBUG_SAVEALL)
+        del L
+        gc.collect()
+        gc.set_debug(debug)
+
+        self.assertEqual(len(gc.garbage), 1)
+        obj = gc.garbage.pop()
+        self.assertEqual(id(obj), id_L)
+
+    def test_del(self):
+        # __del__ methods can trigger collection, make this to happen
+        thresholds = gc.get_threshold()
+        gc.enable()
+        gc.set_threshold(1)
+
+        class A:
+            def __del__(self):
+                dir(self)
+        a = A()
+        del a
 
-    gc.enable()
-    try:
-        run_test("bug1055820c", test_bug1055820c)
-    finally:
         gc.disable()
+        gc.set_threshold(*thresholds)
 
-    gc.enable()
-    try:
-        run_test("bug1055820d", test_bug1055820d)
-    finally:
+    def test_del_newclass(self):
+        # __del__ methods can trigger collection, make this to happen
+        thresholds = gc.get_threshold()
+        gc.enable()
+        gc.set_threshold(1)
+
+        class A(object):
+            def __del__(self):
+                dir(self)
+        a = A()
+        del a
+
+        gc.disable()
+        gc.set_threshold(*thresholds)
+
+    def test_get_count(self):
+        gc.collect()
+        self.assertEqual(gc.get_count(), (0, 0, 0))
+        a = dict()
+        self.assertEqual(gc.get_count(), (1, 0, 0))
+
+    def test_collect_generations(self):
+        gc.collect()
+        a = dict()
+        gc.collect(0)
+        self.assertEqual(gc.get_count(), (0, 1, 0))
+        gc.collect(1)
+        self.assertEqual(gc.get_count(), (0, 0, 1))
+        gc.collect(2)
+        self.assertEqual(gc.get_count(), (0, 0, 0))
+
+    def test_trashcan(self):
+        class Ouch:
+            n = 0
+            def __del__(self):
+                Ouch.n = Ouch.n + 1
+                if Ouch.n % 17 == 0:
+                    gc.collect()
+
+        # "trashcan" is a hack to prevent stack overflow when deallocating
+        # very deeply nested tuples etc.  It works in part by abusing the
+        # type pointer and refcount fields, and that can yield horrible
+        # problems when gc tries to traverse the structures.
+        # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
+        # most likely die via segfault.
+
+        # Note:  In 2.3 the possibility for compiling without cyclic gc was
+        # removed, and that in turn allows the trashcan mechanism to work
+        # via much simpler means (e.g., it never abuses the type pointer or
+        # refcount fields anymore).  Since it's much less likely to cause a
+        # problem now, the various constants in this expensive (we force a lot
+        # of full collections) test are cut back from the 2.2 version.
+        gc.enable()
+        N = 150
+        for count in range(2):
+            t = []
+            for i in range(N):
+                t = [t, Ouch()]
+            u = []
+            for i in range(N):
+                u = [u, Ouch()]
+            v = {}
+            for i in range(N):
+                v = {1: v, 2: Ouch()}
+        gc.disable()
+
+    def test_boom(self):
+        class Boom:
+            def __getattr__(self, someattribute):
+                del self.attr
+                raise AttributeError
+
+        a = Boom()
+        b = Boom()
+        a.attr = b
+        b.attr = a
+
+        gc.collect()
+        garbagelen = len(gc.garbage)
+        del a, b
+        # a<->b are in a trash cycle now.  Collection will invoke
+        # Boom.__getattr__ (to see whether a and b have __del__ methods), and
+        # __getattr__ deletes the internal "attr" attributes as a side effect.
+        # That causes the trash cycle to get reclaimed via refcounts falling to
+        # 0, thus mutating the trash graph as a side effect of merely asking
+        # whether __del__ exists.  This used to (before 2.3b1) crash Python.
+        # Now __getattr__ isn't called.
+        self.assertEqual(gc.collect(), 4)
+        self.assertEqual(len(gc.garbage), garbagelen)
+
+    def test_boom2(self):
+        class Boom2:
+            def __init__(self):
+                self.x = 0
+
+            def __getattr__(self, someattribute):
+                self.x += 1
+                if self.x > 1:
+                    del self.attr
+                raise AttributeError
+
+        a = Boom2()
+        b = Boom2()
+        a.attr = b
+        b.attr = a
+
+        gc.collect()
+        garbagelen = len(gc.garbage)
+        del a, b
+        # Much like test_boom(), except that __getattr__ doesn't break the
+        # cycle until the second time gc checks for __del__.  As of 2.3b1,
+        # there isn't a second time, so this simply cleans up the trash cycle.
+        # We expect a, b, a.__dict__ and b.__dict__ (4 objects) to get
+        # reclaimed this way.
+        self.assertEqual(gc.collect(), 4)
+        self.assertEqual(len(gc.garbage), garbagelen)
+
+    def test_boom_new(self):
+        # boom__new and boom2_new are exactly like boom and boom2, except use
+        # new-style classes.
+
+        class Boom_New(object):
+            def __getattr__(self, someattribute):
+                del self.attr
+                raise AttributeError
+
+        a = Boom_New()
+        b = Boom_New()
+        a.attr = b
+        b.attr = a
+
+        gc.collect()
+        garbagelen = len(gc.garbage)
+        del a, b
+        self.assertEqual(gc.collect(), 4)
+        self.assertEqual(len(gc.garbage), garbagelen)
+
+    def test_boom2_new(self):
+        class Boom2_New(object):
+            def __init__(self):
+                self.x = 0
+
+            def __getattr__(self, someattribute):
+                self.x += 1
+                if self.x > 1:
+                    del self.attr
+                raise AttributeError
+
+        a = Boom2_New()
+        b = Boom2_New()
+        a.attr = b
+        b.attr = a
+
+        gc.collect()
+        garbagelen = len(gc.garbage)
+        del a, b
+        self.assertEqual(gc.collect(), 4)
+        self.assertEqual(len(gc.garbage), garbagelen)
+
+    def test_get_referents(self):
+        alist = [1, 3, 5]
+        got = gc.get_referents(alist)
+        got.sort()
+        self.assertEqual(got, alist)
+
+        atuple = tuple(alist)
+        got = gc.get_referents(atuple)
+        got.sort()
+        self.assertEqual(got, alist)
+
+        adict = {1: 3, 5: 7}
+        expected = [1, 3, 5, 7]
+        got = gc.get_referents(adict)
+        got.sort()
+        self.assertEqual(got, expected)
+
+        got = gc.get_referents([1, 2], {3: 4}, (0, 0, 0))
+        got.sort()
+        self.assertEqual(got, [0, 0] + range(5))
+
+        self.assertEqual(gc.get_referents(1, 'a', 4j), [])
+
+    def test_bug1055820b(self):
+        # Corresponds to temp2b.py in the bug report.
+
+        ouch = []
+        def callback(ignored):
+            ouch[:] = [wr() for wr in WRs]
+
+        Cs = [C1055820(i) for i in range(2)]
+        WRs = [weakref.ref(c, callback) for c in Cs]
+        c = None
+
+        gc.collect()
+        self.assertEqual(len(ouch), 0)
+        # Make the two instances trash, and collect again.  The bug was that
+        # the callback materialized a strong reference to an instance, but gc
+        # cleared the instance's dict anyway.
+        Cs = None
+        gc.collect()
+        self.assertEqual(len(ouch), 2)  # else the callbacks didn't run
+        for x in ouch:
+            # If the callback resurrected one of these guys, the instance
+            # would be damaged, with an empty __dict__.
+            self.assertEqual(x, None)
+
+class GCTogglingTests(unittest.TestCase):
+    def setUp(self):
+        gc.enable()
+
+    def tearDown(self):
         gc.disable()
 
-def test():
-    if verbose:
-        print("disabling automatic collection")
+    def test_bug1055820c(self):
+        # Corresponds to temp2c.py in the bug report.  This is pretty
+        # elaborate.
+
+        c0 = C1055820(0)
+        # Move c0 into generation 2.
+        gc.collect()
+
+        c1 = C1055820(1)
+        c1.keep_c0_alive = c0
+        del c0.loop # now only c1 keeps c0 alive
+
+        c2 = C1055820(2)
+        c2wr = weakref.ref(c2) # no callback!
+
+        ouch = []
+        def callback(ignored):
+            ouch[:] = [c2wr()]
+
+        # The callback gets associated with a wr on an object in generation 2.
+        c0wr = weakref.ref(c0, callback)
+
+        c0 = c1 = c2 = None
+
+        # What we've set up:  c0, c1, and c2 are all trash now.  c0 is in
+        # generation 2.  The only thing keeping it alive is that c1 points to
+        # it. c1 and c2 are in generation 0, and are in self-loops.  There's a
+        # global weakref to c2 (c2wr), but that weakref has no callback.
+        # There's also a global weakref to c0 (c0wr), and that does have a
+        # callback, and that callback references c2 via c2wr().
+        #
+        #               c0 has a wr with callback, which references c2wr
+        #               ^
+        #               |
+        #               |     Generation 2 above dots
+        #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
+        #               |     Generation 0 below dots
+        #               |
+        #               |
+        #            ^->c1   ^->c2 has a wr but no callback
+        #            |  |    |  |
+        #            <--v    <--v
+        #
+        # So this is the nightmare:  when generation 0 gets collected, we see
+        # that c2 has a callback-free weakref, and c1 doesn't even have a
+        # weakref.  Collecting generation 0 doesn't see c0 at all, and c0 is
+        # the only object that has a weakref with a callback.  gc clears c1
+        # and c2.  Clearing c1 has the side effect of dropping the refcount on
+        # c0 to 0, so c0 goes away (despite that it's in an older generation)
+        # and c0's wr callback triggers.  That in turn materializes a reference
+        # to c2 via c2wr(), but c2 gets cleared anyway by gc.
+
+        # We want to let gc happen "naturally", to preserve the distinction
+        # between generations.
+        junk = []
+        i = 0
+        detector = GC_Detector()
+        while not detector.gc_happened:
+            i += 1
+            if i > 10000:
+                self.fail("gc didn't happen after 10000 iterations")
+            self.assertEqual(len(ouch), 0)
+            junk.append([])  # this will eventually trigger gc
+
+        self.assertEqual(len(ouch), 1)  # else the callback wasn't invoked
+        for x in ouch:
+            # If the callback resurrected c2, the instance would be damaged,
+            # with an empty __dict__.
+            self.assertEqual(x, None)
+
+    def test_bug1055820d(self):
+        # Corresponds to temp2d.py in the bug report.  This is very much like
+        # test_bug1055820c, but uses a __del__ method instead of a weakref
+        # callback to sneak in a resurrection of cyclic trash.
+
+        ouch = []
+        class D(C1055820):
+            def __del__(self):
+                ouch[:] = [c2wr()]
+
+        d0 = D(0)
+        # Move all the above into generation 2.
+        gc.collect()
+
+        c1 = C1055820(1)
+        c1.keep_d0_alive = d0
+        del d0.loop # now only c1 keeps d0 alive
+
+        c2 = C1055820(2)
+        c2wr = weakref.ref(c2) # no callback!
+
+        d0 = c1 = c2 = None
+
+        # What we've set up:  d0, c1, and c2 are all trash now.  d0 is in
+        # generation 2.  The only thing keeping it alive is that c1 points to
+        # it.  c1 and c2 are in generation 0, and are in self-loops.  There's
+        # a global weakref to c2 (c2wr), but that weakref has no callback.
+        # There are no other weakrefs.
+        #
+        #               d0 has a __del__ method that references c2wr
+        #               ^
+        #               |
+        #               |     Generation 2 above dots
+        #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
+        #               |     Generation 0 below dots
+        #               |
+        #               |
+        #            ^->c1   ^->c2 has a wr but no callback
+        #            |  |    |  |
+        #            <--v    <--v
+        #
+        # So this is the nightmare:  when generation 0 gets collected, we see
+        # that c2 has a callback-free weakref, and c1 doesn't even have a
+        # weakref.  Collecting generation 0 doesn't see d0 at all.  gc clears
+        # c1 and c2.  Clearing c1 has the side effect of dropping the refcount
+        # on d0 to 0, so d0 goes away (despite that it's in an older
+        # generation) and d0's __del__ triggers.  That in turn materializes
+        # a reference to c2 via c2wr(), but c2 gets cleared anyway by gc.
+
+        # We want to let gc happen "naturally", to preserve the distinction
+        # between generations.
+        detector = GC_Detector()
+        junk = []
+        i = 0
+        while not detector.gc_happened:
+            i += 1
+            if i > 10000:
+                self.fail("gc didn't happen after 10000 iterations")
+            self.assertEqual(len(ouch), 0)
+            junk.append([])  # this will eventually trigger gc
+
+        self.assertEqual(len(ouch), 1)  # else __del__ wasn't invoked
+        for x in ouch:
+            # If __del__ resurrected c2, the instance would be damaged, with an
+            # empty __dict__.
+            self.assertEqual(x, None)
+
+def test_main():
     enabled = gc.isenabled()
     gc.disable()
-    verify(not gc.isenabled())
+    assert not gc.isenabled()
     debug = gc.get_debug()
     gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
 
     try:
-        test_all()
+        gc.collect() # Delete 2nd generation garbage
+        run_unittest(GCTests, GCTogglingTests)
     finally:
         gc.set_debug(debug)
         # test gc.enable() even if GC is disabled by default
@@ -628,9 +588,9 @@
             print("restoring automatic collection")
         # make sure to always test gc.enable()
         gc.enable()
-        verify(gc.isenabled())
+        assert gc.isenabled()
         if not enabled:
             gc.disable()
 
-
-test()
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_getopt.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_getopt.py	(original)
+++ python/branches/p3yk/Lib/test/test_getopt.py	Fri Apr 27 21:54:29 2007
@@ -1,180 +1,179 @@
 # test_getopt.py
 # David Goodger <dgoodger at bigfoot.com> 2000-08-19
 
+from test.test_support import verbose, run_doctest, run_unittest
+import unittest
+
 import getopt
-from getopt import GetoptError
-from test.test_support import verify, verbose, run_doctest
 import os
 
-def expectException(teststr, expected, failure=AssertionError):
-    """Executes a statement passed in teststr, and raises an exception
-       (failure) if the expected exception is *not* raised."""
-    try:
-        exec(teststr)
-    except expected:
-        pass
-    else:
-        raise failure
-
-old_posixly_correct = os.environ.get("POSIXLY_CORRECT")
-if old_posixly_correct is not None:
-    del os.environ["POSIXLY_CORRECT"]
-
-if verbose:
-    print('Running tests on getopt.short_has_arg')
-verify(getopt.short_has_arg('a', 'a:'))
-verify(not getopt.short_has_arg('a', 'a'))
-expectException("tmp = getopt.short_has_arg('a', 'b')", GetoptError)
-expectException("tmp = getopt.short_has_arg('a', '')", GetoptError)
-
-if verbose:
-    print('Running tests on getopt.long_has_args')
-has_arg, option = getopt.long_has_args('abc', ['abc='])
-verify(has_arg)
-verify(option == 'abc')
-has_arg, option = getopt.long_has_args('abc', ['abc'])
-verify(not has_arg)
-verify(option == 'abc')
-has_arg, option = getopt.long_has_args('abc', ['abcd'])
-verify(not has_arg)
-verify(option == 'abcd')
-expectException("has_arg, option = getopt.long_has_args('abc', ['def'])",
-                GetoptError)
-expectException("has_arg, option = getopt.long_has_args('abc', [])",
-                GetoptError)
-expectException("has_arg, option = " + \
-                     "getopt.long_has_args('abc', ['abcd','abcde'])",
-                GetoptError)
-
-if verbose:
-    print('Running tests on getopt.do_shorts')
-opts, args = getopt.do_shorts([], 'a', 'a', [])
-verify(opts == [('-a', '')])
-verify(args == [])
-opts, args = getopt.do_shorts([], 'a1', 'a:', [])
-verify(opts == [('-a', '1')])
-verify(args == [])
-#opts, args = getopt.do_shorts([], 'a=1', 'a:', [])
-#verify(opts == [('-a', '1')])
-#verify(args == [])
-opts, args = getopt.do_shorts([], 'a', 'a:', ['1'])
-verify(opts == [('-a', '1')])
-verify(args == [])
-opts, args = getopt.do_shorts([], 'a', 'a:', ['1', '2'])
-verify(opts == [('-a', '1')])
-verify(args == ['2'])
-expectException("opts, args = getopt.do_shorts([], 'a1', 'a', [])",
-                GetoptError)
-expectException("opts, args = getopt.do_shorts([], 'a', 'a:', [])",
-                GetoptError)
-
-if verbose:
-    print('Running tests on getopt.do_longs')
-opts, args = getopt.do_longs([], 'abc', ['abc'], [])
-verify(opts == [('--abc', '')])
-verify(args == [])
-opts, args = getopt.do_longs([], 'abc=1', ['abc='], [])
-verify(opts == [('--abc', '1')])
-verify(args == [])
-opts, args = getopt.do_longs([], 'abc=1', ['abcd='], [])
-verify(opts == [('--abcd', '1')])
-verify(args == [])
-opts, args = getopt.do_longs([], 'abc', ['ab', 'abc', 'abcd'], [])
-verify(opts == [('--abc', '')])
-verify(args == [])
-# Much like the preceding, except with a non-alpha character ("-") in
-# option name that precedes "="; failed in
-# http://sourceforge.net/bugs/?func=detailbug&bug_id=126863&group_id=5470
-opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], [])
-verify(opts == [('--foo', '42')])
-verify(args == [])
-expectException("opts, args = getopt.do_longs([], 'abc=1', ['abc'], [])",
-                GetoptError)
-expectException("opts, args = getopt.do_longs([], 'abc', ['abc='], [])",
-                GetoptError)
-
-# note: the empty string between '-a' and '--beta' is significant:
-# it simulates an empty string option argument ('-a ""') on the command line.
-cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', '',
-           '--beta', 'arg1', 'arg2']
-
-if verbose:
-    print('Running tests on getopt.getopt')
-opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta'])
-verify(opts == [('-a', '1'), ('-b', ''), ('--alpha', '2'), ('--beta', ''),
-                ('-a', '3'), ('-a', ''), ('--beta', '')] )
-# Note ambiguity of ('-b', '') and ('-a', '') above. This must be
-# accounted for in the code that calls getopt().
-verify(args == ['arg1', 'arg2'])
-
-expectException(
-    "opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
-    GetoptError)
-
-# Test handling of GNU style scanning mode.
-if verbose:
-    print('Running tests on getopt.gnu_getopt')
-cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2']
-# GNU style
-opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
-verify(opts == [('-a', ''), ('-b', '1'), ('--alpha', ''), ('--beta', '2')])
-verify(args == ['arg1'])
-# Posix style via +
-opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
-verify(opts == [('-a', '')])
-verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
-# Posix style via POSIXLY_CORRECT
-os.environ["POSIXLY_CORRECT"] = "1"
-opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
-verify(opts == [('-a', '')])
-verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
-
-
-if old_posixly_correct is None:
-    del os.environ["POSIXLY_CORRECT"]
-else:
-    os.environ["POSIXLY_CORRECT"] = old_posixly_correct
-
-#------------------------------------------------------------------------------
-
-libreftest = """
-Examples from the Library Reference:  Doc/lib/libgetopt.tex
-
-An example using only Unix style options:
-
-
->>> import getopt
->>> args = '-a -b -cfoo -d bar a1 a2'.split()
->>> args
-['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
->>> optlist, args = getopt.getopt(args, 'abc:d:')
->>> optlist
-[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
->>> args
-['a1', 'a2']
-
-Using long option names is equally easy:
-
-
->>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
->>> args = s.split()
->>> args
-['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
->>> optlist, args = getopt.getopt(args, 'x', [
-...     'condition=', 'output-file=', 'testing'])
->>> optlist
-[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
->>> args
-['a1', 'a2']
-
-"""
-
-__test__ = {'libreftest' : libreftest}
+sentinel = object()
+
+class GetoptTests(unittest.TestCase):
+    def setUp(self):
+        self.old_posixly_correct = os.environ.get("POSIXLY_CORRECT", sentinel)
+        if self.old_posixly_correct is not sentinel:
+            del os.environ["POSIXLY_CORRECT"]
+
+    def tearDown(self):
+        if self.old_posixly_correct is sentinel:
+            os.environ.pop("POSIXLY_CORRECT", None)
+        else:
+            os.environ["POSIXLY_CORRECT"] = self.old_posixly_correct
+
+    def assertError(self, *args, **kwargs):
+        self.assertRaises(getopt.GetoptError, *args, **kwargs)
+
+    def test_short_has_arg(self):
+        self.failUnless(getopt.short_has_arg('a', 'a:'))
+        self.failIf(getopt.short_has_arg('a', 'a'))
+        self.assertError(getopt.short_has_arg, 'a', 'b')
+
+    def test_long_has_args(self):
+        has_arg, option = getopt.long_has_args('abc', ['abc='])
+        self.failUnless(has_arg)
+        self.assertEqual(option, 'abc')
+
+        has_arg, option = getopt.long_has_args('abc', ['abc'])
+        self.failIf(has_arg)
+        self.assertEqual(option, 'abc')
+
+        has_arg, option = getopt.long_has_args('abc', ['abcd'])
+        self.failIf(has_arg)
+        self.assertEqual(option, 'abcd')
+
+        self.assertError(getopt.long_has_args, 'abc', ['def'])
+        self.assertError(getopt.long_has_args, 'abc', [])
+        self.assertError(getopt.long_has_args, 'abc', ['abcd','abcde'])
+
+    def test_do_shorts(self):
+        opts, args = getopt.do_shorts([], 'a', 'a', [])
+        self.assertEqual(opts, [('-a', '')])
+        self.assertEqual(args, [])
+
+        opts, args = getopt.do_shorts([], 'a1', 'a:', [])
+        self.assertEqual(opts, [('-a', '1')])
+        self.assertEqual(args, [])
+
+        #opts, args = getopt.do_shorts([], 'a=1', 'a:', [])
+        #self.assertEqual(opts, [('-a', '1')])
+        #self.assertEqual(args, [])
+
+        opts, args = getopt.do_shorts([], 'a', 'a:', ['1'])
+        self.assertEqual(opts, [('-a', '1')])
+        self.assertEqual(args, [])
+
+        opts, args = getopt.do_shorts([], 'a', 'a:', ['1', '2'])
+        self.assertEqual(opts, [('-a', '1')])
+        self.assertEqual(args, ['2'])
+
+        self.assertError(getopt.do_shorts, [], 'a1', 'a', [])
+        self.assertError(getopt.do_shorts, [], 'a', 'a:', [])
+
+    def test_do_longs(self):
+        opts, args = getopt.do_longs([], 'abc', ['abc'], [])
+        self.assertEqual(opts, [('--abc', '')])
+        self.assertEqual(args, [])
+
+        opts, args = getopt.do_longs([], 'abc=1', ['abc='], [])
+        self.assertEqual(opts, [('--abc', '1')])
+        self.assertEqual(args, [])
+
+        opts, args = getopt.do_longs([], 'abc=1', ['abcd='], [])
+        self.assertEqual(opts, [('--abcd', '1')])
+        self.assertEqual(args, [])
+
+        opts, args = getopt.do_longs([], 'abc', ['ab', 'abc', 'abcd'], [])
+        self.assertEqual(opts, [('--abc', '')])
+        self.assertEqual(args, [])
+
+        # Much like the preceding, except with a non-alpha character ("-") in
+        # option name that precedes "="; failed in
+        # http://python.org/sf/126863
+        opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], [])
+        self.assertEqual(opts, [('--foo', '42')])
+        self.assertEqual(args, [])
+
+        self.assertError(getopt.do_longs, [], 'abc=1', ['abc'], [])
+        self.assertError(getopt.do_longs, [], 'abc', ['abc='], [])
+
+    def test_getopt(self):
+        # note: the empty string between '-a' and '--beta' is significant:
+        # it simulates an empty string option argument ('-a ""') on the
+        # command line.
+        cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a',
+                   '', '--beta', 'arg1', 'arg2']
+
+        opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta'])
+        self.assertEqual(opts, [('-a', '1'), ('-b', ''),
+                                ('--alpha', '2'), ('--beta', ''),
+                                ('-a', '3'), ('-a', ''), ('--beta', '')])
+        # Note ambiguity of ('-b', '') and ('-a', '') above. This must be
+        # accounted for in the code that calls getopt().
+        self.assertEqual(args, ['arg1', 'arg2'])
+
+        self.assertError(getopt.getopt, cmdline, 'a:b', ['alpha', 'beta'])
+
+    def test_gnu_getopt(self):
+        # Test handling of GNU style scanning mode.
+        cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2']
+
+        # GNU style
+        opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
+        self.assertEqual(args, ['arg1'])
+        self.assertEqual(opts, [('-a', ''), ('-b', '1'),
+                                ('--alpha', ''), ('--beta', '2')])
+
+        # Posix style via +
+        opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
+        self.assertEqual(opts, [('-a', '')])
+        self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2'])
+
+        # Posix style via POSIXLY_CORRECT
+        os.environ["POSIXLY_CORRECT"] = "1"
+        opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
+        self.assertEqual(opts, [('-a', '')])
+        self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2'])
+
+    def test_libref_examples(self):
+        s = """
+        Examples from the Library Reference:  Doc/lib/libgetopt.tex
+
+        An example using only Unix style options:
+
+
+        >>> import getopt
+        >>> args = '-a -b -cfoo -d bar a1 a2'.split()
+        >>> args
+        ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
+        >>> optlist, args = getopt.getopt(args, 'abc:d:')
+        >>> optlist
+        [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
+        >>> args
+        ['a1', 'a2']
+
+        Using long option names is equally easy:
+
+
+        >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
+        >>> args = s.split()
+        >>> args
+        ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
+        >>> optlist, args = getopt.getopt(args, 'x', [
+        ...     'condition=', 'output-file=', 'testing'])
+        >>> optlist
+        [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
+        >>> args
+        ['a1', 'a2']
+        """
+
+        import new
+        m = new.module("libreftest", s)
+        run_doctest(m, verbose)
 
-import sys
-run_doctest(sys.modules[__name__], verbose)
 
-#------------------------------------------------------------------------------
+def test_main():
+    run_unittest(GetoptTests)
 
-if verbose:
-    print("Module getopt: tests completed successfully.")
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_gettext.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_gettext.py	(original)
+++ python/branches/p3yk/Lib/test/test_gettext.py	Fri Apr 27 21:54:29 2007
@@ -4,7 +4,7 @@
 import gettext
 import unittest
 
-from test.test_support import run_suite
+from test import test_support
 
 
 # TODO:
@@ -336,19 +336,8 @@
            'John Doe <jdoe at example.com>\nJane Foobar <jfoobar at example.com>')
 
 
-def suite():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(GettextTestCase1))
-    suite.addTest(unittest.makeSuite(GettextTestCase2))
-    suite.addTest(unittest.makeSuite(PluralFormsTestCase))
-    suite.addTest(unittest.makeSuite(UnicodeTranslationsTest))
-    suite.addTest(unittest.makeSuite(WeirdMetadataTest))
-    return suite
-
-
 def test_main():
-    run_suite(suite())
-
+    test_support.run_unittest(__name__)
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/p3yk/Lib/test/test_glob.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_glob.py	(original)
+++ python/branches/p3yk/Lib/test/test_glob.py	Fri Apr 27 21:54:29 2007
@@ -52,6 +52,16 @@
         eq(self.glob('aab'), [self.norm('aab')])
         eq(self.glob('zymurgy'), [])
 
+        # test return types are unicode, but only if os.listdir
+        # returns unicode filenames
+        uniset = set([unicode])
+        tmp = os.listdir(u'.')
+        if set(type(x) for x in tmp) == uniset:
+            u1 = glob.glob(u'*')
+            u2 = glob.glob(u'./*')
+            self.assertEquals(set(type(r) for r in u1), uniset)
+            self.assertEquals(set(type(r) for r in u2), uniset)
+
     def test_glob_one_directory(self):
         eq = self.assertSequencesEqual_noorder
         eq(self.glob('a*'), map(self.norm, ['a', 'aab', 'aaa']))

Modified: python/branches/p3yk/Lib/test/test_grammar.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_grammar.py	(original)
+++ python/branches/p3yk/Lib/test/test_grammar.py	Fri Apr 27 21:54:29 2007
@@ -364,7 +364,7 @@
             x = 1; pass; del x;
         foo()
 
-    ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt 
+    ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt
     # Tested below
 
     def testExprStmt(self):

Modified: python/branches/p3yk/Lib/test/test_htmlparser.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_htmlparser.py	(original)
+++ python/branches/p3yk/Lib/test/test_htmlparser.py	Fri Apr 27 21:54:29 2007
@@ -309,6 +309,11 @@
             ("endtag", "script"),
             ])
 
+    def test_entityrefs_in_attributes(self):
+        self._run_check("<html foo='&euro;&amp;&#97;&#x61;&unsupported;'>", [
+                ("starttag", "html", [("foo", u"\u20AC&aa&unsupported;")])
+                ])
+
 
 def test_main():
     test_support.run_unittest(HTMLParserTestCase)

Modified: python/branches/p3yk/Lib/test/test_httplib.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_httplib.py	(original)
+++ python/branches/p3yk/Lib/test/test_httplib.py	Fri Apr 27 21:54:29 2007
@@ -1,6 +1,7 @@
 import httplib
 import StringIO
 import sys
+import socket
 
 from unittest import TestCase
 
@@ -149,8 +150,52 @@
     def test_responses(self):
         self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
 
+PORT = 50003
+HOST = "localhost"
+
+class TimeoutTest(TestCase):
+
+    def setUp(self):
+        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        global PORT
+        PORT = test_support.bind_port(self.serv, HOST, PORT)
+        self.serv.listen(5)
+
+    def tearDown(self):
+        self.serv.close()
+        self.serv = None
+
+    def testTimeoutAttribute(self):
+        '''This will prove that the timeout gets through
+        HTTPConnection and into the socket.
+        '''
+        # default
+        httpConn = httplib.HTTPConnection(HOST, PORT)
+        httpConn.connect()
+        self.assertTrue(httpConn.sock.gettimeout() is None)
+        httpConn.close()
+
+        # a value
+        httpConn = httplib.HTTPConnection(HOST, PORT, timeout=30)
+        httpConn.connect()
+        self.assertEqual(httpConn.sock.gettimeout(), 30)
+        httpConn.close()
+
+        # None, having other default
+        previous = socket.getdefaulttimeout()
+        socket.setdefaulttimeout(30)
+        try:
+            httpConn = httplib.HTTPConnection(HOST, PORT, timeout=None)
+            httpConn.connect()
+        finally:
+            socket.setdefaulttimeout(previous)
+        self.assertEqual(httpConn.sock.gettimeout(), 30)
+        httpConn.close()
+
+
 def test_main(verbose=None):
-    test_support.run_unittest(HeaderTests, OfflineTest, BasicTest)
+    test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest)
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/p3yk/Lib/test/test_import.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_import.py	(original)
+++ python/branches/p3yk/Lib/test/test_import.py	Fri Apr 27 21:54:29 2007
@@ -193,6 +193,16 @@
             if TESTFN in sys.modules:
                 del sys.modules[TESTFN]
 
+    def test_infinite_reload(self):
+        # Bug #742342 reports that Python segfaults (infinite recursion in C)
+        #  when faced with self-recursive reload()ing.
+
+        sys.path.insert(0, os.path.dirname(__file__))
+        try:
+            import infinite_reload
+        finally:
+            sys.path.pop(0)
+
     def test_import_name_binding(self):
         # import x.y.z binds x in the current namespace
         import test as x

Modified: python/branches/p3yk/Lib/test/test_itertools.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_itertools.py	(original)
+++ python/branches/p3yk/Lib/test/test_itertools.py	Fri Apr 27 21:54:29 2007
@@ -215,20 +215,20 @@
             self.assertEqual(list(izip_longest(*args, **{})), target)
             target = [tuple((e is None and 'X' or e) for e in t) for t in target]   # Replace None fills with 'X'
             self.assertEqual(list(izip_longest(*args, **dict(fillvalue='X'))), target)
-        
+
         self.assertEqual(take(3,izip_longest('abcdef', count())), list(zip('abcdef', range(3)))) # take 3 from infinite input
 
         self.assertEqual(list(izip_longest()), list(zip()))
         self.assertEqual(list(izip_longest([])), list(zip([])))
         self.assertEqual(list(izip_longest('abcdef')), list(zip('abcdef')))
-    
+
         self.assertEqual(list(izip_longest('abc', 'defg', **{})), map(None, 'abc', 'defg')) # empty keyword dict
         self.assertRaises(TypeError, izip_longest, 3)
         self.assertRaises(TypeError, izip_longest, range(3), 3)
 
         for stmt in [
             "izip_longest('abc', fv=1)",
-            "izip_longest('abc', fillvalue=1, bogus_keyword=None)",            
+            "izip_longest('abc', fillvalue=1, bogus_keyword=None)",
         ]:
             try:
                 eval(stmt, globals(), locals())
@@ -236,7 +236,7 @@
                 pass
             else:
                 self.fail('Did not raise Type in:  ' + stmt)
-        
+
         # Check tuple re-use (implementation detail)
         self.assertEqual([tuple(list(pair)) for pair in izip_longest('abc', 'def')],
                          list(zip('abc', 'def')))
@@ -818,7 +818,7 @@
 >>> amounts = [120.15, 764.05, 823.14]
 >>> for checknum, amount in izip(count(1200), amounts):
 ...     print('Check %d is for $%.2f' % (checknum, amount))
-... 
+...
 Check 1200 is for $120.15
 Check 1201 is for $764.05
 Check 1202 is for $823.14
@@ -826,7 +826,7 @@
 >>> import operator
 >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)):
 ...    print(cube)
-... 
+...
 1
 8
 27
@@ -834,7 +834,7 @@
 >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
 >>> for name in islice(reportlines, 3, None, 2):
 ...    print(name.title())
-... 
+...
 Alex
 Laura
 Martin
@@ -846,7 +846,7 @@
 >>> di = sorted(sorted(d.items()), key=itemgetter(1))
 >>> for k, g in groupby(di, itemgetter(1)):
 ...     print(k, map(itemgetter(0), g))
-... 
+...
 1 ['a', 'c', 'e']
 2 ['b', 'd', 'f']
 3 ['g']
@@ -857,7 +857,7 @@
 >>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
 >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
 ...     print(map(operator.itemgetter(1), g))
-... 
+...
 [1]
 [4, 5, 6]
 [10]

Modified: python/branches/p3yk/Lib/test/test_keywordonlyarg.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_keywordonlyarg.py	(original)
+++ python/branches/p3yk/Lib/test/test_keywordonlyarg.py	Fri Apr 27 21:54:29 2007
@@ -71,7 +71,7 @@
             fundef3 += "i%d, "%i
         fundef3 += "lastarg):\n  pass\n"
         compile(fundef3, "<test>", "single")
- 
+
     def testSyntaxErrorForFunctionCall(self):
         self.assertRaisesSyntaxError("f(p, k=1, p2)")
         self.assertRaisesSyntaxError("f(p, *(1,2), k1=100)")

Modified: python/branches/p3yk/Lib/test/test_locale.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_locale.py	(original)
+++ python/branches/p3yk/Lib/test/test_locale.py	Fri Apr 27 21:54:29 2007
@@ -7,7 +7,7 @@
 oldlocale = locale.setlocale(locale.LC_NUMERIC)
 
 if sys.platform.startswith("win"):
-    tlocs = ("en",)
+    tlocs = ("En", "English")
 else:
     tlocs = ("en_US.UTF-8", "en_US.US-ASCII", "en_US")
 

Modified: python/branches/p3yk/Lib/test/test_logging.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_logging.py	(original)
+++ python/branches/p3yk/Lib/test/test_logging.py	Fri Apr 27 21:54:29 2007
@@ -554,6 +554,8 @@
         except KeyError:
             logging.exception("just testing")
         os.remove(fn)
+        hdlr = logging.getLogger().handlers[0]
+        logging.getLogger().handlers.remove(hdlr)
     finally:
         logging._acquireLock()
         try:

Modified: python/branches/p3yk/Lib/test/test_long_future.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_long_future.py	(original)
+++ python/branches/p3yk/Lib/test/test_long_future.py	Fri Apr 27 21:54:29 2007
@@ -3,53 +3,53 @@
 # test_long.py instead.  In the meantime, it's too obscure to try to
 # trick just part of test_long into using future division.
 
-from test.test_support import TestFailed, verify, verbose
+import unittest
+from test.test_support import run_unittest
 
-def test_true_division():
-    if verbose:
-        print("long true division")
-    huge = 1 << 40000
-    mhuge = -huge
-    verify(huge / huge == 1.0)
-    verify(mhuge / mhuge == 1.0)
-    verify(huge / mhuge == -1.0)
-    verify(mhuge / huge == -1.0)
-    verify(1 / huge == 0.0)
-    verify(1 / huge == 0.0)
-    verify(1 / mhuge == 0.0)
-    verify(1 / mhuge == 0.0)
-    verify((666 * huge + (huge >> 1)) / huge == 666.5)
-    verify((666 * mhuge + (mhuge >> 1)) / mhuge == 666.5)
-    verify((666 * huge + (huge >> 1)) / mhuge == -666.5)
-    verify((666 * mhuge + (mhuge >> 1)) / huge == -666.5)
-    verify(huge / (huge << 1) == 0.5)
-    verify((1000000 * huge) / huge == 1000000)
-
-    namespace = {'huge': huge, 'mhuge': mhuge}
-
-    for overflow in ["float(huge)", "float(mhuge)",
-                     "huge / 1", "huge / 2", "huge / -1", "huge / -2",
-                     "mhuge / 100", "mhuge / 100"]:
-        try:
-            eval(overflow, namespace)
-        except OverflowError:
-            pass
-        else:
-            raise TestFailed("expected OverflowError from %r" % overflow)
-
-    for underflow in ["1 / huge", "2 / huge", "-1 / huge", "-2 / huge",
-                     "100 / mhuge", "100 / mhuge"]:
-        result = eval(underflow, namespace)
-        if result != 0.0:
-            raise TestFailed("expected underflow to 0 from %r" % underflow)
-
-    for zero in ["huge / 0", "huge / 0",
-                 "mhuge / 0", "mhuge / 0"]:
-        try:
-            eval(zero, namespace)
-        except ZeroDivisionError:
-            pass
-        else:
-            raise TestFailed("expected ZeroDivisionError from %r" % zero)
+class TrueDivisionTests(unittest.TestCase):
+    def test(self):
+        huge = 1 << 40000
+        mhuge = -huge
+        self.assertEqual(huge / huge, 1.0)
+        self.assertEqual(mhuge / mhuge, 1.0)
+        self.assertEqual(huge / mhuge, -1.0)
+        self.assertEqual(mhuge / huge, -1.0)
+        self.assertEqual(1 / huge, 0.0)
+        self.assertEqual(1 / huge, 0.0)
+        self.assertEqual(1 / mhuge, 0.0)
+        self.assertEqual(1 / mhuge, 0.0)
+        self.assertEqual((666 * huge + (huge >> 1)) / huge, 666.5)
+        self.assertEqual((666 * mhuge + (mhuge >> 1)) / mhuge, 666.5)
+        self.assertEqual((666 * huge + (huge >> 1)) / mhuge, -666.5)
+        self.assertEqual((666 * mhuge + (mhuge >> 1)) / huge, -666.5)
+        self.assertEqual(huge / (huge << 1), 0.5)
+        self.assertEqual((1000000 * huge) / huge, 1000000)
+
+        namespace = {'huge': huge, 'mhuge': mhuge}
+
+        for overflow in ["float(huge)", "float(mhuge)",
+                         "huge / 1", "huge / 2", "huge / -1", "huge / -2",
+                         "mhuge / 100", "mhuge / 200"]:
+            # XXX(cwinter) this test doesn't pass when converted to
+            # use assertRaises.
+            try:
+                eval(overflow, namespace)
+                self.fail("expected OverflowError from %r" % overflow)
+            except OverflowError:
+                pass
+
+        for underflow in ["1 / huge", "2 / huge", "-1 / huge", "-2 / huge",
+                         "100 / mhuge", "200 / mhuge"]:
+            result = eval(underflow, namespace)
+            self.assertEqual(result, 0.0,
+                             "expected underflow to 0 from %r" % underflow)
+
+        for zero in ["huge / 0", "mhuge / 0"]:
+            self.assertRaises(ZeroDivisionError, eval, zero, namespace)
 
-test_true_division()
+
+def test_main():
+    run_unittest(TrueDivisionTests)
+
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_macpath.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_macpath.py	(original)
+++ python/branches/p3yk/Lib/test/test_macpath.py	Fri Apr 27 21:54:29 2007
@@ -48,7 +48,7 @@
         splitext = macpath.splitext
         self.assertEquals(splitext(":foo.ext"), (':foo', '.ext'))
         self.assertEquals(splitext("foo:foo.ext"), ('foo:foo', '.ext'))
-        self.assertEquals(splitext(".ext"), ('', '.ext'))
+        self.assertEquals(splitext(".ext"), ('.ext', ''))
         self.assertEquals(splitext("foo.ext:foo"), ('foo.ext:foo', ''))
         self.assertEquals(splitext(":foo.ext:"), (':foo.ext:', ''))
         self.assertEquals(splitext(""), ('', ''))

Modified: python/branches/p3yk/Lib/test/test_mailbox.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_mailbox.py	(original)
+++ python/branches/p3yk/Lib/test/test_mailbox.py	Fri Apr 27 21:54:29 2007
@@ -54,6 +54,7 @@
 
     def setUp(self):
         self._path = test_support.TESTFN
+        self._delete_recursively(self._path)
         self._box = self._factory(self._path)
 
     def tearDown(self):
@@ -686,7 +687,7 @@
         self._box.close()
         self._delete_recursively(self._path)
         for lock_remnant in glob.glob(self._path + '.*'):
-            os.remove(lock_remnant)
+            test_support.unlink(lock_remnant)
 
     def test_add_from_string(self):
         # Add a string starting with 'From ' to the mailbox
@@ -909,7 +910,7 @@
         self._box.close()
         self._delete_recursively(self._path)
         for lock_remnant in glob.glob(self._path + '.*'):
-            os.remove(lock_remnant)
+            test_support.unlink(lock_remnant)
 
     def test_labels(self):
         # Get labels from the mailbox

Modified: python/branches/p3yk/Lib/test/test_metaclass.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_metaclass.py	(original)
+++ python/branches/p3yk/Lib/test/test_metaclass.py	Fri Apr 27 21:54:29 2007
@@ -63,6 +63,8 @@
     ...    def __new__(cls, name, bases, namespace, **kwds):
     ...        print("New called:", kwds)
     ...        return type.__new__(cls, name, bases, namespace)
+    ...    def __init__(cls, *args, **kwds):
+    ...        pass
     ...
     >>> class C(metaclass=M):
     ...     def meth(self): print("Hello")

Modified: python/branches/p3yk/Lib/test/test_minidom.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_minidom.py	(original)
+++ python/branches/p3yk/Lib/test/test_minidom.py	Fri Apr 27 21:54:29 2007
@@ -5,7 +5,8 @@
 import pickle
 import traceback
 from StringIO import StringIO
-from test.test_support import verbose
+from test.test_support import verbose, run_unittest, TestSkipped
+import unittest
 
 import xml.dom
 import xml.dom.minidom
@@ -22,680 +23,9 @@
 tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
 del base
 
-def confirm(test, testname = "Test"):
-    if not test:
-        print("Failed " + testname)
-        raise Exception
-
-def testParseFromFile():
-    dom = parse(StringIO(open(tstfile).read()))
-    dom.unlink()
-    confirm(isinstance(dom,Document))
-
-def testGetElementsByTagName():
-    dom = parse(tstfile)
-    confirm(dom.getElementsByTagName("LI") == \
-            dom.documentElement.getElementsByTagName("LI"))
-    dom.unlink()
-
-def testInsertBefore():
-    dom = parseString("<doc><foo/></doc>")
-    root = dom.documentElement
-    elem = root.childNodes[0]
-    nelem = dom.createElement("element")
-    root.insertBefore(nelem, elem)
-    confirm(len(root.childNodes) == 2
-            and root.childNodes.length == 2
-            and root.childNodes[0] is nelem
-            and root.childNodes.item(0) is nelem
-            and root.childNodes[1] is elem
-            and root.childNodes.item(1) is elem
-            and root.firstChild is nelem
-            and root.lastChild is elem
-            and root.toxml() == "<doc><element/><foo/></doc>"
-            , "testInsertBefore -- node properly placed in tree")
-    nelem = dom.createElement("element")
-    root.insertBefore(nelem, None)
-    confirm(len(root.childNodes) == 3
-            and root.childNodes.length == 3
-            and root.childNodes[1] is elem
-            and root.childNodes.item(1) is elem
-            and root.childNodes[2] is nelem
-            and root.childNodes.item(2) is nelem
-            and root.lastChild is nelem
-            and nelem.previousSibling is elem
-            and root.toxml() == "<doc><element/><foo/><element/></doc>"
-            , "testInsertBefore -- node properly placed in tree")
-    nelem2 = dom.createElement("bar")
-    root.insertBefore(nelem2, nelem)
-    confirm(len(root.childNodes) == 4
-            and root.childNodes.length == 4
-            and root.childNodes[2] is nelem2
-            and root.childNodes.item(2) is nelem2
-            and root.childNodes[3] is nelem
-            and root.childNodes.item(3) is nelem
-            and nelem2.nextSibling is nelem
-            and nelem.previousSibling is nelem2
-            and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
-            , "testInsertBefore -- node properly placed in tree")
-    dom.unlink()
-
-def _create_fragment_test_nodes():
-    dom = parseString("<doc/>")
-    orig = dom.createTextNode("original")
-    c1 = dom.createTextNode("foo")
-    c2 = dom.createTextNode("bar")
-    c3 = dom.createTextNode("bat")
-    dom.documentElement.appendChild(orig)
-    frag = dom.createDocumentFragment()
-    frag.appendChild(c1)
-    frag.appendChild(c2)
-    frag.appendChild(c3)
-    return dom, orig, c1, c2, c3, frag
-
-def testInsertBeforeFragment():
-    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
-    dom.documentElement.insertBefore(frag, None)
-    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
-            "insertBefore(<fragment>, None)")
-    frag.unlink()
-    dom.unlink()
-    #
-    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
-    dom.documentElement.insertBefore(frag, orig)
-    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
-            "insertBefore(<fragment>, orig)")
-    frag.unlink()
-    dom.unlink()
-
-def testAppendChild():
-    dom = parse(tstfile)
-    dom.documentElement.appendChild(dom.createComment(u"Hello"))
-    confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
-    confirm(dom.documentElement.childNodes[-1].data == "Hello")
-    dom.unlink()
-
-def testAppendChildFragment():
-    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
-    dom.documentElement.appendChild(frag)
-    confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
-            "appendChild(<fragment>)")
-    frag.unlink()
-    dom.unlink()
-
-def testReplaceChildFragment():
-    dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
-    dom.documentElement.replaceChild(frag, orig)
-    orig.unlink()
-    confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
-            "replaceChild(<fragment>)")
-    frag.unlink()
-    dom.unlink()
-
-def testLegalChildren():
-    dom = Document()
-    elem = dom.createElement('element')
-    text = dom.createTextNode('text')
-
-    try: dom.appendChild(text)
-    except xml.dom.HierarchyRequestErr: pass
-    else:
-        print("dom.appendChild didn't raise HierarchyRequestErr")
-
-    dom.appendChild(elem)
-    try: dom.insertBefore(text, elem)
-    except xml.dom.HierarchyRequestErr: pass
-    else:
-        print("dom.appendChild didn't raise HierarchyRequestErr")
-
-    try: dom.replaceChild(text, elem)
-    except xml.dom.HierarchyRequestErr: pass
-    else:
-        print("dom.appendChild didn't raise HierarchyRequestErr")
-
-    nodemap = elem.attributes
-    try: nodemap.setNamedItem(text)
-    except xml.dom.HierarchyRequestErr: pass
-    else:
-        print("NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr")
-
-    try: nodemap.setNamedItemNS(text)
-    except xml.dom.HierarchyRequestErr: pass
-    else:
-        print("NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr")
-
-    elem.appendChild(text)
-    dom.unlink()
-
-def testNamedNodeMapSetItem():
-    dom = Document()
-    elem = dom.createElement('element')
-    attrs = elem.attributes
-    attrs["foo"] = "bar"
-    a = attrs.item(0)
-    confirm(a.ownerDocument is dom,
-            "NamedNodeMap.__setitem__() sets ownerDocument")
-    confirm(a.ownerElement is elem,
-            "NamedNodeMap.__setitem__() sets ownerElement")
-    confirm(a.value == "bar",
-            "NamedNodeMap.__setitem__() sets value")
-    confirm(a.nodeValue == "bar",
-            "NamedNodeMap.__setitem__() sets nodeValue")
-    elem.unlink()
-    dom.unlink()
-
-def testNonZero():
-    dom = parse(tstfile)
-    confirm(dom)# should not be zero
-    dom.appendChild(dom.createComment("foo"))
-    confirm(not dom.childNodes[-1].childNodes)
-    dom.unlink()
-
-def testUnlink():
-    dom = parse(tstfile)
-    dom.unlink()
-
-def testElement():
-    dom = Document()
-    dom.appendChild(dom.createElement("abc"))
-    confirm(dom.documentElement)
-    dom.unlink()
-
-def testAAA():
-    dom = parseString("<abc/>")
-    el = dom.documentElement
-    el.setAttribute("spam", "jam2")
-    confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
-    a = el.getAttributeNode("spam")
-    confirm(a.ownerDocument is dom,
-            "setAttribute() sets ownerDocument")
-    confirm(a.ownerElement is dom.documentElement,
-            "setAttribute() sets ownerElement")
-    dom.unlink()
-
-def testAAB():
-    dom = parseString("<abc/>")
-    el = dom.documentElement
-    el.setAttribute("spam", "jam")
-    el.setAttribute("spam", "jam2")
-    confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
-    dom.unlink()
-
-def testAddAttr():
-    dom = Document()
-    child = dom.appendChild(dom.createElement("abc"))
-
-    child.setAttribute("def", "ghi")
-    confirm(child.getAttribute("def") == "ghi")
-    confirm(child.attributes["def"].value == "ghi")
-
-    child.setAttribute("jkl", "mno")
-    confirm(child.getAttribute("jkl") == "mno")
-    confirm(child.attributes["jkl"].value == "mno")
-
-    confirm(len(child.attributes) == 2)
-
-    child.setAttribute("def", "newval")
-    confirm(child.getAttribute("def") == "newval")
-    confirm(child.attributes["def"].value == "newval")
-
-    confirm(len(child.attributes) == 2)
-    dom.unlink()
-
-def testDeleteAttr():
-    dom = Document()
-    child = dom.appendChild(dom.createElement("abc"))
-
-    confirm(len(child.attributes) == 0)
-    child.setAttribute("def", "ghi")
-    confirm(len(child.attributes) == 1)
-    del child.attributes["def"]
-    confirm(len(child.attributes) == 0)
-    dom.unlink()
-
-def testRemoveAttr():
-    dom = Document()
-    child = dom.appendChild(dom.createElement("abc"))
-
-    child.setAttribute("def", "ghi")
-    confirm(len(child.attributes) == 1)
-    child.removeAttribute("def")
-    confirm(len(child.attributes) == 0)
-
-    dom.unlink()
-
-def testRemoveAttrNS():
-    dom = Document()
-    child = dom.appendChild(
-            dom.createElementNS("http://www.python.org", "python:abc"))
-    child.setAttributeNS("http://www.w3.org", "xmlns:python",
-                                            "http://www.python.org")
-    child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
-    confirm(len(child.attributes) == 2)
-    child.removeAttributeNS("http://www.python.org", "abcattr")
-    confirm(len(child.attributes) == 1)
-
-    dom.unlink()
-
-def testRemoveAttributeNode():
-    dom = Document()
-    child = dom.appendChild(dom.createElement("foo"))
-    child.setAttribute("spam", "jam")
-    confirm(len(child.attributes) == 1)
-    node = child.getAttributeNode("spam")
-    child.removeAttributeNode(node)
-    confirm(len(child.attributes) == 0
-            and child.getAttributeNode("spam") is None)
-
-    dom.unlink()
-
-def testChangeAttr():
-    dom = parseString("<abc/>")
-    el = dom.documentElement
-    el.setAttribute("spam", "jam")
-    confirm(len(el.attributes) == 1)
-    el.setAttribute("spam", "bam")
-    # Set this attribute to be an ID and make sure that doesn't change
-    # when changing the value:
-    el.setIdAttribute("spam")
-    confirm(len(el.attributes) == 1
-            and el.attributes["spam"].value == "bam"
-            and el.attributes["spam"].nodeValue == "bam"
-            and el.getAttribute("spam") == "bam"
-            and el.getAttributeNode("spam").isId)
-    el.attributes["spam"] = "ham"
-    confirm(len(el.attributes) == 1
-            and el.attributes["spam"].value == "ham"
-            and el.attributes["spam"].nodeValue == "ham"
-            and el.getAttribute("spam") == "ham"
-            and el.attributes["spam"].isId)
-    el.setAttribute("spam2", "bam")
-    confirm(len(el.attributes) == 2
-            and el.attributes["spam"].value == "ham"
-            and el.attributes["spam"].nodeValue == "ham"
-            and el.getAttribute("spam") == "ham"
-            and el.attributes["spam2"].value == "bam"
-            and el.attributes["spam2"].nodeValue == "bam"
-            and el.getAttribute("spam2") == "bam")
-    el.attributes["spam2"] = "bam2"
-    confirm(len(el.attributes) == 2
-            and el.attributes["spam"].value == "ham"
-            and el.attributes["spam"].nodeValue == "ham"
-            and el.getAttribute("spam") == "ham"
-            and el.attributes["spam2"].value == "bam2"
-            and el.attributes["spam2"].nodeValue == "bam2"
-            and el.getAttribute("spam2") == "bam2")
-    dom.unlink()
-
-def testGetAttrList():
-    pass
-
-def testGetAttrValues(): pass
-
-def testGetAttrLength(): pass
-
-def testGetAttribute(): pass
-
-def testGetAttributeNS(): pass
-
-def testGetAttributeNode(): pass
-
-def testGetElementsByTagNameNS():
-    d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
-    <minidom:myelem/>
-    </foo>"""
-    dom = parseString(d)
-    elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
-    confirm(len(elems) == 1
-            and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
-            and elems[0].localName == "myelem"
-            and elems[0].prefix == "minidom"
-            and elems[0].tagName == "minidom:myelem"
-            and elems[0].nodeName == "minidom:myelem")
-    dom.unlink()
-
-def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
-    nodelist = doc.getElementsByTagNameNS(nsuri, lname)
-    confirm(len(nodelist) == 0)
-
-def testGetEmptyNodeListFromElementsByTagNameNS():
-    doc = parseString('<doc/>')
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, 'http://xml.python.org/namespaces/a', 'localname')
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, '*', 'splat')
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, 'http://xml.python.org/namespaces/a', '*')
-
-    doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, "http://xml.python.org/splat", "not-there")
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, "*", "not-there")
-    get_empty_nodelist_from_elements_by_tagName_ns_helper(
-        doc, "http://somewhere.else.net/not-there", "e")
-
-def testElementReprAndStr():
-    dom = Document()
-    el = dom.appendChild(dom.createElement("abc"))
-    string1 = repr(el)
-    string2 = str(el)
-    confirm(string1 == string2)
-    dom.unlink()
-
-# commented out until Fredrick's fix is checked in
-def _testElementReprAndStrUnicode():
-    dom = Document()
-    el = dom.appendChild(dom.createElement(u"abc"))
-    string1 = repr(el)
-    string2 = str(el)
-    confirm(string1 == string2)
-    dom.unlink()
-
-# commented out until Fredrick's fix is checked in
-def _testElementReprAndStrUnicodeNS():
-    dom = Document()
-    el = dom.appendChild(
-        dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
-    string1 = repr(el)
-    string2 = str(el)
-    confirm(string1 == string2)
-    confirm(string1.find("slash:abc") != -1)
-    dom.unlink()
-
-def testAttributeRepr():
-    dom = Document()
-    el = dom.appendChild(dom.createElement(u"abc"))
-    node = el.setAttribute("abc", "def")
-    confirm(str(node) == repr(node))
-    dom.unlink()
-
-def testTextNodeRepr(): pass
-
-def testWriteXML():
-    str = '<?xml version="1.0" ?><a b="c"/>'
-    dom = parseString(str)
-    domstr = dom.toxml()
-    dom.unlink()
-    confirm(str == domstr)
-
-def testAltNewline():
-    str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
-    dom = parseString(str)
-    domstr = dom.toprettyxml(newl="\r\n")
-    dom.unlink()
-    confirm(domstr == str.replace("\n", "\r\n"))
-
-def testProcessingInstruction():
-    dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
-    pi = dom.documentElement.firstChild
-    confirm(pi.target == "mypi"
-            and pi.data == "data \t\n "
-            and pi.nodeName == "mypi"
-            and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
-            and pi.attributes is None
-            and not pi.hasChildNodes()
-            and len(pi.childNodes) == 0
-            and pi.firstChild is None
-            and pi.lastChild is None
-            and pi.localName is None
-            and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
-
-def testProcessingInstructionRepr(): pass
-
-def testTextRepr(): pass
-
-def testWriteText(): pass
-
-def testDocumentElement(): pass
-
-def testTooManyDocumentElements():
-    doc = parseString("<doc/>")
-    elem = doc.createElement("extra")
-    try:
-        doc.appendChild(elem)
-    except xml.dom.HierarchyRequestErr:
-        pass
-    else:
-        print("Failed to catch expected exception when" \
-              " adding extra document element.")
-    elem.unlink()
-    doc.unlink()
-
-def testCreateElementNS(): pass
-
-def testCreateAttributeNS(): pass
-
-def testParse(): pass
-
-def testParseString(): pass
-
-def testComment(): pass
-
-def testAttrListItem(): pass
-
-def testAttrListItems(): pass
-
-def testAttrListItemNS(): pass
-
-def testAttrListKeys(): pass
-
-def testAttrListKeysNS(): pass
-
-def testRemoveNamedItem():
-    doc = parseString("<doc a=''/>")
-    e = doc.documentElement
-    attrs = e.attributes
-    a1 = e.getAttributeNode("a")
-    a2 = attrs.removeNamedItem("a")
-    confirm(a1.isSameNode(a2))
-    try:
-        attrs.removeNamedItem("a")
-    except xml.dom.NotFoundErr:
-        pass
-
-def testRemoveNamedItemNS():
-    doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
-    e = doc.documentElement
-    attrs = e.attributes
-    a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
-    a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
-    confirm(a1.isSameNode(a2))
-    try:
-        attrs.removeNamedItemNS("http://xml.python.org/", "b")
-    except xml.dom.NotFoundErr:
-        pass
-
-def testAttrListValues(): pass
-
-def testAttrListLength(): pass
-
-def testAttrList__getitem__(): pass
-
-def testAttrList__setitem__(): pass
-
-def testSetAttrValueandNodeValue(): pass
-
-def testParseElement(): pass
-
-def testParseAttributes(): pass
-
-def testParseElementNamespaces(): pass
-
-def testParseAttributeNamespaces(): pass
-
-def testParseProcessingInstructions(): pass
-
-def testChildNodes(): pass
-
-def testFirstChild(): pass
-
-def testHasChildNodes(): pass
-
-def testCloneElementShallow():
-    dom, clone = _setupCloneElement(0)
-    confirm(len(clone.childNodes) == 0
-            and clone.childNodes.length == 0
-            and clone.parentNode is None
-            and clone.toxml() == '<doc attr="value"/>'
-            , "testCloneElementShallow")
-    dom.unlink()
-
-def testCloneElementDeep():
-    dom, clone = _setupCloneElement(1)
-    confirm(len(clone.childNodes) == 1
-            and clone.childNodes.length == 1
-            and clone.parentNode is None
-            and clone.toxml() == '<doc attr="value"><foo/></doc>'
-            , "testCloneElementDeep")
-    dom.unlink()
-
-def _setupCloneElement(deep):
-    dom = parseString("<doc attr='value'><foo/></doc>")
-    root = dom.documentElement
-    clone = root.cloneNode(deep)
-    _testCloneElementCopiesAttributes(
-        root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
-    # mutilate the original so shared data is detected
-    root.tagName = root.nodeName = "MODIFIED"
-    root.setAttribute("attr", "NEW VALUE")
-    root.setAttribute("added", "VALUE")
-    return dom, clone
-
-def _testCloneElementCopiesAttributes(e1, e2, test):
-    attrs1 = e1.attributes
-    attrs2 = e2.attributes
-    keys1 = sorted(attrs1.keys())
-    keys2 = sorted(attrs2.keys())
-    confirm(keys1 == keys2, "clone of element has same attribute keys")
-    for i in range(len(keys1)):
-        a1 = attrs1.item(i)
-        a2 = attrs2.item(i)
-        confirm(a1 is not a2
-                and a1.value == a2.value
-                and a1.nodeValue == a2.nodeValue
-                and a1.namespaceURI == a2.namespaceURI
-                and a1.localName == a2.localName
-                , "clone of attribute node has proper attribute values")
-        confirm(a2.ownerElement is e2,
-                "clone of attribute node correctly owned")
-
-def testCloneDocumentShallow():
-    doc = parseString("<?xml version='1.0'?>\n"
-                      "<!-- comment -->"
-                      "<!DOCTYPE doc [\n"
-                      "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
-                      "]>\n"
-                      "<doc attr='value'/>")
-    doc2 = doc.cloneNode(0)
-    confirm(doc2 is None,
-            "testCloneDocumentShallow:"
-            " shallow cloning of documents makes no sense!")
-
-def testCloneDocumentDeep():
-    doc = parseString("<?xml version='1.0'?>\n"
-                      "<!-- comment -->"
-                      "<!DOCTYPE doc [\n"
-                      "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
-                      "]>\n"
-                      "<doc attr='value'/>")
-    doc2 = doc.cloneNode(1)
-    confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
-            "testCloneDocumentDeep: document objects not distinct")
-    confirm(len(doc.childNodes) == len(doc2.childNodes),
-            "testCloneDocumentDeep: wrong number of Document children")
-    confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
-            "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
-    confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
-            "testCloneDocumentDeep: documentElement owner is not new document")
-    confirm(not doc.documentElement.isSameNode(doc2.documentElement),
-            "testCloneDocumentDeep: documentElement should not be shared")
-    if doc.doctype is not None:
-        # check the doctype iff the original DOM maintained it
-        confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
-                "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
-        confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
-        confirm(not doc.doctype.isSameNode(doc2.doctype))
-
-def testCloneDocumentTypeDeepOk():
-    doctype = create_nonempty_doctype()
-    clone = doctype.cloneNode(1)
-    confirm(clone is not None
-            and clone.nodeName == doctype.nodeName
-            and clone.name == doctype.name
-            and clone.publicId == doctype.publicId
-            and clone.systemId == doctype.systemId
-            and len(clone.entities) == len(doctype.entities)
-            and clone.entities.item(len(clone.entities)) is None
-            and len(clone.notations) == len(doctype.notations)
-            and clone.notations.item(len(clone.notations)) is None
-            and len(clone.childNodes) == 0)
-    for i in range(len(doctype.entities)):
-        se = doctype.entities.item(i)
-        ce = clone.entities.item(i)
-        confirm((not se.isSameNode(ce))
-                and (not ce.isSameNode(se))
-                and ce.nodeName == se.nodeName
-                and ce.notationName == se.notationName
-                and ce.publicId == se.publicId
-                and ce.systemId == se.systemId
-                and ce.encoding == se.encoding
-                and ce.actualEncoding == se.actualEncoding
-                and ce.version == se.version)
-    for i in range(len(doctype.notations)):
-        sn = doctype.notations.item(i)
-        cn = clone.notations.item(i)
-        confirm((not sn.isSameNode(cn))
-                and (not cn.isSameNode(sn))
-                and cn.nodeName == sn.nodeName
-                and cn.publicId == sn.publicId
-                and cn.systemId == sn.systemId)
-
-def testCloneDocumentTypeDeepNotOk():
-    doc = create_doc_with_doctype()
-    clone = doc.doctype.cloneNode(1)
-    confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
-
-def testCloneDocumentTypeShallowOk():
-    doctype = create_nonempty_doctype()
-    clone = doctype.cloneNode(0)
-    confirm(clone is not None
-            and clone.nodeName == doctype.nodeName
-            and clone.name == doctype.name
-            and clone.publicId == doctype.publicId
-            and clone.systemId == doctype.systemId
-            and len(clone.entities) == 0
-            and clone.entities.item(0) is None
-            and len(clone.notations) == 0
-            and clone.notations.item(0) is None
-            and len(clone.childNodes) == 0)
-
-def testCloneDocumentTypeShallowNotOk():
-    doc = create_doc_with_doctype()
-    clone = doc.doctype.cloneNode(0)
-    confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
-
-def check_import_document(deep, testName):
-    doc1 = parseString("<doc/>")
-    doc2 = parseString("<doc/>")
-    try:
-        doc1.importNode(doc2, deep)
-    except xml.dom.NotSupportedErr:
-        pass
-    else:
-        raise Exception(testName +
-                        ": expected NotSupportedErr when importing a document")
-
-def testImportDocumentShallow():
-    check_import_document(0, "testImportDocumentShallow")
-
-def testImportDocumentDeep():
-    check_import_document(1, "testImportDocumentDeep")
-
 # The tests of DocumentType importing use these helpers to construct
 # the documents to work with, since not all DOM builders actually
 # create the DocumentType nodes.
-
 def create_doc_without_doctype(doctype=None):
     return getDOMImplementation().createDocument(None, "doc", doctype)
 
@@ -722,673 +52,1263 @@
     doctype.notations.item(0).ownerDocument = doc
     return doc
 
-def testImportDocumentTypeShallow():
-    src = create_doc_with_doctype()
-    target = create_doc_without_doctype()
-    try:
-        imported = target.importNode(src.doctype, 0)
-    except xml.dom.NotSupportedErr:
-        pass
-    else:
-        raise Exception(
-            "testImportDocumentTypeShallow: expected NotSupportedErr")
-
-def testImportDocumentTypeDeep():
-    src = create_doc_with_doctype()
-    target = create_doc_without_doctype()
-    try:
-        imported = target.importNode(src.doctype, 1)
-    except xml.dom.NotSupportedErr:
-        pass
-    else:
-        raise Exception(
-            "testImportDocumentTypeDeep: expected NotSupportedErr")
-
-# Testing attribute clones uses a helper, and should always be deep,
-# even if the argument to cloneNode is false.
-def check_clone_attribute(deep, testName):
-    doc = parseString("<doc attr='value'/>")
-    attr = doc.documentElement.getAttributeNode("attr")
-    assert attr is not None
-    clone = attr.cloneNode(deep)
-    confirm(not clone.isSameNode(attr))
-    confirm(not attr.isSameNode(clone))
-    confirm(clone.ownerElement is None,
-            testName + ": ownerElement should be None")
-    confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
-            testName + ": ownerDocument does not match")
-    confirm(clone.specified,
-            testName + ": cloned attribute must have specified == True")
-
-def testCloneAttributeShallow():
-    check_clone_attribute(0, "testCloneAttributeShallow")
-
-def testCloneAttributeDeep():
-    check_clone_attribute(1, "testCloneAttributeDeep")
-
-def check_clone_pi(deep, testName):
-    doc = parseString("<?target data?><doc/>")
-    pi = doc.firstChild
-    assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
-    clone = pi.cloneNode(deep)
-    confirm(clone.target == pi.target
-            and clone.data == pi.data)
-
-def testClonePIShallow():
-    check_clone_pi(0, "testClonePIShallow")
-
-def testClonePIDeep():
-    check_clone_pi(1, "testClonePIDeep")
-
-def testNormalize():
-    doc = parseString("<doc/>")
-    root = doc.documentElement
-    root.appendChild(doc.createTextNode("first"))
-    root.appendChild(doc.createTextNode("second"))
-    confirm(len(root.childNodes) == 2
-            and root.childNodes.length == 2, "testNormalize -- preparation")
-    doc.normalize()
-    confirm(len(root.childNodes) == 1
-            and root.childNodes.length == 1
-            and root.firstChild is root.lastChild
-            and root.firstChild.data == "firstsecond"
-            , "testNormalize -- result")
-    doc.unlink()
-
-    doc = parseString("<doc/>")
-    root = doc.documentElement
-    root.appendChild(doc.createTextNode(""))
-    doc.normalize()
-    confirm(len(root.childNodes) == 0
-            and root.childNodes.length == 0,
-            "testNormalize -- single empty node removed")
-    doc.unlink()
-
-def testSiblings():
-    doc = parseString("<doc><?pi?>text?<elm/></doc>")
-    root = doc.documentElement
-    (pi, text, elm) = root.childNodes
-
-    confirm(pi.nextSibling is text and
-            pi.previousSibling is None and
-            text.nextSibling is elm and
-            text.previousSibling is pi and
-            elm.nextSibling is None and
-            elm.previousSibling is text, "testSiblings")
-
-    doc.unlink()
-
-def testParents():
-    doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
-    root = doc.documentElement
-    elm1 = root.childNodes[0]
-    (elm2a, elm2b) = elm1.childNodes
-    elm3 = elm2b.childNodes[0]
-
-    confirm(root.parentNode is doc and
-            elm1.parentNode is root and
-            elm2a.parentNode is elm1 and
-            elm2b.parentNode is elm1 and
-            elm3.parentNode is elm2b, "testParents")
-
-    doc.unlink()
-
-def testNodeListItem():
-    doc = parseString("<doc><e/><e/></doc>")
-    children = doc.childNodes
-    docelem = children[0]
-    confirm(children[0] is children.item(0)
-            and children.item(1) is None
-            and docelem.childNodes.item(0) is docelem.childNodes[0]
-            and docelem.childNodes.item(1) is docelem.childNodes[1]
-            and docelem.childNodes.item(0).childNodes.item(0) is None,
-            "test NodeList.item()")
-    doc.unlink()
-
-def testSAX2DOM():
-    from xml.dom import pulldom
-
-    sax2dom = pulldom.SAX2DOM()
-    sax2dom.startDocument()
-    sax2dom.startElement("doc", {})
-    sax2dom.characters("text")
-    sax2dom.startElement("subelm", {})
-    sax2dom.characters("text")
-    sax2dom.endElement("subelm")
-    sax2dom.characters("text")
-    sax2dom.endElement("doc")
-    sax2dom.endDocument()
-
-    doc = sax2dom.document
-    root = doc.documentElement
-    (text1, elm1, text2) = root.childNodes
-    text3 = elm1.childNodes[0]
-
-    confirm(text1.previousSibling is None and
-            text1.nextSibling is elm1 and
-            elm1.previousSibling is text1 and
-            elm1.nextSibling is text2 and
-            text2.previousSibling is elm1 and
-            text2.nextSibling is None and
-            text3.previousSibling is None and
-            text3.nextSibling is None, "testSAX2DOM - siblings")
-
-    confirm(root.parentNode is doc and
-            text1.parentNode is root and
-            elm1.parentNode is root and
-            text2.parentNode is root and
-            text3.parentNode is elm1, "testSAX2DOM - parents")
-
-    doc.unlink()
-
-def testEncodings():
-    doc = parseString('<foo>&#x20ac;</foo>')
-    confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
-            and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
-            and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
-            "testEncodings - encoding EURO SIGN")
-
-    # Verify that character decoding errors throw exceptions instead of crashing
-    try:
-        doc = parseString('<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
-    except UnicodeDecodeError:
-        pass
-    else:
-        print('parsing with bad encoding should raise a UnicodeDecodeError')
+class MinidomTest(unittest.TestCase):
+    def tearDown(self):
+        try:
+            Node.allnodes
+        except AttributeError:
+            # We don't actually have the minidom from the standard library,
+            # but are picking up the PyXML version from site-packages.
+            pass
+        else:
+            self.confirm(len(Node.allnodes) == 0,
+                    "assertion: len(Node.allnodes) == 0")
+            if len(Node.allnodes):
+                print("Garbage left over:")
+                if verbose:
+                    print(list(Node.allnodes.items())[0:10])
+                else:
+                    # Don't print specific nodes if repeatable results
+                    # are needed
+                    print(len(Node.allnodes))
+            Node.allnodes = {}
+
+    def confirm(self, test, testname = "Test"):
+        self.assertTrue(test, testname)
 
-    doc.unlink()
+    def checkWholeText(self, node, s):
+        t = node.wholeText
+        self.confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
+
+    def testParseFromFile(self):
+        dom = parse(StringIO(open(tstfile).read()))
+        dom.unlink()
+        self.confirm(isinstance(dom, Document))
+
+    def testGetElementsByTagName(self):
+        dom = parse(tstfile)
+        self.confirm(dom.getElementsByTagName("LI") == \
+                dom.documentElement.getElementsByTagName("LI"))
+        dom.unlink()
+
+    def testInsertBefore(self):
+        dom = parseString("<doc><foo/></doc>")
+        root = dom.documentElement
+        elem = root.childNodes[0]
+        nelem = dom.createElement("element")
+        root.insertBefore(nelem, elem)
+        self.confirm(len(root.childNodes) == 2
+                and root.childNodes.length == 2
+                and root.childNodes[0] is nelem
+                and root.childNodes.item(0) is nelem
+                and root.childNodes[1] is elem
+                and root.childNodes.item(1) is elem
+                and root.firstChild is nelem
+                and root.lastChild is elem
+                and root.toxml() == "<doc><element/><foo/></doc>"
+                , "testInsertBefore -- node properly placed in tree")
+        nelem = dom.createElement("element")
+        root.insertBefore(nelem, None)
+        self.confirm(len(root.childNodes) == 3
+                and root.childNodes.length == 3
+                and root.childNodes[1] is elem
+                and root.childNodes.item(1) is elem
+                and root.childNodes[2] is nelem
+                and root.childNodes.item(2) is nelem
+                and root.lastChild is nelem
+                and nelem.previousSibling is elem
+                and root.toxml() == "<doc><element/><foo/><element/></doc>"
+                , "testInsertBefore -- node properly placed in tree")
+        nelem2 = dom.createElement("bar")
+        root.insertBefore(nelem2, nelem)
+        self.confirm(len(root.childNodes) == 4
+                and root.childNodes.length == 4
+                and root.childNodes[2] is nelem2
+                and root.childNodes.item(2) is nelem2
+                and root.childNodes[3] is nelem
+                and root.childNodes.item(3) is nelem
+                and nelem2.nextSibling is nelem
+                and nelem.previousSibling is nelem2
+                and root.toxml() ==
+                "<doc><element/><foo/><bar/><element/></doc>"
+                , "testInsertBefore -- node properly placed in tree")
+        dom.unlink()
+
+    def _create_fragment_test_nodes(self):
+        dom = parseString("<doc/>")
+        orig = dom.createTextNode("original")
+        c1 = dom.createTextNode("foo")
+        c2 = dom.createTextNode("bar")
+        c3 = dom.createTextNode("bat")
+        dom.documentElement.appendChild(orig)
+        frag = dom.createDocumentFragment()
+        frag.appendChild(c1)
+        frag.appendChild(c2)
+        frag.appendChild(c3)
+        return dom, orig, c1, c2, c3, frag
+
+    def testInsertBeforeFragment(self):
+        dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
+        dom.documentElement.insertBefore(frag, None)
+        self.confirm(tuple(dom.documentElement.childNodes) ==
+                     (orig, c1, c2, c3),
+                     "insertBefore(<fragment>, None)")
+        frag.unlink()
+        dom.unlink()
+
+        dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
+        dom.documentElement.insertBefore(frag, orig)
+        self.confirm(tuple(dom.documentElement.childNodes) ==
+                     (c1, c2, c3, orig),
+                     "insertBefore(<fragment>, orig)")
+        frag.unlink()
+        dom.unlink()
+
+    def testAppendChild(self):
+        dom = parse(tstfile)
+        dom.documentElement.appendChild(dom.createComment(u"Hello"))
+        self.confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
+        self.confirm(dom.documentElement.childNodes[-1].data == "Hello")
+        dom.unlink()
+
+    def testAppendChildFragment(self):
+        dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
+        dom.documentElement.appendChild(frag)
+        self.confirm(tuple(dom.documentElement.childNodes) ==
+                     (orig, c1, c2, c3),
+                     "appendChild(<fragment>)")
+        frag.unlink()
+        dom.unlink()
+
+    def testReplaceChildFragment(self):
+        dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
+        dom.documentElement.replaceChild(frag, orig)
+        orig.unlink()
+        self.confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
+                "replaceChild(<fragment>)")
+        frag.unlink()
+        dom.unlink()
+
+    def testLegalChildren(self):
+        dom = Document()
+        elem = dom.createElement('element')
+        text = dom.createTextNode('text')
+        self.assertRaises(xml.dom.HierarchyRequestErr, dom.appendChild, text)
+
+        dom.appendChild(elem)
+        self.assertRaises(xml.dom.HierarchyRequestErr, dom.insertBefore, text,
+                          elem)
+        self.assertRaises(xml.dom.HierarchyRequestErr, dom.replaceChild, text,
+                          elem)
+
+        nodemap = elem.attributes
+        self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItem,
+                          text)
+        self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItemNS,
+                          text)
+
+        elem.appendChild(text)
+        dom.unlink()
+
+    def testNamedNodeMapSetItem(self):
+        dom = Document()
+        elem = dom.createElement('element')
+        attrs = elem.attributes
+        attrs["foo"] = "bar"
+        a = attrs.item(0)
+        self.confirm(a.ownerDocument is dom,
+                "NamedNodeMap.__setitem__() sets ownerDocument")
+        self.confirm(a.ownerElement is elem,
+                "NamedNodeMap.__setitem__() sets ownerElement")
+        self.confirm(a.value == "bar",
+                "NamedNodeMap.__setitem__() sets value")
+        self.confirm(a.nodeValue == "bar",
+                "NamedNodeMap.__setitem__() sets nodeValue")
+        elem.unlink()
+        dom.unlink()
+
+    def testNonZero(self):
+        dom = parse(tstfile)
+        self.confirm(dom)# should not be zero
+        dom.appendChild(dom.createComment("foo"))
+        self.confirm(not dom.childNodes[-1].childNodes)
+        dom.unlink()
+
+    def testUnlink(self):
+        dom = parse(tstfile)
+        dom.unlink()
+
+    def testElement(self):
+        dom = Document()
+        dom.appendChild(dom.createElement("abc"))
+        self.confirm(dom.documentElement)
+        dom.unlink()
+
+    def testAAA(self):
+        dom = parseString("<abc/>")
+        el = dom.documentElement
+        el.setAttribute("spam", "jam2")
+        self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
+        a = el.getAttributeNode("spam")
+        self.confirm(a.ownerDocument is dom,
+                "setAttribute() sets ownerDocument")
+        self.confirm(a.ownerElement is dom.documentElement,
+                "setAttribute() sets ownerElement")
+        dom.unlink()
+
+    def testAAB(self):
+        dom = parseString("<abc/>")
+        el = dom.documentElement
+        el.setAttribute("spam", "jam")
+        el.setAttribute("spam", "jam2")
+        self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
+        dom.unlink()
+
+    def testAddAttr(self):
+        dom = Document()
+        child = dom.appendChild(dom.createElement("abc"))
+
+        child.setAttribute("def", "ghi")
+        self.confirm(child.getAttribute("def") == "ghi")
+        self.confirm(child.attributes["def"].value == "ghi")
+
+        child.setAttribute("jkl", "mno")
+        self.confirm(child.getAttribute("jkl") == "mno")
+        self.confirm(child.attributes["jkl"].value == "mno")
+
+        self.confirm(len(child.attributes) == 2)
+
+        child.setAttribute("def", "newval")
+        self.confirm(child.getAttribute("def") == "newval")
+        self.confirm(child.attributes["def"].value == "newval")
+
+        self.confirm(len(child.attributes) == 2)
+        dom.unlink()
+
+    def testDeleteAttr(self):
+        dom = Document()
+        child = dom.appendChild(dom.createElement("abc"))
+
+        self.confirm(len(child.attributes) == 0)
+        child.setAttribute("def", "ghi")
+        self.confirm(len(child.attributes) == 1)
+        del child.attributes["def"]
+        self.confirm(len(child.attributes) == 0)
+        dom.unlink()
+
+    def testRemoveAttr(self):
+        dom = Document()
+        child = dom.appendChild(dom.createElement("abc"))
+
+        child.setAttribute("def", "ghi")
+        self.confirm(len(child.attributes) == 1)
+        child.removeAttribute("def")
+        self.confirm(len(child.attributes) == 0)
+        dom.unlink()
+
+    def testRemoveAttrNS(self):
+        dom = Document()
+        child = dom.appendChild(
+                dom.createElementNS("http://www.python.org", "python:abc"))
+        child.setAttributeNS("http://www.w3.org", "xmlns:python",
+                                                "http://www.python.org")
+        child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
+        self.confirm(len(child.attributes) == 2)
+        child.removeAttributeNS("http://www.python.org", "abcattr")
+        self.confirm(len(child.attributes) == 1)
+        dom.unlink()
+
+    def testRemoveAttributeNode(self):
+        dom = Document()
+        child = dom.appendChild(dom.createElement("foo"))
+        child.setAttribute("spam", "jam")
+        self.confirm(len(child.attributes) == 1)
+        node = child.getAttributeNode("spam")
+        child.removeAttributeNode(node)
+        self.confirm(len(child.attributes) == 0
+                and child.getAttributeNode("spam") is None)
+        dom.unlink()
+
+    def testChangeAttr(self):
+        dom = parseString("<abc/>")
+        el = dom.documentElement
+        el.setAttribute("spam", "jam")
+        self.confirm(len(el.attributes) == 1)
+        el.setAttribute("spam", "bam")
+        # Set this attribute to be an ID and make sure that doesn't change
+        # when changing the value:
+        el.setIdAttribute("spam")
+        self.confirm(len(el.attributes) == 1
+                and el.attributes["spam"].value == "bam"
+                and el.attributes["spam"].nodeValue == "bam"
+                and el.getAttribute("spam") == "bam"
+                and el.getAttributeNode("spam").isId)
+        el.attributes["spam"] = "ham"
+        self.confirm(len(el.attributes) == 1
+                and el.attributes["spam"].value == "ham"
+                and el.attributes["spam"].nodeValue == "ham"
+                and el.getAttribute("spam") == "ham"
+                and el.attributes["spam"].isId)
+        el.setAttribute("spam2", "bam")
+        self.confirm(len(el.attributes) == 2
+                and el.attributes["spam"].value == "ham"
+                and el.attributes["spam"].nodeValue == "ham"
+                and el.getAttribute("spam") == "ham"
+                and el.attributes["spam2"].value == "bam"
+                and el.attributes["spam2"].nodeValue == "bam"
+                and el.getAttribute("spam2") == "bam")
+        el.attributes["spam2"] = "bam2"
+        self.confirm(len(el.attributes) == 2
+                and el.attributes["spam"].value == "ham"
+                and el.attributes["spam"].nodeValue == "ham"
+                and el.getAttribute("spam") == "ham"
+                and el.attributes["spam2"].value == "bam2"
+                and el.attributes["spam2"].nodeValue == "bam2"
+                and el.getAttribute("spam2") == "bam2")
+        dom.unlink()
 
-class UserDataHandler:
-    called = 0
-    def handle(self, operation, key, data, src, dst):
-        dst.setUserData(key, data + 1, self)
-        src.setUserData(key, None, None)
-        self.called = 1
-
-def testUserData():
-    dom = Document()
-    n = dom.createElement('e')
-    confirm(n.getUserData("foo") is None)
-    n.setUserData("foo", None, None)
-    confirm(n.getUserData("foo") is None)
-    n.setUserData("foo", 12, 12)
-    n.setUserData("bar", 13, 13)
-    confirm(n.getUserData("foo") == 12)
-    confirm(n.getUserData("bar") == 13)
-    n.setUserData("foo", None, None)
-    confirm(n.getUserData("foo") is None)
-    confirm(n.getUserData("bar") == 13)
-
-    handler = UserDataHandler()
-    n.setUserData("bar", 12, handler)
-    c = n.cloneNode(1)
-    confirm(handler.called
-            and n.getUserData("bar") is None
-            and c.getUserData("bar") == 13)
-    n.unlink()
-    c.unlink()
-    dom.unlink()
-
-def testRenameAttribute():
-    doc = parseString("<doc a='v'/>")
-    elem = doc.documentElement
-    attrmap = elem.attributes
-    attr = elem.attributes['a']
-
-    # Simple renaming
-    attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
-    confirm(attr.name == "b"
-            and attr.nodeName == "b"
-            and attr.localName is None
-            and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
-            and attr.prefix is None
-            and attr.value == "v"
-            and elem.getAttributeNode("a") is None
-            and elem.getAttributeNode("b").isSameNode(attr)
-            and attrmap["b"].isSameNode(attr)
-            and attr.ownerDocument.isSameNode(doc)
-            and attr.ownerElement.isSameNode(elem))
-
-    # Rename to have a namespace, no prefix
-    attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
-    confirm(attr.name == "c"
-            and attr.nodeName == "c"
-            and attr.localName == "c"
-            and attr.namespaceURI == "http://xml.python.org/ns"
-            and attr.prefix is None
-            and attr.value == "v"
-            and elem.getAttributeNode("a") is None
-            and elem.getAttributeNode("b") is None
-            and elem.getAttributeNode("c").isSameNode(attr)
-            and elem.getAttributeNodeNS(
-                "http://xml.python.org/ns", "c").isSameNode(attr)
-            and attrmap["c"].isSameNode(attr)
-            and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
-
-    # Rename to have a namespace, with prefix
-    attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
-    confirm(attr.name == "p:d"
-            and attr.nodeName == "p:d"
-            and attr.localName == "d"
-            and attr.namespaceURI == "http://xml.python.org/ns2"
-            and attr.prefix == "p"
-            and attr.value == "v"
-            and elem.getAttributeNode("a") is None
-            and elem.getAttributeNode("b") is None
-            and elem.getAttributeNode("c") is None
-            and elem.getAttributeNodeNS(
-                "http://xml.python.org/ns", "c") is None
-            and elem.getAttributeNode("p:d").isSameNode(attr)
-            and elem.getAttributeNodeNS(
-                "http://xml.python.org/ns2", "d").isSameNode(attr)
-            and attrmap["p:d"].isSameNode(attr)
-            and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
-
-    # Rename back to a simple non-NS node
-    attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
-    confirm(attr.name == "e"
-            and attr.nodeName == "e"
-            and attr.localName is None
-            and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
-            and attr.prefix is None
-            and attr.value == "v"
-            and elem.getAttributeNode("a") is None
-            and elem.getAttributeNode("b") is None
-            and elem.getAttributeNode("c") is None
-            and elem.getAttributeNode("p:d") is None
-            and elem.getAttributeNodeNS(
-                "http://xml.python.org/ns", "c") is None
-            and elem.getAttributeNode("e").isSameNode(attr)
-            and attrmap["e"].isSameNode(attr))
-
-    try:
-        doc.renameNode(attr, "http://xml.python.org/ns", "xmlns")
-    except xml.dom.NamespaceErr:
+    def testGetAttrList(self):
         pass
-    else:
-        print("expected NamespaceErr")
 
-    checkRenameNodeSharedConstraints(doc, attr)
-    doc.unlink()
+    def testGetAttrValues(self): pass
 
-def testRenameElement():
-    doc = parseString("<doc/>")
-    elem = doc.documentElement
-
-    # Simple renaming
-    elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
-    confirm(elem.tagName == "a"
-            and elem.nodeName == "a"
-            and elem.localName is None
-            and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
-            and elem.prefix is None
-            and elem.ownerDocument.isSameNode(doc))
-
-    # Rename to have a namespace, no prefix
-    elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
-    confirm(elem.tagName == "b"
-            and elem.nodeName == "b"
-            and elem.localName == "b"
-            and elem.namespaceURI == "http://xml.python.org/ns"
-            and elem.prefix is None
-            and elem.ownerDocument.isSameNode(doc))
-
-    # Rename to have a namespace, with prefix
-    elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
-    confirm(elem.tagName == "p:c"
-            and elem.nodeName == "p:c"
-            and elem.localName == "c"
-            and elem.namespaceURI == "http://xml.python.org/ns2"
-            and elem.prefix == "p"
-            and elem.ownerDocument.isSameNode(doc))
-
-    # Rename back to a simple non-NS node
-    elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
-    confirm(elem.tagName == "d"
-            and elem.nodeName == "d"
-            and elem.localName is None
-            and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
-            and elem.prefix is None
-            and elem.ownerDocument.isSameNode(doc))
-
-    checkRenameNodeSharedConstraints(doc, elem)
-    doc.unlink()
-
-def checkRenameNodeSharedConstraints(doc, node):
-    # Make sure illegal NS usage is detected:
-    try:
-        doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
-    except xml.dom.NamespaceErr:
-        pass
-    else:
-        print("expected NamespaceErr")
+    def testGetAttrLength(self): pass
 
-    doc2 = parseString("<doc/>")
-    try:
-        doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
-    except xml.dom.WrongDocumentErr:
-        pass
-    else:
-        print("expected WrongDocumentErr")
+    def testGetAttribute(self): pass
 
-def testRenameOther():
-    # We have to create a comment node explicitly since not all DOM
-    # builders used with minidom add comments to the DOM.
-    doc = xml.dom.minidom.getDOMImplementation().createDocument(
-        xml.dom.EMPTY_NAMESPACE, "e", None)
-    node = doc.createComment("comment")
-    try:
-        doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
-    except xml.dom.NotSupportedErr:
-        pass
-    else:
-        print("expected NotSupportedErr when renaming comment node")
-    doc.unlink()
-
-def checkWholeText(node, s):
-    t = node.wholeText
-    confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
-
-def testWholeText():
-    doc = parseString("<doc>a</doc>")
-    elem = doc.documentElement
-    text = elem.childNodes[0]
-    assert text.nodeType == Node.TEXT_NODE
-
-    checkWholeText(text, "a")
-    elem.appendChild(doc.createTextNode("b"))
-    checkWholeText(text, "ab")
-    elem.insertBefore(doc.createCDATASection("c"), text)
-    checkWholeText(text, "cab")
-
-    # make sure we don't cross other nodes
-    splitter = doc.createComment("comment")
-    elem.appendChild(splitter)
-    text2 = doc.createTextNode("d")
-    elem.appendChild(text2)
-    checkWholeText(text, "cab")
-    checkWholeText(text2, "d")
-
-    x = doc.createElement("x")
-    elem.replaceChild(x, splitter)
-    splitter = x
-    checkWholeText(text, "cab")
-    checkWholeText(text2, "d")
-
-    x = doc.createProcessingInstruction("y", "z")
-    elem.replaceChild(x, splitter)
-    splitter = x
-    checkWholeText(text, "cab")
-    checkWholeText(text2, "d")
-
-    elem.removeChild(splitter)
-    checkWholeText(text, "cabd")
-    checkWholeText(text2, "cabd")
-
-def testPatch1094164 ():
-    doc = parseString("<doc><e/></doc>")
-    elem = doc.documentElement
-    e = elem.firstChild
-    confirm(e.parentNode is elem, "Before replaceChild()")
-    # Check that replacing a child with itself leaves the tree unchanged
-    elem.replaceChild(e, e)
-    confirm(e.parentNode is elem, "After replaceChild()")
+    def testGetAttributeNS(self): pass
 
+    def testGetAttributeNode(self): pass
+
+    def testGetElementsByTagNameNS(self):
+        d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
+        <minidom:myelem/>
+        </foo>"""
+        dom = parseString(d)
+        elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom",
+                                           "myelem")
+        self.confirm(len(elems) == 1
+                and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
+                and elems[0].localName == "myelem"
+                and elems[0].prefix == "minidom"
+                and elems[0].tagName == "minidom:myelem"
+                and elems[0].nodeName == "minidom:myelem")
+        dom.unlink()
+
+    def get_empty_nodelist_from_elements_by_tagName_ns_helper(self, doc, nsuri,
+                                                              lname):
+        nodelist = doc.getElementsByTagNameNS(nsuri, lname)
+        self.confirm(len(nodelist) == 0)
+
+    def testGetEmptyNodeListFromElementsByTagNameNS(self):
+        doc = parseString('<doc/>')
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, 'http://xml.python.org/namespaces/a', 'localname')
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, '*', 'splat')
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, 'http://xml.python.org/namespaces/a', '*')
+
+        doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, "http://xml.python.org/splat", "not-there")
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, "*", "not-there")
+        self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
+            doc, "http://somewhere.else.net/not-there", "e")
+
+    def testElementReprAndStr(self):
+        dom = Document()
+        el = dom.appendChild(dom.createElement("abc"))
+        string1 = repr(el)
+        string2 = str(el)
+        self.confirm(string1 == string2)
+        dom.unlink()
+
+    def testElementReprAndStrUnicode(self):
+        dom = Document()
+        el = dom.appendChild(dom.createElement(u"abc"))
+        string1 = repr(el)
+        string2 = str(el)
+        self.confirm(string1 == string2)
+        dom.unlink()
+
+    def testElementReprAndStrUnicodeNS(self):
+        dom = Document()
+        el = dom.appendChild(
+            dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
+        string1 = repr(el)
+        string2 = str(el)
+        self.confirm(string1 == string2)
+        self.confirm(string1.find("slash:abc") != -1)
+        dom.unlink()
+
+    def testAttributeRepr(self):
+        dom = Document()
+        el = dom.appendChild(dom.createElement(u"abc"))
+        node = el.setAttribute("abc", "def")
+        self.confirm(str(node) == repr(node))
+        dom.unlink()
+
+    def testTextNodeRepr(self): pass
+
+    def testWriteXML(self):
+        str = '<?xml version="1.0" ?><a b="c"/>'
+        dom = parseString(str)
+        domstr = dom.toxml()
+        dom.unlink()
+        self.confirm(str == domstr)
+
+    def testAltNewline(self):
+        str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
+        dom = parseString(str)
+        domstr = dom.toprettyxml(newl="\r\n")
+        dom.unlink()
+        self.confirm(domstr == str.replace("\n", "\r\n"))
+
+    def testProcessingInstruction(self):
+        dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
+        pi = dom.documentElement.firstChild
+        self.confirm(pi.target == "mypi"
+                and pi.data == "data \t\n "
+                and pi.nodeName == "mypi"
+                and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
+                and pi.attributes is None
+                and not pi.hasChildNodes()
+                and len(pi.childNodes) == 0
+                and pi.firstChild is None
+                and pi.lastChild is None
+                and pi.localName is None
+                and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
+
+    def testProcessingInstructionRepr(self): pass
+
+    def testTextRepr(self): pass
+
+    def testWriteText(self): pass
+
+    def testDocumentElement(self): pass
+
+    def testTooManyDocumentElements(self):
+        doc = parseString("<doc/>")
+        elem = doc.createElement("extra")
+        # Should raise an exception when adding an extra document element.
+        self.assertRaises(xml.dom.HierarchyRequestErr, doc.appendChild, elem)
+        elem.unlink()
+        doc.unlink()
+
+    def testCreateElementNS(self): pass
+
+    def testCreateAttributeNS(self): pass
+
+    def testParse(self): pass
+
+    def testParseString(self): pass
+
+    def testComment(self): pass
+
+    def testAttrListItem(self): pass
+
+    def testAttrListItems(self): pass
+
+    def testAttrListItemNS(self): pass
+
+    def testAttrListKeys(self): pass
+
+    def testAttrListKeysNS(self): pass
+
+    def testRemoveNamedItem(self):
+        doc = parseString("<doc a=''/>")
+        e = doc.documentElement
+        attrs = e.attributes
+        a1 = e.getAttributeNode("a")
+        a2 = attrs.removeNamedItem("a")
+        self.confirm(a1.isSameNode(a2))
+        self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItem, "a")
+
+    def testRemoveNamedItemNS(self):
+        doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
+        e = doc.documentElement
+        attrs = e.attributes
+        a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
+        a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
+        self.confirm(a1.isSameNode(a2))
+        self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItemNS,
+                          "http://xml.python.org/", "b")
+
+    def testAttrListValues(self): pass
+
+    def testAttrListLength(self): pass
+
+    def testAttrList__getitem__(self): pass
+
+    def testAttrList__setitem__(self): pass
+
+    def testSetAttrValueandNodeValue(self): pass
+
+    def testParseElement(self): pass
+
+    def testParseAttributes(self): pass
+
+    def testParseElementNamespaces(self): pass
+
+    def testParseAttributeNamespaces(self): pass
+
+    def testParseProcessingInstructions(self): pass
+
+    def testChildNodes(self): pass
+
+    def testFirstChild(self): pass
+
+    def testHasChildNodes(self): pass
+
+    def _testCloneElementCopiesAttributes(self, e1, e2, test):
+        attrs1 = e1.attributes
+        attrs2 = e2.attributes
+        keys1 = list(attrs1.keys())
+        keys2 = list(attrs2.keys())
+        keys1.sort()
+        keys2.sort()
+        self.confirm(keys1 == keys2, "clone of element has same attribute keys")
+        for i in range(len(keys1)):
+            a1 = attrs1.item(i)
+            a2 = attrs2.item(i)
+            self.confirm(a1 is not a2
+                    and a1.value == a2.value
+                    and a1.nodeValue == a2.nodeValue
+                    and a1.namespaceURI == a2.namespaceURI
+                    and a1.localName == a2.localName
+                    , "clone of attribute node has proper attribute values")
+            self.confirm(a2.ownerElement is e2,
+                    "clone of attribute node correctly owned")
+
+    def _setupCloneElement(self, deep):
+        dom = parseString("<doc attr='value'><foo/></doc>")
+        root = dom.documentElement
+        clone = root.cloneNode(deep)
+        self._testCloneElementCopiesAttributes(
+            root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
+        # mutilate the original so shared data is detected
+        root.tagName = root.nodeName = "MODIFIED"
+        root.setAttribute("attr", "NEW VALUE")
+        root.setAttribute("added", "VALUE")
+        return dom, clone
+
+    def testCloneElementShallow(self):
+        dom, clone = self._setupCloneElement(0)
+        self.confirm(len(clone.childNodes) == 0
+                and clone.childNodes.length == 0
+                and clone.parentNode is None
+                and clone.toxml() == '<doc attr="value"/>'
+                , "testCloneElementShallow")
+        dom.unlink()
+
+    def testCloneElementDeep(self):
+        dom, clone = self._setupCloneElement(1)
+        self.confirm(len(clone.childNodes) == 1
+                and clone.childNodes.length == 1
+                and clone.parentNode is None
+                and clone.toxml() == '<doc attr="value"><foo/></doc>'
+                , "testCloneElementDeep")
+        dom.unlink()
+
+    def testCloneDocumentShallow(self):
+        doc = parseString("<?xml version='1.0'?>\n"
+                    "<!-- comment -->"
+                    "<!DOCTYPE doc [\n"
+                    "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
+                    "]>\n"
+                    "<doc attr='value'/>")
+        doc2 = doc.cloneNode(0)
+        self.confirm(doc2 is None,
+                "testCloneDocumentShallow:"
+                " shallow cloning of documents makes no sense!")
+
+    def testCloneDocumentDeep(self):
+        doc = parseString("<?xml version='1.0'?>\n"
+                    "<!-- comment -->"
+                    "<!DOCTYPE doc [\n"
+                    "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
+                    "]>\n"
+                    "<doc attr='value'/>")
+        doc2 = doc.cloneNode(1)
+        self.confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
+                "testCloneDocumentDeep: document objects not distinct")
+        self.confirm(len(doc.childNodes) == len(doc2.childNodes),
+                "testCloneDocumentDeep: wrong number of Document children")
+        self.confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
+                "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
+        self.confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
+            "testCloneDocumentDeep: documentElement owner is not new document")
+        self.confirm(not doc.documentElement.isSameNode(doc2.documentElement),
+                "testCloneDocumentDeep: documentElement should not be shared")
+        if doc.doctype is not None:
+            # check the doctype iff the original DOM maintained it
+            self.confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
+                    "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
+            self.confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
+            self.confirm(not doc.doctype.isSameNode(doc2.doctype))
+
+    def testCloneDocumentTypeDeepOk(self):
+        doctype = create_nonempty_doctype()
+        clone = doctype.cloneNode(1)
+        self.confirm(clone is not None
+                and clone.nodeName == doctype.nodeName
+                and clone.name == doctype.name
+                and clone.publicId == doctype.publicId
+                and clone.systemId == doctype.systemId
+                and len(clone.entities) == len(doctype.entities)
+                and clone.entities.item(len(clone.entities)) is None
+                and len(clone.notations) == len(doctype.notations)
+                and clone.notations.item(len(clone.notations)) is None
+                and len(clone.childNodes) == 0)
+        for i in range(len(doctype.entities)):
+            se = doctype.entities.item(i)
+            ce = clone.entities.item(i)
+            self.confirm((not se.isSameNode(ce))
+                    and (not ce.isSameNode(se))
+                    and ce.nodeName == se.nodeName
+                    and ce.notationName == se.notationName
+                    and ce.publicId == se.publicId
+                    and ce.systemId == se.systemId
+                    and ce.encoding == se.encoding
+                    and ce.actualEncoding == se.actualEncoding
+                    and ce.version == se.version)
+        for i in range(len(doctype.notations)):
+            sn = doctype.notations.item(i)
+            cn = clone.notations.item(i)
+            self.confirm((not sn.isSameNode(cn))
+                    and (not cn.isSameNode(sn))
+                    and cn.nodeName == sn.nodeName
+                    and cn.publicId == sn.publicId
+                    and cn.systemId == sn.systemId)
+
+    def testCloneDocumentTypeDeepNotOk(self):
+        doc = create_doc_with_doctype()
+        clone = doc.doctype.cloneNode(1)
+        self.confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
+
+    def testCloneDocumentTypeShallowOk(self):
+        doctype = create_nonempty_doctype()
+        clone = doctype.cloneNode(0)
+        self.confirm(clone is not None
+                and clone.nodeName == doctype.nodeName
+                and clone.name == doctype.name
+                and clone.publicId == doctype.publicId
+                and clone.systemId == doctype.systemId
+                and len(clone.entities) == 0
+                and clone.entities.item(0) is None
+                and len(clone.notations) == 0
+                and clone.notations.item(0) is None
+                and len(clone.childNodes) == 0)
+
+    def testCloneDocumentTypeShallowNotOk(self):
+        doc = create_doc_with_doctype()
+        clone = doc.doctype.cloneNode(0)
+        self.confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
+
+    def check_import_document(self, deep, testName):
+        doc1 = parseString("<doc/>")
+        doc2 = parseString("<doc/>")
+        self.assertRaises(xml.dom.NotSupportedErr, doc1.importNode, doc2, deep)
+
+    def testImportDocumentShallow(self):
+        self.check_import_document(0, "testImportDocumentShallow")
+
+    def testImportDocumentDeep(self):
+        self.check_import_document(1, "testImportDocumentDeep")
+
+    def testImportDocumentTypeShallow(self):
+        src = create_doc_with_doctype()
+        target = create_doc_without_doctype()
+        self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
+                          src.doctype, 0)
+
+    def testImportDocumentTypeDeep(self):
+        src = create_doc_with_doctype()
+        target = create_doc_without_doctype()
+        self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
+                          src.doctype, 1)
+
+    # Testing attribute clones uses a helper, and should always be deep,
+    # even if the argument to cloneNode is false.
+    def check_clone_attribute(self, deep, testName):
+        doc = parseString("<doc attr='value'/>")
+        attr = doc.documentElement.getAttributeNode("attr")
+        self.failIfEqual(attr, None)
+        clone = attr.cloneNode(deep)
+        self.confirm(not clone.isSameNode(attr))
+        self.confirm(not attr.isSameNode(clone))
+        self.confirm(clone.ownerElement is None,
+                testName + ": ownerElement should be None")
+        self.confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
+                testName + ": ownerDocument does not match")
+        self.confirm(clone.specified,
+                testName + ": cloned attribute must have specified == True")
+
+    def testCloneAttributeShallow(self):
+        self.check_clone_attribute(0, "testCloneAttributeShallow")
+
+    def testCloneAttributeDeep(self):
+        self.check_clone_attribute(1, "testCloneAttributeDeep")
+
+    def check_clone_pi(self, deep, testName):
+        doc = parseString("<?target data?><doc/>")
+        pi = doc.firstChild
+        self.assertEquals(pi.nodeType, Node.PROCESSING_INSTRUCTION_NODE)
+        clone = pi.cloneNode(deep)
+        self.confirm(clone.target == pi.target
+                and clone.data == pi.data)
+
+    def testClonePIShallow(self):
+        self.check_clone_pi(0, "testClonePIShallow")
+
+    def testClonePIDeep(self):
+        self.check_clone_pi(1, "testClonePIDeep")
+
+    def testNormalize(self):
+        doc = parseString("<doc/>")
+        root = doc.documentElement
+        root.appendChild(doc.createTextNode("first"))
+        root.appendChild(doc.createTextNode("second"))
+        self.confirm(len(root.childNodes) == 2
+                and root.childNodes.length == 2,
+                "testNormalize -- preparation")
+        doc.normalize()
+        self.confirm(len(root.childNodes) == 1
+                and root.childNodes.length == 1
+                and root.firstChild is root.lastChild
+                and root.firstChild.data == "firstsecond"
+                , "testNormalize -- result")
+        doc.unlink()
+
+        doc = parseString("<doc/>")
+        root = doc.documentElement
+        root.appendChild(doc.createTextNode(""))
+        doc.normalize()
+        self.confirm(len(root.childNodes) == 0
+                and root.childNodes.length == 0,
+                "testNormalize -- single empty node removed")
+        doc.unlink()
+
+    def testSiblings(self):
+        doc = parseString("<doc><?pi?>text?<elm/></doc>")
+        root = doc.documentElement
+        (pi, text, elm) = root.childNodes
+
+        self.confirm(pi.nextSibling is text and
+                pi.previousSibling is None and
+                text.nextSibling is elm and
+                text.previousSibling is pi and
+                elm.nextSibling is None and
+                elm.previousSibling is text, "testSiblings")
+
+        doc.unlink()
+
+    def testParents(self):
+        doc = parseString(
+            "<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
+        root = doc.documentElement
+        elm1 = root.childNodes[0]
+        (elm2a, elm2b) = elm1.childNodes
+        elm3 = elm2b.childNodes[0]
+
+        self.confirm(root.parentNode is doc and
+                elm1.parentNode is root and
+                elm2a.parentNode is elm1 and
+                elm2b.parentNode is elm1 and
+                elm3.parentNode is elm2b, "testParents")
+        doc.unlink()
+
+    def testNodeListItem(self):
+        doc = parseString("<doc><e/><e/></doc>")
+        children = doc.childNodes
+        docelem = children[0]
+        self.confirm(children[0] is children.item(0)
+                and children.item(1) is None
+                and docelem.childNodes.item(0) is docelem.childNodes[0]
+                and docelem.childNodes.item(1) is docelem.childNodes[1]
+                and docelem.childNodes.item(0).childNodes.item(0) is None,
+                "test NodeList.item()")
+        doc.unlink()
+
+    def testSAX2DOM(self):
+        from xml.dom import pulldom
+
+        sax2dom = pulldom.SAX2DOM()
+        sax2dom.startDocument()
+        sax2dom.startElement("doc", {})
+        sax2dom.characters("text")
+        sax2dom.startElement("subelm", {})
+        sax2dom.characters("text")
+        sax2dom.endElement("subelm")
+        sax2dom.characters("text")
+        sax2dom.endElement("doc")
+        sax2dom.endDocument()
+
+        doc = sax2dom.document
+        root = doc.documentElement
+        (text1, elm1, text2) = root.childNodes
+        text3 = elm1.childNodes[0]
+
+        self.confirm(text1.previousSibling is None and
+                text1.nextSibling is elm1 and
+                elm1.previousSibling is text1 and
+                elm1.nextSibling is text2 and
+                text2.previousSibling is elm1 and
+                text2.nextSibling is None and
+                text3.previousSibling is None and
+                text3.nextSibling is None, "testSAX2DOM - siblings")
+
+        self.confirm(root.parentNode is doc and
+                text1.parentNode is root and
+                elm1.parentNode is root and
+                text2.parentNode is root and
+                text3.parentNode is elm1, "testSAX2DOM - parents")
+        doc.unlink()
+
+    def testEncodings(self):
+        doc = parseString('<foo>&#x20ac;</foo>')
+        self.confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
+                and doc.toxml('utf-8') ==
+                '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
+                and doc.toxml('iso-8859-15') ==
+                '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
+                "testEncodings - encoding EURO SIGN")
+
+        # Verify that character decoding errors throw exceptions instead
+        # of crashing
+        self.assertRaises(UnicodeDecodeError, parseString,
+                '<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
+
+        doc.unlink()
+
+    class UserDataHandler:
+        called = 0
+        def handle(self, operation, key, data, src, dst):
+            dst.setUserData(key, data + 1, self)
+            src.setUserData(key, None, None)
+            self.called = 1
+
+    def testUserData(self):
+        dom = Document()
+        n = dom.createElement('e')
+        self.confirm(n.getUserData("foo") is None)
+        n.setUserData("foo", None, None)
+        self.confirm(n.getUserData("foo") is None)
+        n.setUserData("foo", 12, 12)
+        n.setUserData("bar", 13, 13)
+        self.confirm(n.getUserData("foo") == 12)
+        self.confirm(n.getUserData("bar") == 13)
+        n.setUserData("foo", None, None)
+        self.confirm(n.getUserData("foo") is None)
+        self.confirm(n.getUserData("bar") == 13)
+
+        handler = self.UserDataHandler()
+        n.setUserData("bar", 12, handler)
+        c = n.cloneNode(1)
+        self.confirm(handler.called
+                and n.getUserData("bar") is None
+                and c.getUserData("bar") == 13)
+        n.unlink()
+        c.unlink()
+        dom.unlink()
+
+    def checkRenameNodeSharedConstraints(self, doc, node):
+        # Make sure illegal NS usage is detected:
+        self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, node,
+                          "http://xml.python.org/ns", "xmlns:foo")
+        doc2 = parseString("<doc/>")
+        self.assertRaises(xml.dom.WrongDocumentErr, doc2.renameNode, node,
+                          xml.dom.EMPTY_NAMESPACE, "foo")
 
+    def testRenameAttribute(self):
+        doc = parseString("<doc a='v'/>")
+        elem = doc.documentElement
+        attrmap = elem.attributes
+        attr = elem.attributes['a']
 
-def testReplaceWholeText():
-    def setup():
-        doc = parseString("<doc>a<e/>d</doc>")
+        # Simple renaming
+        attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
+        self.confirm(attr.name == "b"
+                and attr.nodeName == "b"
+                and attr.localName is None
+                and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
+                and attr.prefix is None
+                and attr.value == "v"
+                and elem.getAttributeNode("a") is None
+                and elem.getAttributeNode("b").isSameNode(attr)
+                and attrmap["b"].isSameNode(attr)
+                and attr.ownerDocument.isSameNode(doc)
+                and attr.ownerElement.isSameNode(elem))
+
+        # Rename to have a namespace, no prefix
+        attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
+        self.confirm(attr.name == "c"
+                and attr.nodeName == "c"
+                and attr.localName == "c"
+                and attr.namespaceURI == "http://xml.python.org/ns"
+                and attr.prefix is None
+                and attr.value == "v"
+                and elem.getAttributeNode("a") is None
+                and elem.getAttributeNode("b") is None
+                and elem.getAttributeNode("c").isSameNode(attr)
+                and elem.getAttributeNodeNS(
+                    "http://xml.python.org/ns", "c").isSameNode(attr)
+                and attrmap["c"].isSameNode(attr)
+                and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
+
+        # Rename to have a namespace, with prefix
+        attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
+        self.confirm(attr.name == "p:d"
+                and attr.nodeName == "p:d"
+                and attr.localName == "d"
+                and attr.namespaceURI == "http://xml.python.org/ns2"
+                and attr.prefix == "p"
+                and attr.value == "v"
+                and elem.getAttributeNode("a") is None
+                and elem.getAttributeNode("b") is None
+                and elem.getAttributeNode("c") is None
+                and elem.getAttributeNodeNS(
+                    "http://xml.python.org/ns", "c") is None
+                and elem.getAttributeNode("p:d").isSameNode(attr)
+                and elem.getAttributeNodeNS(
+                    "http://xml.python.org/ns2", "d").isSameNode(attr)
+                and attrmap["p:d"].isSameNode(attr)
+                and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
+
+        # Rename back to a simple non-NS node
+        attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
+        self.confirm(attr.name == "e"
+                and attr.nodeName == "e"
+                and attr.localName is None
+                and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
+                and attr.prefix is None
+                and attr.value == "v"
+                and elem.getAttributeNode("a") is None
+                and elem.getAttributeNode("b") is None
+                and elem.getAttributeNode("c") is None
+                and elem.getAttributeNode("p:d") is None
+                and elem.getAttributeNodeNS(
+                    "http://xml.python.org/ns", "c") is None
+                and elem.getAttributeNode("e").isSameNode(attr)
+                and attrmap["e"].isSameNode(attr))
+
+        self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, attr,
+                          "http://xml.python.org/ns", "xmlns")
+        self.checkRenameNodeSharedConstraints(doc, attr)
+        doc.unlink()
+
+    def testRenameElement(self):
+        doc = parseString("<doc/>")
+        elem = doc.documentElement
+
+        # Simple renaming
+        elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
+        self.confirm(elem.tagName == "a"
+                and elem.nodeName == "a"
+                and elem.localName is None
+                and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
+                and elem.prefix is None
+                and elem.ownerDocument.isSameNode(doc))
+
+        # Rename to have a namespace, no prefix
+        elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
+        self.confirm(elem.tagName == "b"
+                and elem.nodeName == "b"
+                and elem.localName == "b"
+                and elem.namespaceURI == "http://xml.python.org/ns"
+                and elem.prefix is None
+                and elem.ownerDocument.isSameNode(doc))
+
+        # Rename to have a namespace, with prefix
+        elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
+        self.confirm(elem.tagName == "p:c"
+                and elem.nodeName == "p:c"
+                and elem.localName == "c"
+                and elem.namespaceURI == "http://xml.python.org/ns2"
+                and elem.prefix == "p"
+                and elem.ownerDocument.isSameNode(doc))
+
+        # Rename back to a simple non-NS node
+        elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
+        self.confirm(elem.tagName == "d"
+                and elem.nodeName == "d"
+                and elem.localName is None
+                and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
+                and elem.prefix is None
+                and elem.ownerDocument.isSameNode(doc))
+
+        self.checkRenameNodeSharedConstraints(doc, elem)
+        doc.unlink()
+
+    def testRenameOther(self):
+        # We have to create a comment node explicitly since not all DOM
+        # builders used with minidom add comments to the DOM.
+        doc = xml.dom.minidom.getDOMImplementation().createDocument(
+            xml.dom.EMPTY_NAMESPACE, "e", None)
+        node = doc.createComment("comment")
+        self.assertRaises(xml.dom.NotSupportedErr, doc.renameNode, node,
+                          xml.dom.EMPTY_NAMESPACE, "foo")
+        doc.unlink()
+
+    def testWholeText(self):
+        doc = parseString("<doc>a</doc>")
+        elem = doc.documentElement
+        text = elem.childNodes[0]
+        self.assertEquals(text.nodeType, Node.TEXT_NODE)
+
+        self.checkWholeText(text, "a")
+        elem.appendChild(doc.createTextNode("b"))
+        self.checkWholeText(text, "ab")
+        elem.insertBefore(doc.createCDATASection("c"), text)
+        self.checkWholeText(text, "cab")
+
+        # make sure we don't cross other nodes
+        splitter = doc.createComment("comment")
+        elem.appendChild(splitter)
+        text2 = doc.createTextNode("d")
+        elem.appendChild(text2)
+        self.checkWholeText(text, "cab")
+        self.checkWholeText(text2, "d")
+
+        x = doc.createElement("x")
+        elem.replaceChild(x, splitter)
+        splitter = x
+        self.checkWholeText(text, "cab")
+        self.checkWholeText(text2, "d")
+
+        x = doc.createProcessingInstruction("y", "z")
+        elem.replaceChild(x, splitter)
+        splitter = x
+        self.checkWholeText(text, "cab")
+        self.checkWholeText(text2, "d")
+
+        elem.removeChild(splitter)
+        self.checkWholeText(text, "cabd")
+        self.checkWholeText(text2, "cabd")
+
+    def testPatch1094164(self):
+        doc = parseString("<doc><e/></doc>")
         elem = doc.documentElement
-        text1 = elem.firstChild
-        text2 = elem.lastChild
-        splitter = text1.nextSibling
-        elem.insertBefore(doc.createTextNode("b"), splitter)
-        elem.insertBefore(doc.createCDATASection("c"), text1)
-        return doc, elem, text1, splitter, text2
-
-    doc, elem, text1, splitter, text2 = setup()
-    text = text1.replaceWholeText("new content")
-    checkWholeText(text, "new content")
-    checkWholeText(text2, "d")
-    confirm(len(elem.childNodes) == 3)
-
-    doc, elem, text1, splitter, text2 = setup()
-    text = text2.replaceWholeText("new content")
-    checkWholeText(text, "new content")
-    checkWholeText(text1, "cab")
-    confirm(len(elem.childNodes) == 5)
-
-    doc, elem, text1, splitter, text2 = setup()
-    text = text1.replaceWholeText("")
-    checkWholeText(text2, "d")
-    confirm(text is None
-            and len(elem.childNodes) == 2)
-
-def testSchemaType():
-    doc = parseString(
-        "<!DOCTYPE doc [\n"
-        "  <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
-        "  <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
-        "  <!ATTLIST doc id   ID       #IMPLIED \n"
-        "                ref  IDREF    #IMPLIED \n"
-        "                refs IDREFS   #IMPLIED \n"
-        "                enum (a|b)    #IMPLIED \n"
-        "                ent  ENTITY   #IMPLIED \n"
-        "                ents ENTITIES #IMPLIED \n"
-        "                nm   NMTOKEN  #IMPLIED \n"
-        "                nms  NMTOKENS #IMPLIED \n"
-        "                text CDATA    #IMPLIED \n"
-        "    >\n"
-        "]><doc id='name' notid='name' text='splat!' enum='b'"
-        "       ref='name' refs='name name' ent='e1' ents='e1 e2'"
-        "       nm='123' nms='123 abc' />")
-    elem = doc.documentElement
-    # We don't want to rely on any specific loader at this point, so
-    # just make sure we can get to all the names, and that the
-    # DTD-based namespace is right.  The names can vary by loader
-    # since each supports a different level of DTD information.
-    t = elem.schemaType
-    confirm(t.name is None
-            and t.namespace == xml.dom.EMPTY_NAMESPACE)
-    names = "id notid text enum ref refs ent ents nm nms".split()
-    for name in names:
-        a = elem.getAttributeNode(name)
-        t = a.schemaType
-        confirm(hasattr(t, "name")
+        e = elem.firstChild
+        self.confirm(e.parentNode is elem, "Before replaceChild()")
+        # Check that replacing a child with itself leaves the tree unchanged
+        elem.replaceChild(e, e)
+        self.confirm(e.parentNode is elem, "After replaceChild()")
+
+    def testReplaceWholeText(self):
+        def setup():
+            doc = parseString("<doc>a<e/>d</doc>")
+            elem = doc.documentElement
+            text1 = elem.firstChild
+            text2 = elem.lastChild
+            splitter = text1.nextSibling
+            elem.insertBefore(doc.createTextNode("b"), splitter)
+            elem.insertBefore(doc.createCDATASection("c"), text1)
+            return doc, elem, text1, splitter, text2
+
+        doc, elem, text1, splitter, text2 = setup()
+        text = text1.replaceWholeText("new content")
+        self.checkWholeText(text, "new content")
+        self.checkWholeText(text2, "d")
+        self.confirm(len(elem.childNodes) == 3)
+
+        doc, elem, text1, splitter, text2 = setup()
+        text = text2.replaceWholeText("new content")
+        self.checkWholeText(text, "new content")
+        self.checkWholeText(text1, "cab")
+        self.confirm(len(elem.childNodes) == 5)
+
+        doc, elem, text1, splitter, text2 = setup()
+        text = text1.replaceWholeText("")
+        self.checkWholeText(text2, "d")
+        self.confirm(text is None
+                and len(elem.childNodes) == 2)
+
+    def testSchemaType(self):
+        doc = parseString(
+            "<!DOCTYPE doc [\n"
+            "  <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
+            "  <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
+            "  <!ATTLIST doc id   ID       #IMPLIED \n"
+            "                ref  IDREF    #IMPLIED \n"
+            "                refs IDREFS   #IMPLIED \n"
+            "                enum (a|b)    #IMPLIED \n"
+            "                ent  ENTITY   #IMPLIED \n"
+            "                ents ENTITIES #IMPLIED \n"
+            "                nm   NMTOKEN  #IMPLIED \n"
+            "                nms  NMTOKENS #IMPLIED \n"
+            "                text CDATA    #IMPLIED \n"
+            "    >\n"
+            "]><doc id='name' notid='name' text='splat!' enum='b'"
+            "       ref='name' refs='name name' ent='e1' ents='e1 e2'"
+            "       nm='123' nms='123 abc' />")
+        elem = doc.documentElement
+        # We don't want to rely on any specific loader at this point, so
+        # just make sure we can get to all the names, and that the
+        # DTD-based namespace is right.  The names can vary by loader
+        # since each supports a different level of DTD information.
+        t = elem.schemaType
+        self.confirm(t.name is None
                 and t.namespace == xml.dom.EMPTY_NAMESPACE)
+        names = "id notid text enum ref refs ent ents nm nms".split()
+        for name in names:
+            a = elem.getAttributeNode(name)
+            t = a.schemaType
+            self.confirm(hasattr(t, "name")
+                    and t.namespace == xml.dom.EMPTY_NAMESPACE)
+
+    def testSetIdAttribute(self):
+        doc = parseString("<doc a1='v' a2='w'/>")
+        e = doc.documentElement
+        a1 = e.getAttributeNode("a1")
+        a2 = e.getAttributeNode("a2")
+        self.confirm(doc.getElementById("v") is None
+                and not a1.isId
+                and not a2.isId)
+        e.setIdAttribute("a1")
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and a1.isId
+                and not a2.isId)
+        e.setIdAttribute("a2")
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and e.isSameNode(doc.getElementById("w"))
+                and a1.isId
+                and a2.isId)
+        # replace the a1 node; the new node should *not* be an ID
+        a3 = doc.createAttribute("a1")
+        a3.value = "v"
+        e.setAttributeNode(a3)
+        self.confirm(doc.getElementById("v") is None
+                and e.isSameNode(doc.getElementById("w"))
+                and not a1.isId
+                and a2.isId
+                and not a3.isId)
+        # renaming an attribute should not affect its ID-ness:
+        doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+        self.confirm(e.isSameNode(doc.getElementById("w"))
+                and a2.isId)
+
+    def testSetIdAttributeNS(self):
+        NS1 = "http://xml.python.org/ns1"
+        NS2 = "http://xml.python.org/ns2"
+        doc = parseString("<doc"
+                          " xmlns:ns1='" + NS1 + "'"
+                          " xmlns:ns2='" + NS2 + "'"
+                          " ns1:a1='v' ns2:a2='w'/>")
+        e = doc.documentElement
+        a1 = e.getAttributeNodeNS(NS1, "a1")
+        a2 = e.getAttributeNodeNS(NS2, "a2")
+        self.confirm(doc.getElementById("v") is None
+                and not a1.isId
+                and not a2.isId)
+        e.setIdAttributeNS(NS1, "a1")
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and a1.isId
+                and not a2.isId)
+        e.setIdAttributeNS(NS2, "a2")
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and e.isSameNode(doc.getElementById("w"))
+                and a1.isId
+                and a2.isId)
+        # replace the a1 node; the new node should *not* be an ID
+        a3 = doc.createAttributeNS(NS1, "a1")
+        a3.value = "v"
+        e.setAttributeNode(a3)
+        self.confirm(e.isSameNode(doc.getElementById("w")))
+        self.confirm(not a1.isId)
+        self.confirm(a2.isId)
+        self.confirm(not a3.isId)
+        self.confirm(doc.getElementById("v") is None)
+        # renaming an attribute should not affect its ID-ness:
+        doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+        self.confirm(e.isSameNode(doc.getElementById("w"))
+                and a2.isId)
+
+    def testSetIdAttributeNode(self):
+        NS1 = "http://xml.python.org/ns1"
+        NS2 = "http://xml.python.org/ns2"
+        doc = parseString("<doc"
+                          " xmlns:ns1='" + NS1 + "'"
+                          " xmlns:ns2='" + NS2 + "'"
+                          " ns1:a1='v' ns2:a2='w'/>")
+        e = doc.documentElement
+        a1 = e.getAttributeNodeNS(NS1, "a1")
+        a2 = e.getAttributeNodeNS(NS2, "a2")
+        self.confirm(doc.getElementById("v") is None
+                and not a1.isId
+                and not a2.isId)
+        e.setIdAttributeNode(a1)
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and a1.isId
+                and not a2.isId)
+        e.setIdAttributeNode(a2)
+        self.confirm(e.isSameNode(doc.getElementById("v"))
+                and e.isSameNode(doc.getElementById("w"))
+                and a1.isId
+                and a2.isId)
+        # replace the a1 node; the new node should *not* be an ID
+        a3 = doc.createAttributeNS(NS1, "a1")
+        a3.value = "v"
+        e.setAttributeNode(a3)
+        self.confirm(e.isSameNode(doc.getElementById("w")))
+        self.confirm(not a1.isId)
+        self.confirm(a2.isId)
+        self.confirm(not a3.isId)
+        self.confirm(doc.getElementById("v") is None)
+        # renaming an attribute should not affect its ID-ness:
+        doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
+        self.confirm(e.isSameNode(doc.getElementById("w"))
+                and a2.isId)
+
+    def testPickledDocument(self):
+        doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
+                    "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
+                    " 'http://xml.python.org/system' [\n"
+                    "  <!ELEMENT e EMPTY>\n"
+                    "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
+                    "]><doc attr='value'> text\n"
+                    "<?pi sample?> <!-- comment --> <e/> </doc>")
+        s = pickle.dumps(doc)
+        doc2 = pickle.loads(s)
+        stack = [(doc, doc2)]
+        while stack:
+            n1, n2 = stack.pop()
+            self.confirm(n1.nodeType == n2.nodeType
+                    and len(n1.childNodes) == len(n2.childNodes)
+                    and n1.nodeName == n2.nodeName
+                    and not n1.isSameNode(n2)
+                    and not n2.isSameNode(n1))
+            if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
+                len(n1.entities)
+                len(n2.entities)
+                len(n1.notations)
+                len(n2.notations)
+                self.confirm(len(n1.entities) == len(n2.entities)
+                        and len(n1.notations) == len(n2.notations))
+                for i in range(len(n1.notations)):
+                    no1 = n1.notations.item(i)
+                    no2 = n1.notations.item(i)
+                    self.confirm(no1.name == no2.name
+                            and no1.publicId == no2.publicId
+                            and no1.systemId == no2.systemId)
+                    statck.append((no1, no2))
+                for i in range(len(n1.entities)):
+                    e1 = n1.entities.item(i)
+                    e2 = n2.entities.item(i)
+                    self.confirm(e1.notationName == e2.notationName
+                            and e1.publicId == e2.publicId
+                            and e1.systemId == e2.systemId)
+                    stack.append((e1, e2))
+            if n1.nodeType != Node.DOCUMENT_NODE:
+                self.confirm(n1.ownerDocument.isSameNode(doc)
+                        and n2.ownerDocument.isSameNode(doc2))
+            for i in range(len(n1.childNodes)):
+                stack.append((n1.childNodes[i], n2.childNodes[i]))
 
-def testSetIdAttribute():
-    doc = parseString("<doc a1='v' a2='w'/>")
-    e = doc.documentElement
-    a1 = e.getAttributeNode("a1")
-    a2 = e.getAttributeNode("a2")
-    confirm(doc.getElementById("v") is None
-            and not a1.isId
-            and not a2.isId)
-    e.setIdAttribute("a1")
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and a1.isId
-            and not a2.isId)
-    e.setIdAttribute("a2")
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and e.isSameNode(doc.getElementById("w"))
-            and a1.isId
-            and a2.isId)
-    # replace the a1 node; the new node should *not* be an ID
-    a3 = doc.createAttribute("a1")
-    a3.value = "v"
-    e.setAttributeNode(a3)
-    confirm(doc.getElementById("v") is None
-            and e.isSameNode(doc.getElementById("w"))
-            and not a1.isId
-            and a2.isId
-            and not a3.isId)
-    # renaming an attribute should not affect its ID-ness:
-    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
-    confirm(e.isSameNode(doc.getElementById("w"))
-            and a2.isId)
-
-def testSetIdAttributeNS():
-    NS1 = "http://xml.python.org/ns1"
-    NS2 = "http://xml.python.org/ns2"
-    doc = parseString("<doc"
-                      " xmlns:ns1='" + NS1 + "'"
-                      " xmlns:ns2='" + NS2 + "'"
-                      " ns1:a1='v' ns2:a2='w'/>")
-    e = doc.documentElement
-    a1 = e.getAttributeNodeNS(NS1, "a1")
-    a2 = e.getAttributeNodeNS(NS2, "a2")
-    confirm(doc.getElementById("v") is None
-            and not a1.isId
-            and not a2.isId)
-    e.setIdAttributeNS(NS1, "a1")
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and a1.isId
-            and not a2.isId)
-    e.setIdAttributeNS(NS2, "a2")
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and e.isSameNode(doc.getElementById("w"))
-            and a1.isId
-            and a2.isId)
-    # replace the a1 node; the new node should *not* be an ID
-    a3 = doc.createAttributeNS(NS1, "a1")
-    a3.value = "v"
-    e.setAttributeNode(a3)
-    confirm(e.isSameNode(doc.getElementById("w")))
-    confirm(not a1.isId)
-    confirm(a2.isId)
-    confirm(not a3.isId)
-    confirm(doc.getElementById("v") is None)
-    # renaming an attribute should not affect its ID-ness:
-    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
-    confirm(e.isSameNode(doc.getElementById("w"))
-            and a2.isId)
-
-def testSetIdAttributeNode():
-    NS1 = "http://xml.python.org/ns1"
-    NS2 = "http://xml.python.org/ns2"
-    doc = parseString("<doc"
-                      " xmlns:ns1='" + NS1 + "'"
-                      " xmlns:ns2='" + NS2 + "'"
-                      " ns1:a1='v' ns2:a2='w'/>")
-    e = doc.documentElement
-    a1 = e.getAttributeNodeNS(NS1, "a1")
-    a2 = e.getAttributeNodeNS(NS2, "a2")
-    confirm(doc.getElementById("v") is None
-            and not a1.isId
-            and not a2.isId)
-    e.setIdAttributeNode(a1)
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and a1.isId
-            and not a2.isId)
-    e.setIdAttributeNode(a2)
-    confirm(e.isSameNode(doc.getElementById("v"))
-            and e.isSameNode(doc.getElementById("w"))
-            and a1.isId
-            and a2.isId)
-    # replace the a1 node; the new node should *not* be an ID
-    a3 = doc.createAttributeNS(NS1, "a1")
-    a3.value = "v"
-    e.setAttributeNode(a3)
-    confirm(e.isSameNode(doc.getElementById("w")))
-    confirm(not a1.isId)
-    confirm(a2.isId)
-    confirm(not a3.isId)
-    confirm(doc.getElementById("v") is None)
-    # renaming an attribute should not affect its ID-ness:
-    doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
-    confirm(e.isSameNode(doc.getElementById("w"))
-            and a2.isId)
-
-def testPickledDocument():
-    doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
-                      "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
-                      " 'http://xml.python.org/system' [\n"
-                      "  <!ELEMENT e EMPTY>\n"
-                      "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
-                      "]><doc attr='value'> text\n"
-                      "<?pi sample?> <!-- comment --> <e/> </doc>")
-    s = pickle.dumps(doc)
-    doc2 = pickle.loads(s)
-    stack = [(doc, doc2)]
-    while stack:
-        n1, n2 = stack.pop()
-        confirm(n1.nodeType == n2.nodeType
-                and len(n1.childNodes) == len(n2.childNodes)
-                and n1.nodeName == n2.nodeName
-                and not n1.isSameNode(n2)
-                and not n2.isSameNode(n1))
-        if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
-            len(n1.entities)
-            len(n2.entities)
-            len(n1.notations)
-            len(n2.notations)
-            confirm(len(n1.entities) == len(n2.entities)
-                    and len(n1.notations) == len(n2.notations))
-            for i in range(len(n1.notations)):
-                no1 = n1.notations.item(i)
-                no2 = n1.notations.item(i)
-                confirm(no1.name == no2.name
-                        and no1.publicId == no2.publicId
-                        and no1.systemId == no2.systemId)
-                statck.append((no1, no2))
-            for i in range(len(n1.entities)):
-                e1 = n1.entities.item(i)
-                e2 = n2.entities.item(i)
-                confirm(e1.notationName == e2.notationName
-                        and e1.publicId == e2.publicId
-                        and e1.systemId == e2.systemId)
-                stack.append((e1, e2))
-        if n1.nodeType != Node.DOCUMENT_NODE:
-            confirm(n1.ownerDocument.isSameNode(doc)
-                    and n2.ownerDocument.isSameNode(doc2))
-        for i in range(len(n1.childNodes)):
-            stack.append((n1.childNodes[i], n2.childNodes[i]))
-
-
-# --- MAIN PROGRAM
-
-names = sorted(globals().keys())
-
-failed = []
-
-try:
-    Node.allnodes
-except AttributeError:
-    # We don't actually have the minidom from the standard library,
-    # but are picking up the PyXML version from site-packages.
-    def check_allnodes():
-        pass
-else:
-    def check_allnodes():
-        confirm(len(Node.allnodes) == 0,
-                "assertion: len(Node.allnodes) == 0")
-        if len(Node.allnodes):
-            print("Garbage left over:")
-            if verbose:
-                print(Node.allnodes.items()[0:10])
-            else:
-                # Don't print specific nodes if repeatable results
-                # are needed
-                print(len(Node.allnodes))
-        Node.allnodes = {}
-
-for name in names:
-    if name.startswith("test"):
-        func = globals()[name]
-        try:
-            func()
-            check_allnodes()
-        except:
-            failed.append(name)
-            print("Test Failed: ", name)
-            sys.stdout.flush()
-            traceback.print_exception(*sys.exc_info())
-            print(repr(sys.exc_info()[1]))
-            Node.allnodes = {}
+def test_main():
+    run_unittest(MinidomTest)
 
-if failed:
-    print("\n\n\n**** Check for failures in these tests:")
-    for name in failed:
-        print("  " + name)
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_module.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_module.py	(original)
+++ python/branches/p3yk/Lib/test/test_module.py	Fri Apr 27 21:54:29 2007
@@ -1,48 +1,61 @@
 # Test the module type
-
-from test.test_support import verify, vereq, verbose, TestFailed
+import unittest
+from test.test_support import verbose, run_unittest
 
 import sys
-module = type(sys)
+ModuleType = type(sys)
+
+class ModuleTests(unittest.TestCase):
+    def test_uninitialized(self):
+        # An uninitialized module has no __dict__ or __name__,
+        # and __doc__ is None
+        foo = ModuleType.__new__(ModuleType)
+        self.failUnless(foo.__dict__ is None)
+        try:
+            s = foo.__name__
+            self.fail("__name__ = %s" % repr(s))
+        except AttributeError:
+            pass
+        self.assertEqual(foo.__doc__, ModuleType.__doc__)
+
+    def test_no_docstring(self):
+        # Regularly initialized module, no docstring
+        foo = ModuleType("foo")
+        self.assertEqual(foo.__name__, "foo")
+        self.assertEqual(foo.__doc__, None)
+        self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": None})
+
+    def test_ascii_docstring(self):
+        # ASCII docstring
+        foo = ModuleType("foo", "foodoc")
+        self.assertEqual(foo.__name__, "foo")
+        self.assertEqual(foo.__doc__, "foodoc")
+        self.assertEqual(foo.__dict__,
+                         {"__name__": "foo", "__doc__": "foodoc"})
+
+    def test_unicode_docstring(self):
+        # Unicode docstring
+        foo = ModuleType("foo", u"foodoc\u1234")
+        self.assertEqual(foo.__name__, "foo")
+        self.assertEqual(foo.__doc__, u"foodoc\u1234")
+        self.assertEqual(foo.__dict__,
+                         {"__name__": "foo", "__doc__": u"foodoc\u1234"})
+
+    def test_reinit(self):
+        # Reinitialization should not replace the __dict__
+        foo = ModuleType("foo", u"foodoc\u1234")
+        foo.bar = 42
+        d = foo.__dict__
+        foo.__init__("foo", "foodoc")
+        self.assertEqual(foo.__name__, "foo")
+        self.assertEqual(foo.__doc__, "foodoc")
+        self.assertEqual(foo.bar, 42)
+        self.assertEqual(foo.__dict__,
+              {"__name__": "foo", "__doc__": "foodoc", "bar": 42})
+        self.failUnless(foo.__dict__ is d)
 
-# An uninitialized module has no __dict__ or __name__, and __doc__ is None
-foo = module.__new__(module)
-verify(foo.__dict__ is None)
-try:
-    s = foo.__name__
-except AttributeError:
-    pass
-else:
-    raise TestFailed, "__name__ = %s" % repr(s)
-vereq(foo.__doc__, module.__doc__)
-
-# Regularly initialized module, no docstring
-foo = module("foo")
-vereq(foo.__name__, "foo")
-vereq(foo.__doc__, None)
-vereq(foo.__dict__, {"__name__": "foo", "__doc__": None})
-
-# ASCII docstring
-foo = module("foo", "foodoc")
-vereq(foo.__name__, "foo")
-vereq(foo.__doc__, "foodoc")
-vereq(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc"})
-
-# Unicode docstring
-foo = module("foo", u"foodoc\u1234")
-vereq(foo.__name__, "foo")
-vereq(foo.__doc__, u"foodoc\u1234")
-vereq(foo.__dict__, {"__name__": "foo", "__doc__": u"foodoc\u1234"})
-
-# Reinitialization should not replace the __dict__
-foo.bar = 42
-d = foo.__dict__
-foo.__init__("foo", "foodoc")
-vereq(foo.__name__, "foo")
-vereq(foo.__doc__, "foodoc")
-vereq(foo.bar, 42)
-vereq(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc", "bar": 42})
-verify(foo.__dict__ is d)
+def test_main():
+    run_unittest(ModuleTests)
 
-if verbose:
-    print("All OK")
+if __name__ == '__main__':
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_multibytecodec.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_multibytecodec.py	(original)
+++ python/branches/p3yk/Lib/test/test_multibytecodec.py	Fri Apr 27 21:54:29 2007
@@ -219,13 +219,7 @@
             myunichr(x).encode('iso_2022_jp', 'ignore')
 
 def test_main():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(Test_MultibyteCodec))
-    suite.addTest(unittest.makeSuite(Test_IncrementalEncoder))
-    suite.addTest(unittest.makeSuite(Test_IncrementalDecoder))
-    suite.addTest(unittest.makeSuite(Test_StreamWriter))
-    suite.addTest(unittest.makeSuite(Test_ISO2022))
-    test_support.run_suite(suite)
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_normalization.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_normalization.py	(original)
+++ python/branches/p3yk/Lib/test/test_normalization.py	Fri Apr 27 21:54:29 2007
@@ -1,5 +1,6 @@
-from test.test_support import (verbose, TestFailed, TestSkipped, verify,
-                               open_urlresource)
+from test.test_support import run_unittest, open_urlresource
+import unittest
+
 import sys
 import os
 from unicodedata import normalize
@@ -29,60 +30,67 @@
             raise RangeError
     return u"".join([unichr(x) for x in data])
 
-def test_main():
-    part1_data = {}
-    for line in open_urlresource(TESTDATAURL):
-        if '#' in line:
-            line = line.split('#')[0]
-        line = line.strip()
-        if not line:
-            continue
-        if line.startswith("@Part"):
-            part = line.split()[0]
-            continue
-        if part == "@Part3":
-            # XXX we don't support PRI #29 yet, so skip these tests for now
-            continue
-        try:
-            c1,c2,c3,c4,c5 = [unistr(x) for x in line.split(';')[:-1]]
-        except RangeError:
-            # Skip unsupported characters;
-            # try atleast adding c1 if we are in part1
+class NormalizationTest(unittest.TestCase):
+    def test_main(self):
+        part1_data = {}
+        for line in open_urlresource(TESTDATAURL):
+            if '#' in line:
+                line = line.split('#')[0]
+            line = line.strip()
+            if not line:
+                continue
+            if line.startswith("@Part"):
+                part = line.split()[0]
+                continue
+            if part == "@Part3":
+                # XXX we don't support PRI #29 yet, so skip these tests for now
+                continue
+            try:
+                c1,c2,c3,c4,c5 = [unistr(x) for x in line.split(';')[:-1]]
+            except RangeError:
+                # Skip unsupported characters;
+                # try atleast adding c1 if we are in part1
+                if part == "@Part1":
+                    try:
+                        c1 = unistr(line.split(';')[0])
+                    except RangeError:
+                        pass
+                    else:
+                        part1_data[c1] = 1
+                continue
+
+            # Perform tests
+            self.failUnless(c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3), line)
+            self.failUnless(c4 ==  NFC(c4) ==  NFC(c5), line)
+            self.failUnless(c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3), line)
+            self.failUnless(c5 ==  NFD(c4) ==  NFD(c5), line)
+            self.failUnless(c4 == NFKC(c1) == NFKC(c2) == \
+                            NFKC(c3) == NFKC(c4) == NFKC(c5),
+                            line)
+            self.failUnless(c5 == NFKD(c1) == NFKD(c2) == \
+                            NFKD(c3) == NFKD(c4) == NFKD(c5),
+                            line)
+
+            # Record part 1 data
             if part == "@Part1":
-                try:
-                    c1=unistr(line.split(';')[0])
-                except RangeError:
-                    pass
-                else:
-                    part1_data[c1] = 1
-            continue
-
-        if verbose:
-            print(line)
-
-        # Perform tests
-        verify(c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3), line)
-        verify(c4 ==  NFC(c4) ==  NFC(c5), line)
-        verify(c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3), line)
-        verify(c5 ==  NFD(c4) ==  NFD(c5), line)
-        verify(c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5),
-               line)
-        verify(c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5),
-               line)
-
-        # Record part 1 data
-        if part == "@Part1":
-            part1_data[c1] = 1
-
-    # Perform tests for all other data
-    for c in range(sys.maxunicode+1):
-        X = unichr(c)
-        if X in part1_data:
-            continue
-        assert X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X), c
+                part1_data[c1] = 1
 
-    # Check for bug 834676
-    normalize('NFC',u'\ud55c\uae00')
+        # Perform tests for all other data
+        for c in range(sys.maxunicode+1):
+            X = unichr(c)
+            if X in part1_data:
+                continue
+            self.failUnless(X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X), c)
+
+    def test_bug_834676(self):
+        # Check for bug 834676
+        normalize('NFC', u'\ud55c\uae00')
+
+
+def test_main():
+    # Hit the exception early
+    open_urlresource(TESTDATAURL)
+    run_unittest(NormalizationTest)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/p3yk/Lib/test/test_ntpath.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_ntpath.py	(original)
+++ python/branches/p3yk/Lib/test/test_ntpath.py	Fri Apr 27 21:54:29 2007
@@ -18,13 +18,14 @@
 
 tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
 tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
-tester('ntpath.splitext(".ext")', ('', '.ext'))
+tester('ntpath.splitext(".ext")', ('.ext', ''))
 tester('ntpath.splitext("\\foo.ext\\foo")', ('\\foo.ext\\foo', ''))
 tester('ntpath.splitext("foo.ext\\")', ('foo.ext\\', ''))
 tester('ntpath.splitext("")', ('', ''))
 tester('ntpath.splitext("foo.bar.ext")', ('foo.bar', '.ext'))
 tester('ntpath.splitext("xx/foo.bar.ext")', ('xx/foo.bar', '.ext'))
 tester('ntpath.splitext("xx\\foo.bar.ext")', ('xx\\foo.bar', '.ext'))
+tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d'))
 
 tester('ntpath.splitdrive("c:\\foo\\bar")',
        ('c:', '\\foo\\bar'))
@@ -133,6 +134,13 @@
     tester('ntpath.expandvars("${{foo}}")', "baz1}")
     tester('ntpath.expandvars("$foo$foo")', "barbar")
     tester('ntpath.expandvars("$bar$bar")', "$bar$bar")
+    tester('ntpath.expandvars("%foo% bar")', "bar bar")
+    tester('ntpath.expandvars("%foo%bar")', "barbar")
+    tester('ntpath.expandvars("%foo%%foo%")', "barbar")
+    tester('ntpath.expandvars("%%foo%%foo%foo%")', "%foo%foobar")
+    tester('ntpath.expandvars("%?bar%")', "%?bar%")
+    tester('ntpath.expandvars("%foo%%bar")', "bar%bar")
+    tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar")
 finally:
     os.environ.clear()
     os.environ.update(oldenv)
@@ -149,6 +157,16 @@
 else:
     tester('ntpath.abspath("C:\\")', "C:\\")
 
+currentdir = os.path.split(os.getcwd())[-1]
+tester('ntpath.relpath("a")', 'a')
+tester('ntpath.relpath(os.path.abspath("a"))', 'a')
+tester('ntpath.relpath("a/b")', 'a\\b')
+tester('ntpath.relpath("../a/b")', '..\\a\\b')
+tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a')
+tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b')
+tester('ntpath.relpath("a", "b/c")', '..\\..\\a')
+tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a')
+
 if errors:
     raise TestFailed(str(errors) + " errors.")
 elif verbose:

Deleted: /python/branches/p3yk/Lib/test/test_operations.py
==============================================================================
--- /python/branches/p3yk/Lib/test/test_operations.py	Fri Apr 27 21:54:29 2007
+++ (empty file)
@@ -1,77 +0,0 @@
-# Python test set -- part 3, built-in operations.
-
-
-print('3. Operations')
-print('XXX Mostly not yet implemented')
-
-
-print('3.1 Dictionary lookups fail if __cmp__() raises an exception')
-
-class BadDictKey:
-
-    def __hash__(self):
-        return hash(self.__class__)
-
-    def __eq__(self, other):
-        if isinstance(other, self.__class__):
-            print("raising error")
-            raise RuntimeError, "gotcha"
-        return other
-
-d = {}
-x1 = BadDictKey()
-x2 = BadDictKey()
-d[x1] = 1
-for stmt in ['d[x2] = 2',
-             'z = d[x2]',
-             'x2 in d',
-             'd.get(x2)',
-             'd.setdefault(x2, 42)',
-             'd.pop(x2)',
-             'd.update({x2: 2})']:
-    try:
-        exec(stmt)
-    except RuntimeError:
-        print("%s: caught the RuntimeError outside" % (stmt,))
-    else:
-        print("%s: No exception passed through!" % (stmt,)) # old CPython behavior
-
-
-# Dict resizing bug, found by Jack Jansen in 2.2 CVS development.
-# This version got an assert failure in debug build, infinite loop in
-# release build.  Unfortunately, provoking this kind of stuff requires
-# a mix of inserts and deletes hitting exactly the right hash codes in
-# exactly the right order, and I can't think of a randomized approach
-# that would be *likely* to hit a failing case in reasonable time.
-
-d = {}
-for i in range(5):
-    d[i] = i
-for i in range(5):
-    del d[i]
-for i in range(5, 9):  # i==8 was the problem
-    d[i] = i
-
-
-# Another dict resizing bug (SF bug #1456209).
-# This caused Segmentation faults or Illegal instructions.
-
-class X(object):
-    def __hash__(self):
-        return 5
-    def __eq__(self, other):
-        if resizing:
-            d.clear()
-        return False
-d = {}
-resizing = False
-d[X()] = 1
-d[X()] = 2
-d[X()] = 3
-d[X()] = 4
-d[X()] = 5
-# now trigger a resize
-resizing = True
-d[9] = 6
-
-print('resize bugs not triggered.')

Modified: python/branches/p3yk/Lib/test/test_operator.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_operator.py	(original)
+++ python/branches/p3yk/Lib/test/test_operator.py	Fri Apr 27 21:54:29 2007
@@ -143,6 +143,8 @@
         self.failUnlessRaises(TypeError, operator.delslice, a, None, None)
         self.failUnless(operator.delslice(a, 2, 8) is None)
         self.assert_(a == [0, 1, 8, 9])
+        operator.delslice(a, 0, test_support.MAX_Py_ssize_t)
+        self.assert_(a == [])
 
     def test_floordiv(self):
         self.failUnlessRaises(TypeError, operator.floordiv, 5)
@@ -165,6 +167,8 @@
         self.failUnlessRaises(TypeError, operator.getslice)
         self.failUnlessRaises(TypeError, operator.getslice, a, None, None)
         self.failUnless(operator.getslice(a, 4, 6) == [4, 5])
+        b = operator.getslice(a, 0, test_support.MAX_Py_ssize_t)
+        self.assert_(b == a)
 
     def test_indexOf(self):
         self.failUnlessRaises(TypeError, operator.indexOf)
@@ -300,6 +304,8 @@
         self.failUnlessRaises(TypeError, operator.setslice, a, None, None, None)
         self.failUnless(operator.setslice(a, 1, 3, [2, 1]) is None)
         self.assert_(a == [0, 2, 1, 3])
+        operator.setslice(a, 0, test_support.MAX_Py_ssize_t, [])
+        self.assert_(a == [])
 
     def test_sub(self):
         self.failUnlessRaises(TypeError, operator.sub)

Modified: python/branches/p3yk/Lib/test/test_optparse.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_optparse.py	(original)
+++ python/branches/p3yk/Lib/test/test_optparse.py	Fri Apr 27 21:54:29 2007
@@ -1631,18 +1631,8 @@
                              "option -l: invalid integer value: '0x12x'")
 
 
-def _testclasses():
-    mod = sys.modules[__name__]
-    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
-
-def suite():
-    suite = unittest.TestSuite()
-    for testclass in _testclasses():
-        suite.addTest(unittest.makeSuite(testclass))
-    return suite
-
 def test_main():
-    test_support.run_suite(suite())
+    test_support.run_unittest(__name__)
 
 if __name__ == '__main__':
-    unittest.main()
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_os.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_os.py	(original)
+++ python/branches/p3yk/Lib/test/test_os.py	Fri Apr 27 21:54:29 2007
@@ -240,6 +240,15 @@
             os.utime(self.fname, (t1, t1))
             self.assertEquals(os.stat(self.fname).st_mtime, t1)
 
+        def test_1686475(self):
+            # Verify that an open file can be stat'ed
+            try:
+                os.stat(r"c:\pagefile.sys")
+            except WindowsError as e:
+                if e == 2: # file does not exist; cannot run test
+                    return
+                self.fail("Could not stat pagefile.sys")
+
 from test import mapping_tests
 
 class EnvironTests(mapping_tests.BasicTestMappingProtocol):
@@ -272,75 +281,104 @@
         from os.path import join
 
         # Build:
-        #     TESTFN/               a file kid and two directory kids
+        #     TESTFN/
+        #       TEST1/              a file kid and two directory kids
         #         tmp1
         #         SUB1/             a file kid and a directory kid
-        #             tmp2
-        #             SUB11/        no kids
-        #         SUB2/             just a file kid
-        #             tmp3
-        sub1_path = join(test_support.TESTFN, "SUB1")
+        #           tmp2
+        #           SUB11/          no kids
+        #         SUB2/             a file kid and a dirsymlink kid
+        #           tmp3
+        #           link/           a symlink to TESTFN.2
+        #       TEST2/
+        #         tmp4              a lone file
+        walk_path = join(test_support.TESTFN, "TEST1")
+        sub1_path = join(walk_path, "SUB1")
         sub11_path = join(sub1_path, "SUB11")
-        sub2_path = join(test_support.TESTFN, "SUB2")
-        tmp1_path = join(test_support.TESTFN, "tmp1")
+        sub2_path = join(walk_path, "SUB2")
+        tmp1_path = join(walk_path, "tmp1")
         tmp2_path = join(sub1_path, "tmp2")
         tmp3_path = join(sub2_path, "tmp3")
+        link_path = join(sub2_path, "link")
+        t2_path = join(test_support.TESTFN, "TEST2")
+        tmp4_path = join(test_support.TESTFN, "TEST2", "tmp4")
 
         # Create stuff.
         os.makedirs(sub11_path)
         os.makedirs(sub2_path)
-        for path in tmp1_path, tmp2_path, tmp3_path:
+        os.makedirs(t2_path)
+        for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
             f = open(path, "w")
             f.write("I'm " + path + " and proud of it.  Blame test_os.\n")
             f.close()
+        if hasattr(os, "symlink"):
+            os.symlink(os.path.abspath(t2_path), link_path)
+            sub2_tree = (sub2_path, ["link"], ["tmp3"])
+        else:
+            sub2_tree = (sub2_path, [], ["tmp3"])
 
         # Walk top-down.
-        all = list(os.walk(test_support.TESTFN))
+        all = list(os.walk(walk_path))
         self.assertEqual(len(all), 4)
         # We can't know which order SUB1 and SUB2 will appear in.
         # Not flipped:  TESTFN, SUB1, SUB11, SUB2
         #     flipped:  TESTFN, SUB2, SUB1, SUB11
         flipped = all[0][1][0] != "SUB1"
         all[0][1].sort()
-        self.assertEqual(all[0], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
+        self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
         self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
         self.assertEqual(all[2 + flipped], (sub11_path, [], []))
-        self.assertEqual(all[3 - 2 * flipped], (sub2_path, [], ["tmp3"]))
+        self.assertEqual(all[3 - 2 * flipped], sub2_tree)
 
         # Prune the search.
         all = []
-        for root, dirs, files in os.walk(test_support.TESTFN):
+        for root, dirs, files in os.walk(walk_path):
             all.append((root, dirs, files))
             # Don't descend into SUB1.
             if 'SUB1' in dirs:
                 # Note that this also mutates the dirs we appended to all!
                 dirs.remove('SUB1')
         self.assertEqual(len(all), 2)
-        self.assertEqual(all[0], (test_support.TESTFN, ["SUB2"], ["tmp1"]))
-        self.assertEqual(all[1], (sub2_path, [], ["tmp3"]))
+        self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
+        self.assertEqual(all[1], sub2_tree)
 
         # Walk bottom-up.
-        all = list(os.walk(test_support.TESTFN, topdown=False))
+        all = list(os.walk(walk_path, topdown=False))
         self.assertEqual(len(all), 4)
         # We can't know which order SUB1 and SUB2 will appear in.
         # Not flipped:  SUB11, SUB1, SUB2, TESTFN
         #     flipped:  SUB2, SUB11, SUB1, TESTFN
         flipped = all[3][1][0] != "SUB1"
         all[3][1].sort()
-        self.assertEqual(all[3], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"]))
+        self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
         self.assertEqual(all[flipped], (sub11_path, [], []))
         self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
-        self.assertEqual(all[2 - 2 * flipped], (sub2_path, [], ["tmp3"]))
+        self.assertEqual(all[2 - 2 * flipped], sub2_tree)
+
+        if hasattr(os, "symlink"):
+            # Walk, following symlinks.
+            for root, dirs, files in os.walk(walk_path, followlinks=True):
+                if root == link_path:
+                    self.assertEqual(dirs, [])
+                    self.assertEqual(files, ["tmp4"])
+                    break
+            else:
+                self.fail("Didn't follow symlink with followlinks=True")
 
+    def tearDown(self):
         # Tear everything down.  This is a decent use for bottom-up on
         # Windows, which doesn't have a recursive delete command.  The
         # (not so) subtlety is that rmdir will fail unless the dir's
         # kids are removed first, so bottom up is essential.
         for root, dirs, files in os.walk(test_support.TESTFN, topdown=False):
             for name in files:
-                os.remove(join(root, name))
+                os.remove(os.path.join(root, name))
             for name in dirs:
-                os.rmdir(join(root, name))
+                dirname = os.path.join(root, name)
+                if not os.path.islink(dirname):
+                    os.rmdir(dirname)
+                else:
+                    os.remove(dirname)
         os.rmdir(test_support.TESTFN)
 
 class MakedirTests (unittest.TestCase):

Modified: python/branches/p3yk/Lib/test/test_ossaudiodev.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_ossaudiodev.py	(original)
+++ python/branches/p3yk/Lib/test/test_ossaudiodev.py	Fri Apr 27 21:54:29 2007
@@ -1,7 +1,7 @@
 from test import test_support
 test_support.requires('audio')
 
-from test.test_support import verbose, findfile, TestFailed, TestSkipped
+from test.test_support import verbose, findfile, TestSkipped
 
 import errno
 import fcntl
@@ -12,6 +12,7 @@
 import sunaudio
 import time
 import audioop
+import unittest
 
 # Arggh, AFMT_S16_NE not defined on all platforms -- seems to be a
 # fairly recent addition to OSS.
@@ -33,131 +34,143 @@
     fp.close()
 
     if enc != SND_FORMAT_MULAW_8:
-        print("Expect .au file with 8-bit mu-law samples")
-        return
+        raise RuntimeError("Expect .au file with 8-bit mu-law samples")
 
     # Convert the data to 16-bit signed.
     data = audioop.ulaw2lin(data, 2)
     return (data, rate, 16, nchannels)
 
-# version of assert that still works with -O
-def _assert(expr, message=None):
-    if not expr:
-        raise AssertionError(message or "assertion failed")
+class OSSAudioDevTests(unittest.TestCase):
 
-def play_sound_file(data, rate, ssize, nchannels):
-    try:
-        dsp = ossaudiodev.open('w')
-    except IOError as msg:
-        if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
-            raise TestSkipped, msg
-        raise TestFailed, msg
-
-    # at least check that these methods can be invoked
-    dsp.bufsize()
-    dsp.obufcount()
-    dsp.obuffree()
-    dsp.getptr()
-    dsp.fileno()
-
-    # Make sure the read-only attributes work.
-    _assert(dsp.closed is False, "dsp.closed is not False")
-    _assert(dsp.name == "/dev/dsp")
-    _assert(dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode)
-
-    # And make sure they're really read-only.
-    for attr in ('closed', 'name', 'mode'):
+    def play_sound_file(self, data, rate, ssize, nchannels):
         try:
-            setattr(dsp, attr, 42)
-            raise RuntimeError("dsp.%s not read-only" % attr)
-        except TypeError:
-            pass
-
-    # Compute expected running time of sound sample (in seconds).
-    expected_time = float(len(data)) / (ssize/8) / nchannels / rate
-
-    # set parameters based on .au file headers
-    dsp.setparameters(AFMT_S16_NE, nchannels, rate)
-    print(("playing test sound file (expected running time: %.2f sec)"
-           % expected_time))
-    t1 = time.time()
-    dsp.write(data)
-    dsp.close()
-    t2 = time.time()
-    elapsed_time = t2 - t1
-
-    percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
-    _assert(percent_diff <= 10.0, \
-            ("elapsed time (%.2f sec) > 10%% off of expected time (%.2f sec)"
-             % (elapsed_time, expected_time)))
-
-def test_setparameters(dsp):
-    # Two configurations for testing:
-    #   config1 (8-bit, mono, 8 kHz) should work on even the most
-    #      ancient and crufty sound card, but maybe not on special-
-    #      purpose high-end hardware
-    #   config2 (16-bit, stereo, 44.1kHz) should work on all but the
-    #      most ancient and crufty hardware
-    config1 = (ossaudiodev.AFMT_U8, 1, 8000)
-    config2 = (AFMT_S16_NE, 2, 44100)
-
-    for config in [config1, config2]:
-        (fmt, channels, rate) = config
-        if (dsp.setfmt(fmt) == fmt and
-            dsp.channels(channels) == channels and
-            dsp.speed(rate) == rate):
-            break
-    else:
-        raise RuntimeError("unable to set audio sampling parameters: "
-                           "you must have really weird audio hardware")
+            dsp = ossaudiodev.open('w')
+        except IOError as msg:
+            if msg.args[0] in (errno.EACCES, errno.ENOENT,
+                               errno.ENODEV, errno.EBUSY):
+                raise TestSkipped(msg)
+            raise
+
+        # at least check that these methods can be invoked
+        dsp.bufsize()
+        dsp.obufcount()
+        dsp.obuffree()
+        dsp.getptr()
+        dsp.fileno()
+
+        # Make sure the read-only attributes work.
+        self.failUnless(dsp.close)
+        self.assertEqual(dsp.name, "/dev/dsp")
+        self.assertEqual(dsp.mode, "w", "bad dsp.mode: %r" % dsp.mode)
+
+        # And make sure they're really read-only.
+        for attr in ('closed', 'name', 'mode'):
+            try:
+                setattr(dsp, attr, 42)
+            except TypeError:
+                pass
+            else:
+                self.fail("dsp.%s not read-only" % attr)
+
+        # Compute expected running time of sound sample (in seconds).
+        expected_time = float(len(data)) / (ssize/8) / nchannels / rate
+
+        # set parameters based on .au file headers
+        dsp.setparameters(AFMT_S16_NE, nchannels, rate)
+        print ("playing test sound file (expected running time: %.2f sec)"
+               % expected_time)
+        t1 = time.time()
+        dsp.write(data)
+        dsp.close()
+        t2 = time.time()
+        elapsed_time = t2 - t1
+
+        percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
+        self.failUnless(percent_diff <= 10.0,
+                        "elapsed time > 10% off of expected time")
+
+    def set_parameters(self, dsp):
+        # Two configurations for testing:
+        #   config1 (8-bit, mono, 8 kHz) should work on even the most
+        #      ancient and crufty sound card, but maybe not on special-
+        #      purpose high-end hardware
+        #   config2 (16-bit, stereo, 44.1kHz) should work on all but the
+        #      most ancient and crufty hardware
+        config1 = (ossaudiodev.AFMT_U8, 1, 8000)
+        config2 = (AFMT_S16_NE, 2, 44100)
+
+        for config in [config1, config2]:
+            (fmt, channels, rate) = config
+            if (dsp.setfmt(fmt) == fmt and
+                dsp.channels(channels) == channels and
+                dsp.speed(rate) == rate):
+                break
+        else:
+            raise RuntimeError("unable to set audio sampling parameters: "
+                               "you must have really weird audio hardware")
 
-    # setparameters() should be able to set this configuration in
-    # either strict or non-strict mode.
-    result = dsp.setparameters(fmt, channels, rate, False)
-    _assert(result == (fmt, channels, rate),
-            "setparameters%r: returned %r" % (config, result))
-    result = dsp.setparameters(fmt, channels, rate, True)
-    _assert(result == (fmt, channels, rate),
-            "setparameters%r: returned %r" % (config, result))
-
-def test_bad_setparameters(dsp):
-
-    # Now try some configurations that are presumably bogus: eg. 300
-    # channels currently exceeds even Hollywood's ambitions, and
-    # negative sampling rate is utter nonsense.  setparameters() should
-    # accept these in non-strict mode, returning something other than
-    # was requested, but should barf in strict mode.
-    fmt = AFMT_S16_NE
-    rate = 44100
-    channels = 2
-    for config in [(fmt, 300, rate),       # ridiculous nchannels
-                   (fmt, -5, rate),        # impossible nchannels
-                   (fmt, channels, -50),   # impossible rate
-                  ]:
-        (fmt, channels, rate) = config
+        # setparameters() should be able to set this configuration in
+        # either strict or non-strict mode.
         result = dsp.setparameters(fmt, channels, rate, False)
-        _assert(result != config,
-                "setparameters: unexpectedly got requested configuration")
+        self.assertEqual(result, (fmt, channels, rate),
+                         "setparameters%r: returned %r" % (config, result))
 
+        result = dsp.setparameters(fmt, channels, rate, True)
+        self.assertEqual(result, (fmt, channels, rate),
+                         "setparameters%r: returned %r" % (config, result))
+
+    def set_bad_parameters(self, dsp):
+
+        # Now try some configurations that are presumably bogus: eg. 300
+        # channels currently exceeds even Hollywood's ambitions, and
+        # negative sampling rate is utter nonsense.  setparameters() should
+        # accept these in non-strict mode, returning something other than
+        # was requested, but should barf in strict mode.
+        fmt = AFMT_S16_NE
+        rate = 44100
+        channels = 2
+        for config in [(fmt, 300, rate),       # ridiculous nchannels
+                       (fmt, -5, rate),        # impossible nchannels
+                       (fmt, channels, -50),   # impossible rate
+                      ]:
+            (fmt, channels, rate) = config
+            result = dsp.setparameters(fmt, channels, rate, False)
+            self.failIfEqual(result, config,
+                             "unexpectedly got requested configuration")
+
+            try:
+                result = dsp.setparameters(fmt, channels, rate, True)
+            except ossaudiodev.OSSAudioError as err:
+                pass
+            else:
+                self.fail("expected OSSAudioError")
+
+    def test_playback(self):
+        sound_info = read_sound_file(findfile('audiotest.au'))
+        self.play_sound_file(*sound_info)
+
+    def test_set_parameters(self):
+        dsp = ossaudiodev.open("w")
         try:
-            result = dsp.setparameters(fmt, channels, rate, True)
-            raise AssertionError("setparameters: expected OSSAudioError")
-        except ossaudiodev.OSSAudioError as err:
-            print("setparameters: got OSSAudioError as expected")
-
-def test():
-    (data, rate, ssize, nchannels) = read_sound_file(findfile('audiotest.au'))
-    play_sound_file(data, rate, ssize, nchannels)
+            self.set_parameters(dsp)
 
-    dsp = ossaudiodev.open("w")
-    try:
-        test_setparameters(dsp)
+            # Disabled because it fails under Linux 2.6 with ALSA's OSS
+            # emulation layer.
+            #self.set_bad_parameters(dsp)
+        finally:
+            dsp.close()
+            self.failUnless(dsp.closed)
 
-        # Disabled because it fails under Linux 2.6 with ALSA's OSS
-        # emulation layer.
-        #test_bad_setparameters(dsp)
-    finally:
-        dsp.close()
-        _assert(dsp.closed is True, "dsp.closed is not True")
 
-test()
+def test_main():
+    try:
+        dsp = ossaudiodev.open('w')
+    except IOError as msg:
+        if msg.args[0] in (errno.EACCES, errno.ENOENT,
+                           errno.ENODEV, errno.EBUSY):
+            raise TestSkipped(msg)
+        raise
+    test_support.run_unittest(__name__)
+
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/p3yk/Lib/test/test_peepholer.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_peepholer.py	(original)
+++ python/branches/p3yk/Lib/test/test_peepholer.py	Fri Apr 27 21:54:29 2007
@@ -49,6 +49,11 @@
             self.assert_(elem not in asm)
         for elem in ('LOAD_CONST', '(None)'):
             self.assert_(elem in asm)
+        def f():
+            'Adding a docstring made this test fail in Py2.5.0'
+            return None
+        self.assert_('LOAD_CONST' in disassemble(f))
+        self.assert_('LOAD_GLOBAL' not in disassemble(f))
 
     def test_while_one(self):
         # Skip over:  LOAD_CONST trueconst  JUMP_IF_FALSE xx  POP_TOP
@@ -195,14 +200,14 @@
         # There should be one jump for the while loop.
         self.assertEqual(asm.split().count('JUMP_ABSOLUTE'), 1)
         self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
-        
+
     def test_make_function_doesnt_bail(self):
         def f():
-            def g()->1+1: 
+            def g()->1+1:
                 pass
             return g
         asm = disassemble(f)
-        self.assert_('BINARY_ADD' not in asm)              
+        self.assert_('BINARY_ADD' not in asm)
 
 
 def test_main(verbose=None):

Modified: python/branches/p3yk/Lib/test/test_popen2.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_popen2.py	(original)
+++ python/branches/p3yk/Lib/test/test_popen2.py	Fri Apr 27 21:54:29 2007
@@ -1,78 +1,92 @@
 #! /usr/bin/env python
-"""Test script for popen2.py
-   Christian Tismer
-"""
+"""Test script for popen2.py"""
 
 import os
 import sys
-from test.test_support import TestSkipped, reap_children
+import unittest
+import popen2
 
-# popen2 contains its own testing routine
-# which is especially useful to see if open files
-# like stdin can be read successfully by a forked
-# subprocess.
-
-def main():
-    print("Test popen2 module:")
-    if (sys.platform[:4] == 'beos' or sys.platform[:6] == 'atheos') \
-           and __name__ != '__main__':
-        #  Locks get messed up or something.  Generally we're supposed
-        #  to avoid mixing "posix" fork & exec with native threads, and
-        #  they may be right about that after all.
-        raise TestSkipped, "popen2() doesn't work during import on " + sys.platform
-    try:
-        from os import popen
-    except ImportError:
-        # if we don't have os.popen, check that
-        # we have os.fork.  if not, skip the test
-        # (by raising an ImportError)
-        from os import fork
-    import popen2
-    popen2._test()
-
-
-def _test():
-    # same test as popen2._test(), but using the os.popen*() API
-    print("Testing os module:")
-    import popen2
-    # When the test runs, there shouldn't be any open pipes
-    popen2._cleanup()
-    assert not popen2._active, "Active pipes when test starts " + repr([c.cmd for c in popen2._active])
-    cmd  = "cat"
-    teststr = "ab cd\n"
+from test.test_support import TestSkipped, run_unittest, reap_children
+
+if sys.platform[:4] == 'beos' or sys.platform[:6] == 'atheos':
+    #  Locks get messed up or something.  Generally we're supposed
+    #  to avoid mixing "posix" fork & exec with native threads, and
+    #  they may be right about that after all.
+    raise TestSkipped("popen2() doesn't work on " + sys.platform)
+
+# if we don't have os.popen, check that
+# we have os.fork.  if