[Python-checkins] r58018 - in python/branches/bcannon-objcap: Doc Doc/Makefile Doc/howto Doc/howto/functional.rst Doc/howto/unicode.rst Doc/howto/urllib2.rst Doc/tools Doc/whatsnew Include/abstract.h Include/boolobject.h Include/bufferobject.h Include/cStringIO.h Include/cellobject.h Include/cobject.h Include/code.h Include/complexobject.h Include/datetime.h Include/descrobject.h Include/dictobject.h Include/fileobject.h Include/floatobject.h Include/funcobject.h Include/genobject.h Include/iterobject.h Include/listobject.h Include/longobject.h Include/methodobject.h Include/moduleobject.h Include/object.h Include/objimpl.h Include/opcode.h Include/py_curses.h Include/rangeobject.h Include/setobject.h Include/sliceobject.h Include/stringobject.h Include/structmember.h Include/symtable.h Include/traceback.h Include/tupleobject.h Include/unicodeobject.h Include/weakrefobject.h Lib/SimpleXMLRPCServer.py Lib/UserString.py Lib/bsddb/__init__.py Lib/bsddb/test/test_1413192.py Lib/calendar.py Lib/contextlib.py Lib/ctypes/__init__.py Lib/ctypes/test/test_arrays.py Lib/ctypes/test/test_buffers.py Lib/ctypes/test/test_cast.py Lib/ctypes/test/test_find.py Lib/ctypes/test/test_memfunctions.py Lib/ctypes/test/test_slicing.py Lib/ctypes/test/test_strings.py Lib/ctypes/test/test_structures.py Lib/ctypes/test/test_unicode.py Lib/ctypes/test/test_win32.py Lib/decimal.py Lib/distutils/command/bdist_msi.py Lib/distutils/command/register.py Lib/distutils/command/upload.py Lib/distutils/util.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/encodings/aliases.py Lib/encodings/quopri_codec.py Lib/encodings/uu_codec.py Lib/functools.py Lib/httplib.py Lib/idlelib/macosxSupport.py Lib/imaplib.py Lib/inspect.py Lib/logging/__init__.py Lib/mailbox.py Lib/ntpath.py Lib/pipes.py Lib/poplib.py Lib/posixpath.py Lib/robotparser.py Lib/runpy.py Lib/sgmllib.py Lib/smtplib.py Lib/socket.py Lib/sre_compile.py Lib/tarfile.py Lib/test/cjkencodings_test.py Lib/test/list_tests.py Lib/test/output/test_class Lib/test/output/test_frozen Lib/test/output/test_linuxaudiodev Lib/test/output/test_ossaudiodev Lib/test/output/test_pkg Lib/test/output/test_rgbimg Lib/test/output/test_signal Lib/test/output/test_winreg Lib/test/regrtest.py Lib/test/string_tests.py Lib/test/test_StringIO.py Lib/test/test_array.py Lib/test/test_asynchat.py Lib/test/test_bsddb.py Lib/test/test_calendar.py Lib/test/test_class.py Lib/test/test_cmd_line.py Lib/test/test_codeccallbacks.py Lib/test/test_codecencodings_kr.py Lib/test/test_codecmaps_cn.py Lib/test/test_codecmaps_kr.py Lib/test/test_codecs.py Lib/test/test_compiler.py Lib/test/test_datetime.py Lib/test/test_exceptions.py Lib/test/test_float.py Lib/test/test_format.py Lib/test/test_frozen.py Lib/test/test_httplib.py Lib/test/test_import.py Lib/test/test_linuxaudiodev.py Lib/test/test_macostools.py Lib/test/test_mailbox.py Lib/test/test_math.py Lib/test/test_mmap.py Lib/test/test_multibytecodec_support.py Lib/test/test_os.py Lib/test/test_ossaudiodev.py Lib/test/test_parser.py Lib/test/test_pep352.py Lib/test/test_pkg.py Lib/test/test_pow.py Lib/test/test_random.py Lib/test/test_re.py Lib/test/test_resource.py Lib/test/test_robotparser.py Lib/test/test_runpy.py Lib/test/test_signal.py Lib/test/test_smtplib.py Lib/test/test_socket_ssl.py Lib/test/test_socketserver.py Lib/test/test_struct.py Lib/test/test_structmembers.py Lib/test/test_structseq.py Lib/test/test_sundry.py Lib/test/test_support.py Lib/test/test_tarfile.py Lib/test/test_unicode.py Lib/test/test_unicodedata.py Lib/test/test_urllib2.py Lib/test/test_urllib2_localnet.py Lib/test/test_userstring.py Lib/test/test_warnings.py Lib/test/test_winreg.py Lib/test/test_xmlrpc.py Lib/test/test_zipfile.py Lib/threading.py Lib/urllib.py Lib/urllib2.py Lib/uuid.py Lib/webbrowser.py Lib/zipfile.py Makefile.pre.in Misc/ACKS Misc/BeOS-NOTES Misc/NEWS Misc/build.sh Misc/developers.txt Modules/_bsddb.c Modules/_codecsmodule.c Modules/_collectionsmodule.c Modules/_csv.c Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/ctypes.h Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Modules/_ctypes/stgdict.c Modules/_curses_panel.c Modules/_cursesmodule.c Modules/_elementtree.c Modules/_functoolsmodule.c Modules/_hashopenssl.c Modules/_hotshot.c Modules/_lsprof.c Modules/_randommodule.c Modules/_sqlite/cache.c Modules/_sqlite/connection.c Modules/_sqlite/cursor.c Modules/_sqlite/prepare_protocol.c Modules/_sqlite/row.c Modules/_sqlite/statement.c Modules/_sre.c Modules/_ssl.c Modules/_struct.c Modules/_testcapimodule.c Modules/_tkinter.c Modules/_typesmodule.c Modules/_weakref.c Modules/arraymodule.c Modules/bz2module.c Modules/cPickle.c Modules/cStringIO.c Modules/cjkcodecs/_codecs_cn.c Modules/cjkcodecs/_codecs_kr.c Modules/cjkcodecs/multibytecodec.c Modules/datetimemodule.c Modules/dbmmodule.c Modules/dlmodule.c Modules/gcmodule.c Modules/gdbmmodule.c Modules/itertoolsmodule.c Modules/linuxaudiodev.c Modules/main.c Modules/makesetup Modules/md5module.c Modules/mmapmodule.c Modules/operator.c Modules/ossaudiodev.c Modules/parsermodule.c Modules/posixmodule.c Modules/pyexpat.c Modules/readline.c Modules/selectmodule.c Modules/sha256module.c Modules/sha512module.c Modules/shamodule.c Modules/socketmodule.c Modules/sunaudiodev.c Modules/threadmodule.c Modules/unicodedata.c Modules/xxmodule.c Modules/xxsubtype.c Modules/zipimport.c Modules/zlibmodule.c Objects/boolobject.c Objects/bufferobject.c Objects/cellobject.c Objects/cobject.c Objects/codeobject.c Objects/complexobject.c Objects/descrobject.c Objects/dictobject.c Objects/enumobject.c Objects/exceptions.c Objects/fileobject.c Objects/floatobject.c Objects/frameobject.c Objects/funcobject.c Objects/genobject.c Objects/intobject.c Objects/iterobject.c Objects/listobject.c Objects/longobject.c Objects/methodobject.c Objects/moduleobject.c Objects/object.c Objects/obmalloc.c Objects/setobject.c Objects/sliceobject.c Objects/stringobject.c Objects/structseq.c Objects/tupleobject.c Objects/typeobject.c Objects/unicodeobject.c Objects/weakrefobject.c PC/_msi.c PC/_winreg.c PC/pyconfig.h PCbuild8/build.bat PCbuild8/readme.txt Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h Python/ast.c Python/ceval.c Python/compile.c Python/import.c Python/structmember.c Python/symtable.c Python/traceback.c Tools/msi/msi.py Tools/msi/msilib.py Tools/scripts/setup.py Tools/ssl configure configure.in pyconfig.h.in setup.py

brett.cannon python-checkins at python.org
Thu Sep 6 21:35:56 CEST 2007


Author: brett.cannon
Date: Thu Sep  6 21:35:45 2007
New Revision: 58018

Added:
   python/branches/bcannon-objcap/Doc/   (props changed)
      - copied from r57993, python/trunk/Doc/
   python/branches/bcannon-objcap/Doc/Makefile
      - copied unchanged from r57993, python/trunk/Doc/Makefile
   python/branches/bcannon-objcap/Doc/howto/
      - copied from r57993, python/trunk/Doc/howto/
   python/branches/bcannon-objcap/Doc/howto/functional.rst
      - copied unchanged from r57993, python/trunk/Doc/howto/functional.rst
   python/branches/bcannon-objcap/Doc/howto/unicode.rst
      - copied unchanged from r57993, python/trunk/Doc/howto/unicode.rst
   python/branches/bcannon-objcap/Doc/howto/urllib2.rst
      - copied unchanged from r57993, python/trunk/Doc/howto/urllib2.rst
   python/branches/bcannon-objcap/Doc/tools/   (props changed)
      - copied from r57993, python/trunk/Doc/tools/
   python/branches/bcannon-objcap/Doc/whatsnew/
      - copied from r57993, python/trunk/Doc/whatsnew/
   python/branches/bcannon-objcap/Tools/ssl/
      - copied from r57993, python/trunk/Tools/ssl/
Removed:
   python/branches/bcannon-objcap/Lib/test/output/test_class
   python/branches/bcannon-objcap/Lib/test/output/test_frozen
   python/branches/bcannon-objcap/Lib/test/output/test_linuxaudiodev
   python/branches/bcannon-objcap/Lib/test/output/test_ossaudiodev
   python/branches/bcannon-objcap/Lib/test/output/test_pkg
   python/branches/bcannon-objcap/Lib/test/output/test_rgbimg
   python/branches/bcannon-objcap/Lib/test/output/test_signal
   python/branches/bcannon-objcap/Lib/test/output/test_winreg
Modified:
   python/branches/bcannon-objcap/   (props changed)
   python/branches/bcannon-objcap/Include/abstract.h
   python/branches/bcannon-objcap/Include/boolobject.h
   python/branches/bcannon-objcap/Include/bufferobject.h
   python/branches/bcannon-objcap/Include/cStringIO.h
   python/branches/bcannon-objcap/Include/cellobject.h
   python/branches/bcannon-objcap/Include/cobject.h
   python/branches/bcannon-objcap/Include/code.h
   python/branches/bcannon-objcap/Include/complexobject.h
   python/branches/bcannon-objcap/Include/datetime.h
   python/branches/bcannon-objcap/Include/descrobject.h
   python/branches/bcannon-objcap/Include/dictobject.h
   python/branches/bcannon-objcap/Include/fileobject.h
   python/branches/bcannon-objcap/Include/floatobject.h
   python/branches/bcannon-objcap/Include/funcobject.h
   python/branches/bcannon-objcap/Include/genobject.h
   python/branches/bcannon-objcap/Include/iterobject.h
   python/branches/bcannon-objcap/Include/listobject.h
   python/branches/bcannon-objcap/Include/longobject.h
   python/branches/bcannon-objcap/Include/methodobject.h
   python/branches/bcannon-objcap/Include/moduleobject.h
   python/branches/bcannon-objcap/Include/object.h
   python/branches/bcannon-objcap/Include/objimpl.h
   python/branches/bcannon-objcap/Include/opcode.h
   python/branches/bcannon-objcap/Include/py_curses.h
   python/branches/bcannon-objcap/Include/rangeobject.h
   python/branches/bcannon-objcap/Include/setobject.h
   python/branches/bcannon-objcap/Include/sliceobject.h
   python/branches/bcannon-objcap/Include/stringobject.h
   python/branches/bcannon-objcap/Include/structmember.h
   python/branches/bcannon-objcap/Include/symtable.h
   python/branches/bcannon-objcap/Include/traceback.h
   python/branches/bcannon-objcap/Include/tupleobject.h
   python/branches/bcannon-objcap/Include/unicodeobject.h
   python/branches/bcannon-objcap/Include/weakrefobject.h
   python/branches/bcannon-objcap/Lib/SimpleXMLRPCServer.py
   python/branches/bcannon-objcap/Lib/UserString.py
   python/branches/bcannon-objcap/Lib/bsddb/__init__.py
   python/branches/bcannon-objcap/Lib/bsddb/test/test_1413192.py
   python/branches/bcannon-objcap/Lib/calendar.py
   python/branches/bcannon-objcap/Lib/contextlib.py
   python/branches/bcannon-objcap/Lib/ctypes/__init__.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_arrays.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_buffers.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_cast.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_find.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_memfunctions.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_slicing.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_strings.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_structures.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_unicode.py
   python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py
   python/branches/bcannon-objcap/Lib/decimal.py
   python/branches/bcannon-objcap/Lib/distutils/command/bdist_msi.py
   python/branches/bcannon-objcap/Lib/distutils/command/register.py
   python/branches/bcannon-objcap/Lib/distutils/command/upload.py
   python/branches/bcannon-objcap/Lib/distutils/util.py
   python/branches/bcannon-objcap/Lib/email/test/test_email.py
   python/branches/bcannon-objcap/Lib/email/test/test_email_renamed.py
   python/branches/bcannon-objcap/Lib/encodings/aliases.py
   python/branches/bcannon-objcap/Lib/encodings/quopri_codec.py
   python/branches/bcannon-objcap/Lib/encodings/uu_codec.py
   python/branches/bcannon-objcap/Lib/functools.py
   python/branches/bcannon-objcap/Lib/httplib.py
   python/branches/bcannon-objcap/Lib/idlelib/macosxSupport.py
   python/branches/bcannon-objcap/Lib/imaplib.py
   python/branches/bcannon-objcap/Lib/inspect.py
   python/branches/bcannon-objcap/Lib/logging/__init__.py
   python/branches/bcannon-objcap/Lib/mailbox.py
   python/branches/bcannon-objcap/Lib/ntpath.py
   python/branches/bcannon-objcap/Lib/pipes.py
   python/branches/bcannon-objcap/Lib/poplib.py
   python/branches/bcannon-objcap/Lib/posixpath.py
   python/branches/bcannon-objcap/Lib/robotparser.py
   python/branches/bcannon-objcap/Lib/runpy.py
   python/branches/bcannon-objcap/Lib/sgmllib.py
   python/branches/bcannon-objcap/Lib/smtplib.py
   python/branches/bcannon-objcap/Lib/socket.py
   python/branches/bcannon-objcap/Lib/sre_compile.py
   python/branches/bcannon-objcap/Lib/tarfile.py
   python/branches/bcannon-objcap/Lib/test/cjkencodings_test.py
   python/branches/bcannon-objcap/Lib/test/list_tests.py
   python/branches/bcannon-objcap/Lib/test/regrtest.py
   python/branches/bcannon-objcap/Lib/test/string_tests.py
   python/branches/bcannon-objcap/Lib/test/test_StringIO.py
   python/branches/bcannon-objcap/Lib/test/test_array.py
   python/branches/bcannon-objcap/Lib/test/test_asynchat.py
   python/branches/bcannon-objcap/Lib/test/test_bsddb.py
   python/branches/bcannon-objcap/Lib/test/test_calendar.py
   python/branches/bcannon-objcap/Lib/test/test_class.py
   python/branches/bcannon-objcap/Lib/test/test_cmd_line.py
   python/branches/bcannon-objcap/Lib/test/test_codeccallbacks.py
   python/branches/bcannon-objcap/Lib/test/test_codecencodings_kr.py
   python/branches/bcannon-objcap/Lib/test/test_codecmaps_cn.py
   python/branches/bcannon-objcap/Lib/test/test_codecmaps_kr.py
   python/branches/bcannon-objcap/Lib/test/test_codecs.py
   python/branches/bcannon-objcap/Lib/test/test_compiler.py
   python/branches/bcannon-objcap/Lib/test/test_datetime.py
   python/branches/bcannon-objcap/Lib/test/test_exceptions.py
   python/branches/bcannon-objcap/Lib/test/test_float.py
   python/branches/bcannon-objcap/Lib/test/test_format.py
   python/branches/bcannon-objcap/Lib/test/test_frozen.py
   python/branches/bcannon-objcap/Lib/test/test_httplib.py
   python/branches/bcannon-objcap/Lib/test/test_import.py
   python/branches/bcannon-objcap/Lib/test/test_linuxaudiodev.py
   python/branches/bcannon-objcap/Lib/test/test_macostools.py
   python/branches/bcannon-objcap/Lib/test/test_mailbox.py
   python/branches/bcannon-objcap/Lib/test/test_math.py
   python/branches/bcannon-objcap/Lib/test/test_mmap.py
   python/branches/bcannon-objcap/Lib/test/test_multibytecodec_support.py
   python/branches/bcannon-objcap/Lib/test/test_os.py
   python/branches/bcannon-objcap/Lib/test/test_ossaudiodev.py
   python/branches/bcannon-objcap/Lib/test/test_parser.py
   python/branches/bcannon-objcap/Lib/test/test_pep352.py
   python/branches/bcannon-objcap/Lib/test/test_pkg.py
   python/branches/bcannon-objcap/Lib/test/test_pow.py
   python/branches/bcannon-objcap/Lib/test/test_random.py
   python/branches/bcannon-objcap/Lib/test/test_re.py
   python/branches/bcannon-objcap/Lib/test/test_resource.py
   python/branches/bcannon-objcap/Lib/test/test_robotparser.py
   python/branches/bcannon-objcap/Lib/test/test_runpy.py
   python/branches/bcannon-objcap/Lib/test/test_signal.py
   python/branches/bcannon-objcap/Lib/test/test_smtplib.py
   python/branches/bcannon-objcap/Lib/test/test_socket_ssl.py
   python/branches/bcannon-objcap/Lib/test/test_socketserver.py
   python/branches/bcannon-objcap/Lib/test/test_struct.py
   python/branches/bcannon-objcap/Lib/test/test_structmembers.py
   python/branches/bcannon-objcap/Lib/test/test_structseq.py
   python/branches/bcannon-objcap/Lib/test/test_sundry.py
   python/branches/bcannon-objcap/Lib/test/test_support.py
   python/branches/bcannon-objcap/Lib/test/test_tarfile.py
   python/branches/bcannon-objcap/Lib/test/test_unicode.py
   python/branches/bcannon-objcap/Lib/test/test_unicodedata.py
   python/branches/bcannon-objcap/Lib/test/test_urllib2.py
   python/branches/bcannon-objcap/Lib/test/test_urllib2_localnet.py
   python/branches/bcannon-objcap/Lib/test/test_userstring.py
   python/branches/bcannon-objcap/Lib/test/test_warnings.py
   python/branches/bcannon-objcap/Lib/test/test_winreg.py
   python/branches/bcannon-objcap/Lib/test/test_xmlrpc.py
   python/branches/bcannon-objcap/Lib/test/test_zipfile.py
   python/branches/bcannon-objcap/Lib/threading.py
   python/branches/bcannon-objcap/Lib/urllib.py
   python/branches/bcannon-objcap/Lib/urllib2.py
   python/branches/bcannon-objcap/Lib/uuid.py
   python/branches/bcannon-objcap/Lib/webbrowser.py
   python/branches/bcannon-objcap/Lib/zipfile.py
   python/branches/bcannon-objcap/Makefile.pre.in
   python/branches/bcannon-objcap/Misc/ACKS
   python/branches/bcannon-objcap/Misc/BeOS-NOTES
   python/branches/bcannon-objcap/Misc/NEWS
   python/branches/bcannon-objcap/Misc/build.sh
   python/branches/bcannon-objcap/Misc/developers.txt
   python/branches/bcannon-objcap/Modules/_bsddb.c
   python/branches/bcannon-objcap/Modules/_codecsmodule.c
   python/branches/bcannon-objcap/Modules/_collectionsmodule.c
   python/branches/bcannon-objcap/Modules/_csv.c
   python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c
   python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c
   python/branches/bcannon-objcap/Modules/_ctypes/callproc.c
   python/branches/bcannon-objcap/Modules/_ctypes/cfield.c
   python/branches/bcannon-objcap/Modules/_ctypes/ctypes.h
   python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure
   python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure.ac
   python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c
   python/branches/bcannon-objcap/Modules/_curses_panel.c
   python/branches/bcannon-objcap/Modules/_cursesmodule.c
   python/branches/bcannon-objcap/Modules/_elementtree.c
   python/branches/bcannon-objcap/Modules/_functoolsmodule.c
   python/branches/bcannon-objcap/Modules/_hashopenssl.c
   python/branches/bcannon-objcap/Modules/_hotshot.c
   python/branches/bcannon-objcap/Modules/_lsprof.c
   python/branches/bcannon-objcap/Modules/_randommodule.c
   python/branches/bcannon-objcap/Modules/_sqlite/cache.c
   python/branches/bcannon-objcap/Modules/_sqlite/connection.c
   python/branches/bcannon-objcap/Modules/_sqlite/cursor.c
   python/branches/bcannon-objcap/Modules/_sqlite/prepare_protocol.c
   python/branches/bcannon-objcap/Modules/_sqlite/row.c
   python/branches/bcannon-objcap/Modules/_sqlite/statement.c
   python/branches/bcannon-objcap/Modules/_sre.c
   python/branches/bcannon-objcap/Modules/_ssl.c
   python/branches/bcannon-objcap/Modules/_struct.c
   python/branches/bcannon-objcap/Modules/_testcapimodule.c
   python/branches/bcannon-objcap/Modules/_tkinter.c
   python/branches/bcannon-objcap/Modules/_typesmodule.c
   python/branches/bcannon-objcap/Modules/_weakref.c
   python/branches/bcannon-objcap/Modules/arraymodule.c
   python/branches/bcannon-objcap/Modules/bz2module.c
   python/branches/bcannon-objcap/Modules/cPickle.c
   python/branches/bcannon-objcap/Modules/cStringIO.c
   python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_cn.c
   python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_kr.c
   python/branches/bcannon-objcap/Modules/cjkcodecs/multibytecodec.c
   python/branches/bcannon-objcap/Modules/datetimemodule.c
   python/branches/bcannon-objcap/Modules/dbmmodule.c
   python/branches/bcannon-objcap/Modules/dlmodule.c
   python/branches/bcannon-objcap/Modules/gcmodule.c
   python/branches/bcannon-objcap/Modules/gdbmmodule.c
   python/branches/bcannon-objcap/Modules/itertoolsmodule.c
   python/branches/bcannon-objcap/Modules/linuxaudiodev.c
   python/branches/bcannon-objcap/Modules/main.c
   python/branches/bcannon-objcap/Modules/makesetup
   python/branches/bcannon-objcap/Modules/md5module.c
   python/branches/bcannon-objcap/Modules/mmapmodule.c
   python/branches/bcannon-objcap/Modules/operator.c
   python/branches/bcannon-objcap/Modules/ossaudiodev.c
   python/branches/bcannon-objcap/Modules/parsermodule.c
   python/branches/bcannon-objcap/Modules/posixmodule.c
   python/branches/bcannon-objcap/Modules/pyexpat.c
   python/branches/bcannon-objcap/Modules/readline.c
   python/branches/bcannon-objcap/Modules/selectmodule.c
   python/branches/bcannon-objcap/Modules/sha256module.c
   python/branches/bcannon-objcap/Modules/sha512module.c
   python/branches/bcannon-objcap/Modules/shamodule.c
   python/branches/bcannon-objcap/Modules/socketmodule.c
   python/branches/bcannon-objcap/Modules/sunaudiodev.c
   python/branches/bcannon-objcap/Modules/threadmodule.c
   python/branches/bcannon-objcap/Modules/unicodedata.c
   python/branches/bcannon-objcap/Modules/xxmodule.c
   python/branches/bcannon-objcap/Modules/xxsubtype.c
   python/branches/bcannon-objcap/Modules/zipimport.c
   python/branches/bcannon-objcap/Modules/zlibmodule.c
   python/branches/bcannon-objcap/Objects/boolobject.c
   python/branches/bcannon-objcap/Objects/bufferobject.c
   python/branches/bcannon-objcap/Objects/cellobject.c
   python/branches/bcannon-objcap/Objects/cobject.c
   python/branches/bcannon-objcap/Objects/codeobject.c
   python/branches/bcannon-objcap/Objects/complexobject.c
   python/branches/bcannon-objcap/Objects/descrobject.c
   python/branches/bcannon-objcap/Objects/dictobject.c
   python/branches/bcannon-objcap/Objects/enumobject.c
   python/branches/bcannon-objcap/Objects/exceptions.c
   python/branches/bcannon-objcap/Objects/fileobject.c
   python/branches/bcannon-objcap/Objects/floatobject.c
   python/branches/bcannon-objcap/Objects/frameobject.c
   python/branches/bcannon-objcap/Objects/funcobject.c
   python/branches/bcannon-objcap/Objects/genobject.c
   python/branches/bcannon-objcap/Objects/intobject.c
   python/branches/bcannon-objcap/Objects/iterobject.c
   python/branches/bcannon-objcap/Objects/listobject.c
   python/branches/bcannon-objcap/Objects/longobject.c
   python/branches/bcannon-objcap/Objects/methodobject.c
   python/branches/bcannon-objcap/Objects/moduleobject.c
   python/branches/bcannon-objcap/Objects/object.c
   python/branches/bcannon-objcap/Objects/obmalloc.c
   python/branches/bcannon-objcap/Objects/setobject.c
   python/branches/bcannon-objcap/Objects/sliceobject.c
   python/branches/bcannon-objcap/Objects/stringobject.c
   python/branches/bcannon-objcap/Objects/structseq.c
   python/branches/bcannon-objcap/Objects/tupleobject.c
   python/branches/bcannon-objcap/Objects/typeobject.c
   python/branches/bcannon-objcap/Objects/unicodeobject.c
   python/branches/bcannon-objcap/Objects/weakrefobject.c
   python/branches/bcannon-objcap/PC/_msi.c
   python/branches/bcannon-objcap/PC/_winreg.c
   python/branches/bcannon-objcap/PC/pyconfig.h
   python/branches/bcannon-objcap/PCbuild8/build.bat
   python/branches/bcannon-objcap/PCbuild8/readme.txt
   python/branches/bcannon-objcap/Parser/parsetok.c
   python/branches/bcannon-objcap/Parser/tokenizer.c
   python/branches/bcannon-objcap/Parser/tokenizer.h
   python/branches/bcannon-objcap/Python/ast.c
   python/branches/bcannon-objcap/Python/ceval.c
   python/branches/bcannon-objcap/Python/compile.c
   python/branches/bcannon-objcap/Python/import.c
   python/branches/bcannon-objcap/Python/structmember.c
   python/branches/bcannon-objcap/Python/symtable.c
   python/branches/bcannon-objcap/Python/traceback.c
   python/branches/bcannon-objcap/Tools/msi/msi.py
   python/branches/bcannon-objcap/Tools/msi/msilib.py
   python/branches/bcannon-objcap/Tools/scripts/setup.py
   python/branches/bcannon-objcap/configure
   python/branches/bcannon-objcap/configure.in
   python/branches/bcannon-objcap/pyconfig.h.in
   python/branches/bcannon-objcap/setup.py
Log:
Merged revisions 56058-57998 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk



Modified: python/branches/bcannon-objcap/Include/abstract.h
==============================================================================
--- python/branches/bcannon-objcap/Include/abstract.h	(original)
+++ python/branches/bcannon-objcap/Include/abstract.h	Thu Sep  6 21:35:45 2007
@@ -1064,7 +1064,7 @@
        */
 
 #define PySequence_ITEM(o, i)\
-	( o->ob_type->tp_as_sequence->sq_item(o, i) )
+	( Py_Type(o)->tp_as_sequence->sq_item(o, i) )
        /* Assume tp_as_sequence and sq_item exist and that i does not
 	  need to be corrected for a negative index
        */     

Modified: python/branches/bcannon-objcap/Include/boolobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/boolobject.h	(original)
+++ python/branches/bcannon-objcap/Include/boolobject.h	Thu Sep  6 21:35:45 2007
@@ -11,7 +11,7 @@
 
 PyAPI_DATA(PyTypeObject) PyBool_Type;
 
-#define PyBool_Check(x) ((x)->ob_type == &PyBool_Type)
+#define PyBool_Check(x) (Py_Type(x) == &PyBool_Type)
 
 /* Py_False and Py_True are the only two bools in existence.
 Don't forget to apply Py_INCREF() when returning either!!! */

Modified: python/branches/bcannon-objcap/Include/bufferobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/bufferobject.h	(original)
+++ python/branches/bcannon-objcap/Include/bufferobject.h	Thu Sep  6 21:35:45 2007
@@ -12,7 +12,7 @@
 
 PyAPI_DATA(PyTypeObject) PyBuffer_Type;
 
-#define PyBuffer_Check(op) ((op)->ob_type == &PyBuffer_Type)
+#define PyBuffer_Check(op) (Py_Type(op) == &PyBuffer_Type)
 
 #define Py_END_OF_BUFFER	(-1)
 

Modified: python/branches/bcannon-objcap/Include/cStringIO.h
==============================================================================
--- python/branches/bcannon-objcap/Include/cStringIO.h	(original)
+++ python/branches/bcannon-objcap/Include/cStringIO.h	Thu Sep  6 21:35:45 2007
@@ -60,9 +60,9 @@
 
 /* These can be used to test if you have one */
 #define PycStringIO_InputCheck(O) \
-  ((O)->ob_type==PycStringIO->InputType)
+  (Py_Type(O)==PycStringIO->InputType)
 #define PycStringIO_OutputCheck(O) \
-  ((O)->ob_type==PycStringIO->OutputType)
+  (Py_Type(O)==PycStringIO->OutputType)
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Include/cellobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/cellobject.h	(original)
+++ python/branches/bcannon-objcap/Include/cellobject.h	Thu Sep  6 21:35:45 2007
@@ -13,7 +13,7 @@
 
 PyAPI_DATA(PyTypeObject) PyCell_Type;
 
-#define PyCell_Check(op) ((op)->ob_type == &PyCell_Type)
+#define PyCell_Check(op) (Py_Type(op) == &PyCell_Type)
 
 PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);

Modified: python/branches/bcannon-objcap/Include/cobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/cobject.h	(original)
+++ python/branches/bcannon-objcap/Include/cobject.h	Thu Sep  6 21:35:45 2007
@@ -16,7 +16,7 @@
 
 PyAPI_DATA(PyTypeObject) PyCObject_Type;
 
-#define PyCObject_Check(op) ((op)->ob_type == &PyCObject_Type)
+#define PyCObject_Check(op) (Py_Type(op) == &PyCObject_Type)
 
 /* Create a PyCObject from a pointer to a C object and an optional
    destructor function.  If the second argument is non-null, then it

Modified: python/branches/bcannon-objcap/Include/code.h
==============================================================================
--- python/branches/bcannon-objcap/Include/code.h	(original)
+++ python/branches/bcannon-objcap/Include/code.h	Thu Sep  6 21:35:45 2007
@@ -60,7 +60,7 @@
 
 PyAPI_DATA(PyTypeObject) PyCode_Type;
 
-#define PyCode_Check(op) ((op)->ob_type == &PyCode_Type)
+#define PyCode_Check(op) (Py_Type(op) == &PyCode_Type)
 #define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars))
 
 /* Public interface */
@@ -72,7 +72,7 @@
 
 /* for internal use only */
 #define _PyCode_GETCODEPTR(co, pp) \
-	((*(co)->co_code->ob_type->tp_as_buffer->bf_getreadbuffer) \
+	((*Py_Type((co)->co_code)->tp_as_buffer->bf_getreadbuffer) \
 	 ((co)->co_code, 0, (void **)(pp)))
 
 typedef struct _addr_pair {

Modified: python/branches/bcannon-objcap/Include/complexobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/complexobject.h	(original)
+++ python/branches/bcannon-objcap/Include/complexobject.h	Thu Sep  6 21:35:45 2007
@@ -43,7 +43,7 @@
 PyAPI_DATA(PyTypeObject) PyComplex_Type;
 
 #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
-#define PyComplex_CheckExact(op) ((op)->ob_type == &PyComplex_Type)
+#define PyComplex_CheckExact(op) (Py_Type(op) == &PyComplex_Type)
 
 PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
 PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);

Modified: python/branches/bcannon-objcap/Include/datetime.h
==============================================================================
--- python/branches/bcannon-objcap/Include/datetime.h	(original)
+++ python/branches/bcannon-objcap/Include/datetime.h	Thu Sep  6 21:35:45 2007
@@ -166,19 +166,19 @@
 
 /* Macros for type checking when building the Python core. */
 #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
-#define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType)
+#define PyDate_CheckExact(op) (Py_Type(op) == &PyDateTime_DateType)
 
 #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
-#define PyDateTime_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeType)
+#define PyDateTime_CheckExact(op) (Py_Type(op) == &PyDateTime_DateTimeType)
 
 #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
-#define PyTime_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeType)
+#define PyTime_CheckExact(op) (Py_Type(op) == &PyDateTime_TimeType)
 
 #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
-#define PyDelta_CheckExact(op) ((op)->ob_type == &PyDateTime_DeltaType)
+#define PyDelta_CheckExact(op) (Py_Type(op) == &PyDateTime_DeltaType)
 
 #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
-#define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType)
+#define PyTZInfo_CheckExact(op) (Py_Type(op) == &PyDateTime_TZInfoType)
 
 #else
 
@@ -198,19 +198,19 @@
 
 /* Macros for type checking when not building the Python core. */
 #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
-#define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType)
+#define PyDate_CheckExact(op) (Py_Type(op) == PyDateTimeAPI->DateType)
 
 #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
-#define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType)
+#define PyDateTime_CheckExact(op) (Py_Type(op) == PyDateTimeAPI->DateTimeType)
 
 #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
-#define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType)
+#define PyTime_CheckExact(op) (Py_Type(op) == PyDateTimeAPI->TimeType)
 
 #define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
-#define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType)
+#define PyDelta_CheckExact(op) (Py_Type(op) == PyDateTimeAPI->DeltaType)
 
 #define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
-#define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType)
+#define PyTZInfo_CheckExact(op) (Py_Type(op) == PyDateTimeAPI->TZInfoType)
 
 /* Macros for accessing constructors in a simplified fashion. */
 #define PyDate_FromDate(year, month, day) \

Modified: python/branches/bcannon-objcap/Include/descrobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/descrobject.h	(original)
+++ python/branches/bcannon-objcap/Include/descrobject.h	Thu Sep  6 21:35:45 2007
@@ -77,7 +77,7 @@
 					       struct PyGetSetDef *);
 PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
 						struct wrapperbase *, void *);
-#define PyDescr_IsData(d) ((d)->ob_type->tp_descr_set != NULL)
+#define PyDescr_IsData(d) (Py_Type(d)->tp_descr_set != NULL)
 
 PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);

Modified: python/branches/bcannon-objcap/Include/dictobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/dictobject.h	(original)
+++ python/branches/bcannon-objcap/Include/dictobject.h	Thu Sep  6 21:35:45 2007
@@ -91,8 +91,8 @@
 PyAPI_DATA(PyTypeObject) PyDict_Type;
 
 #define PyDict_Check(op) \
-                 PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_DICT_SUBCLASS)
-#define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type)
+                 PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_DICT_SUBCLASS)
+#define PyDict_CheckExact(op) (Py_Type(op) == &PyDict_Type)
 
 PyAPI_FUNC(PyObject *) PyDict_New(void);
 PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);

Modified: python/branches/bcannon-objcap/Include/fileobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/fileobject.h	(original)
+++ python/branches/bcannon-objcap/Include/fileobject.h	Thu Sep  6 21:35:45 2007
@@ -30,7 +30,7 @@
 PyAPI_DATA(PyTypeObject) PyFile_Type;
 
 #define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)
-#define PyFile_CheckExact(op) ((op)->ob_type == &PyFile_Type)
+#define PyFile_CheckExact(op) (Py_Type(op) == &PyFile_Type)
 
 PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);
 PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);

Modified: python/branches/bcannon-objcap/Include/floatobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/floatobject.h	(original)
+++ python/branches/bcannon-objcap/Include/floatobject.h	Thu Sep  6 21:35:45 2007
@@ -19,7 +19,7 @@
 PyAPI_DATA(PyTypeObject) PyFloat_Type;
 
 #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
-#define PyFloat_CheckExact(op) ((op)->ob_type == &PyFloat_Type)
+#define PyFloat_CheckExact(op) (Py_Type(op) == &PyFloat_Type)
 
 /* Return Python float from string PyObject.  Second argument ignored on
    input, and, if non-NULL, NULL is stored into *junk (this tried to serve a

Modified: python/branches/bcannon-objcap/Include/funcobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/funcobject.h	(original)
+++ python/branches/bcannon-objcap/Include/funcobject.h	Thu Sep  6 21:35:45 2007
@@ -39,7 +39,7 @@
 
 PyAPI_DATA(PyTypeObject) PyFunction_Type;
 
-#define PyFunction_Check(op) ((op)->ob_type == &PyFunction_Type)
+#define PyFunction_Check(op) (Py_Type(op) == &PyFunction_Type)
 
 PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
 PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);

Modified: python/branches/bcannon-objcap/Include/genobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/genobject.h	(original)
+++ python/branches/bcannon-objcap/Include/genobject.h	Thu Sep  6 21:35:45 2007
@@ -26,7 +26,7 @@
 PyAPI_DATA(PyTypeObject) PyGen_Type;
 
 #define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
-#define PyGen_CheckExact(op) ((op)->ob_type == &PyGen_Type)
+#define PyGen_CheckExact(op) (Py_Type(op) == &PyGen_Type)
 
 PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
 PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);

Modified: python/branches/bcannon-objcap/Include/iterobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/iterobject.h	(original)
+++ python/branches/bcannon-objcap/Include/iterobject.h	Thu Sep  6 21:35:45 2007
@@ -7,13 +7,13 @@
 
 PyAPI_DATA(PyTypeObject) PySeqIter_Type;
 
-#define PySeqIter_Check(op) ((op)->ob_type == &PySeqIter_Type)
+#define PySeqIter_Check(op) (Py_Type(op) == &PySeqIter_Type)
 
 PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *);
 
 PyAPI_DATA(PyTypeObject) PyCallIter_Type;
 
-#define PyCallIter_Check(op) ((op)->ob_type == &PyCallIter_Type)
+#define PyCallIter_Check(op) (Py_Type(op) == &PyCallIter_Type)
 
 PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *);
 #ifdef __cplusplus

Modified: python/branches/bcannon-objcap/Include/listobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/listobject.h	(original)
+++ python/branches/bcannon-objcap/Include/listobject.h	Thu Sep  6 21:35:45 2007
@@ -41,8 +41,8 @@
 PyAPI_DATA(PyTypeObject) PyList_Type;
 
 #define PyList_Check(op) \
-		PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_LIST_SUBCLASS)
-#define PyList_CheckExact(op) ((op)->ob_type == &PyList_Type)
+		PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_LIST_SUBCLASS)
+#define PyList_CheckExact(op) (Py_Type(op) == &PyList_Type)
 
 PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size);
 PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *);
@@ -60,7 +60,7 @@
 /* Macro, trading safety for speed */
 #define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i])
 #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v))
-#define PyList_GET_SIZE(op)    (((PyListObject *)(op))->ob_size)
+#define PyList_GET_SIZE(op)    Py_Size(op)
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Include/longobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/longobject.h	(original)
+++ python/branches/bcannon-objcap/Include/longobject.h	Thu Sep  6 21:35:45 2007
@@ -12,8 +12,8 @@
 PyAPI_DATA(PyTypeObject) PyLong_Type;
 
 #define PyLong_Check(op) \
-		PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_LONG_SUBCLASS)
-#define PyLong_CheckExact(op) ((op)->ob_type == &PyLong_Type)
+		PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_LONG_SUBCLASS)
+#define PyLong_CheckExact(op) (Py_Type(op) == &PyLong_Type)
 
 PyAPI_FUNC(PyObject *) PyLong_FromLong(long);
 PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long);

Modified: python/branches/bcannon-objcap/Include/methodobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/methodobject.h	(original)
+++ python/branches/bcannon-objcap/Include/methodobject.h	Thu Sep  6 21:35:45 2007
@@ -13,7 +13,7 @@
 
 PyAPI_DATA(PyTypeObject) PyCFunction_Type;
 
-#define PyCFunction_Check(op) ((op)->ob_type == &PyCFunction_Type)
+#define PyCFunction_Check(op) (Py_Type(op) == &PyCFunction_Type)
 
 typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
 typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,

Modified: python/branches/bcannon-objcap/Include/moduleobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/moduleobject.h	(original)
+++ python/branches/bcannon-objcap/Include/moduleobject.h	Thu Sep  6 21:35:45 2007
@@ -10,7 +10,7 @@
 PyAPI_DATA(PyTypeObject) PyModule_Type;
 
 #define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type)
-#define PyModule_CheckExact(op) ((op)->ob_type == &PyModule_Type)
+#define PyModule_CheckExact(op) (Py_Type(op) == &PyModule_Type)
 
 PyAPI_FUNC(PyObject *) PyModule_New(const char *);
 PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *);

Modified: python/branches/bcannon-objcap/Include/object.h
==============================================================================
--- python/branches/bcannon-objcap/Include/object.h	(original)
+++ python/branches/bcannon-objcap/Include/object.h	Thu Sep  6 21:35:45 2007
@@ -84,6 +84,9 @@
 	_PyObject_EXTRA_INIT		\
 	1, type,
 
+#define PyVarObject_HEAD_INIT(type, size)	\
+	PyObject_HEAD_INIT(type) size,
+
 /* PyObject_VAR_HEAD defines the initial segment of all variable-size
  * container objects.  These end with a declaration of an array with 1
  * element, but enough space is malloc'ed so that the array actually
@@ -108,6 +111,9 @@
 	PyObject_VAR_HEAD
 } PyVarObject;
 
+#define Py_Refcnt(ob)		(((PyObject*)(ob))->ob_refcnt)
+#define Py_Type(ob)		(((PyObject*)(ob))->ob_type)
+#define Py_Size(ob)		(((PyVarObject*)(ob))->ob_size)
 
 /*
 Type objects contain a string containing the type name (to help somewhat
@@ -364,21 +370,21 @@
 
 /* access macro to the members which are floating "behind" the object */
 #define PyHeapType_GET_MEMBERS(etype) \
-    ((PyMemberDef *)(((char *)etype) + (etype)->ht_type.ob_type->tp_basicsize))
+    ((PyMemberDef *)(((char *)etype) + Py_Type(etype)->tp_basicsize))
 
 
 /* Generic type check */
 PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
 #define PyObject_TypeCheck(ob, tp) \
-	((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp)))
+	(Py_Type(ob) == (tp) || PyType_IsSubtype(Py_Type(ob), (tp)))
 
 PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */
 PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
 PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */
 
 #define PyType_Check(op) \
-	PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_TYPE_SUBCLASS)
-#define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type)
+	PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_TYPE_SUBCLASS)
+#define PyType_CheckExact(op) (Py_Type(op) == &PyType_Type)
 
 PyAPI_FUNC(int) PyType_Ready(PyTypeObject *);
 PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t);
@@ -599,7 +605,7 @@
 #define _Py_DEC_REFTOTAL	_Py_RefTotal--
 #define _Py_REF_DEBUG_COMMA	,
 #define _Py_CHECK_REFCNT(OP)					\
-{	if ((OP)->ob_refcnt < 0)				\
+{	if (((PyObject*)OP)->ob_refcnt < 0)				\
 		_Py_NegativeRefcount(__FILE__, __LINE__,	\
 				     (PyObject *)(OP));		\
 }
@@ -613,9 +619,9 @@
 #ifdef COUNT_ALLOCS
 PyAPI_FUNC(void) inc_count(PyTypeObject *);
 PyAPI_FUNC(void) dec_count(PyTypeObject *);
-#define _Py_INC_TPALLOCS(OP)	inc_count((OP)->ob_type)
-#define _Py_INC_TPFREES(OP)	dec_count((OP)->ob_type)
-#define _Py_DEC_TPFREES(OP)	(OP)->ob_type->tp_frees--
+#define _Py_INC_TPALLOCS(OP)	inc_count(Py_Type(OP))
+#define _Py_INC_TPFREES(OP)	dec_count(Py_Type(OP))
+#define _Py_DEC_TPFREES(OP)	Py_Type(OP)->tp_frees--
 #define _Py_COUNT_ALLOCS_COMMA	,
 #else
 #define _Py_INC_TPALLOCS(OP)
@@ -640,22 +646,22 @@
 #define _Py_NewReference(op) (				\
 	_Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA	\
 	_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA		\
-	(op)->ob_refcnt = 1)
+	Py_Refcnt(op) = 1)
 
 #define _Py_ForgetReference(op) _Py_INC_TPFREES(op)
 
 #define _Py_Dealloc(op) (				\
 	_Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA	\
-	(*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
+	(*Py_Type(op)->tp_dealloc)((PyObject *)(op)))
 #endif /* !Py_TRACE_REFS */
 
 #define Py_INCREF(op) (				\
 	_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA	\
-	(op)->ob_refcnt++)
+	((PyObject*)(op))->ob_refcnt++)
 
 #define Py_DECREF(op)					\
 	if (_Py_DEC_REFTOTAL  _Py_REF_DEBUG_COMMA	\
-	    --(op)->ob_refcnt != 0)			\
+	    --((PyObject*)(op))->ob_refcnt != 0)		\
 		_Py_CHECK_REFCNT(op)			\
 	else						\
 		_Py_Dealloc((PyObject *)(op))

Modified: python/branches/bcannon-objcap/Include/objimpl.h
==============================================================================
--- python/branches/bcannon-objcap/Include/objimpl.h	(original)
+++ python/branches/bcannon-objcap/Include/objimpl.h	Thu Sep  6 21:35:45 2007
@@ -154,9 +154,9 @@
 /* Macros trading binary compatibility for speed. See also pymem.h.
    Note that these macros expect non-NULL object pointers.*/
 #define PyObject_INIT(op, typeobj) \
-	( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
+	( Py_Type(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
 #define PyObject_INIT_VAR(op, typeobj, size) \
-	( (op)->ob_size = (size), PyObject_INIT((op), (typeobj)) )
+	( Py_Size(op) = (size), PyObject_INIT((op), (typeobj)) )
 
 #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
 
@@ -231,8 +231,8 @@
 #define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
 
 /* Test if an object has a GC head */
-#define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \
-	((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o)))
+#define PyObject_IS_GC(o) (PyType_IS_GC(Py_Type(o)) && \
+	(Py_Type(o)->tp_is_gc == NULL || Py_Type(o)->tp_is_gc(o)))
 
 PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);
 #define PyObject_GC_Resize(type, op, n) \
@@ -328,7 +328,7 @@
          && ((t)->tp_weaklistoffset > 0))
 
 #define PyObject_GET_WEAKREFS_LISTPTR(o) \
-	((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset))
+	((PyObject **) (((char *) (o)) + Py_Type(o)->tp_weaklistoffset))
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Include/opcode.h
==============================================================================
--- python/branches/bcannon-objcap/Include/opcode.h	(original)
+++ python/branches/bcannon-objcap/Include/opcode.h	Thu Sep  6 21:35:45 2007
@@ -112,7 +112,7 @@
 #define LOAD_GLOBAL	116	/* Index in name list */
 
 #define CONTINUE_LOOP	119	/* Start of loop (absolute) */
-#define SETUP_LOOP	120	/* Target address (absolute) */
+#define SETUP_LOOP	120	/* Target address (relative) */
 #define SETUP_EXCEPT	121	/* "" */
 #define SETUP_FINALLY	122	/* "" */
 

Modified: python/branches/bcannon-objcap/Include/py_curses.h
==============================================================================
--- python/branches/bcannon-objcap/Include/py_curses.h	(original)
+++ python/branches/bcannon-objcap/Include/py_curses.h	Thu Sep  6 21:35:45 2007
@@ -73,7 +73,7 @@
 	WINDOW *win;
 } PyCursesWindowObject;
 
-#define PyCursesWindow_Check(v)	 ((v)->ob_type == &PyCursesWindow_Type)
+#define PyCursesWindow_Check(v)	 (Py_Type(v) == &PyCursesWindow_Type)
 
 #ifdef CURSES_MODULE
 /* This section is used when compiling _cursesmodule.c */

Modified: python/branches/bcannon-objcap/Include/rangeobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/rangeobject.h	(original)
+++ python/branches/bcannon-objcap/Include/rangeobject.h	Thu Sep  6 21:35:45 2007
@@ -20,7 +20,7 @@
 
 PyAPI_DATA(PyTypeObject) PyRange_Type;
 
-#define PyRange_Check(op) ((op)->ob_type == &PyRange_Type)
+#define PyRange_Check(op) (Py_Type(op) == &PyRange_Type)
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Include/setobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/setobject.h	(original)
+++ python/branches/bcannon-objcap/Include/setobject.h	Thu Sep  6 21:35:45 2007
@@ -66,13 +66,13 @@
  *     hash is -1
  */
 
-#define PyFrozenSet_CheckExact(ob) ((ob)->ob_type == &PyFrozenSet_Type)
+#define PyFrozenSet_CheckExact(ob) (Py_Type(ob) == &PyFrozenSet_Type)
 #define PyAnySet_CheckExact(ob) \
-	((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type)
+	(Py_Type(ob) == &PySet_Type || Py_Type(ob) == &PyFrozenSet_Type)
 #define PyAnySet_Check(ob) \
-	((ob)->ob_type == &PySet_Type || (ob)->ob_type == &PyFrozenSet_Type || \
-	  PyType_IsSubtype((ob)->ob_type, &PySet_Type) || \
-	  PyType_IsSubtype((ob)->ob_type, &PyFrozenSet_Type))
+	(Py_Type(ob) == &PySet_Type || Py_Type(ob) == &PyFrozenSet_Type || \
+	  PyType_IsSubtype(Py_Type(ob), &PySet_Type) || \
+	  PyType_IsSubtype(Py_Type(ob), &PyFrozenSet_Type))
 
 PyAPI_FUNC(PyObject *) PySet_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *);

Modified: python/branches/bcannon-objcap/Include/sliceobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/sliceobject.h	(original)
+++ python/branches/bcannon-objcap/Include/sliceobject.h	Thu Sep  6 21:35:45 2007
@@ -26,7 +26,7 @@
 
 PyAPI_DATA(PyTypeObject) PySlice_Type;
 
-#define PySlice_Check(op) ((op)->ob_type == &PySlice_Type)
+#define PySlice_Check(op) (Py_Type(op) == &PySlice_Type)
 
 PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop,
                                   PyObject* step);

Modified: python/branches/bcannon-objcap/Include/stringobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/stringobject.h	(original)
+++ python/branches/bcannon-objcap/Include/stringobject.h	Thu Sep  6 21:35:45 2007
@@ -56,8 +56,8 @@
 PyAPI_DATA(PyTypeObject) PyString_Type;
 
 #define PyString_Check(op) \
-                 PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_STRING_SUBCLASS)
-#define PyString_CheckExact(op) ((op)->ob_type == &PyString_Type)
+                 PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_STRING_SUBCLASS)
+#define PyString_CheckExact(op) (Py_Type(op) == &PyString_Type)
 
 PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t);
 PyAPI_FUNC(PyObject *) PyString_FromString(const char *);
@@ -89,7 +89,7 @@
 
 /* Macro, trading safety for speed */
 #define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval)
-#define PyString_GET_SIZE(op)  (((PyStringObject *)(op))->ob_size)
+#define PyString_GET_SIZE(op)  Py_Size(op)
 
 /* _PyString_Join(sep, x) is like sep.join(x).  sep must be PyStringObject*,
    x must be an iterable object. */

Modified: python/branches/bcannon-objcap/Include/structmember.h
==============================================================================
--- python/branches/bcannon-objcap/Include/structmember.h	(original)
+++ python/branches/bcannon-objcap/Include/structmember.h	Thu Sep  6 21:35:45 2007
@@ -68,9 +68,11 @@
 #ifdef HAVE_LONG_LONG
 #define T_LONGLONG      17  
 #define T_ULONGLONG      18
-#define T_PYSSIZET       19 /* Py_ssize_t */
 #endif /* HAVE_LONG_LONG */
 
+#define T_PYSSIZET       19 /* Py_ssize_t */
+
+
 /* Flags */
 #define READONLY	1
 #define RO		READONLY		/* Shorthand */

Modified: python/branches/bcannon-objcap/Include/symtable.h
==============================================================================
--- python/branches/bcannon-objcap/Include/symtable.h	(original)
+++ python/branches/bcannon-objcap/Include/symtable.h	Thu Sep  6 21:35:45 2007
@@ -49,7 +49,7 @@
 
 PyAPI_DATA(PyTypeObject) PySTEntry_Type;
 
-#define PySTEntry_Check(op) ((op)->ob_type == &PySTEntry_Type)
+#define PySTEntry_Check(op) (Py_Type(op) == &PySTEntry_Type)
 
 PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *);
 

Modified: python/branches/bcannon-objcap/Include/traceback.h
==============================================================================
--- python/branches/bcannon-objcap/Include/traceback.h	(original)
+++ python/branches/bcannon-objcap/Include/traceback.h	Thu Sep  6 21:35:45 2007
@@ -22,7 +22,7 @@
 
 /* Reveal traceback type so we can typecheck traceback objects */
 PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
-#define PyTraceBack_Check(v) ((v)->ob_type == &PyTraceBack_Type)
+#define PyTraceBack_Check(v) (Py_Type(v) == &PyTraceBack_Type)
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Include/tupleobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/tupleobject.h	(original)
+++ python/branches/bcannon-objcap/Include/tupleobject.h	Thu Sep  6 21:35:45 2007
@@ -34,8 +34,8 @@
 PyAPI_DATA(PyTypeObject) PyTuple_Type;
 
 #define PyTuple_Check(op) \
-                 PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_TUPLE_SUBCLASS)
-#define PyTuple_CheckExact(op) ((op)->ob_type == &PyTuple_Type)
+                 PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_TUPLE_SUBCLASS)
+#define PyTuple_CheckExact(op) (Py_Type(op) == &PyTuple_Type)
 
 PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size);
 PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *);
@@ -47,7 +47,7 @@
 
 /* Macro, trading safety for speed */
 #define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
-#define PyTuple_GET_SIZE(op)    (((PyTupleObject *)(op))->ob_size)
+#define PyTuple_GET_SIZE(op)    Py_Size(op)
 
 /* Macro, *only* to be used to fill in brand new tuples */
 #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)

Modified: python/branches/bcannon-objcap/Include/unicodeobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/unicodeobject.h	(original)
+++ python/branches/bcannon-objcap/Include/unicodeobject.h	Thu Sep  6 21:35:45 2007
@@ -145,6 +145,7 @@
 # define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString
 # define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String
 # define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString
+# define PyUnicode_AsUTF32String PyUnicodeUCS2_AsUTF32String
 # define PyUnicode_AsUTF16String PyUnicodeUCS2_AsUTF16String
 # define PyUnicode_AsUTF8String PyUnicodeUCS2_AsUTF8String
 # define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode
@@ -159,6 +160,8 @@
 # define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap
 # define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1
 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape
+# define PyUnicode_DecodeUTF32 PyUnicodeUCS2_DecodeUTF32
+# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS2_DecodeUTF32Stateful
 # define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16
 # define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful
 # define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8
@@ -170,6 +173,7 @@
 # define PyUnicode_EncodeDecimal PyUnicodeUCS2_EncodeDecimal
 # define PyUnicode_EncodeLatin1 PyUnicodeUCS2_EncodeLatin1
 # define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS2_EncodeRawUnicodeEscape
+# define PyUnicode_EncodeUTF32 PyUnicodeUCS2_EncodeUTF32
 # define PyUnicode_EncodeUTF16 PyUnicodeUCS2_EncodeUTF16
 # define PyUnicode_EncodeUTF8 PyUnicodeUCS2_EncodeUTF8
 # define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS2_EncodeUnicodeEscape
@@ -223,6 +227,7 @@
 # define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString
 # define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String
 # define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString
+# define PyUnicode_AsUTF32String PyUnicodeUCS4_AsUTF32String
 # define PyUnicode_AsUTF16String PyUnicodeUCS4_AsUTF16String
 # define PyUnicode_AsUTF8String PyUnicodeUCS4_AsUTF8String
 # define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode
@@ -237,6 +242,8 @@
 # define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap
 # define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1
 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape
+# define PyUnicode_DecodeUTF32 PyUnicodeUCS4_DecodeUTF32
+# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS4_DecodeUTF32Stateful
 # define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16
 # define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful
 # define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8
@@ -248,6 +255,7 @@
 # define PyUnicode_EncodeDecimal PyUnicodeUCS4_EncodeDecimal
 # define PyUnicode_EncodeLatin1 PyUnicodeUCS4_EncodeLatin1
 # define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS4_EncodeRawUnicodeEscape
+# define PyUnicode_EncodeUTF32 PyUnicodeUCS4_EncodeUTF32
 # define PyUnicode_EncodeUTF16 PyUnicodeUCS4_EncodeUTF16
 # define PyUnicode_EncodeUTF8 PyUnicodeUCS4_EncodeUTF8
 # define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS4_EncodeUnicodeEscape
@@ -393,8 +401,8 @@
 PyAPI_DATA(PyTypeObject) PyUnicode_Type;
 
 #define PyUnicode_Check(op) \
-                 PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_UNICODE_SUBCLASS)
-#define PyUnicode_CheckExact(op) ((op)->ob_type == &PyUnicode_Type)
+                 PyType_FastSubclass(Py_Type(op), Py_TPFLAGS_UNICODE_SUBCLASS)
+#define PyUnicode_CheckExact(op) (Py_Type(op) == &PyUnicode_Type)
 
 /* Fast access macros */
 #define PyUnicode_GET_SIZE(op) \
@@ -701,6 +709,80 @@
     const char *errors		/* error handling */
     );
 
+/* --- UTF-32 Codecs ------------------------------------------------------ */
+
+/* Decodes length bytes from a UTF-32 encoded buffer string and returns
+   the corresponding Unicode object.
+
+   errors (if non-NULL) defines the error handling. It defaults
+   to "strict". 
+
+   If byteorder is non-NULL, the decoder starts decoding using the
+   given byte order:
+
+	*byteorder == -1: little endian
+	*byteorder == 0:  native order
+	*byteorder == 1:  big endian
+
+   In native mode, the first four bytes of the stream are checked for a
+   BOM mark. If found, the BOM mark is analysed, the byte order
+   adjusted and the BOM skipped.  In the other modes, no BOM mark
+   interpretation is done. After completion, *byteorder is set to the
+   current byte order at the end of input data.
+
+   If byteorder is NULL, the codec starts in native order mode.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32(
+    const char *string, 	/* UTF-32 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors,		/* error handling */
+    int *byteorder		/* pointer to byteorder to use
+				   0=native;-1=LE,1=BE; updated on
+				   exit */
+    );
+
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32Stateful(
+    const char *string, 	/* UTF-32 encoded string */
+    Py_ssize_t length,	 	/* size of string */
+    const char *errors,		/* error handling */
+    int *byteorder,		/* pointer to byteorder to use
+				   0=native;-1=LE,1=BE; updated on
+				   exit */
+    Py_ssize_t *consumed	/* bytes consumed */
+    );
+
+/* Returns a Python string using the UTF-32 encoding in native byte
+   order. The string always starts with a BOM mark.  */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsUTF32String(
+    PyObject *unicode	 	/* Unicode object */
+    );
+
+/* Returns a Python string object holding the UTF-32 encoded value of
+   the Unicode data.
+
+   If byteorder is not 0, output is written according to the following
+   byte order:
+
+   byteorder == -1: little endian
+   byteorder == 0:  native byte order (writes a BOM mark)
+   byteorder == 1:  big endian
+
+   If byteorder is 0, the output string will always start with the
+   Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is
+   prepended.
+
+*/
+
+PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32(
+    const Py_UNICODE *data, 	/* Unicode char buffer */
+    Py_ssize_t length,	 	/* number of Py_UNICODE chars to encode */
+    const char *errors,		/* error handling */
+    int byteorder		/* byteorder to use 0=BOM+native;-1=LE,1=BE */
+    );
+
 /* --- UTF-16 Codecs ------------------------------------------------------ */
 
 /* Decodes length bytes from a UTF-16 encoded buffer string and returns

Modified: python/branches/bcannon-objcap/Include/weakrefobject.h
==============================================================================
--- python/branches/bcannon-objcap/Include/weakrefobject.h	(original)
+++ python/branches/bcannon-objcap/Include/weakrefobject.h	Thu Sep  6 21:35:45 2007
@@ -44,10 +44,10 @@
 
 #define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType)
 #define PyWeakref_CheckRefExact(op) \
-        ((op)->ob_type == &_PyWeakref_RefType)
+        (Py_Type(op) == &_PyWeakref_RefType)
 #define PyWeakref_CheckProxy(op) \
-        (((op)->ob_type == &_PyWeakref_ProxyType) || \
-         ((op)->ob_type == &_PyWeakref_CallableProxyType))
+        ((Py_Type(op) == &_PyWeakref_ProxyType) || \
+         (Py_Type(op) == &_PyWeakref_CallableProxyType))
 
 /* This macro calls PyWeakref_CheckRef() last since that can involve a
    function call; this makes it more likely that the function call

Modified: python/branches/bcannon-objcap/Lib/SimpleXMLRPCServer.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/SimpleXMLRPCServer.py	(original)
+++ python/branches/bcannon-objcap/Lib/SimpleXMLRPCServer.py	Thu Sep  6 21:35:45 2007
@@ -105,6 +105,7 @@
 import BaseHTTPServer
 import sys
 import os
+import traceback
 try:
     import fcntl
 except ImportError:
@@ -470,9 +471,16 @@
             response = self.server._marshaled_dispatch(
                     data, getattr(self, '_dispatch', None)
                 )
-        except: # This should only happen if the module is buggy
+        except Exception, e: # This should only happen if the module is buggy
             # internal error, report as HTTP server error
             self.send_response(500)
+
+            # Send information about the exception if requested
+            if hasattr(self.server, '_send_traceback_header') and \
+                    self.server._send_traceback_header:
+                self.send_header("X-exception", str(e))
+                self.send_header("X-traceback", traceback.format_exc())
+
             self.end_headers()
         else:
             # got a valid XML RPC response
@@ -517,6 +525,12 @@
 
     allow_reuse_address = True
 
+    # Warning: this is for debugging purposes only! Never set this to True in
+    # production code, as will be sending out sensitive information (exception
+    # and stack trace details) when exceptions are raised inside
+    # SimpleXMLRPCRequestHandler.do_POST
+    _send_traceback_header = False
+
     def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
                  logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
         self.logRequests = logRequests

Modified: python/branches/bcannon-objcap/Lib/UserString.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/UserString.py	(original)
+++ python/branches/bcannon-objcap/Lib/UserString.py	Thu Sep  6 21:35:45 2007
@@ -149,15 +149,41 @@
     def __hash__(self):
         raise TypeError, "unhashable type (it is mutable)"
     def __setitem__(self, index, sub):
-        if index < 0:
-            index += len(self.data)
-        if index < 0 or index >= len(self.data): raise IndexError
-        self.data = self.data[:index] + sub + self.data[index+1:]
+        if isinstance(index, slice):
+            if isinstance(sub, UserString):
+                sub = sub.data
+            elif not isinstance(sub, basestring):
+                sub = str(sub)
+            start, stop, step = index.indices(len(self.data))
+            if step == -1:
+                start, stop = stop+1, start+1
+                sub = sub[::-1]
+            elif step != 1:
+                # XXX(twouters): I guess we should be reimplementing
+                # the extended slice assignment/deletion algorithm here...
+                raise TypeError, "invalid step in slicing assignment"
+            start = min(start, stop)
+            self.data = self.data[:start] + sub + self.data[stop:]
+        else:
+            if index < 0:
+                index += len(self.data)
+            if index < 0 or index >= len(self.data): raise IndexError
+            self.data = self.data[:index] + sub + self.data[index+1:]
     def __delitem__(self, index):
-        if index < 0:
-            index += len(self.data)
-        if index < 0 or index >= len(self.data): raise IndexError
-        self.data = self.data[:index] + self.data[index+1:]
+        if isinstance(index, slice):
+            start, stop, step = index.indices(len(self.data))
+            if step == -1:
+                start, stop = stop+1, start+1
+            elif step != 1:
+                # XXX(twouters): see same block in __setitem__
+                raise TypeError, "invalid step in slicing deletion"
+            start = min(start, stop)
+            self.data = self.data[:start] + self.data[stop:]
+        else:
+            if index < 0:
+                index += len(self.data)
+            if index < 0 or index >= len(self.data): raise IndexError
+            self.data = self.data[:index] + self.data[index+1:]
     def __setslice__(self, start, end, sub):
         start = max(start, 0); end = max(end, 0)
         if isinstance(sub, UserString):

Modified: python/branches/bcannon-objcap/Lib/bsddb/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/bsddb/__init__.py	(original)
+++ python/branches/bcannon-objcap/Lib/bsddb/__init__.py	Thu Sep  6 21:35:45 2007
@@ -274,12 +274,16 @@
 
     def first(self):
         self._checkOpen()
+        # fix 1725856: don't needlessly try to restore our cursor position
+        self.saved_dbc_key = None
         self._checkCursor()
         rv = _DeadlockWrap(self.dbc.first)
         return rv
 
     def last(self):
         self._checkOpen()
+        # fix 1725856: don't needlessly try to restore our cursor position
+        self.saved_dbc_key = None
         self._checkCursor()
         rv = _DeadlockWrap(self.dbc.last)
         return rv

Modified: python/branches/bcannon-objcap/Lib/bsddb/test/test_1413192.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/bsddb/test/test_1413192.py	(original)
+++ python/branches/bcannon-objcap/Lib/bsddb/test/test_1413192.py	Thu Sep  6 21:35:45 2007
@@ -4,6 +4,8 @@
 # This test relies on the variable names, see the bug report for details.
 # The problem was that the env was deallocated prior to the txn.
 
+import shutil
+import tempfile
 try:
     # For Pythons w/distutils and add-on pybsddb
     from bsddb3 import db
@@ -11,7 +13,7 @@
     # For Python >= 2.3 builtin bsddb distribution
     from bsddb import db
 
-env_name = '.'
+env_name = tempfile.mkdtemp()
 
 env = db.DBEnv()
 env.open(env_name, db.DB_CREATE | db.DB_INIT_TXN | db.DB_INIT_MPOOL)
@@ -19,3 +21,9 @@
 
 map = db.DB(env)
 map.open('xxx.db', "p", db.DB_HASH, db.DB_CREATE, 0666, txn=the_txn)
+
+# try not to leave a turd (won't help Windows since files are still open)
+try:
+    shutil.rmtree(env_name)
+except EnvironmentError:
+    pass

Modified: python/branches/bcannon-objcap/Lib/calendar.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/calendar.py	(original)
+++ python/branches/bcannon-objcap/Lib/calendar.py	Thu Sep  6 21:35:45 2007
@@ -471,7 +471,7 @@
         a('<meta http-equiv="Content-Type" content="text/html; charset=%s" />\n' % encoding)
         if css is not None:
             a('<link rel="stylesheet" type="text/css" href="%s" />\n' % css)
-        a('<title>Calendar for %d</title\n' % theyear)
+        a('<title>Calendar for %d</title>\n' % theyear)
         a('</head>\n')
         a('<body>\n')
         a(self.formatyear(theyear, width))

Modified: python/branches/bcannon-objcap/Lib/contextlib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/contextlib.py	(original)
+++ python/branches/bcannon-objcap/Lib/contextlib.py	Thu Sep  6 21:35:45 2007
@@ -105,15 +105,14 @@
     vars = []
     exc = (None, None, None)
     try:
-        try:
-            for mgr in managers:
-                exit = mgr.__exit__
-                enter = mgr.__enter__
-                vars.append(enter())
-                exits.append(exit)
-            yield vars
-        except:
-            exc = sys.exc_info()
+        for mgr in managers:
+            exit = mgr.__exit__
+            enter = mgr.__enter__
+            vars.append(enter())
+            exits.append(exit)
+        yield vars
+    except:
+        exc = sys.exc_info()
     finally:
         while exits:
             exit = exits.pop()

Modified: python/branches/bcannon-objcap/Lib/ctypes/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/__init__.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/__init__.py	Thu Sep  6 21:35:45 2007
@@ -226,6 +226,14 @@
 
 class c_char_p(_SimpleCData):
     _type_ = "z"
+    if _os.name == "nt":
+        def __repr__(self):
+            if not windll.kernel32.IsBadStringPtrA(self, -1):
+                return "%s(%r)" % (self.__class__.__name__, self.value)
+            return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
+    else:
+        def __repr__(self):
+            return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
 _check_size(c_char_p, "P")
 
 class c_void_p(_SimpleCData):
@@ -331,7 +339,7 @@
     <obj>['qsort'] -> callable object
 
     Calling the functions releases the Python GIL during the call and
-    reaquires it afterwards.
+    reacquires it afterwards.
     """
     class _FuncPtr(_CFuncPtr):
         _flags_ = _FUNCFLAG_CDECL

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_arrays.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_arrays.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_arrays.py	Thu Sep  6 21:35:45 2007
@@ -95,6 +95,10 @@
         p = create_string_buffer("foo")
         sz = (c_char * 3).from_address(addressof(p))
         self.failUnlessEqual(sz[:], "foo")
+        self.failUnlessEqual(sz[::], "foo")
+        self.failUnlessEqual(sz[::-1], "oof")
+        self.failUnlessEqual(sz[::3], "f")
+        self.failUnlessEqual(sz[1:4:2], "o")
         self.failUnlessEqual(sz.value, "foo")
 
     try:
@@ -106,6 +110,10 @@
             p = create_unicode_buffer("foo")
             sz = (c_wchar * 3).from_address(addressof(p))
             self.failUnlessEqual(sz[:], "foo")
+            self.failUnlessEqual(sz[::], "foo")
+            self.failUnlessEqual(sz[::-1], "oof")
+            self.failUnlessEqual(sz[::3], "f")
+            self.failUnlessEqual(sz[1:4:2], "o")
             self.failUnlessEqual(sz.value, "foo")
 
 if __name__ == '__main__':

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_buffers.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_buffers.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_buffers.py	Thu Sep  6 21:35:45 2007
@@ -15,6 +15,10 @@
         self.failUnless(type(b[0]) is str)
         self.failUnlessEqual(b[0], "a")
         self.failUnlessEqual(b[:], "abc\0")
+        self.failUnlessEqual(b[::], "abc\0")
+        self.failUnlessEqual(b[::-1], "\0cba")
+        self.failUnlessEqual(b[::2], "ac")
+        self.failUnlessEqual(b[::5], "a")
 
     def test_string_conversion(self):
         b = create_string_buffer(u"abc")
@@ -23,6 +27,10 @@
         self.failUnless(type(b[0]) is str)
         self.failUnlessEqual(b[0], "a")
         self.failUnlessEqual(b[:], "abc\0")
+        self.failUnlessEqual(b[::], "abc\0")
+        self.failUnlessEqual(b[::-1], "\0cba")
+        self.failUnlessEqual(b[::2], "ac")
+        self.failUnlessEqual(b[::5], "a")
 
     try:
         c_wchar
@@ -41,6 +49,10 @@
             self.failUnless(type(b[0]) is unicode)
             self.failUnlessEqual(b[0], u"a")
             self.failUnlessEqual(b[:], "abc\0")
+            self.failUnlessEqual(b[::], "abc\0")
+            self.failUnlessEqual(b[::-1], "\0cba")
+            self.failUnlessEqual(b[::2], "ac")
+            self.failUnlessEqual(b[::5], "a")
 
         def test_unicode_conversion(self):
             b = create_unicode_buffer("abc")
@@ -49,6 +61,10 @@
             self.failUnless(type(b[0]) is unicode)
             self.failUnlessEqual(b[0], u"a")
             self.failUnlessEqual(b[:], "abc\0")
+            self.failUnlessEqual(b[::], "abc\0")
+            self.failUnlessEqual(b[::-1], "\0cba")
+            self.failUnlessEqual(b[::2], "ac")
+            self.failUnlessEqual(b[::5], "a")
 
 if __name__ == "__main__":
     unittest.main()

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_cast.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_cast.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_cast.py	Thu Sep  6 21:35:45 2007
@@ -50,12 +50,24 @@
     def test_other(self):
         p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
         self.failUnlessEqual(p[:4], [1,2, 3, 4])
+        self.failUnlessEqual(p[:4:], [1, 2, 3, 4])
+        self.failUnlessEqual(p[3:-1:-1], [4, 3, 2, 1])
+        self.failUnlessEqual(p[:4:3], [1, 4])
         c_int()
         self.failUnlessEqual(p[:4], [1, 2, 3, 4])
+        self.failUnlessEqual(p[:4:], [1, 2, 3, 4])
+        self.failUnlessEqual(p[3:-1:-1], [4, 3, 2, 1])
+        self.failUnlessEqual(p[:4:3], [1, 4])
         p[2] = 96
         self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+        self.failUnlessEqual(p[:4:], [1, 2, 96, 4])
+        self.failUnlessEqual(p[3:-1:-1], [4, 96, 2, 1])
+        self.failUnlessEqual(p[:4:3], [1, 4])
         c_int()
         self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+        self.failUnlessEqual(p[:4:], [1, 2, 96, 4])
+        self.failUnlessEqual(p[3:-1:-1], [4, 96, 2, 1])
+        self.failUnlessEqual(p[:4:3], [1, 4])
 
     def test_char_p(self):
         # This didn't work: bad argument to internal function

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_find.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_find.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_find.py	Thu Sep  6 21:35:45 2007
@@ -7,25 +7,21 @@
 if sys.platform == "win32":
     lib_gl = find_library("OpenGL32")
     lib_glu = find_library("Glu32")
-    lib_glut = find_library("glut32")
     lib_gle = None
 elif sys.platform == "darwin":
     lib_gl = lib_glu = find_library("OpenGL")
-    lib_glut = find_library("GLUT")
     lib_gle = None
 else:
     lib_gl = find_library("GL")
     lib_glu = find_library("GLU")
-    lib_glut = find_library("glut")
     lib_gle = find_library("gle")
 
 ## print, for debugging
 if is_resource_enabled("printing"):
-    if lib_gl or lib_glu or lib_glut or lib_gle:
+    if lib_gl or lib_glu or lib_gle:
         print "OpenGL libraries:"
         for item in (("GL", lib_gl),
                      ("GLU", lib_glu),
-                     ("glut", lib_glut),
                      ("gle", lib_gle)):
             print "\t", item
 
@@ -33,24 +29,11 @@
 # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
 class Test_OpenGL_libs(unittest.TestCase):
     def setUp(self):
-        self.gl = self.glu = self.gle = self.glut = None
+        self.gl = self.glu = self.gle = None
         if lib_gl:
             self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
         if lib_glu:
             self.glu = CDLL(lib_glu, RTLD_GLOBAL)
-        if lib_glut:
-            # On some systems, additional libraries seem to be
-            # required, loading glut fails with
-            # "OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion"
-            # I cannot figure out how to repair the test on these
-            # systems (red hat), so we ignore it when the glut or gle
-            # libraries cannot be loaded.  See also:
-            # https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470
-            # http://mail.python.org/pipermail/python-dev/2006-May/064789.html
-            try:
-                self.glut = CDLL(lib_glut)
-            except OSError:
-                pass
         if lib_gle:
             try:
                 self.gle = CDLL(lib_gle)
@@ -67,11 +50,6 @@
             if self.glu:
                 self.glu.gluBeginCurve
 
-    if lib_glut:
-        def test_glut(self):
-            if self.glut:
-                self.glut.glutWireTetrahedron
-
     if lib_gle:
         def test_gle(self):
             if self.gle:

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_memfunctions.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_memfunctions.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_memfunctions.py	Thu Sep  6 21:35:45 2007
@@ -30,6 +30,14 @@
         self.failUnlessEqual(cast(a, c_char_p).value, "abcdef")
         self.failUnlessEqual(cast(a, POINTER(c_byte))[:7],
                              [97, 98, 99, 100, 101, 102, 0])
+        self.failUnlessEqual(cast(a, POINTER(c_byte))[:7:],
+                             [97, 98, 99, 100, 101, 102, 0])
+        self.failUnlessEqual(cast(a, POINTER(c_byte))[6:-1:-1],
+                             [0, 102, 101, 100, 99, 98, 97])
+        self.failUnlessEqual(cast(a, POINTER(c_byte))[:7:2],
+                             [97, 99, 101, 0])
+        self.failUnlessEqual(cast(a, POINTER(c_byte))[:7:7],
+                             [97])
 
     def test_string_at(self):
         s = string_at("foo bar")

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_slicing.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_slicing.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_slicing.py	Thu Sep  6 21:35:45 2007
@@ -8,13 +8,22 @@
         a = (c_int * 100)(*xrange(1100, 1200))
         b = range(1100, 1200)
         self.failUnlessEqual(a[0:2], b[0:2])
+        self.failUnlessEqual(a[0:2:], b[0:2:])
         self.failUnlessEqual(len(a), len(b))
         self.failUnlessEqual(a[5:7], b[5:7])
+        self.failUnlessEqual(a[5:7:], b[5:7:])
         self.failUnlessEqual(a[-1], b[-1])
         self.failUnlessEqual(a[:], b[:])
+        self.failUnlessEqual(a[::], b[::])
+        self.failUnlessEqual(a[10::-1], b[10::-1])
+        self.failUnlessEqual(a[30:20:-1], b[30:20:-1])
+        self.failUnlessEqual(a[:12:6], b[:12:6])
+        self.failUnlessEqual(a[2:6:4], b[2:6:4])
 
         a[0:5] = range(5, 10)
         self.failUnlessEqual(a[0:5], range(5, 10))
+        self.failUnlessEqual(a[0:5:], range(5, 10))
+        self.failUnlessEqual(a[4::-1], range(9, 4, -1))
 
     def test_setslice_cint(self):
         a = (c_int * 100)(*xrange(1100, 1200))
@@ -22,17 +31,36 @@
 
         a[32:47] = range(32, 47)
         self.failUnlessEqual(a[32:47], range(32, 47))
+        a[32:47] = range(132, 147)
+        self.failUnlessEqual(a[32:47:], range(132, 147))
+        a[46:31:-1] = range(232, 247)
+        self.failUnlessEqual(a[32:47:1], range(246, 231, -1))
+
+        a[32:47] = range(1132, 1147)
+        self.failUnlessEqual(a[:], b)
+        a[32:47:7] = range(3)
+        b[32:47:7] = range(3)
+        self.failUnlessEqual(a[:], b)
+        a[33::-3] = range(12)
+        b[33::-3] = range(12)
+        self.failUnlessEqual(a[:], b)
 
-        from operator import setslice
+        from operator import setslice, setitem
 
         # TypeError: int expected instead of str instance
         self.assertRaises(TypeError, setslice, a, 0, 5, "abcde")
+        self.assertRaises(TypeError, setitem, a, slice(0, 5), "abcde")
         # TypeError: int expected instead of str instance
         self.assertRaises(TypeError, setslice, a, 0, 5, ["a", "b", "c", "d", "e"])
+        self.assertRaises(TypeError, setitem, a, slice(0, 5),
+                          ["a", "b", "c", "d", "e"])
         # TypeError: int expected instead of float instance
         self.assertRaises(TypeError, setslice, a, 0, 5, [1, 2, 3, 4, 3.14])
+        self.assertRaises(TypeError, setitem, a, slice(0, 5),
+                          [1, 2, 3, 4, 3.14])
         # ValueError: Can only assign sequence of same size
         self.assertRaises(ValueError, setslice, a, 0, 5, range(32))
+        self.assertRaises(ValueError, setitem, a, slice(0, 5), range(32))
 
     def test_char_ptr(self):
         s = "abcdefghijklmnopqrstuvwxyz"
@@ -42,15 +70,32 @@
         dll.my_free.restype = None
         res = dll.my_strdup(s)
         self.failUnlessEqual(res[:len(s)], s)
+        self.failUnlessEqual(res[:3], s[:3])
+        self.failUnlessEqual(res[:len(s):], s)
+        self.failUnlessEqual(res[len(s)-1:-1:-1], s[::-1])
+        self.failUnlessEqual(res[len(s)-1:5:-7], s[:5:-7])
+        self.failUnlessEqual(res[0:-1:-1], s[0::-1])
 
         import operator
+        self.assertRaises(ValueError, operator.getitem,
+                          res, slice(None, None, None))
+        self.assertRaises(ValueError, operator.getitem,
+                          res, slice(0, None, None))
+        self.assertRaises(ValueError, operator.getitem,
+                          res, slice(None, 5, -1))
+        self.assertRaises(ValueError, operator.getitem,
+                          res, slice(-5, None, None))
+
         self.assertRaises(TypeError, operator.setslice,
                           res, 0, 5, u"abcde")
+        self.assertRaises(TypeError, operator.setitem,
+                          res, slice(0, 5), u"abcde")
         dll.my_free(res)
 
         dll.my_strdup.restype = POINTER(c_byte)
         res = dll.my_strdup(s)
         self.failUnlessEqual(res[:len(s)], range(ord("a"), ord("z")+1))
+        self.failUnlessEqual(res[:len(s):], range(ord("a"), ord("z")+1))
         dll.my_free(res)
 
     def test_char_ptr_with_free(self):
@@ -80,6 +125,10 @@
 
         p = (c_char * 27)(*s)
         self.failUnlessEqual(p[:], s)
+        self.failUnlessEqual(p[::], s)
+        self.failUnlessEqual(p[::-1], s[::-1])
+        self.failUnlessEqual(p[5::-2], s[5::-2])
+        self.failUnlessEqual(p[2:5:-3], s[2:5:-3])
 
 
     try:
@@ -96,10 +145,15 @@
             dll.my_free.restype = None
             res = dll.my_wcsdup(s)
             self.failUnlessEqual(res[:len(s)], s)
+            self.failUnlessEqual(res[:len(s):], s)
+            self.failUnlessEqual(res[len(s)-1:-1:-1], s[::-1])
+            self.failUnlessEqual(res[len(s)-1:5:-7], s[:5:-7])
 
             import operator
             self.assertRaises(TypeError, operator.setslice,
                               res, 0, 5, u"abcde")
+            self.assertRaises(TypeError, operator.setitem,
+                              res, slice(0, 5), u"abcde")
             dll.my_free(res)
 
             if sizeof(c_wchar) == sizeof(c_short):
@@ -111,7 +165,11 @@
             else:
                 return
             res = dll.my_wcsdup(s)
-            self.failUnlessEqual(res[:len(s)-1], range(ord("a"), ord("z")+1))
+            tmpl = range(ord("a"), ord("z")+1)
+            self.failUnlessEqual(res[:len(s)-1], tmpl)
+            self.failUnlessEqual(res[:len(s)-1:], tmpl)
+            self.failUnlessEqual(res[len(s)-2:-1:-1], tmpl[::-1])
+            self.failUnlessEqual(res[len(s)-2:5:-7], tmpl[:5:-7])
             dll.my_free(res)
 
 ################################################################

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_strings.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_strings.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_strings.py	Thu Sep  6 21:35:45 2007
@@ -121,6 +121,9 @@
     def XX_test_initialized_strings(self):
 
         self.failUnless(c_string("ab", 4).raw[:2] == "ab")
+        self.failUnless(c_string("ab", 4).raw[:2:] == "ab")
+        self.failUnless(c_string("ab", 4).raw[:2:-1] == "ba")
+        self.failUnless(c_string("ab", 4).raw[:2:2] == "a")
         self.failUnless(c_string("ab", 4).raw[-1] == "\000")
         self.failUnless(c_string("ab", 2).raw == "a\000")
 

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_structures.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_structures.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_structures.py	Thu Sep  6 21:35:45 2007
@@ -236,7 +236,13 @@
 
         # can use tuple to initialize array (but not list!)
         self.failUnlessEqual(SomeInts((1, 2)).a[:], [1, 2, 0, 0])
+        self.failUnlessEqual(SomeInts((1, 2)).a[::], [1, 2, 0, 0])
+        self.failUnlessEqual(SomeInts((1, 2)).a[::-1], [0, 0, 2, 1])
+        self.failUnlessEqual(SomeInts((1, 2)).a[::2], [1, 0])
+        self.failUnlessEqual(SomeInts((1, 2)).a[1:5:6], [2])
+        self.failUnlessEqual(SomeInts((1, 2)).a[6:4:-1], [])
         self.failUnlessEqual(SomeInts((1, 2, 3, 4)).a[:], [1, 2, 3, 4])
+        self.failUnlessEqual(SomeInts((1, 2, 3, 4)).a[::], [1, 2, 3, 4])
         # too long
         # XXX Should raise ValueError?, not RuntimeError
         self.assertRaises(RuntimeError, SomeInts, (1, 2, 3, 4, 5))

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_unicode.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_unicode.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_unicode.py	Thu Sep  6 21:35:45 2007
@@ -59,11 +59,19 @@
             ctypes.set_conversion_mode("ascii", "replace")
             buf = ctypes.create_unicode_buffer("abäöü")
             self.failUnlessEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0")
+            self.failUnlessEqual(buf[::], u"ab\uFFFD\uFFFD\uFFFD\0")
+            self.failUnlessEqual(buf[::-1], u"\0\uFFFD\uFFFD\uFFFDba")
+            self.failUnlessEqual(buf[::2], u"a\uFFFD\uFFFD")
+            self.failUnlessEqual(buf[6:5:-1], u"")
 
             ctypes.set_conversion_mode("ascii", "ignore")
             buf = ctypes.create_unicode_buffer("abäöü")
             # is that correct? not sure.  But with 'ignore', you get what you pay for..
             self.failUnlessEqual(buf[:], u"ab\0\0\0\0")
+            self.failUnlessEqual(buf[::], u"ab\0\0\0\0")
+            self.failUnlessEqual(buf[::-1], u"\0\0\0\0ba")
+            self.failUnlessEqual(buf[::2], u"a\0\0")
+            self.failUnlessEqual(buf[6:5:-1], u"")
 
     import _ctypes_test
     func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
@@ -105,11 +113,17 @@
             ctypes.set_conversion_mode("ascii", "replace")
             buf = ctypes.create_string_buffer(u"abäöü")
             self.failUnlessEqual(buf[:], "ab???\0")
+            self.failUnlessEqual(buf[::], "ab???\0")
+            self.failUnlessEqual(buf[::-1], "\0???ba")
+            self.failUnlessEqual(buf[::2], "a??")
+            self.failUnlessEqual(buf[6:5:-1], "")
 
             ctypes.set_conversion_mode("ascii", "ignore")
             buf = ctypes.create_string_buffer(u"abäöü")
             # is that correct? not sure.  But with 'ignore', you get what you pay for..
             self.failUnlessEqual(buf[:], "ab\0\0\0\0")
+            self.failUnlessEqual(buf[::], "ab\0\0\0\0")
+            self.failUnlessEqual(buf[::-1], "\0\0\0\0ba")
 
 if __name__ == '__main__':
     unittest.main()

Modified: python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py	(original)
+++ python/branches/bcannon-objcap/Lib/ctypes/test/test_win32.py	Thu Sep  6 21:35:45 2007
@@ -58,6 +58,15 @@
             self.failUnlessEqual(sizeof(wintypes.LPARAM),
                                  sizeof(c_void_p))
 
+        def test_COMError(self):
+            from _ctypes import COMError
+            self.assertEqual(COMError.__doc__, "Raised when a COM method call failed.")
+
+            ex = COMError(-1, "text", ("details",))
+            self.assertEqual(ex.hresult, -1)
+            self.assertEqual(ex.text, "text")
+            self.assertEqual(ex.details, ("details",))
+
 class Structures(unittest.TestCase):
 
     def test_struct_by_value(self):

Modified: python/branches/bcannon-objcap/Lib/decimal.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/decimal.py	(original)
+++ python/branches/bcannon-objcap/Lib/decimal.py	Thu Sep  6 21:35:45 2007
@@ -612,7 +612,8 @@
             except ValueError:
                 self._is_special = True
                 self._sign, self._int, self._exp = \
-                                        context._raise_error(ConversionSyntax)
+                              context._raise_error(ConversionSyntax,
+                                  "Invalid literal for Decimal: %r" % value)
             return self
 
         raise TypeError("Cannot convert %r to Decimal" % value)

Modified: python/branches/bcannon-objcap/Lib/distutils/command/bdist_msi.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/command/bdist_msi.py	(original)
+++ python/branches/bcannon-objcap/Lib/distutils/command/bdist_msi.py	Thu Sep  6 21:35:45 2007
@@ -633,7 +633,8 @@
 
     def get_installer_filename(self, fullname):
         # Factored out to allow overriding in subclasses
+        plat = get_platform()
         installer_name = os.path.join(self.dist_dir,
-                                      "%s.win32-py%s.msi" %
-                                       (fullname, self.target_version))
+                                      "%s.%s-py%s.msi" %
+                                       (fullname, plat, self.target_version))
         return installer_name

Modified: python/branches/bcannon-objcap/Lib/distutils/command/register.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/command/register.py	(original)
+++ python/branches/bcannon-objcap/Lib/distutils/command/register.py	Thu Sep  6 21:35:45 2007
@@ -17,7 +17,7 @@
 
     description = ("register the distribution with the Python package index")
 
-    DEFAULT_REPOSITORY = 'http://www.python.org/pypi'
+    DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
 
     user_options = [
         ('repository=', 'r',

Modified: python/branches/bcannon-objcap/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/command/upload.py	(original)
+++ python/branches/bcannon-objcap/Lib/distutils/command/upload.py	Thu Sep  6 21:35:45 2007
@@ -20,7 +20,7 @@
 
     description = "upload binary package to PyPI"
 
-    DEFAULT_REPOSITORY = 'http://www.python.org/pypi'
+    DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
 
     user_options = [
         ('repository=', 'r',

Modified: python/branches/bcannon-objcap/Lib/distutils/util.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/distutils/util.py	(original)
+++ python/branches/bcannon-objcap/Lib/distutils/util.py	Thu Sep  6 21:35:45 2007
@@ -29,8 +29,27 @@
        irix-5.3
        irix64-6.2
 
-    For non-POSIX platforms, currently just returns 'sys.platform'.
-    """
+    Windows will return one of:
+       win-x86_64 (64bit Windows on x86_64 (AMD64))
+       win-ia64 (64bit Windows on Itanium)
+       win32 (all others - specifically, sys.platform is returned)
+
+    For other non-POSIX platforms, currently just returns 'sys.platform'.
+    """
+    if os.name == 'nt':
+        # sniff sys.version for architecture.
+        prefix = " bit ("
+        i = string.find(sys.version, prefix)
+        if i == -1:
+            return sys.platform
+        j = string.find(sys.version, ")", i)
+        look = sys.version[i+len(prefix):j].lower()
+        if look=='amd64':
+            return 'win-x86_64'
+        if look=='itanium':
+            return 'win-ia64'
+        return sys.platform
+
     if os.name != "posix" or not hasattr(os, 'uname'):
         # XXX what about the architecture? NT is Intel or Alpha,
         # Mac OS is M68k or PPC, etc.

Modified: python/branches/bcannon-objcap/Lib/email/test/test_email.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/email/test/test_email.py	(original)
+++ python/branches/bcannon-objcap/Lib/email/test/test_email.py	Thu Sep  6 21:35:45 2007
@@ -1492,6 +1492,18 @@
         self.failUnless(isinstance(bad.defects[0],
                                    Errors.StartBoundaryNotFoundDefect))
 
+    def test_first_line_is_continuation_header(self):
+        eq = self.assertEqual
+        m = ' Line 1\nLine 2\nLine 3'
+        msg = email.message_from_string(m)
+        eq(msg.keys(), [])
+        eq(msg.get_payload(), 'Line 2\nLine 3')
+        eq(len(msg.defects), 1)
+        self.failUnless(isinstance(msg.defects[0],
+                                   Errors.FirstHeaderLineIsContinuationDefect))
+        eq(msg.defects[0].line, ' Line 1\n')
+
+
 
 
 # Test RFC 2047 header encoding and decoding

Modified: python/branches/bcannon-objcap/Lib/email/test/test_email_renamed.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/email/test/test_email_renamed.py	(original)
+++ python/branches/bcannon-objcap/Lib/email/test/test_email_renamed.py	Thu Sep  6 21:35:45 2007
@@ -1490,6 +1490,17 @@
         self.failUnless(isinstance(bad.defects[0],
                                    errors.StartBoundaryNotFoundDefect))
 
+    def test_first_line_is_continuation_header(self):
+        eq = self.assertEqual
+        m = ' Line 1\nLine 2\nLine 3'
+        msg = email.message_from_string(m)
+        eq(msg.keys(), [])
+        eq(msg.get_payload(), 'Line 2\nLine 3')
+        eq(len(msg.defects), 1)
+        self.failUnless(isinstance(msg.defects[0],
+                                   errors.FirstHeaderLineIsContinuationDefect))
+        eq(msg.defects[0].line, ' Line 1\n')
+
 
 
 # Test RFC 2047 header encoding and decoding

Modified: python/branches/bcannon-objcap/Lib/encodings/aliases.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/encodings/aliases.py	(original)
+++ python/branches/bcannon-objcap/Lib/encodings/aliases.py	Thu Sep  6 21:35:45 2007
@@ -490,6 +490,16 @@
     'unicodelittleunmarked' : 'utf_16_le',
     'utf_16le'           : 'utf_16_le',
 
+    # utf_32 codec
+    'u32'                : 'utf_32',
+    'utf32'              : 'utf_32',
+
+    # utf_32_be codec
+    'utf_32be'           : 'utf_32_be',
+
+    # utf_32_le codec
+    'utf_32le'           : 'utf_32_le',
+
     # utf_7 codec
     'u7'                 : 'utf_7',
     'utf7'               : 'utf_7',

Modified: python/branches/bcannon-objcap/Lib/encodings/quopri_codec.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/encodings/quopri_codec.py	(original)
+++ python/branches/bcannon-objcap/Lib/encodings/quopri_codec.py	Thu Sep  6 21:35:45 2007
@@ -18,7 +18,8 @@
 
     """
     assert errors == 'strict'
-    f = StringIO(input)
+    # using str() because of cStringIO's Unicode undesired Unicode behavior.
+    f = StringIO(str(input))
     g = StringIO()
     quopri.encode(f, g, 1)
     output = g.getvalue()
@@ -33,7 +34,7 @@
 
     """
     assert errors == 'strict'
-    f = StringIO(input)
+    f = StringIO(str(input))
     g = StringIO()
     quopri.decode(f, g)
     output = g.getvalue()

Modified: python/branches/bcannon-objcap/Lib/encodings/uu_codec.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/encodings/uu_codec.py	(original)
+++ python/branches/bcannon-objcap/Lib/encodings/uu_codec.py	Thu Sep  6 21:35:45 2007
@@ -25,7 +25,8 @@
     assert errors == 'strict'
     from cStringIO import StringIO
     from binascii import b2a_uu
-    infile = StringIO(input)
+    # using str() because of cStringIO's Unicode undesired Unicode behavior.
+    infile = StringIO(str(input))
     outfile = StringIO()
     read = infile.read
     write = outfile.write
@@ -60,7 +61,7 @@
     assert errors == 'strict'
     from cStringIO import StringIO
     from binascii import a2b_uu
-    infile = StringIO(input)
+    infile = StringIO(str(input))
     outfile = StringIO()
     readline = infile.readline
     write = outfile.write

Modified: python/branches/bcannon-objcap/Lib/functools.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/functools.py	(original)
+++ python/branches/bcannon-objcap/Lib/functools.py	Thu Sep  6 21:35:45 2007
@@ -8,6 +8,7 @@
 # See C source code for _functools credits/copyright
 
 from _functools import partial
+from __builtin__ import reduce
 
 # update_wrapper() and wraps() are tools to help write
 # wrapper functions that can handle naive introspection

Modified: python/branches/bcannon-objcap/Lib/httplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/httplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/httplib.py	Thu Sep  6 21:35:45 2007
@@ -70,13 +70,14 @@
 import mimetools
 import socket
 from urlparse import urlsplit
+import warnings
 
 try:
     from cStringIO import StringIO
 except ImportError:
     from StringIO import StringIO
 
-__all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection",
+__all__ = ["HTTP", "HTTPResponse", "HTTPConnection",
            "HTTPException", "NotConnected", "UnknownProtocol",
            "UnknownTransferEncoding", "UnimplementedFileMode",
            "IncompleteRead", "InvalidURL", "ImproperConnectionState",
@@ -940,202 +941,6 @@
 
         return response
 
-# The next several classes are used to define FakeSocket, a socket-like
-# interface to an SSL connection.
-
-# The primary complexity comes from faking a makefile() method.  The
-# standard socket makefile() implementation calls dup() on the socket
-# file descriptor.  As a consequence, clients can call close() on the
-# parent socket and its makefile children in any order.  The underlying
-# socket isn't closed until they are all closed.
-
-# The implementation uses reference counting to keep the socket open
-# until the last client calls close().  SharedSocket keeps track of
-# the reference counting and SharedSocketClient provides an constructor
-# and close() method that call incref() and decref() correctly.
-
-class SharedSocket:
-
-    def __init__(self, sock):
-        self.sock = sock
-        self._refcnt = 0
-
-    def incref(self):
-        self._refcnt += 1
-
-    def decref(self):
-        self._refcnt -= 1
-        assert self._refcnt >= 0
-        if self._refcnt == 0:
-            self.sock.close()
-
-    def __del__(self):
-        self.sock.close()
-
-class SharedSocketClient:
-
-    def __init__(self, shared):
-        self._closed = 0
-        self._shared = shared
-        self._shared.incref()
-        self._sock = shared.sock
-
-    def close(self):
-        if not self._closed:
-            self._shared.decref()
-            self._closed = 1
-            self._shared = None
-
-class SSLFile(SharedSocketClient):
-    """File-like object wrapping an SSL socket."""
-
-    BUFSIZE = 8192
-
-    def __init__(self, sock, ssl, bufsize=None):
-        SharedSocketClient.__init__(self, sock)
-        self._ssl = ssl
-        self._buf = ''
-        self._bufsize = bufsize or self.__class__.BUFSIZE
-
-    def _read(self):
-        buf = ''
-        # put in a loop so that we retry on transient errors
-        while True:
-            try:
-                buf = self._ssl.read(self._bufsize)
-            except socket.sslerror, err:
-                if (err[0] == socket.SSL_ERROR_WANT_READ
-                    or err[0] == socket.SSL_ERROR_WANT_WRITE):
-                    continue
-                if (err[0] == socket.SSL_ERROR_ZERO_RETURN
-                    or err[0] == socket.SSL_ERROR_EOF):
-                    break
-                raise
-            except socket.error, err:
-                if err[0] == errno.EINTR:
-                    continue
-                if err[0] == errno.EBADF:
-                    # XXX socket was closed?
-                    break
-                raise
-            else:
-                break
-        return buf
-
-    def read(self, size=None):
-        L = [self._buf]
-        avail = len(self._buf)
-        while size is None or avail < size:
-            s = self._read()
-            if s == '':
-                break
-            L.append(s)
-            avail += len(s)
-        all = "".join(L)
-        if size is None:
-            self._buf = ''
-            return all
-        else:
-            self._buf = all[size:]
-            return all[:size]
-
-    def readline(self):
-        L = [self._buf]
-        self._buf = ''
-        while 1:
-            i = L[-1].find("\n")
-            if i >= 0:
-                break
-            s = self._read()
-            if s == '':
-                break
-            L.append(s)
-        if i == -1:
-            # loop exited because there is no more data
-            return "".join(L)
-        else:
-            all = "".join(L)
-            # XXX could do enough bookkeeping not to do a 2nd search
-            i = all.find("\n") + 1
-            line = all[:i]
-            self._buf = all[i:]
-            return line
-
-    def readlines(self, sizehint=0):
-        total = 0
-        list = []
-        while True:
-            line = self.readline()
-            if not line:
-                break
-            list.append(line)
-            total += len(line)
-            if sizehint and total >= sizehint:
-                break
-        return list
-
-    def fileno(self):
-        return self._sock.fileno()
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        line = self.readline()
-        if not line:
-            raise StopIteration
-        return line
-
-class FakeSocket(SharedSocketClient):
-
-    class _closedsocket:
-        def __getattr__(self, name):
-            raise error(9, 'Bad file descriptor')
-
-    def __init__(self, sock, ssl):
-        sock = SharedSocket(sock)
-        SharedSocketClient.__init__(self, sock)
-        self._ssl = ssl
-
-    def close(self):
-        SharedSocketClient.close(self)
-        self._sock = self.__class__._closedsocket()
-
-    def makefile(self, mode, bufsize=None):
-        if mode != 'r' and mode != 'rb':
-            raise UnimplementedFileMode()
-        return SSLFile(self._shared, self._ssl, bufsize)
-
-    def send(self, stuff, flags = 0):
-        return self._ssl.write(stuff)
-
-    sendall = send
-
-    def recv(self, len = 1024, flags = 0):
-        return self._ssl.read(len)
-
-    def __getattr__(self, attr):
-        return getattr(self._sock, attr)
-
-
-class HTTPSConnection(HTTPConnection):
-    "This class allows communication via SSL."
-
-    default_port = HTTPS_PORT
-
-    def __init__(self, host, port=None, key_file=None, cert_file=None,
-                 strict=None, timeout=None):
-        HTTPConnection.__init__(self, host, port, strict, timeout)
-        self.key_file = key_file
-        self.cert_file = cert_file
-
-    def connect(self):
-        "Connect to a host on a given (SSL) port."
-
-        sock = socket.create_connection((self.host, self.port), self.timeout)
-        ssl = socket.ssl(sock, self.key_file, self.cert_file)
-        self.sock = FakeSocket(sock, ssl)
-
 
 class HTTP:
     "Compatibility class with httplib.py from 1.5."
@@ -1226,7 +1031,30 @@
         ### do it
         self.file = None
 
-if hasattr(socket, 'ssl'):
+try:
+    import ssl
+except ImportError:
+    pass
+else:
+    class HTTPSConnection(HTTPConnection):
+        "This class allows communication via SSL."
+
+        default_port = HTTPS_PORT
+
+        def __init__(self, host, port=None, key_file=None, cert_file=None,
+                     strict=None, timeout=None):
+            HTTPConnection.__init__(self, host, port, strict, timeout)
+            self.key_file = key_file
+            self.cert_file = cert_file
+
+        def connect(self):
+            "Connect to a host on a given (SSL) port."
+
+            sock = socket.create_connection((self.host, self.port), self.timeout)
+            self.sock = ssl.sslsocket(sock, self.key_file, self.cert_file)
+
+    __all__.append("HTTPSConnection")
+
     class HTTPS(HTTP):
         """Compatibility with 1.5 httplib interface
 
@@ -1253,6 +1081,13 @@
             self.cert_file = cert_file
 
 
+    def FakeSocket (sock, sslobj):
+        warnings.warn("FakeSocket is deprecated, and won't be in 3.x.  " +
+                      "Use the result of ssl.sslsocket directly instead.",
+                      DeprecationWarning, stacklevel=2)
+        return sslobj
+
+
 class HTTPException(Exception):
     # Subclasses that define an __init__ must call Exception.__init__
     # or define self.args.  Otherwise, str() will fail.
@@ -1410,7 +1245,11 @@
     h.getreply()
     h.close()
 
-    if hasattr(socket, 'ssl'):
+    try:
+        import ssl
+    except ImportError:
+        pass
+    else:
 
         for host, selector in (('sourceforge.net', '/projects/python'),
                                ):

Modified: python/branches/bcannon-objcap/Lib/idlelib/macosxSupport.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/idlelib/macosxSupport.py	(original)
+++ python/branches/bcannon-objcap/Lib/idlelib/macosxSupport.py	Thu Sep  6 21:35:45 2007
@@ -3,6 +3,7 @@
 GUI application (as opposed to an X11 application).
 """
 import sys
+import Tkinter
 
 def runningAsOSXApp():
     """ Returns True iff running from the IDLE.app bundle on OSX """
@@ -23,7 +24,11 @@
     root.createcommand("::tk::mac::OpenDocument", doOpenFile)
 
 def hideTkConsole(root):
-    root.tk.call('console', 'hide')
+    try:
+        root.tk.call('console', 'hide')
+    except Tkinter.TclError:
+        # Some versions of the Tk framework don't have a console object
+        pass
 
 def overrideRootMenu(root, flist):
     """
@@ -75,32 +80,40 @@
         import configDialog
         configDialog.ConfigDialog(root, 'Settings')
 
+
     root.bind('<<about-idle>>', about_dialog)
     root.bind('<<open-config-dialog>>', config_dialog)
     if flist:
         root.bind('<<close-all-windows>>', flist.close_all_callback)
 
-    for mname, entrylist in Bindings.menudefs:
-        menu = menudict.get(mname)
-        if not menu:
-            continue
-        for entry in entrylist:
-            if not entry:
-                menu.add_separator()
+
+    ###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding
+    tkversion = root.tk.eval('info patchlevel')
+    if tkversion >= '8.4.14':
+        Bindings.menudefs[0] =  ('application', [
+                ('About IDLE', '<<about-idle>>'),
+                None,
+            ])
+        root.createcommand('::tk::mac::ShowPreferences', config_dialog)
+    else:
+        for mname, entrylist in Bindings.menudefs:
+            menu = menudict.get(mname)
+            if not menu:
+                continue
             else:
-                label, eventname = entry
-                underline, label = prepstr(label)
-                accelerator = get_accelerator(Bindings.default_keydefs,
+                for entry in entrylist:
+                    if not entry:
+                        menu.add_separator()
+                    else:
+                        label, eventname = entry
+                        underline, label = prepstr(label)
+                        accelerator = get_accelerator(Bindings.default_keydefs,
                         eventname)
-                def command(text=root, eventname=eventname):
-                    text.event_generate(eventname)
-                menu.add_command(label=label, underline=underline,
+                        def command(text=root, eventname=eventname):
+                            text.event_generate(eventname)
+                        menu.add_command(label=label, underline=underline,
                         command=command, accelerator=accelerator)
 
-
-
-
-
 def setupApp(root, flist):
     """
     Perform setup for the OSX application bundle.

Modified: python/branches/bcannon-objcap/Lib/imaplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/imaplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/imaplib.py	Thu Sep  6 21:35:45 2007
@@ -24,7 +24,7 @@
 
 import binascii, os, random, re, socket, sys, time
 
-__all__ = ["IMAP4", "IMAP4_SSL", "IMAP4_stream", "Internaldate2tuple",
+__all__ = ["IMAP4", "IMAP4_stream", "Internaldate2tuple",
            "Int2AP", "ParseFlags", "Time2Internaldate"]
 
 #       Globals
@@ -1111,95 +1111,99 @@
 
 
 
-class IMAP4_SSL(IMAP4):
+try:
+    import ssl
+except ImportError:
+    pass
+else:
+    class IMAP4_SSL(IMAP4):
 
-    """IMAP4 client class over SSL connection
+        """IMAP4 client class over SSL connection
 
-    Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile]]]])
+        Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile]]]])
 
-            host - host's name (default: localhost);
-            port - port number (default: standard IMAP4 SSL port).
-            keyfile - PEM formatted file that contains your private key (default: None);
-            certfile - PEM formatted certificate chain file (default: None);
+                host - host's name (default: localhost);
+                port - port number (default: standard IMAP4 SSL port).
+                keyfile - PEM formatted file that contains your private key (default: None);
+                certfile - PEM formatted certificate chain file (default: None);
 
-    for more documentation see the docstring of the parent class IMAP4.
-    """
+        for more documentation see the docstring of the parent class IMAP4.
+        """
 
 
-    def __init__(self, host = '', port = IMAP4_SSL_PORT, keyfile = None, certfile = None):
-        self.keyfile = keyfile
-        self.certfile = certfile
-        IMAP4.__init__(self, host, port)
+        def __init__(self, host = '', port = IMAP4_SSL_PORT, keyfile = None, certfile = None):
+            self.keyfile = keyfile
+            self.certfile = certfile
+            IMAP4.__init__(self, host, port)
 
 
-    def open(self, host = '', port = IMAP4_SSL_PORT):
-        """Setup connection to remote server on "host:port".
-            (default: localhost:standard IMAP4 SSL port).
-        This connection will be used by the routines:
-            read, readline, send, shutdown.
-        """
-        self.host = host
-        self.port = port
-        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sock.connect((host, port))
-        self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
+        def open(self, host = '', port = IMAP4_SSL_PORT):
+            """Setup connection to remote server on "host:port".
+                (default: localhost:standard IMAP4 SSL port).
+            This connection will be used by the routines:
+                read, readline, send, shutdown.
+            """
+            self.host = host
+            self.port = port
+            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.sock.connect((host, port))
+            self.sslobj = ssl.sslsocket(self.sock, self.keyfile, self.certfile)
 
 
-    def read(self, size):
-        """Read 'size' bytes from remote."""
-        # sslobj.read() sometimes returns < size bytes
-        chunks = []
-        read = 0
-        while read < size:
-            data = self.sslobj.read(size-read)
-            read += len(data)
-            chunks.append(data)
+        def read(self, size):
+            """Read 'size' bytes from remote."""
+            # sslobj.read() sometimes returns < size bytes
+            chunks = []
+            read = 0
+            while read < size:
+                data = self.sslobj.read(size-read)
+                read += len(data)
+                chunks.append(data)
 
-        return ''.join(chunks)
+            return ''.join(chunks)
 
 
-    def readline(self):
-        """Read line from remote."""
-        # NB: socket.ssl needs a "readline" method, or perhaps a "makefile" method.
-        line = []
-        while 1:
-            char = self.sslobj.read(1)
-            line.append(char)
-            if char == "\n": return ''.join(line)
+        def readline(self):
+            """Read line from remote."""
+            line = []
+            while 1:
+                char = self.sslobj.read(1)
+                line.append(char)
+                if char == "\n": return ''.join(line)
 
 
-    def send(self, data):
-        """Send data to remote."""
-        # NB: socket.ssl needs a "sendall" method to match socket objects.
-        bytes = len(data)
-        while bytes > 0:
-            sent = self.sslobj.write(data)
-            if sent == bytes:
-                break    # avoid copy
-            data = data[sent:]
-            bytes = bytes - sent
+        def send(self, data):
+            """Send data to remote."""
+            bytes = len(data)
+            while bytes > 0:
+                sent = self.sslobj.write(data)
+                if sent == bytes:
+                    break    # avoid copy
+                data = data[sent:]
+                bytes = bytes - sent
 
 
-    def shutdown(self):
-        """Close I/O established in "open"."""
-        self.sock.close()
+        def shutdown(self):
+            """Close I/O established in "open"."""
+            self.sock.close()
 
 
-    def socket(self):
-        """Return socket instance used to connect to IMAP4 server.
+        def socket(self):
+            """Return socket instance used to connect to IMAP4 server.
 
-        socket = <instance>.socket()
-        """
-        return self.sock
+            socket = <instance>.socket()
+            """
+            return self.sock
 
 
-    def ssl(self):
-        """Return SSLObject instance used to communicate with the IMAP4 server.
+        def ssl(self):
+            """Return SSLObject instance used to communicate with the IMAP4 server.
 
-        ssl = <instance>.socket.ssl()
-        """
-        return self.sslobj
+            ssl = ssl.sslsocket(<instance>.socket)
+            """
+            return self.sslobj
 
+    __all__.append("IMAP4_SSL")
 
 
 class IMAP4_stream(IMAP4):

Modified: python/branches/bcannon-objcap/Lib/inspect.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/inspect.py	(original)
+++ python/branches/bcannon-objcap/Lib/inspect.py	Thu Sep  6 21:35:45 2007
@@ -679,7 +679,6 @@
     if not iscode(co):
         raise TypeError('arg is not a code object')
 
-    code = co.co_code
     nargs = co.co_argcount
     names = co.co_varnames
     args = list(names[:nargs])
@@ -689,12 +688,12 @@
     for i in range(nargs):
         if args[i][:1] in ('', '.'):
             stack, remain, count = [], [], []
-            while step < len(code):
-                op = ord(code[step])
+            while step < len(co.co_code):
+                op = ord(co.co_code[step])
                 step = step + 1
                 if op >= dis.HAVE_ARGUMENT:
                     opname = dis.opname[op]
-                    value = ord(code[step]) + ord(code[step+1])*256
+                    value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
                     step = step + 2
                     if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
                         remain.append(value)

Modified: python/branches/bcannon-objcap/Lib/logging/__init__.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/logging/__init__.py	(original)
+++ python/branches/bcannon-objcap/Lib/logging/__init__.py	Thu Sep  6 21:35:45 2007
@@ -974,9 +974,7 @@
 
         logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
         """
-        if self.manager.disable >= DEBUG:
-            return
-        if DEBUG >= self.getEffectiveLevel():
+        if self.isEnabledFor(DEBUG):
             apply(self._log, (DEBUG, msg, args), kwargs)
 
     def info(self, msg, *args, **kwargs):
@@ -988,9 +986,7 @@
 
         logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
         """
-        if self.manager.disable >= INFO:
-            return
-        if INFO >= self.getEffectiveLevel():
+        if self.isEnabledFor(INFO):
             apply(self._log, (INFO, msg, args), kwargs)
 
     def warning(self, msg, *args, **kwargs):
@@ -1002,8 +998,6 @@
 
         logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
         """
-        if self.manager.disable >= WARNING:
-            return
         if self.isEnabledFor(WARNING):
             apply(self._log, (WARNING, msg, args), kwargs)
 
@@ -1018,8 +1012,6 @@
 
         logger.error("Houston, we have a %s", "major problem", exc_info=1)
         """
-        if self.manager.disable >= ERROR:
-            return
         if self.isEnabledFor(ERROR):
             apply(self._log, (ERROR, msg, args), kwargs)
 
@@ -1038,9 +1030,7 @@
 
         logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
         """
-        if self.manager.disable >= CRITICAL:
-            return
-        if CRITICAL >= self.getEffectiveLevel():
+        if self.isEnabledFor(CRITICAL):
             apply(self._log, (CRITICAL, msg, args), kwargs)
 
     fatal = critical
@@ -1059,8 +1049,6 @@
                 raise TypeError, "level must be an integer"
             else:
                 return
-        if self.manager.disable >= level:
-            return
         if self.isEnabledFor(level):
             apply(self._log, (level, msg, args), kwargs)
 

Modified: python/branches/bcannon-objcap/Lib/mailbox.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/mailbox.py	(original)
+++ python/branches/bcannon-objcap/Lib/mailbox.py	Thu Sep  6 21:35:45 2007
@@ -459,7 +459,11 @@
         """Update table of contents mapping."""
         self._toc = {}
         for subdir in ('new', 'cur'):
-            for entry in os.listdir(os.path.join(self._path, subdir)):
+            subdir_path = os.path.join(self._path, subdir)
+            for entry in os.listdir(subdir_path):
+                p = os.path.join(subdir_path, entry)
+                if os.path.isdir(p):
+                    continue
                 uniq = entry.split(self.colon)[0]
                 self._toc[uniq] = os.path.join(subdir, entry)
 

Modified: python/branches/bcannon-objcap/Lib/ntpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/ntpath.py	(original)
+++ python/branches/bcannon-objcap/Lib/ntpath.py	Thu Sep  6 21:35:45 2007
@@ -59,7 +59,9 @@
 # Join two (or more) paths.
 
 def join(a, *p):
-    """Join two or more pathname components, inserting "\\" as needed"""
+    """Join two or more pathname components, inserting "\\" as needed.
+    If any component is an absolute path, all previous path components
+    will be discarded."""
     path = a
     for b in p:
         b_wins = 0  # set to 1 iff b makes path irrelevant

Modified: python/branches/bcannon-objcap/Lib/pipes.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/pipes.py	(original)
+++ python/branches/bcannon-objcap/Lib/pipes.py	Thu Sep  6 21:35:45 2007
@@ -60,7 +60,6 @@
 
 
 import re
-
 import os
 import tempfile
 import string
@@ -281,18 +280,3 @@
             c = '\\' + c
         res = res + c
     return '"' + res + '"'
-
-
-# Small test program and example
-
-def test():
-    print 'Testing...'
-    t = Template()
-    t.append('togif $IN $OUT', 'ff')
-    t.append('giftoppm', '--')
-    t.append('ppmtogif >$OUT', '-f')
-    t.append('fromgif $IN $OUT', 'ff')
-    t.debug(1)
-    FILE = '/usr/local/images/rgb/rogues/guido.rgb'
-    t.copy(FILE, '@temp')
-    print 'Done.'

Modified: python/branches/bcannon-objcap/Lib/poplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/poplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/poplib.py	Thu Sep  6 21:35:45 2007
@@ -15,7 +15,7 @@
 
 import re, socket
 
-__all__ = ["POP3","error_proto","POP3_SSL"]
+__all__ = ["POP3","error_proto"]
 
 # Exception raised when an error or invalid response is received:
 
@@ -307,90 +307,97 @@
             return self._shortcmd('UIDL %s' % which)
         return self._longcmd('UIDL')
 
-class POP3_SSL(POP3):
-    """POP3 client class over SSL connection
+try:
+    import ssl
+except ImportError:
+    pass
+else:
+
+    class POP3_SSL(POP3):
+        """POP3 client class over SSL connection
+
+        Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None)
+
+               hostname - the hostname of the pop3 over ssl server
+               port - port number
+               keyfile - PEM formatted file that countains your private key
+               certfile - PEM formatted certificate chain file
 
-    Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None)
-
-           hostname - the hostname of the pop3 over ssl server
-           port - port number
-           keyfile - PEM formatted file that countains your private key
-           certfile - PEM formatted certificate chain file
-
-        See the methods of the parent class POP3 for more documentation.
-    """
-
-    def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None):
-        self.host = host
-        self.port = port
-        self.keyfile = keyfile
-        self.certfile = certfile
-        self.buffer = ""
-        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, msg:
-                if self.sock:
-                    self.sock.close()
-                self.sock = None
-                continue
-            break
-        if not self.sock:
-            raise socket.error, msg
-        self.file = self.sock.makefile('rb')
-        self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
-        self._debugging = 0
-        self.welcome = self._getresp()
-
-    def _fillBuffer(self):
-        localbuf = self.sslobj.read()
-        if len(localbuf) == 0:
-            raise error_proto('-ERR EOF')
-        self.buffer += localbuf
+            See the methods of the parent class POP3 for more documentation.
+        """
 
-    def _getline(self):
-        line = ""
-        renewline = re.compile(r'.*?\n')
-        match = renewline.match(self.buffer)
-        while not match:
-            self._fillBuffer()
+        def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None):
+            self.host = host
+            self.port = port
+            self.keyfile = keyfile
+            self.certfile = certfile
+            self.buffer = ""
+            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, msg:
+                    if self.sock:
+                        self.sock.close()
+                    self.sock = None
+                    continue
+                break
+            if not self.sock:
+                raise socket.error, msg
+            self.file = self.sock.makefile('rb')
+            self.sslobj = ssl.sslsocket(self.sock, self.keyfile, self.certfile)
+            self._debugging = 0
+            self.welcome = self._getresp()
+
+        def _fillBuffer(self):
+            localbuf = self.sslobj.read()
+            if len(localbuf) == 0:
+                raise error_proto('-ERR EOF')
+            self.buffer += localbuf
+
+        def _getline(self):
+            line = ""
+            renewline = re.compile(r'.*?\n')
             match = renewline.match(self.buffer)
-        line = match.group(0)
-        self.buffer = renewline.sub('' ,self.buffer, 1)
-        if self._debugging > 1: print '*get*', repr(line)
+            while not match:
+                self._fillBuffer()
+                match = renewline.match(self.buffer)
+            line = match.group(0)
+            self.buffer = renewline.sub('' ,self.buffer, 1)
+            if self._debugging > 1: print '*get*', repr(line)
+
+            octets = len(line)
+            if line[-2:] == CRLF:
+                return line[:-2], octets
+            if line[0] == CR:
+                return line[1:-1], octets
+            return line[:-1], octets
+
+        def _putline(self, line):
+            if self._debugging > 1: print '*put*', repr(line)
+            line += CRLF
+            bytes = len(line)
+            while bytes > 0:
+                sent = self.sslobj.write(line)
+                if sent == bytes:
+                    break    # avoid copy
+                line = line[sent:]
+                bytes = bytes - sent
 
-        octets = len(line)
-        if line[-2:] == CRLF:
-            return line[:-2], octets
-        if line[0] == CR:
-            return line[1:-1], octets
-        return line[:-1], octets
-
-    def _putline(self, line):
-        if self._debugging > 1: print '*put*', repr(line)
-        line += CRLF
-        bytes = len(line)
-        while bytes > 0:
-            sent = self.sslobj.write(line)
-            if sent == bytes:
-                break    # avoid copy
-            line = line[sent:]
-            bytes = bytes - sent
-
-    def quit(self):
-        """Signoff: commit changes on server, unlock mailbox, close connection."""
-        try:
-            resp = self._shortcmd('QUIT')
-        except error_proto, val:
-            resp = val
-        self.sock.close()
-        del self.sslobj, self.sock
-        return resp
+        def quit(self):
+            """Signoff: commit changes on server, unlock mailbox, close connection."""
+            try:
+                resp = self._shortcmd('QUIT')
+            except error_proto, val:
+                resp = val
+            self.sock.close()
+            del self.sslobj, self.sock
+            return resp
 
+    __all__.append("POP3_SSL")
 
 if __name__ == "__main__":
     import sys

Modified: python/branches/bcannon-objcap/Lib/posixpath.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/posixpath.py	(original)
+++ python/branches/bcannon-objcap/Lib/posixpath.py	Thu Sep  6 21:35:45 2007
@@ -56,7 +56,9 @@
 # Insert a '/' unless the first part is empty or already ends in '/'.
 
 def join(a, *p):
-    """Join two or more pathname components, inserting '/' as needed"""
+    """Join two or more pathname components, inserting '/' as needed.
+    If any component is an absolute path, all previous path components
+    will be discarded."""
     path = a
     for b in p:
         if b.startswith('/'):

Modified: python/branches/bcannon-objcap/Lib/robotparser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/robotparser.py	(original)
+++ python/branches/bcannon-objcap/Lib/robotparser.py	Thu Sep  6 21:35:45 2007
@@ -230,6 +230,11 @@
         urllib.FancyURLopener.__init__(self, *args)
         self.errcode = 200
 
+    def prompt_user_passwd(self, host, realm):
+        ## If robots.txt file is accessible only with a password,
+        ## we act as if the file wasn't there.
+        return None, None
+
     def http_error_default(self, url, fp, errcode, errmsg, headers):
         self.errcode = errcode
         return urllib.FancyURLopener.http_error_default(self, url, fp, errcode,

Modified: python/branches/bcannon-objcap/Lib/runpy.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/runpy.py	(original)
+++ python/branches/bcannon-objcap/Lib/runpy.py	Thu Sep  6 21:35:45 2007
@@ -21,8 +21,9 @@
 ]
 
 
-def _run_code(code, run_globals, init_globals,
-              mod_name, mod_fname, mod_loader):
+def _run_code(code, run_globals, init_globals=None,
+              mod_name=None, mod_fname=None,
+              mod_loader=None):
     """Helper for _run_module_code"""
     if init_globals is not None:
         run_globals.update(init_globals)
@@ -34,35 +35,30 @@
 
 def _run_module_code(code, init_globals=None,
                     mod_name=None, mod_fname=None,
-                    mod_loader=None, alter_sys=False):
+                    mod_loader=None):
     """Helper for run_module"""
     # Set up the top level namespace dictionary
-    if alter_sys:
-        # Modify sys.argv[0] and sys.module[mod_name]
-        temp_module = imp.new_module(mod_name)
-        mod_globals = temp_module.__dict__
-        saved_argv0 = sys.argv[0]
-        restore_module = mod_name in sys.modules
-        if restore_module:
-            saved_module = sys.modules[mod_name]
-        sys.argv[0] = mod_fname
-        sys.modules[mod_name] = temp_module
-        try:
-            _run_code(code, mod_globals, init_globals,
-                      mod_name, mod_fname, mod_loader)
-        finally:
-            sys.argv[0] = saved_argv0
+    temp_module = imp.new_module(mod_name)
+    mod_globals = temp_module.__dict__
+    # Modify sys.argv[0] and sys.module[mod_name]
+    saved_argv0 = sys.argv[0]
+    restore_module = mod_name in sys.modules
+    if restore_module:
+        saved_module = sys.modules[mod_name]
+    sys.argv[0] = mod_fname
+    sys.modules[mod_name] = temp_module
+    try:
+        _run_code(code, mod_globals, init_globals,
+                    mod_name, mod_fname, mod_loader)
+    finally:
+        sys.argv[0] = saved_argv0
         if restore_module:
             sys.modules[mod_name] = saved_module
         else:
             del sys.modules[mod_name]
-        # Copy the globals of the temporary module, as they
-        # may be cleared when the temporary module goes away
-        return mod_globals.copy()
-    else:
-        # Leave the sys module alone
-        return _run_code(code, {}, init_globals,
-                         mod_name, mod_fname, mod_loader)
+    # Copy the globals of the temporary module, as they
+    # may be cleared when the temporary module goes away
+    return mod_globals.copy()
 
 
 # This helper is needed due to a missing component in the PEP 302
@@ -75,24 +71,52 @@
     else:
         return get_filename(mod_name)
 
+# Helper to get the loader, code and filename for a module
+def _get_module_details(mod_name):
+    loader = get_loader(mod_name)
+    if loader is None:
+        raise ImportError("No module named %s" % mod_name)
+    if loader.is_package(mod_name):
+        raise ImportError(("%s is a package and cannot " +
+                          "be directly executed") % mod_name)
+    code = loader.get_code(mod_name)
+    if code is None:
+        raise ImportError("No code object available for %s" % mod_name)
+    filename = _get_filename(loader, mod_name)
+    return loader, code, filename
+
+
+# XXX ncoghlan: Should this be documented and made public?
+def _run_module_as_main(mod_name, set_argv0=True):
+    """Runs the designated module in the __main__ namespace
+
+       These __*__ magic variables will be overwritten:
+           __file__
+           __loader__
+    """
+    loader, code, fname = _get_module_details(mod_name)
+    main_globals = sys.modules["__main__"].__dict__
+    if set_argv0:
+        sys.argv[0] = fname
+    return _run_code(code, main_globals, None,
+                     "__main__", fname, loader)
 
 def run_module(mod_name, init_globals=None,
-                         run_name=None, alter_sys=False):
+               run_name=None, alter_sys=False):
     """Execute a module's code without importing it
 
        Returns the resulting top level namespace dictionary
     """
-    loader = get_loader(mod_name)
-    if loader is None:
-        raise ImportError("No module named " + mod_name)
-    code = loader.get_code(mod_name)
-    if code is None:
-        raise ImportError("No code object available for " + mod_name)
-    filename = _get_filename(loader, mod_name)
+    loader, code, fname = _get_module_details(mod_name)
     if run_name is None:
         run_name = mod_name
-    return _run_module_code(code, init_globals, run_name,
-                            filename, loader, alter_sys)
+    if alter_sys:
+        return _run_module_code(code, init_globals, run_name,
+                                fname, loader)
+    else:
+        # Leave the sys module alone
+        return _run_code(code, {}, init_globals,
+                         run_name, fname, loader)
 
 
 if __name__ == "__main__":
@@ -101,4 +125,4 @@
         print >> sys.stderr, "No module specified for execution"
     else:
         del sys.argv[0] # Make the requested module sys.argv[0]
-        run_module(sys.argv[0], run_name="__main__", alter_sys=True)
+        _run_module_as_main(sys.argv[0])

Modified: python/branches/bcannon-objcap/Lib/sgmllib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/sgmllib.py	(original)
+++ python/branches/bcannon-objcap/Lib/sgmllib.py	Thu Sep  6 21:35:45 2007
@@ -428,7 +428,7 @@
         if replacement is None:
             self.unknown_entityref(name)
         else:
-            self.handle_data(self.convert_entityref(name))
+            self.handle_data(replacement)
 
     # Example -- handle data, should be overridden
     def handle_data(self, data):

Modified: python/branches/bcannon-objcap/Lib/smtplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/smtplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/smtplib.py	Thu Sep  6 21:35:45 2007
@@ -52,7 +52,7 @@
 __all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
            "SMTPSenderRefused","SMTPRecipientsRefused","SMTPDataError",
            "SMTPConnectError","SMTPHeloError","SMTPAuthenticationError",
-           "quoteaddr","quotedata","SMTP","SMTP_SSL"]
+           "quoteaddr","quotedata","SMTP"]
 
 SMTP_PORT = 25
 SMTP_SSL_PORT = 465
@@ -128,43 +128,6 @@
     combination provided.
     """
 
-class SSLFakeSocket:
-    """A fake socket object that really wraps a SSLObject.
-
-    It only supports what is needed in smtplib.
-    """
-    def __init__(self, realsock, sslobj):
-        self.realsock = realsock
-        self.sslobj = sslobj
-
-    def send(self, str):
-        self.sslobj.write(str)
-        return len(str)
-
-    sendall = send
-
-    def close(self):
-        self.realsock.close()
-
-class SSLFakeFile:
-    """A fake file like object that really wraps a SSLObject.
-
-    It only supports what is needed in smtplib.
-    """
-    def __init__(self, sslobj):
-        self.sslobj = sslobj
-
-    def readline(self):
-        str = ""
-        chr = None
-        while chr != "\n":
-            chr = self.sslobj.read(1)
-            str += chr
-        return str
-
-    def close(self):
-        pass
-
 def quoteaddr(addr):
     """Quote a subset of the email addresses defined by RFC 821.
 
@@ -194,6 +157,32 @@
         re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data))
 
 
+try:
+    import ssl
+except ImportError:
+    _have_ssl = False
+else:
+    class SSLFakeFile:
+        """A fake file like object that really wraps a SSLObject.
+
+        It only supports what is needed in smtplib.
+        """
+        def __init__(self, sslobj):
+            self.sslobj = sslobj
+
+        def readline(self):
+            str = ""
+            chr = None
+            while chr != "\n":
+                chr = self.sslobj.read(1)
+                str += chr
+            return str
+
+        def close(self):
+            pass
+
+    _have_ssl = True
+
 class SMTP:
     """This class manages a connection to an SMTP or ESMTP server.
     SMTP Objects:
@@ -596,9 +585,10 @@
         """
         (resp, reply) = self.docmd("STARTTLS")
         if resp == 220:
-            sslobj = socket.ssl(self.sock, keyfile, certfile)
-            self.sock = SSLFakeSocket(self.sock, sslobj)
-            self.file = SSLFakeFile(sslobj)
+            if not _have_ssl:
+                raise RuntimeError("No SSL support included in this Python")
+            self.sock = ssl.sslsocket(self.sock, keyfile, certfile)
+            self.file = SSLFakeFile(self.sock)
         return (resp, reply)
 
     def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
@@ -710,27 +700,30 @@
         self.docmd("quit")
         self.close()
 
-class SMTP_SSL(SMTP):
-    """ This is a subclass derived from SMTP that connects over an SSL encrypted
-    socket (to use this class you need a socket module that was compiled with SSL
-    support). If host is not specified, '' (the local host) is used. If port is
-    omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
-    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, timeout=None):
-        self.keyfile = keyfile
-        self.certfile = certfile
-        SMTP.__init__(self, host, port, local_hostname, timeout)
-        self.default_port = SMTP_SSL_PORT
+if _have_ssl:
 
-    def _get_socket(self, host, port, timeout):
-        if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
-        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)
+    class SMTP_SSL(SMTP):
+        """ This is a subclass derived from SMTP that connects over an SSL encrypted
+        socket (to use this class you need a socket module that was compiled with SSL
+        support). If host is not specified, '' (the local host) is used. If port is
+        omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
+        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, timeout=None):
+            self.keyfile = keyfile
+            self.certfile = certfile
+            SMTP.__init__(self, host, port, local_hostname, timeout)
+            self.default_port = SMTP_SSL_PORT
+
+        def _get_socket(self, host, port, timeout):
+            if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+            self.sock = socket.create_connection((host, port), timeout)
+            self.sock = ssl.sslsocket(self.sock, self.keyfile, self.certfile)
+            self.file = SSLFakeFile(self.sock)
+
+    __all__.append("SMTP_SSL")
 
 #
 # LMTP extension

Modified: python/branches/bcannon-objcap/Lib/socket.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/socket.py	(original)
+++ python/branches/bcannon-objcap/Lib/socket.py	Thu Sep  6 21:35:45 2007
@@ -46,15 +46,37 @@
 import _socket
 from _socket import *
 
-_have_ssl = False
 try:
     import _ssl
-    from _ssl import *
-    _have_ssl = True
 except ImportError:
+    # no SSL support
     pass
+else:
+    def ssl(sock, keyfile=None, certfile=None):
+        # we do an internal import here because the ssl
+        # module imports the socket module
+        import ssl as _realssl
+        warnings.warn("socket.ssl() is deprecated.  Use ssl.sslsocket() instead.",
+                      DeprecationWarning, stacklevel=2)
+        return _realssl.sslwrap_simple(sock, keyfile, certfile)
+
+    # we need to import the same constants we used to...
+    from _ssl import \
+         sslerror, \
+         RAND_add, \
+         RAND_egd, \
+         RAND_status, \
+         SSL_ERROR_ZERO_RETURN, \
+         SSL_ERROR_WANT_READ, \
+         SSL_ERROR_WANT_WRITE, \
+         SSL_ERROR_WANT_X509_LOOKUP, \
+         SSL_ERROR_SYSCALL, \
+         SSL_ERROR_SSL, \
+         SSL_ERROR_WANT_CONNECT, \
+         SSL_ERROR_EOF, \
+         SSL_ERROR_INVALID_ERROR_CODE
 
-import os, sys
+import os, sys, warnings
 
 try:
     from errno import EBADF
@@ -63,16 +85,9 @@
 
 __all__ = ["getfqdn"]
 __all__.extend(os._get_exports_list(_socket))
-if _have_ssl:
-    __all__.extend(os._get_exports_list(_ssl))
+
 
 _realsocket = socket
-if _have_ssl:
-    _realssl = ssl
-    def ssl(sock, keyfile=None, certfile=None):
-        if hasattr(sock, "_sock"):
-            sock = sock._sock
-        return _realssl(sock, keyfile, certfile)
 
 # WSA error codes
 if sys.platform.lower().startswith("win"):
@@ -144,6 +159,10 @@
     send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
     __getattr__ = _dummy
 
+# Wrapper around platform socket objects. This implements
+# a platform-independent dup() functionality. The
+# implementation currently relies on reference counting
+# to close the underlying socket object.
 class _socketobject(object):
 
     __doc__ = _realsocket.__doc__

Modified: python/branches/bcannon-objcap/Lib/sre_compile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/sre_compile.py	(original)
+++ python/branches/bcannon-objcap/Lib/sre_compile.py	Thu Sep  6 21:35:45 2007
@@ -280,7 +280,7 @@
 
 # To represent a big charset, first a bitmap of all characters in the
 # set is constructed. Then, this bitmap is sliced into chunks of 256
-# characters, duplicate chunks are eliminitated, and each chunk is
+# characters, duplicate chunks are eliminated, and each chunk is
 # given a number. In the compiled expression, the charset is
 # represented by a 16-bit word sequence, consisting of one word for
 # the number of different chunks, a sequence of 256 bytes (128 words)

Modified: python/branches/bcannon-objcap/Lib/tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/tarfile.py	(original)
+++ python/branches/bcannon-objcap/Lib/tarfile.py	Thu Sep  6 21:35:45 2007
@@ -1523,7 +1523,7 @@
             if hasattr(fileobj, "mode"):
                 self._mode = fileobj.mode
             self._extfileobj = True
-        self.name = os.path.abspath(name)
+        self.name = os.path.abspath(name) if name else None
         self.fileobj = fileobj
 
         # Init attributes.

Modified: python/branches/bcannon-objcap/Lib/test/cjkencodings_test.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/cjkencodings_test.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/cjkencodings_test.py	Thu Sep  6 21:35:45 2007
@@ -376,13 +376,20 @@
 "\xcc\xc7\xce\x2c\x20\xb1\xd7\xb8\xae\xb0\xed\x20\xc0\xce\xc5\xcd"
 "\xc7\xc1\xb8\xae\xc6\xc3\x0a\xc8\xaf\xb0\xe6\xc0\xba\x20\xc6\xc4"
 "\xc0\xcc\xbd\xe3\xc0\xbb\x20\xbd\xba\xc5\xa9\xb8\xb3\xc6\xc3\xb0"
-"\xfa\x20\xbf\xa9\xb7\xc1\x20\xba\xd0\xbe\xdf\xbf\xa1\xbc\xad\xbf"
+"\xfa\x20\xbf\xa9\xb7\xaf\x20\xba\xd0\xbe\xdf\xbf\xa1\xbc\xad\xbf"
 "\xcd\x20\xb4\xeb\xba\xce\xba\xd0\xc0\xc7\x20\xc7\xc3\xb7\xa7\xc6"
 "\xfb\xbf\xa1\xbc\xad\xc0\xc7\x20\xba\xfc\xb8\xa5\x0a\xbe\xd6\xc7"
 "\xc3\xb8\xae\xc4\xc9\xc0\xcc\xbc\xc7\x20\xb0\xb3\xb9\xdf\xc0\xbb"
 "\x20\xc7\xd2\x20\xbc\xf6\x20\xc0\xd6\xb4\xc2\x20\xc0\xcc\xbb\xf3"
 "\xc0\xfb\xc0\xce\x20\xbe\xf0\xbe\xee\xb7\xce\x20\xb8\xb8\xb5\xe9"
-"\xbe\xee\xc1\xdd\xb4\xcf\xb4\xd9\x2e\x0a\x0a",
+"\xbe\xee\xc1\xdd\xb4\xcf\xb4\xd9\x2e\x0a\x0a\xa1\xd9\xc3\xb9\xb0"
+"\xa1\xb3\xa1\x3a\x20\xb3\xaf\xbe\xc6\xb6\xf3\x20\xa4\xd4\xa4\xb6"
+"\xa4\xd0\xa4\xd4\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4\xbe\xb1\x7e\x20"
+"\xa4\xd4\xa4\xa4\xa4\xd2\xa4\xb7\xc5\xad\x21\x20\xa4\xd4\xa4\xa8"
+"\xa4\xd1\xa4\xb7\xb1\xdd\xbe\xf8\xc0\xcc\x20\xc0\xfc\xa4\xd4\xa4"
+"\xbe\xa4\xc8\xa4\xb2\xb4\xcf\xb4\xd9\x2e\x20\xa4\xd4\xa4\xb2\xa4"
+"\xce\xa4\xaa\x2e\x20\xb1\xd7\xb7\xb1\xb0\xc5\x20\xa4\xd4\xa4\xb7"
+"\xa4\xd1\xa4\xb4\xb4\xd9\x2e\x0a",
 "\xe2\x97\x8e\x20\xed\x8c\x8c\xec\x9d\xb4\xec\x8d\xac\x28\x50\x79"
 "\x74\x68\x6f\x6e\x29\xec\x9d\x80\x20\xeb\xb0\xb0\xec\x9a\xb0\xea"
 "\xb8\xb0\x20\xec\x89\xbd\xea\xb3\xa0\x2c\x20\xea\xb0\x95\xeb\xa0"
@@ -404,7 +411,7 @@
 "\xec\x9d\xb8\xed\x84\xb0\xed\x94\x84\xeb\xa6\xac\xed\x8c\x85\x0a"
 "\xed\x99\x98\xea\xb2\xbd\xec\x9d\x80\x20\xed\x8c\x8c\xec\x9d\xb4"
 "\xec\x8d\xac\xec\x9d\x84\x20\xec\x8a\xa4\xed\x81\xac\xeb\xa6\xbd"
-"\xed\x8c\x85\xea\xb3\xbc\x20\xec\x97\xac\xeb\xa0\xa4\x20\xeb\xb6"
+"\xed\x8c\x85\xea\xb3\xbc\x20\xec\x97\xac\xeb\x9f\xac\x20\xeb\xb6"
 "\x84\xec\x95\xbc\xec\x97\x90\xec\x84\x9c\xec\x99\x80\x20\xeb\x8c"
 "\x80\xeb\xb6\x80\xeb\xb6\x84\xec\x9d\x98\x20\xed\x94\x8c\xeb\x9e"
 "\xab\xed\x8f\xbc\xec\x97\x90\xec\x84\x9c\xec\x9d\x98\x20\xeb\xb9"
@@ -413,7 +420,13 @@
 "\x84\x20\xed\x95\xa0\x20\xec\x88\x98\x20\xec\x9e\x88\xeb\x8a\x94"
 "\x20\xec\x9d\xb4\xec\x83\x81\xec\xa0\x81\xec\x9d\xb8\x20\xec\x96"
 "\xb8\xec\x96\xb4\xeb\xa1\x9c\x20\xeb\xa7\x8c\xeb\x93\xa4\xec\x96"
-"\xb4\xec\xa4\x8d\xeb\x8b\x88\xeb\x8b\xa4\x2e\x0a\x0a"),
+"\xb4\xec\xa4\x8d\xeb\x8b\x88\xeb\x8b\xa4\x2e\x0a\x0a\xe2\x98\x86"
+"\xec\xb2\xab\xea\xb0\x80\xeb\x81\x9d\x3a\x20\xeb\x82\xa0\xec\x95"
+"\x84\xeb\x9d\xbc\x20\xec\x93\x94\xec\x93\x94\xec\x93\xa9\x7e\x20"
+"\xeb\x8b\x81\xed\x81\xbc\x21\x20\xeb\x9c\xbd\xea\xb8\x88\xec\x97"
+"\x86\xec\x9d\xb4\x20\xec\xa0\x84\xed\x99\xa5\xeb\x8b\x88\xeb\x8b"
+"\xa4\x2e\x20\xeb\xb7\x81\x2e\x20\xea\xb7\xb8\xeb\x9f\xb0\xea\xb1"
+"\xb0\x20\xec\x9d\x8e\xeb\x8b\xa4\x2e\x0a"),
 'gb18030': (
 "\x50\x79\x74\x68\x6f\x6e\xa3\xa8\xc5\xc9\xc9\xad\xa3\xa9\xd3\xef"
 "\xd1\xd4\xca\xc7\xd2\xbb\xd6\xd6\xb9\xa6\xc4\xdc\xc7\xbf\xb4\xf3"

Modified: python/branches/bcannon-objcap/Lib/test/list_tests.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/list_tests.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/list_tests.py	Thu Sep  6 21:35:45 2007
@@ -179,8 +179,10 @@
         self.assertEqual(a, self.type2test(range(10)))
 
         self.assertRaises(TypeError, a.__setslice__, 0, 1, 5)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 1, 5))
 
         self.assertRaises(TypeError, a.__setslice__)
+        self.assertRaises(TypeError, a.__setitem__)
 
     def test_delslice(self):
         a = self.type2test([0, 1])

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_class
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_class	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,101 +0,0 @@
-test_class
-__init__: ()
-__coerce__: (1,)
-__add__: (1,)
-__coerce__: (1,)
-__radd__: (1,)
-__coerce__: (1,)
-__sub__: (1,)
-__coerce__: (1,)
-__rsub__: (1,)
-__coerce__: (1,)
-__mul__: (1,)
-__coerce__: (1,)
-__rmul__: (1,)
-__coerce__: (1,)
-__div__: (1,)
-__coerce__: (1,)
-__rdiv__: (1,)
-__coerce__: (1,)
-__mod__: (1,)
-__coerce__: (1,)
-__rmod__: (1,)
-__coerce__: (1,)
-__divmod__: (1,)
-__coerce__: (1,)
-__rdivmod__: (1,)
-__coerce__: (1,)
-__pow__: (1,)
-__coerce__: (1,)
-__rpow__: (1,)
-__coerce__: (1,)
-__rshift__: (1,)
-__coerce__: (1,)
-__rrshift__: (1,)
-__coerce__: (1,)
-__lshift__: (1,)
-__coerce__: (1,)
-__rlshift__: (1,)
-__coerce__: (1,)
-__and__: (1,)
-__coerce__: (1,)
-__rand__: (1,)
-__coerce__: (1,)
-__or__: (1,)
-__coerce__: (1,)
-__ror__: (1,)
-__coerce__: (1,)
-__xor__: (1,)
-__coerce__: (1,)
-__rxor__: (1,)
-__contains__: (1,)
-__getitem__: (1,)
-__setitem__: (1, 1)
-__delitem__: (1,)
-__getslice__: (0, 42)
-__setslice__: (0, 42, 'The Answer')
-__delslice__: (0, 42)
-__getitem__: (slice(2, 1024, 10),)
-__setitem__: (slice(2, 1024, 10), 'A lot')
-__delitem__: (slice(2, 1024, 10),)
-__getitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
-__setitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100), 'Strange')
-__delitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
-__getitem__: (slice(0, 42, None),)
-__setitem__: (slice(0, 42, None), 'The Answer')
-__delitem__: (slice(0, 42, None),)
-__neg__: ()
-__pos__: ()
-__abs__: ()
-__int__: ()
-__long__: ()
-__float__: ()
-__oct__: ()
-__hex__: ()
-__hash__: ()
-__repr__: ()
-__str__: ()
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__del__: ()
-__getattr__: ('spam',)
-__setattr__: ('eggs', 'spam, spam, spam and ham')
-__delattr__: ('cardinal',)

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_frozen
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_frozen	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,4 +0,0 @@
-test_frozen
-Hello world...
-Hello world...
-Hello world...

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_linuxaudiodev
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_linuxaudiodev	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,7 +0,0 @@
-test_linuxaudiodev
-expected rate >= 0, not -1
-expected sample size >= 0, not -2
-nchannels must be 1 or 2, not 3
-unknown audio encoding: 177
-for linear unsigned 16-bit little-endian audio, expected sample size 16, not 8
-for linear unsigned 8-bit audio, expected sample size 8, not 16

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_ossaudiodev
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_ossaudiodev	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,2 +0,0 @@
-test_ossaudiodev
-playing test sound file (expected running time: 2.93 sec)

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_pkg
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_pkg	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,45 +0,0 @@
-test_pkg
-running test t1
-running test t2
-t2 loading
-doc for t2
-t2.sub.subsub loading
-t2 t2.sub t2.sub.subsub
-['sub', 't2']
-t2.sub t2.sub.subsub
-t2.sub.subsub
-['spam', 'sub', 'subsub', 't2']
-t2 t2.sub t2.sub.subsub
-['spam', 'sub', 'subsub', 't2']
-running test t3
-t3 loading
-t3.sub.subsub loading
-t3 t3.sub t3.sub.subsub
-t3 loading
-t3.sub.subsub loading
-running test t4
-t4 loading
-t4.sub.subsub loading
-t4.sub.subsub.spam = 1
-running test t5
-t5.foo loading
-t5.string loading
-1
-['foo', 'string', 't5']
-['__doc__', '__file__', '__name__', '__path__', 'foo', 'string', 't5']
-['__doc__', '__file__', '__name__', 'string']
-['__doc__', '__file__', '__name__', 'spam']
-running test t6
-['__all__', '__doc__', '__file__', '__name__', '__path__']
-t6.spam loading
-t6.ham loading
-t6.eggs loading
-['__all__', '__doc__', '__file__', '__name__', '__path__', 'eggs', 'ham', 'spam']
-['eggs', 'ham', 'spam', 't6']
-running test t7
-t7 loading
-['__doc__', '__file__', '__name__', '__path__']
-['__doc__', '__file__', '__name__', '__path__']
-t7.sub.subsub loading
-['__doc__', '__file__', '__name__', '__path__', 'spam']
-t7.sub.subsub.spam = 1

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_rgbimg
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_rgbimg	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,2 +0,0 @@
-test_rgbimg
-RGBimg test suite:

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_signal
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_signal	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,2 +0,0 @@
-test_signal
-starting pause() loop...

Deleted: /python/branches/bcannon-objcap/Lib/test/output/test_winreg
==============================================================================
--- /python/branches/bcannon-objcap/Lib/test/output/test_winreg	Thu Sep  6 21:35:45 2007
+++ (empty file)
@@ -1,3 +0,0 @@
-test_winreg
-Local registry tests worked
-Remote registry calls can be tested using 'test_winreg.py --remote \\machine_name'

Modified: python/branches/bcannon-objcap/Lib/test/regrtest.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/regrtest.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/regrtest.py	Thu Sep  6 21:35:45 2007
@@ -806,17 +806,16 @@
 #     test_timeout
 #         Controlled by test_timeout.skip_expected.  Requires the network
 #         resource and a socket module.
+#
+# Tests that are expected to be skipped everywhere except on one platform
+# are also handled separately.
 
 _expectations = {
     'win32':
         """
         test__locale
-        test_applesingle
-        test_al
         test_bsddb185
         test_bsddb3
-        test_cd
-        test_cl
         test_commands
         test_crypt
         test_curses
@@ -825,23 +824,19 @@
         test_fcntl
         test_fork1
         test_gdbm
-        test_gl
         test_grp
-        test_imgfile
         test_ioctl
         test_largefile
-        test_linuxaudiodev
         test_mhlib
-        test_nis
         test_openpty
         test_ossaudiodev
+        test_pipes
         test_poll
         test_posix
         test_pty
         test_pwd
         test_resource
         test_signal
-        test_sunaudiodev
         test_threadsignals
         test_timing
         test_wait3
@@ -849,34 +844,19 @@
         """,
     'linux2':
         """
-        test_al
-        test_applesingle
         test_bsddb185
-        test_cd
-        test_cl
         test_curses
         test_dl
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
-        test_nis
-        test_ntpath
         test_ossaudiodev
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
    'mac':
         """
-        test_al
         test_atexit
         test_bsddb
         test_bsddb185
         test_bsddb3
         test_bz2
-        test_cd
-        test_cl
         test_commands
         test_crypt
         test_curses
@@ -884,16 +864,11 @@
         test_dl
         test_fcntl
         test_fork1
-        test_gl
         test_grp
         test_ioctl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mmap
-        test_nis
-        test_ntpath
         test_openpty
         test_ossaudiodev
         test_poll
@@ -904,88 +879,49 @@
         test_pwd
         test_resource
         test_signal
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_tarfile
         test_timing
         """,
     'unixware7':
         """
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
-        test_cd
-        test_cl
         test_dl
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_startfile
-        test_sqlite
-        test_sunaudiodev
         test_sundry
         """,
     'openunix8':
         """
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
-        test_cd
-        test_cl
         test_dl
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         """,
     'sco_sv3':
         """
-        test_al
-        test_applesingle
         test_asynchat
         test_bsddb
         test_bsddb185
-        test_cd
-        test_cl
         test_dl
         test_fork1
         test_gettext
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_queue
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_thread
         test_threaded_import
@@ -994,15 +930,11 @@
         """,
     'riscos':
         """
-        test_al
-        test_applesingle
         test_asynchat
         test_atexit
         test_bsddb
         test_bsddb185
         test_bsddb3
-        test_cd
-        test_cl
         test_commands
         test_crypt
         test_dbm
@@ -1010,24 +942,16 @@
         test_fcntl
         test_fork1
         test_gdbm
-        test_gl
         test_grp
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mmap
-        test_nis
-        test_ntpath
         test_openpty
         test_poll
         test_popen2
         test_pty
         test_pwd
         test_strop
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_thread
         test_threaded_import
@@ -1038,274 +962,143 @@
     'darwin':
         """
         test__locale
-        test_al
         test_bsddb
         test_bsddb3
-        test_cd
-        test_cl
         test_curses
         test_gdbm
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_minidom
-        test_nis
-        test_ntpath
         test_ossaudiodev
         test_poll
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
     'sunos5':
         """
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
-        test_cd
-        test_cl
         test_curses
         test_dbm
         test_gdbm
-        test_gl
         test_gzip
-        test_imgfile
-        test_linuxaudiodev
         test_openpty
-        test_sqlite
-        test_startfile
         test_zipfile
         test_zlib
         """,
     'hp-ux11':
         """
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
-        test_cd
-        test_cl
         test_curses
         test_dl
         test_gdbm
-        test_gl
         test_gzip
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_zipfile
         test_zlib
         """,
     'atheos':
         """
-        test_al
-        test_applesingle
         test_bsddb185
-        test_cd
-        test_cl
         test_curses
         test_dl
         test_gdbm
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mhlib
         test_mmap
-        test_nis
         test_poll
         test_popen2
         test_resource
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
     'cygwin':
         """
-        test_al
-        test_applesingle
         test_bsddb185
         test_bsddb3
-        test_cd
-        test_cl
         test_curses
         test_dbm
-        test_gl
-        test_imgfile
         test_ioctl
         test_largefile
-        test_linuxaudiodev
         test_locale
-        test_nis
         test_ossaudiodev
         test_socketserver
-        test_sqlite
-        test_sunaudiodev
         """,
     'os2emx':
         """
-        test_al
-        test_applesingle
         test_audioop
         test_bsddb185
         test_bsddb3
-        test_cd
-        test_cl
         test_commands
         test_curses
         test_dl
-        test_gl
-        test_imgfile
         test_largefile
-        test_linuxaudiodev
         test_mhlib
         test_mmap
-        test_nis
         test_openpty
         test_ossaudiodev
         test_pty
         test_resource
         test_signal
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
     'freebsd4':
         """
-        test_aepack
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb3
-        test_cd
-        test_cl
         test_gdbm
-        test_gl
-        test_imgfile
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_ossaudiodev
         test_pep277
-        test_plistlib
         test_pty
-        test_scriptpackages
         test_socket_ssl
         test_socketserver
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
         test_timeout
-        test_unicode_file
         test_urllibnet
-        test_winreg
-        test_winsound
         """,
     'aix5':
         """
-        test_aepack
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
         test_bsddb3
         test_bz2
-        test_cd
-        test_cl
         test_dl
         test_gdbm
-        test_gl
         test_gzip
-        test_imgfile
-        test_linuxaudiodev
-        test_macostools
-        test_nis
         test_ossaudiodev
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
-        test_winreg
-        test_winsound
         test_zipimport
         test_zlib
         """,
     'openbsd3':
         """
-        test_aepack
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb3
-        test_cd
-        test_cl
         test_ctypes
         test_dl
         test_gdbm
-        test_gl
-        test_imgfile
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_normalization
         test_ossaudiodev
         test_pep277
-        test_plistlib
-        test_scriptpackages
         test_tcl
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
-        test_unicode_file
-        test_winreg
-        test_winsound
         """,
     'netbsd3':
         """
-        test_aepack
-        test_al
-        test_applesingle
         test_bsddb
         test_bsddb185
         test_bsddb3
-        test_cd
-        test_cl
         test_ctypes
         test_curses
         test_dl
         test_gdbm
-        test_gl
-        test_imgfile
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_ossaudiodev
         test_pep277
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
-        test_unicode_file
-        test_winreg
-        test_winsound
         """,
 }
 _expectations['freebsd5'] = _expectations['freebsd4']
@@ -1323,6 +1116,9 @@
             s = _expectations[sys.platform]
             self.expected = set(s.split())
 
+            # expected to be skipped on every platform, even Linux
+            self.expected.add('test_linuxaudiodev')
+
             if not os.path.supports_unicode_filenames:
                 self.expected.add('test_pep277')
 
@@ -1337,21 +1133,30 @@
 
             if not sys.platform in ("mac", "darwin"):
                 MAC_ONLY = ["test_macostools", "test_aepack",
-                            "test_plistlib", "test_scriptpackages"]
+                            "test_plistlib", "test_scriptpackages",
+                            "test_applesingle"]
                 for skip in MAC_ONLY:
                     self.expected.add(skip)
 
             if sys.platform != "win32":
+                # test_sqlite is only reliable on Windows where the library
+                # is distributed with Python
                 WIN_ONLY = ["test_unicode_file", "test_winreg",
-                            "test_winsound"]
+                            "test_winsound", "test_startfile",
+                            "test_sqlite"]
                 for skip in WIN_ONLY:
                     self.expected.add(skip)
 
             if sys.platform != 'irix':
-                IRIX_ONLY =["test_imageop"]
+                IRIX_ONLY = ["test_imageop", "test_al", "test_cd", "test_cl",
+                             "test_gl", "test_imgfile"]
                 for skip in IRIX_ONLY:
                     self.expected.add(skip)
 
+            if sys.platform != 'sunos5':
+                self.expected.add('test_sunaudiodev')
+                self.expected.add('test_nis')
+
             self.valid = True
 
     def isvalid(self):

Modified: python/branches/bcannon-objcap/Lib/test/string_tests.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/string_tests.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/string_tests.py	Thu Sep  6 21:35:45 2007
@@ -912,7 +912,6 @@
         self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000))
         self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1))
         self.checkequal(u'', 'abc', '__getitem__', slice(0, 0))
-        # FIXME What about negative indices? This is handled differently by [] and __getitem__(slice)
 
         self.checkraises(TypeError, 'abc', '__getitem__', 'def')
 
@@ -926,10 +925,21 @@
         self.checkequal('', 'abc', '__getslice__', 1000, 1000)
         self.checkequal('', 'abc', '__getslice__', 2000, 1000)
         self.checkequal('', 'abc', '__getslice__', 2, 1)
-        # FIXME What about negative indizes? This is handled differently by [] and __getslice__
 
         self.checkraises(TypeError, 'abc', '__getslice__', 'def')
 
+    def test_extended_getslice(self):
+        # Test extended slicing by comparing with list slicing.
+        s = string.ascii_letters + string.digits
+        indices = (0, None, 1, 3, 41, -1, -2, -37)
+        for start in indices:
+            for stop in indices:
+                # Skip step 0 (invalid)
+                for step in indices[1:]:
+                    L = list(s)[start:stop:step]
+                    self.checkequal(u"".join(L), s, '__getitem__',
+                                    slice(start, stop, step))
+
     def test_mul(self):
         self.checkequal('', 'abc', '__mul__', -1)
         self.checkequal('', 'abc', '__mul__', 0)

Modified: python/branches/bcannon-objcap/Lib/test/test_StringIO.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_StringIO.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_StringIO.py	Thu Sep  6 21:35:45 2007
@@ -121,28 +121,6 @@
 class TestcStringIO(TestGenericStringIO):
     MODULE = cStringIO
 
-    def test_unicode(self):
-
-        if not test_support.have_unicode: return
-
-        # The cStringIO module converts Unicode strings to character
-        # strings when writing them to cStringIO objects.
-        # Check that this works.
-
-        f = self.MODULE.StringIO()
-        f.write(unicode(self._line[:5]))
-        s = f.getvalue()
-        self.assertEqual(s, 'abcde')
-        self.assertEqual(type(s), types.StringType)
-
-        f = self.MODULE.StringIO(unicode(self._line[:5]))
-        s = f.getvalue()
-        self.assertEqual(s, 'abcde')
-        self.assertEqual(type(s), types.StringType)
-
-        self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO,
-                          unicode('\xf4', 'latin-1'))
-
 import sys
 if sys.platform.startswith('java'):
     # Jython doesn't have a buffer object, so we just do a useless

Modified: python/branches/bcannon-objcap/Lib/test/test_array.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_array.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_array.py	Thu Sep  6 21:35:45 2007
@@ -474,6 +474,18 @@
             array.array(self.typecode)
         )
 
+    def test_extended_getslice(self):
+        # Test extended slicing by comparing with list slicing
+        # (Assumes list conversion works correctly, too)
+        a = array.array(self.typecode, self.example)
+        indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+        for start in indices:
+            for stop in indices:
+                # Everything except the initial 0 (invalid step)
+                for step in indices[1:]:
+                    self.assertEqual(list(a[start:stop:step]),
+                                     list(a)[start:stop:step])
+
     def test_setslice(self):
         a = array.array(self.typecode, self.example)
         a[:1] = a
@@ -557,12 +569,34 @@
 
         a = array.array(self.typecode, self.example)
         self.assertRaises(TypeError, a.__setslice__, 0, 0, None)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None)
         self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None)
 
         b = array.array(self.badtypecode())
         self.assertRaises(TypeError, a.__setslice__, 0, 0, b)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b)
         self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
 
+    def test_extended_set_del_slice(self):
+        indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+        for start in indices:
+            for stop in indices:
+                # Everything except the initial 0 (invalid step)
+                for step in indices[1:]:
+                    a = array.array(self.typecode, self.example)
+                    L = list(a)
+                    # Make sure we have a slice of exactly the right length,
+                    # but with (hopefully) different data.
+                    data = L[start:stop:step]
+                    data.reverse()
+                    L[start:stop:step] = data
+                    a[start:stop:step] = array.array(self.typecode, data)
+                    self.assertEquals(a, array.array(self.typecode, L))
+
+                    del L[start:stop:step]
+                    del a[start:stop:step]
+                    self.assertEquals(a, array.array(self.typecode, L))
+
     def test_index(self):
         example = 2*self.example
         a = array.array(self.typecode, example)

Modified: python/branches/bcannon-objcap/Lib/test/test_asynchat.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_asynchat.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_asynchat.py	Thu Sep  6 21:35:45 2007
@@ -3,12 +3,17 @@
 import thread # If this fails, we can't test this module
 import asyncore, asynchat, socket, threading, time
 import unittest
+import sys
 from test import test_support
 
 HOST = "127.0.0.1"
 PORT = 54322
+SERVER_QUIT = 'QUIT\n'
 
 class echo_server(threading.Thread):
+    # parameter to determine the number of bytes passed back to the
+    # client each send
+    chunk_size = 1
 
     def run(self):
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -17,15 +22,28 @@
         PORT = test_support.bind_port(sock, HOST, PORT)
         sock.listen(1)
         conn, client = sock.accept()
-        buffer = ""
-        while "\n" not in buffer:
+        self.buffer = ""
+        # collect data until quit message is seen
+        while SERVER_QUIT not in self.buffer:
             data = conn.recv(1)
             if not data:
                 break
-            buffer = buffer + data
-        while buffer:
-            n = conn.send(buffer)
-            buffer = buffer[n:]
+            self.buffer = self.buffer + data
+
+        # remove the SERVER_QUIT message
+        self.buffer = self.buffer.replace(SERVER_QUIT, '')
+
+        # re-send entire set of collected data
+        try:
+            # this may fail on some tests, such as test_close_when_done, since
+            # the client closes the channel when it's done sending
+            while self.buffer:
+                n = conn.send(self.buffer[:self.chunk_size])
+                time.sleep(0.001)
+                self.buffer = self.buffer[n:]
+        except:
+            pass
+
         conn.close()
         sock.close()
 
@@ -33,61 +51,202 @@
 
     def __init__(self, terminator):
         asynchat.async_chat.__init__(self)
-        self.contents = None
+        self.contents = []
         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
         self.connect((HOST, PORT))
         self.set_terminator(terminator)
-        self.buffer = ""
+        self.buffer = ''
 
     def handle_connect(self):
         pass
-        ##print "Connected"
+
+    if sys.platform == 'darwin':
+        # select.poll returns a select.POLLHUP at the end of the tests
+        # on darwin, so just ignore it
+        def handle_expt(self):
+            pass
 
     def collect_incoming_data(self, data):
-        self.buffer = self.buffer + data
+        self.buffer += data
 
     def found_terminator(self):
-        #print "Received:", repr(self.buffer)
-        self.contents = self.buffer
+        self.contents.append(self.buffer)
         self.buffer = ""
-        self.close()
 
 
 class TestAsynchat(unittest.TestCase):
+    usepoll = False
+
     def setUp (self):
         pass
 
     def tearDown (self):
         pass
 
-    def test_line_terminator(self):
+    def line_terminator_check(self, term, server_chunk):
         s = echo_server()
+        s.chunk_size = server_chunk
         s.start()
-        time.sleep(1) # Give server time to initialize
-        c = echo_client('\n')
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client(term)
         c.push("hello ")
-        c.push("world\n")
-        asyncore.loop()
+        c.push("world%s" % term)
+        c.push("I'm not dead yet!%s" % term)
+        c.push(SERVER_QUIT)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
         s.join()
 
-        self.assertEqual(c.contents, 'hello world')
+        self.assertEqual(c.contents, ["hello world", "I'm not dead yet!"])
+
+    # the line terminator tests below check receiving variously-sized
+    # chunks back from the server in order to exercise all branches of
+    # async_chat.handle_read
+
+    def test_line_terminator1(self):
+        # test one-character terminator
+        for l in (1,2,3):
+            self.line_terminator_check('\n', l)
+
+    def test_line_terminator2(self):
+        # test two-character terminator
+        for l in (1,2,3):
+            self.line_terminator_check('\r\n', l)
+
+    def test_line_terminator3(self):
+        # test three-character terminator
+        for l in (1,2,3):
+            self.line_terminator_check('qqq', l)
 
-    def test_numeric_terminator(self):
+    def numeric_terminator_check(self, termlen):
         # Try reading a fixed number of bytes
         s = echo_server()
         s.start()
-        time.sleep(1) # Give server time to initialize
-        c = echo_client(6L)
-        c.push("hello ")
-        c.push("world\n")
-        asyncore.loop()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client(termlen)
+        data = "hello world, I'm not dead yet!\n"
+        c.push(data)
+        c.push(SERVER_QUIT)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+        s.join()
+
+        self.assertEqual(c.contents, [data[:termlen]])
+
+    def test_numeric_terminator1(self):
+        # check that ints & longs both work (since type is
+        # explicitly checked in async_chat.handle_read)
+        self.numeric_terminator_check(1)
+        self.numeric_terminator_check(1L)
+
+    def test_numeric_terminator2(self):
+        self.numeric_terminator_check(6L)
+
+    def test_none_terminator(self):
+        # Try reading a fixed number of bytes
+        s = echo_server()
+        s.start()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client(None)
+        data = "hello world, I'm not dead yet!\n"
+        c.push(data)
+        c.push(SERVER_QUIT)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+        s.join()
+
+        self.assertEqual(c.contents, [])
+        self.assertEqual(c.buffer, data)
+
+    def test_simple_producer(self):
+        s = echo_server()
+        s.start()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client('\n')
+        data = "hello world\nI'm not dead yet!\n"
+        p = asynchat.simple_producer(data+SERVER_QUIT, buffer_size=8)
+        c.push_with_producer(p)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+        s.join()
+
+        self.assertEqual(c.contents, ["hello world", "I'm not dead yet!"])
+
+    def test_string_producer(self):
+        s = echo_server()
+        s.start()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client('\n')
+        data = "hello world\nI'm not dead yet!\n"
+        c.push_with_producer(data+SERVER_QUIT)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+        s.join()
+
+        self.assertEqual(c.contents, ["hello world", "I'm not dead yet!"])
+
+    def test_empty_line(self):
+        # checks that empty lines are handled correctly
+        s = echo_server()
+        s.start()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client('\n')
+        c.push("hello world\n\nI'm not dead yet!\n")
+        c.push(SERVER_QUIT)
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
+        s.join()
+
+        self.assertEqual(c.contents, ["hello world", "", "I'm not dead yet!"])
+
+    def test_close_when_done(self):
+        s = echo_server()
+        s.start()
+        time.sleep(0.5) # Give server time to initialize
+        c = echo_client('\n')
+        c.push("hello world\nI'm not dead yet!\n")
+        c.push(SERVER_QUIT)
+        c.close_when_done()
+        asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01)
         s.join()
 
-        self.assertEqual(c.contents, 'hello ')
+        self.assertEqual(c.contents, [])
+        # the server might have been able to send a byte or two back, but this
+        # at least checks that it received something and didn't just fail
+        # (which could still result in the client not having received anything)
+        self.assertTrue(len(s.buffer) > 0)
+
+
+class TestAsynchat_WithPoll(TestAsynchat):
+    usepoll = True
+
+class TestHelperFunctions(unittest.TestCase):
+    def test_find_prefix_at_end(self):
+        self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
+        self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0)
+
+class TestFifo(unittest.TestCase):
+    def test_basic(self):
+        f = asynchat.fifo()
+        f.push(7)
+        f.push('a')
+        self.assertEqual(len(f), 2)
+        self.assertEqual(f.first(), 7)
+        self.assertEqual(f.pop(), (1, 7))
+        self.assertEqual(len(f), 1)
+        self.assertEqual(f.first(), 'a')
+        self.assertEqual(f.is_empty(), False)
+        self.assertEqual(f.pop(), (1, 'a'))
+        self.assertEqual(len(f), 0)
+        self.assertEqual(f.is_empty(), True)
+        self.assertEqual(f.pop(), (0, None))
+
+    def test_given_list(self):
+        f = asynchat.fifo(['x', 17, 3])
+        self.assertEqual(len(f), 3)
+        self.assertEqual(f.pop(), (1, 'x'))
+        self.assertEqual(f.pop(), (1, 17))
+        self.assertEqual(f.pop(), (1, 3))
+        self.assertEqual(f.pop(), (0, None))
 
 
 def test_main(verbose=None):
-    test_support.run_unittest(TestAsynchat)
+    test_support.run_unittest(TestAsynchat, TestAsynchat_WithPoll,
+                              TestHelperFunctions, TestFifo)
 
 if __name__ == "__main__":
     test_main(verbose=True)

Modified: python/branches/bcannon-objcap/Lib/test/test_bsddb.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_bsddb.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_bsddb.py	Thu Sep  6 21:35:45 2007
@@ -127,6 +127,22 @@
             items.append(self.f.previous())
         self.assertSetEquals(items, self.d.items())
 
+    def test_first_while_deleting(self):
+        # Test for bug 1725856
+        self.assert_(len(self.d) >= 2, "test requires >=2 items")
+        for _ in self.d:
+            key = self.f.first()[0]
+            del self.f[key]
+        self.assertEqual([], self.f.items(), "expected empty db after test")
+
+    def test_last_while_deleting(self):
+        # Test for bug 1725856's evil twin
+        self.assert_(len(self.d) >= 2, "test requires >=2 items")
+        for _ in self.d:
+            key = self.f.last()[0]
+            del self.f[key]
+        self.assertEqual([], self.f.items(), "expected empty db after test")
+
     def test_set_location(self):
         self.assertEqual(self.f.set_location('e'), ('e', self.d['e']))
 

Modified: python/branches/bcannon-objcap/Lib/test/test_calendar.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_calendar.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_calendar.py	Thu Sep  6 21:35:45 2007
@@ -49,7 +49,7 @@
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=ascii" />
 <link rel="stylesheet" type="text/css" href="calendar.css" />
-<title>Calendar for 2004</title
+<title>Calendar for 2004</title>
 </head>
 <body>
 <table border="0" cellpadding="0" cellspacing="0" class="year">

Modified: python/branches/bcannon-objcap/Lib/test/test_class.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_class.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_class.py	Thu Sep  6 21:35:45 2007
@@ -1,6 +1,9 @@
 "Test the functionality of Python classes implementing operators."
 
-from test.test_support import TestFailed
+import unittest
+import sys
+
+from test import test_support
 
 testmeths = [
 
@@ -64,55 +67,62 @@
 #    "setattr",
 #    "delattr",
 
+callLst = []
+def trackCall(f):
+    def track(*args, **kwargs):
+        callLst.append((f.__name__, args))
+        return f(*args, **kwargs)
+    return track
+
 class AllTests:
+    trackCall = trackCall
+
+    @trackCall
     def __coerce__(self, *args):
-        print "__coerce__:", args
         return (self,) + args
 
+    @trackCall
     def __hash__(self, *args):
-        print "__hash__:", args
         return hash(id(self))
 
+    @trackCall
     def __str__(self, *args):
-        print "__str__:", args
         return "AllTests"
 
+    @trackCall
     def __repr__(self, *args):
-        print "__repr__:", args
         return "AllTests"
 
+    @trackCall
     def __int__(self, *args):
-        print "__int__:", args
         return 1
 
+    @trackCall
     def __float__(self, *args):
-        print "__float__:", args
         return 1.0
 
+    @trackCall
     def __long__(self, *args):
-        print "__long__:", args
         return 1L
 
+    @trackCall
     def __oct__(self, *args):
-        print "__oct__:", args
         return '01'
 
+    @trackCall
     def __hex__(self, *args):
-        print "__hex__:", args
         return '0x1'
 
+    @trackCall
     def __cmp__(self, *args):
-        print "__cmp__:", args
         return 0
 
-    def __del__(self, *args):
-        print "__del__:", args
-
-# Synthesize AllTests methods from the names in testmeths.
+# Synthesize all the other AllTests methods from the names in testmeths.
 
 method_template = """\
+ at trackCall
 def __%(method)s__(self, *args):
-    print "__%(method)s__:", args
+    pass
 """
 
 for method in testmeths:
@@ -120,293 +130,494 @@
 
 del method, method_template
 
-# this also tests __init__ of course.
-testme = AllTests()
-
-# Binary operations
-
-testme + 1
-1 + testme
-
-testme - 1
-1 - testme
-
-testme * 1
-1 * testme
-
-if 1/2 == 0:
-    testme / 1
-    1 / testme
-else:
-    # True division is in effect, so "/" doesn't map to __div__ etc; but
-    # the canned expected-output file requires that __div__ etc get called.
-    testme.__coerce__(1)
-    testme.__div__(1)
-    testme.__coerce__(1)
-    testme.__rdiv__(1)
-
-testme % 1
-1 % testme
-
-divmod(testme,1)
-divmod(1, testme)
-
-testme ** 1
-1 ** testme
-
-testme >> 1
-1 >> testme
-
-testme << 1
-1 << testme
-
-testme & 1
-1 & testme
-
-testme | 1
-1 | testme
-
-testme ^ 1
-1 ^ testme
-
-
-# List/dict operations
-
-class Empty: pass
-
-try:
-    1 in Empty()
-    print 'failed, should have raised TypeError'
-except TypeError:
-    pass
-
-1 in testme
-
-testme[1]
-testme[1] = 1
-del testme[1]
-
-testme[:42]
-testme[:42] = "The Answer"
-del testme[:42]
-
-testme[2:1024:10]
-testme[2:1024:10] = "A lot"
-del testme[2:1024:10]
-
-testme[:42, ..., :24:, 24, 100]
-testme[:42, ..., :24:, 24, 100] = "Strange"
-del testme[:42, ..., :24:, 24, 100]
-
+class ClassTests(unittest.TestCase):
+    def setUp(self):
+        callLst[:] = []
+
+    def assertCallStack(self, expected_calls):
+        actualCallList = callLst[:]  # need to copy because the comparison below will add
+                                     # additional calls to callLst
+        if expected_calls != actualCallList:
+            self.fail("Expected call list:\n  %s\ndoes not match actual call list\n  %s" %
+                      (expected_calls, actualCallList))
+
+    def testInit(self):
+        foo = AllTests()
+        self.assertCallStack([("__init__", (foo,))])
+
+    def testBinaryOps(self):
+        testme = AllTests()
+        # Binary operations
+
+        callLst[:] = []
+        testme + 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__add__", (testme, 1))])
+
+        callLst[:] = []
+        1 + testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__radd__", (testme, 1))])
+
+        callLst[:] = []
+        testme - 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__sub__", (testme, 1))])
+
+        callLst[:] = []
+        1 - testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rsub__", (testme, 1))])
+
+        callLst[:] = []
+        testme * 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__mul__", (testme, 1))])
+
+        callLst[:] = []
+        1 * testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rmul__", (testme, 1))])
+
+        if 1/2 == 0:
+            callLst[:] = []
+            testme / 1
+            self.assertCallStack([("__coerce__", (testme, 1)), ("__div__", (testme, 1))])
+
+
+            callLst[:] = []
+            1 / testme
+            self.assertCallStack([("__coerce__", (testme, 1)), ("__rdiv__", (testme, 1))])
+
+        callLst[:] = []
+        testme % 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__mod__", (testme, 1))])
+
+        callLst[:] = []
+        1 % testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rmod__", (testme, 1))])
+
+
+        callLst[:] = []
+        divmod(testme,1)
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__divmod__", (testme, 1))])
+
+        callLst[:] = []
+        divmod(1, testme)
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rdivmod__", (testme, 1))])
+
+        callLst[:] = []
+        testme ** 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__pow__", (testme, 1))])
+
+        callLst[:] = []
+        1 ** testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rpow__", (testme, 1))])
+
+        callLst[:] = []
+        testme >> 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rshift__", (testme, 1))])
+
+        callLst[:] = []
+        1 >> testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rrshift__", (testme, 1))])
+
+        callLst[:] = []
+        testme << 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__lshift__", (testme, 1))])
+
+        callLst[:] = []
+        1 << testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rlshift__", (testme, 1))])
+
+        callLst[:] = []
+        testme & 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__and__", (testme, 1))])
+
+        callLst[:] = []
+        1 & testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rand__", (testme, 1))])
+
+        callLst[:] = []
+        testme | 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__or__", (testme, 1))])
+
+        callLst[:] = []
+        1 | testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__ror__", (testme, 1))])
+
+        callLst[:] = []
+        testme ^ 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__xor__", (testme, 1))])
+
+        callLst[:] = []
+        1 ^ testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rxor__", (testme, 1))])
+
+    def testListAndDictOps(self):
+        testme = AllTests()
+
+        # List/dict operations
+
+        class Empty: pass
+
+        try:
+            1 in Empty()
+            self.fail('failed, should have raised TypeError')
+        except TypeError:
+            pass
+
+        callLst[:] = []
+        1 in testme
+        self.assertCallStack([('__contains__', (testme, 1))])
+
+        callLst[:] = []
+        testme[1]
+        self.assertCallStack([('__getitem__', (testme, 1))])
+
+        callLst[:] = []
+        testme[1] = 1
+        self.assertCallStack([('__setitem__', (testme, 1, 1))])
+
+        callLst[:] = []
+        del testme[1]
+        self.assertCallStack([('__delitem__', (testme, 1))])
+
+        callLst[:] = []
+        testme[:42]
+        self.assertCallStack([('__getslice__', (testme, 0, 42))])
+
+        callLst[:] = []
+        testme[:42] = "The Answer"
+        self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
+
+        callLst[:] = []
+        del testme[:42]
+        self.assertCallStack([('__delslice__', (testme, 0, 42))])
+
+        callLst[:] = []
+        testme[2:1024:10]
+        self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
+
+        callLst[:] = []
+        testme[2:1024:10] = "A lot"
+        self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
+                                                                    "A lot"))])
+        callLst[:] = []
+        del testme[2:1024:10]
+        self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
+
+        callLst[:] = []
+        testme[:42, ..., :24:, 24, 100]
+        self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100)))])
+        callLst[:] = []
+        testme[:42, ..., :24:, 24, 100] = "Strange"
+        self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100), "Strange"))])
+        callLst[:] = []
+        del testme[:42, ..., :24:, 24, 100]
+        self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100)))])
+
+        # Now remove the slice hooks to see if converting normal slices to
+        #  slice object works.
+
+        getslice = AllTests.__getslice__
+        del AllTests.__getslice__
+        setslice = AllTests.__setslice__
+        del AllTests.__setslice__
+        delslice = AllTests.__delslice__
+        del AllTests.__delslice__
+
+        # XXX when using new-style classes the slice testme[:42] produces
+        #  slice(None, 42, None) instead of slice(0, 42, None). py3k will have
+        #  to change this test.
+        callLst[:] = []
+        testme[:42]
+        self.assertCallStack([('__getitem__', (testme, slice(0, 42, None)))])
+
+        callLst[:] = []
+        testme[:42] = "The Answer"
+        self.assertCallStack([('__setitem__', (testme, slice(0, 42, None),
+                                                                "The Answer"))])
+        callLst[:] = []
+        del testme[:42]
+        self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
+
+        # Restore the slice methods, or the tests will fail with regrtest -R.
+        AllTests.__getslice__ = getslice
+        AllTests.__setslice__ = setslice
+        AllTests.__delslice__ = delslice
+
+
+    def testUnaryOps(self):
+        testme = AllTests()
+
+        callLst[:] = []
+        -testme
+        self.assertCallStack([('__neg__', (testme,))])
+        callLst[:] = []
+        +testme
+        self.assertCallStack([('__pos__', (testme,))])
+        callLst[:] = []
+        abs(testme)
+        self.assertCallStack([('__abs__', (testme,))])
+        callLst[:] = []
+        int(testme)
+        self.assertCallStack([('__int__', (testme,))])
+        callLst[:] = []
+        long(testme)
+        self.assertCallStack([('__long__', (testme,))])
+        callLst[:] = []
+        float(testme)
+        self.assertCallStack([('__float__', (testme,))])
+        callLst[:] = []
+        oct(testme)
+        self.assertCallStack([('__oct__', (testme,))])
+        callLst[:] = []
+        hex(testme)
+        self.assertCallStack([('__hex__', (testme,))])
+
+
+    def testMisc(self):
+        testme = AllTests()
+
+        callLst[:] = []
+        hash(testme)
+        self.assertCallStack([('__hash__', (testme,))])
+
+        callLst[:] = []
+        repr(testme)
+        self.assertCallStack([('__repr__', (testme,))])
+
+        callLst[:] = []
+        str(testme)
+        self.assertCallStack([('__str__', (testme,))])
+
+        callLst[:] = []
+        testme == 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme < 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme > 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme <> 1  # XXX kill this in py3k
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme != 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        1 == testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 < testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 > testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 <> testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 != testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+
+    def testGetSetAndDel(self):
+        # Interfering tests
+        class ExtraTests(AllTests):
+            @trackCall
+            def __getattr__(self, *args):
+                return "SomeVal"
+
+            @trackCall
+            def __setattr__(self, *args):
+                pass
+
+            @trackCall
+            def __delattr__(self, *args):
+                pass
+
+        testme = ExtraTests()
+
+        callLst[:] = []
+        testme.spam
+        self.assertCallStack([('__getattr__', (testme, "spam"))])
+
+        callLst[:] = []
+        testme.eggs = "spam, spam, spam and ham"
+        self.assertCallStack([('__setattr__', (testme, "eggs",
+                                               "spam, spam, spam and ham"))])
+
+        callLst[:] = []
+        del testme.cardinal
+        self.assertCallStack([('__delattr__', (testme, "cardinal"))])
+
+    def testDel(self):
+        x = []
+
+        class DelTest:
+            def __del__(self):
+                x.append("crab people, crab people")
+        testme = DelTest()
+        del testme
+        import gc
+        gc.collect()
+        self.assertEquals(["crab people, crab people"], x)
+
+    def testBadTypeReturned(self):
+        # return values of some method are type-checked
+        class BadTypeClass:
+            def __int__(self):
+                return None
+            __float__ = __int__
+            __long__ = __int__
+            __str__ = __int__
+            __repr__ = __int__
+            __oct__ = __int__
+            __hex__ = __int__
+
+        for f in [int, float, long, str, repr, oct, hex]:
+            self.assertRaises(TypeError, f, BadTypeClass())
+
+    def testMixIntsAndLongs(self):
+        # mixing up ints and longs is okay
+        class IntLongMixClass:
+            @trackCall
+            def __int__(self):
+                return 42L
+
+            @trackCall
+            def __long__(self):
+                return 64
+
+        mixIntAndLong = IntLongMixClass()
+
+        callLst[:] = []
+        as_int = int(mixIntAndLong)
+        self.assertEquals(type(as_int), long)
+        self.assertEquals(as_int, 42L)
+        self.assertCallStack([('__int__', (mixIntAndLong,))])
+
+        callLst[:] = []
+        as_long = long(mixIntAndLong)
+        self.assertEquals(type(as_long), int)
+        self.assertEquals(as_long, 64)
+        self.assertCallStack([('__long__', (mixIntAndLong,))])
+
+    def testHashStuff(self):
+        # Test correct errors from hash() on objects with comparisons but
+        #  no __hash__
+
+        class C0:
+            pass
+
+        hash(C0()) # This should work; the next two should raise TypeError
+
+        class C1:
+            def __cmp__(self, other): return 0
+
+        self.assertRaises(TypeError, hash, C1())
+
+        class C2:
+            def __eq__(self, other): return 1
+
+        self.assertRaises(TypeError, hash, C2())
+
+
+    def testSFBug532646(self):
+        # Test for SF bug 532646
+
+        class A:
+            pass
+        A.__call__ = A()
+        a = A()
+
+        try:
+            a() # This should not segfault
+        except RuntimeError:
+            pass
+        else:
+            self.fail("Failed to raise RuntimeError")
+
+    def testForExceptionsRaisedInInstanceGetattr2(self):
+        # Tests for exceptions raised in instance_getattr2().
+
+        def booh(self):
+            raise AttributeError("booh")
+
+        class A:
+            a = property(booh)
+        try:
+            A().a # Raised AttributeError: A instance has no attribute 'a'
+        except AttributeError, x:
+            if str(x) != "booh":
+                self.fail("attribute error for A().a got masked: %s" % x)
+
+        class E:
+            __eq__ = property(booh)
+        E() == E() # In debug mode, caused a C-level assert() to fail
+
+        class I:
+            __init__ = property(booh)
+        try:
+            # In debug mode, printed XXX undetected error and
+            #  raises AttributeError
+            I()
+        except AttributeError, x:
+            pass
+        else:
+            self.fail("attribute error for I.__init__ got masked")
+
+    def testHashComparisonOfMethods(self):
+        # Test comparison and hash of methods
+        class A:
+            def __init__(self, x):
+                self.x = x
+            def f(self):
+                pass
+            def g(self):
+                pass
+            def __eq__(self, other):
+                return self.x == other.x
+            def __hash__(self):
+                return self.x
+        class B(A):
+            pass
+
+        a1 = A(1)
+        a2 = A(2)
+        self.assertEquals(a1.f, a1.f)
+        self.assertNotEquals(a1.f, a2.f)
+        self.assertNotEquals(a1.f, a1.g)
+        self.assertEquals(a1.f, A(1).f)
+        self.assertEquals(hash(a1.f), hash(a1.f))
+        self.assertEquals(hash(a1.f), hash(A(1).f))
+
+        self.assertNotEquals(A.f, a1.f)
+        self.assertNotEquals(A.f, A.g)
+        self.assertEquals(B.f, A.f)
+        self.assertEquals(hash(B.f), hash(A.f))
+
+        # the following triggers a SystemError in 2.4
+        a = A(hash(A.f.im_func)^(-1))
+        hash(a.f)
 
-# Now remove the slice hooks to see if converting normal slices to slice
-# object works.
-
-del AllTests.__getslice__
-del AllTests.__setslice__
-del AllTests.__delslice__
-
-import sys
-if sys.platform[:4] != 'java':
-    testme[:42]
-    testme[:42] = "The Answer"
-    del testme[:42]
-else:
-    # This works under Jython, but the actual slice values are
-    # different.
-    print "__getitem__: (slice(0, 42, None),)"
-    print "__setitem__: (slice(0, 42, None), 'The Answer')"
-    print "__delitem__: (slice(0, 42, None),)"
-
-# Unary operations
-
--testme
-+testme
-abs(testme)
-int(testme)
-long(testme)
-float(testme)
-oct(testme)
-hex(testme)
-
-# And the rest...
-
-hash(testme)
-repr(testme)
-str(testme)
-
-testme == 1
-testme < 1
-testme > 1
-testme <> 1
-testme != 1
-1 == testme
-1 < testme
-1 > testme
-1 <> testme
-1 != testme
-
-# This test has to be last (duh.)
-
-del testme
-if sys.platform[:4] == 'java':
-    import java
-    java.lang.System.gc()
-
-# Interfering tests
-
-class ExtraTests:
-    def __getattr__(self, *args):
-        print "__getattr__:", args
-        return "SomeVal"
-
-    def __setattr__(self, *args):
-        print "__setattr__:", args
-
-    def __delattr__(self, *args):
-        print "__delattr__:", args
-
-testme = ExtraTests()
-testme.spam
-testme.eggs = "spam, spam, spam and ham"
-del testme.cardinal
-
-
-# return values of some method are type-checked
-class BadTypeClass:
-    def __int__(self):
-        return None
-    __float__ = __int__
-    __long__ = __int__
-    __str__ = __int__
-    __repr__ = __int__
-    __oct__ = __int__
-    __hex__ = __int__
-
-def check_exc(stmt, exception):
-    """Raise TestFailed if executing 'stmt' does not raise 'exception'
-    """
-    try:
-        exec stmt
-    except exception:
-        pass
-    else:
-        raise TestFailed, "%s should raise %s" % (stmt, exception)
-
-check_exc("int(BadTypeClass())", TypeError)
-check_exc("float(BadTypeClass())", TypeError)
-check_exc("long(BadTypeClass())", TypeError)
-check_exc("str(BadTypeClass())", TypeError)
-check_exc("repr(BadTypeClass())", TypeError)
-check_exc("oct(BadTypeClass())", TypeError)
-check_exc("hex(BadTypeClass())", TypeError)
-
-# mixing up ints and longs is okay
-class IntLongMixClass:
-    def __int__(self):
-        return 0L
-
-    def __long__(self):
-        return 0
-
-try:
-    int(IntLongMixClass())
-except TypeError:
-    raise TestFailed, "TypeError should not be raised"
-
-try:
-    long(IntLongMixClass())
-except TypeError:
-    raise TestFailed, "TypeError should not be raised"
-
-
-# Test correct errors from hash() on objects with comparisons but no __hash__
-
-class C0:
-    pass
-
-hash(C0()) # This should work; the next two should raise TypeError
-
-class C1:
-    def __cmp__(self, other): return 0
-
-check_exc("hash(C1())", TypeError)
-
-class C2:
-    def __eq__(self, other): return 1
-
-check_exc("hash(C2())", TypeError)
-
-# Test for SF bug 532646
-
-class A:
-    pass
-A.__call__ = A()
-a = A()
-try:
-    a() # This should not segfault
-except RuntimeError:
-    pass
-else:
-    raise TestFailed, "how could this not have overflowed the stack?"
-
-
-# Tests for exceptions raised in instance_getattr2().
-
-def booh(self):
-    raise AttributeError, "booh"
-
-class A:
-    a = property(booh)
-try:
-    A().a # Raised AttributeError: A instance has no attribute 'a'
-except AttributeError, x:
-    if str(x) != "booh":
-        print "attribute error for A().a got masked:", str(x)
-
-class E:
-    __eq__ = property(booh)
-E() == E() # In debug mode, caused a C-level assert() to fail
-
-class I:
-    __init__ = property(booh)
-try:
-    I() # In debug mode, printed XXX undetected error and raises AttributeError
-except AttributeError, x:
-    pass
-else:
-    print "attribute error for I.__init__ got masked"
-
-
-# Test comparison and hash of methods
-class A:
-    def __init__(self, x):
-        self.x = x
-    def f(self):
-        pass
-    def g(self):
-        pass
-    def __eq__(self, other):
-        return self.x == other.x
-    def __hash__(self):
-        return self.x
-class B(A):
-    pass
+def test_main():
+    test_support.run_unittest(ClassTests)
 
-a1 = A(1)
-a2 = A(2)
-assert a1.f == a1.f
-assert a1.f != a2.f
-assert a1.f != a1.g
-assert a1.f == A(1).f
-assert hash(a1.f) == hash(a1.f)
-assert hash(a1.f) == hash(A(1).f)
-
-assert A.f != a1.f
-assert A.f != A.g
-assert B.f == A.f
-assert hash(B.f) == hash(A.f)
-
-# the following triggers a SystemError in 2.4
-a = A(hash(A.f.im_func)^(-1))
-hash(a.f)
+if __name__=='__main__':
+    test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_cmd_line.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_cmd_line.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_cmd_line.py	Thu Sep  6 21:35:45 2007
@@ -3,18 +3,25 @@
 import sys
 import subprocess
 
+def _spawn_python(*args):
+    cmd_line = [sys.executable]
+    cmd_line.extend(args)
+    return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
+                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+def _kill_python(p):
+    p.stdin.close()
+    data = p.stdout.read()
+    p.stdout.close()
+    # try to cleanup the child so we don't appear to leak when running
+    # with regrtest -R.  This should be a no-op on Windows.
+    subprocess._cleanup()
+    return data
+
 class CmdLineTest(unittest.TestCase):
-    def start_python(self, cmd_line):
-        cmd = '"%s" %s' % (sys.executable, cmd_line)
-        p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-        p.stdin.close()
-        data = p.stdout.read()
-        p.stdout.close()
-        # try to cleanup the child so we don't appear to leak when running
-        # with regrtest -R.  This should be a no-op on Windows.
-        subprocess._cleanup()
-        return data
+    def start_python(self, *args):
+        p = _spawn_python(*args)
+        return _kill_python(p)
 
     def exit_code(self, *args):
         cmd_line = [sys.executable]
@@ -72,6 +79,17 @@
             self.exit_code('-m', 'timeit', '-n', '1'),
             0)
 
+    def test_run_module_bug1764407(self):
+        # -m and -i need to play well together
+        # Runs the timeit module and checks the __main__
+        # namespace has been populated appropriately
+        p = _spawn_python('-i', '-m', 'timeit', '-n', '1')
+        p.stdin.write('Timer\n')
+        p.stdin.write('exit()\n')
+        data = _kill_python(p)
+        self.assertTrue(data.startswith('1 loop'))
+        self.assertTrue('__main__.Timer' in data)
+
     def test_run_code(self):
         # Test expected operation of the '-c' switch
         # Switch needs an argument

Modified: python/branches/bcannon-objcap/Lib/test/test_codeccallbacks.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_codeccallbacks.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_codeccallbacks.py	Thu Sep  6 21:35:45 2007
@@ -285,7 +285,8 @@
 
     def test_longstrings(self):
         # test long strings to check for memory overflow problems
-        errors = [ "strict", "ignore", "replace", "xmlcharrefreplace", "backslashreplace"]
+        errors = [ "strict", "ignore", "replace", "xmlcharrefreplace",
+                   "backslashreplace"]
         # register the handlers under different names,
         # to prevent the codec from recognizing the name
         for err in errors:
@@ -293,7 +294,8 @@
         l = 1000
         errors += [ "test." + err for err in errors ]
         for uni in [ s*l for s in (u"x", u"\u3042", u"a\xe4") ]:
-            for enc in ("ascii", "latin-1", "iso-8859-1", "iso-8859-15", "utf-8", "utf-7", "utf-16"):
+            for enc in ("ascii", "latin-1", "iso-8859-1", "iso-8859-15",
+                        "utf-8", "utf-7", "utf-16", "utf-32"):
                 for err in errors:
                     try:
                         uni.encode(enc, err)

Modified: python/branches/bcannon-objcap/Lib/test/test_codecencodings_kr.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_codecencodings_kr.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_codecencodings_kr.py	Thu Sep  6 21:35:45 2007
@@ -30,6 +30,24 @@
         ("abc\x80\x80\xc1\xc4", "replace", u"abc\ufffd\uc894"),
         ("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\uc894\ufffd"),
         ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\uc894"),
+
+        # composed make-up sequence errors
+        ("\xa4\xd4", "strict", None),
+        ("\xa4\xd4\xa4", "strict", None),
+        ("\xa4\xd4\xa4\xb6", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa4", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0\xa4", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4", "strict", u"\uc4d4"),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xd4x", "strict", u"\uc4d4x"),
+        ("a\xa4\xd4\xa4\xb6\xa4", "replace", u"a\ufffd"),
+        ("\xa4\xd4\xa3\xb6\xa4\xd0\xa4\xd4", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa3\xd0\xa4\xd4", "strict", None),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0\xa3\xd4", "strict", None),
+        ("\xa4\xd4\xa4\xff\xa4\xd0\xa4\xd4", "replace", u"\ufffd"),
+        ("\xa4\xd4\xa4\xb6\xa4\xff\xa4\xd4", "replace", u"\ufffd"),
+        ("\xa4\xd4\xa4\xb6\xa4\xd0\xa4\xff", "replace", u"\ufffd"),
+        ("\xc1\xc4", "strict", u"\uc894"),
     )
 
 class Test_JOHAB(test_multibytecodec_support.TestBase, unittest.TestCase):

Modified: python/branches/bcannon-objcap/Lib/test/test_codecmaps_cn.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_codecmaps_cn.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_codecmaps_cn.py	Thu Sep  6 21:35:45 2007
@@ -19,6 +19,13 @@
     mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/' \
                  'MICSFT/WINDOWS/CP936.TXT'
 
+class TestGB18030Map(test_multibytecodec_support.TestBase_Mapping,
+                     unittest.TestCase):
+    encoding = 'gb18030'
+    mapfileurl = 'http://source.icu-project.org/repos/icu/data/' \
+                 'trunk/charset/data/xml/gb-18030-2000.xml'
+
+
 def test_main():
     test_support.run_unittest(__name__)
 

Modified: python/branches/bcannon-objcap/Lib/test/test_codecmaps_kr.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_codecmaps_kr.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_codecmaps_kr.py	Thu Sep  6 21:35:45 2007
@@ -20,6 +20,10 @@
     encoding = 'euc_kr'
     mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-KR.TXT'
 
+    # A4D4 HANGUL FILLER indicates the begin of 8-bytes make-up sequence.
+    pass_enctest = [('\xa4\xd4', u'\u3164')]
+    pass_dectest = [('\xa4\xd4', u'\u3164')]
+
 
 class TestJOHABMap(test_multibytecodec_support.TestBase_Mapping,
                    unittest.TestCase):

Modified: python/branches/bcannon-objcap/Lib/test/test_codecs.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_codecs.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_codecs.py	Thu Sep  6 21:35:45 2007
@@ -244,6 +244,137 @@
         self.assertEqual(reader.readline(), s5)
         self.assertEqual(reader.readline(), u"")
 
+class UTF32Test(ReadTest):
+    encoding = "utf-32"
+
+    spamle = ('\xff\xfe\x00\x00'
+              's\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m\x00\x00\x00'
+              's\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m\x00\x00\x00')
+    spambe = ('\x00\x00\xfe\xff'
+              '\x00\x00\x00s\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m'
+              '\x00\x00\x00s\x00\x00\x00p\x00\x00\x00a\x00\x00\x00m')
+
+    def test_only_one_bom(self):
+        _,_,reader,writer = codecs.lookup(self.encoding)
+        # encode some stream
+        s = StringIO.StringIO()
+        f = writer(s)
+        f.write(u"spam")
+        f.write(u"spam")
+        d = s.getvalue()
+        # check whether there is exactly one BOM in it
+        self.assert_(d == self.spamle or d == self.spambe)
+        # try to read it back
+        s = StringIO.StringIO(d)
+        f = reader(s)
+        self.assertEquals(f.read(), u"spamspam")
+
+    def test_badbom(self):
+        s = StringIO.StringIO(4*"\xff")
+        f = codecs.getreader(self.encoding)(s)
+        self.assertRaises(UnicodeError, f.read)
+
+        s = StringIO.StringIO(8*"\xff")
+        f = codecs.getreader(self.encoding)(s)
+        self.assertRaises(UnicodeError, f.read)
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"", # first byte of BOM read
+                u"", # second byte of BOM read
+                u"", # third byte of BOM read
+                u"", # fourth byte of BOM read => byteorder known
+                u"",
+                u"",
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_32_decode,
+                          "\xff", "strict", True)
+
+class UTF32LETest(ReadTest):
+    encoding = "utf-32-le"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"",
+                u"",
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_simple(self):
+        self.assertEqual(u"\U00010203".encode(self.encoding), "\x03\x02\x01\x00")
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode,
+                          "\xff", "strict", True)
+
+class UTF32BETest(ReadTest):
+    encoding = "utf-32-be"
+
+    def test_partial(self):
+        self.check_partial(
+            u"\x00\xff\u0100\uffff",
+            [
+                u"",
+                u"",
+                u"",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100",
+                u"\x00\xff\u0100\uffff",
+            ]
+        )
+
+    def test_simple(self):
+        self.assertEqual(u"\U00010203".encode(self.encoding), "\x00\x01\x02\x03")
+
+    def test_errors(self):
+        self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode,
+                          "\xff", "strict", True)
+
 class UTF16Test(ReadTest):
     encoding = "utf-16"
 
@@ -1278,6 +1409,9 @@
 
 def test_main():
     test_support.run_unittest(
+        UTF32Test,
+        UTF32LETest,
+        UTF32BETest,
         UTF16Test,
         UTF16LETest,
         UTF16BETest,

Modified: python/branches/bcannon-objcap/Lib/test/test_compiler.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_compiler.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_compiler.py	Thu Sep  6 21:35:45 2007
@@ -155,6 +155,32 @@
         self.assertEquals(dct.get('result'), 1)
 
 
+    def _testErrEnc(self, src, text, offset):
+        try:
+            compile(src, "", "exec")
+        except SyntaxError, e:
+            self.assertEquals(e.offset, offset)
+            self.assertEquals(e.text, text)
+
+    def testSourceCodeEncodingsError(self):
+        # Test SyntaxError with encoding definition
+        sjis = "print '\x83\x70\x83\x43\x83\x5c\x83\x93', '\n"
+        ascii = "print '12345678', '\n"
+        encdef = "#! -*- coding: ShiftJIS -*-\n"
+
+        # ascii source without encdef
+        self._testErrEnc(ascii, ascii, 19)
+
+        # ascii source with encdef
+        self._testErrEnc(encdef+ascii, ascii, 19)
+
+        # non-ascii source with encdef
+        self._testErrEnc(encdef+sjis, sjis, 19)
+
+        # ShiftJIS source without encdef
+        self._testErrEnc(sjis, sjis, 19)
+
+
 NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
 
 ###############################################################################

Modified: python/branches/bcannon-objcap/Lib/test/test_datetime.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_datetime.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_datetime.py	Thu Sep  6 21:35:45 2007
@@ -989,7 +989,7 @@
         self.failUnless(self.theclass.min)
         self.failUnless(self.theclass.max)
 
-    def test_srftime_out_of_range(self):
+    def test_strftime_out_of_range(self):
         # For nasty technical reasons, we can't handle years before 1900.
         cls = self.theclass
         self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")

Modified: python/branches/bcannon-objcap/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_exceptions.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_exceptions.py	Thu Sep  6 21:35:45 2007
@@ -6,7 +6,7 @@
 import pickle, cPickle
 
 from test.test_support import (TESTFN, unlink, run_unittest,
-                                guard_warnings_filter)
+                                catch_warning)
 from test.test_pep352 import ignore_message_warning
 
 # XXX This is not really enough, each *operation* should be tested!
@@ -274,7 +274,7 @@
         except NameError:
             pass
 
-        with guard_warnings_filter():
+        with catch_warning():
             ignore_message_warning()
             for exc, args, expected in exceptionList:
                 try:

Modified: python/branches/bcannon-objcap/Lib/test/test_float.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_float.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_float.py	Thu Sep  6 21:35:45 2007
@@ -81,6 +81,7 @@
 # on an IEEE platform, all we guarantee is that bit patterns
 # representing infinities or NaNs do not raise an exception; all else
 # is accident (today).
+# let's also try to guarantee that -0.0 and 0.0 don't get confused.
 
 class IEEEFormatTestCase(unittest.TestCase):
     if float.__getformat__("double").startswith("IEEE"):
@@ -99,6 +100,20 @@
                               ('<f', LE_FLOAT_NAN)]:
                 struct.unpack(fmt, data)
 
+    if float.__getformat__("double").startswith("IEEE"):
+        def test_negative_zero(self):
+            import math
+            def pos_pos():
+                return 0.0, math.atan2(0.0, -1)
+            def pos_neg():
+                return 0.0, math.atan2(-0.0, -1)
+            def neg_pos():
+                return -0.0, math.atan2(0.0, -1)
+            def neg_neg():
+                return -0.0, math.atan2(-0.0, -1)
+            self.assertEquals(pos_pos(), neg_pos())
+            self.assertEquals(pos_neg(), neg_neg())
+
 
 def test_main():
     test_support.run_unittest(

Modified: python/branches/bcannon-objcap/Lib/test/test_format.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_format.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_format.py	Thu Sep  6 21:35:45 2007
@@ -9,6 +9,7 @@
 # test on unicode strings as well
 
 overflowok = 1
+overflowrequired = 0
 
 def testformat(formatstr, args, output=None):
     if verbose:
@@ -25,11 +26,16 @@
         if verbose:
             print 'overflow (this is fine)'
     else:
-        if output and result != output:
+        if overflowrequired:
             if verbose:
                 print 'no'
-            print "%s %% %s == %s != %s" %\
-                (repr(formatstr), repr(args), repr(result), repr(output))
+            print "overflow expected on %s %% %s" % \
+                  (repr(formatstr), repr(args))
+        elif output and result != output:
+            if verbose:
+                print 'no'
+            print "%s %% %s == %s != %s" % \
+                  (repr(formatstr), repr(args), repr(result), repr(output))
         else:
             if verbose:
                 print 'yes'
@@ -57,6 +63,14 @@
 # test some ridiculously large precision, expect overflow
 testboth('%12.*f', (123456, 1.0))
 
+# check for internal overflow validation on length of precision
+overflowrequired = 1
+testboth("%#.*g", (110, -1.e+100/3.))
+testboth("%#.*G", (110, -1.e+100/3.))
+testboth("%#.*f", (110, -1.e+100/3.))
+testboth("%#.*F", (110, -1.e+100/3.))
+overflowrequired = 0
+
 # Formatting of long integers. Overflow is not ok
 overflowok = 0
 testboth("%x", 10L, "a")

Modified: python/branches/bcannon-objcap/Lib/test/test_frozen.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_frozen.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_frozen.py	Thu Sep  6 21:35:45 2007
@@ -1,27 +1,40 @@
 # Test the frozen module defined in frozen.c.
+from __future__ import with_statement
 
-from test.test_support import TestFailed
+from test.test_support import captured_stdout, run_unittest
+import unittest
 import sys, os
 
-try:
-    import __hello__
-except ImportError, x:
-    raise TestFailed, "import __hello__ failed:" + str(x)
-
-try:
-    import __phello__
-except ImportError, x:
-    raise TestFailed, "import __phello__ failed:" + str(x)
-
-try:
-    import __phello__.spam
-except ImportError, x:
-    raise TestFailed, "import __phello__.spam failed:" + str(x)
-
-if sys.platform != "mac":  # On the Mac this import does succeed.
-    try:
-        import __phello__.foo
-    except ImportError:
-        pass
-    else:
-        raise TestFailed, "import __phello__.foo should have failed"
+class FrozenTests(unittest.TestCase):
+    def test_frozen(self):
+
+        with captured_stdout() as stdout:
+            try:
+                import __hello__
+            except ImportError, x:
+                self.fail("import __hello__ failed:" + str(x))
+
+            try:
+                import __phello__
+            except ImportError, x:
+                self.fail("import __phello__ failed:" + str(x))
+
+            try:
+                import __phello__.spam
+            except ImportError, x:
+                self.fail("import __phello__.spam failed:" + str(x))
+
+            if sys.platform != "mac":  # On the Mac this import does succeed.
+                try:
+                    import __phello__.foo
+                except ImportError:
+                    pass
+                else:
+                    self.fail("import __phello__.foo should have failed")
+
+        self.assertEquals(stdout.getvalue(),
+                          'Hello world...\nHello world...\nHello world...\n')
+
+
+def test_main():
+    run_unittest(FrozenTests)

Modified: python/branches/bcannon-objcap/Lib/test/test_httplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_httplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_httplib.py	Thu Sep  6 21:35:45 2007
@@ -199,8 +199,9 @@
 
     def test_attributes(self):
         # simple test to check it's storing it
-        h = httplib.HTTPSConnection(HOST, PORT, timeout=30)
-        self.assertEqual(h.timeout, 30)
+        if hasattr(httplib, 'HTTPSConnection'):
+            h = httplib.HTTPSConnection(HOST, PORT, timeout=30)
+            self.assertEqual(h.timeout, 30)
 
 def test_main(verbose=None):
     test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, HTTPSTimeoutTest)

Modified: python/branches/bcannon-objcap/Lib/test/test_import.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_import.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_import.py	Thu Sep  6 21:35:45 2007
@@ -1,4 +1,4 @@
-from test.test_support import TESTFN, run_unittest, guard_warnings_filter
+from test.test_support import TESTFN, run_unittest, catch_warning
 
 import unittest
 import os
@@ -215,7 +215,7 @@
         self.assert_(y is test.test_support, y.__name__)
 
     def test_import_initless_directory_warning(self):
-        with guard_warnings_filter():
+        with catch_warning():
             # Just a random non-package directory we always expect to be
             # somewhere in sys.path...
             warnings.simplefilter('error', ImportWarning)

Modified: python/branches/bcannon-objcap/Lib/test/test_linuxaudiodev.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_linuxaudiodev.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_linuxaudiodev.py	Thu Sep  6 21:35:45 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 findfile, TestSkipped, run_unittest
 
 import errno
 import fcntl
@@ -12,81 +12,91 @@
 import sunaudio
 import time
 import audioop
+import unittest
 
 SND_FORMAT_MULAW_8 = 1
 
-def play_sound_file(path):
-    fp = open(path, 'r')
-    size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
-    data = fp.read()
-    fp.close()
-
-    if enc != SND_FORMAT_MULAW_8:
-        print "Expect .au file with 8-bit mu-law samples"
-        return
+class LinuxAudioDevTests(unittest.TestCase):
 
+    def setUp(self):
+        self.dev = linuxaudiodev.open('w')
+
+    def tearDown(self):
+        self.dev.close()
+
+    def test_methods(self):
+        # at least check that these methods can be invoked
+        self.dev.bufsize()
+        self.dev.obufcount()
+        self.dev.obuffree()
+        self.dev.getptr()
+        self.dev.fileno()
+
+    def test_play_sound_file(self):
+        path = findfile("audiotest.au")
+        fp = open(path, 'r')
+        size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
+        data = fp.read()
+        fp.close()
+
+        if enc != SND_FORMAT_MULAW_8:
+            self.fail("Expect .au file with 8-bit mu-law samples")
+
+        # convert the data to 16-bit signed
+        data = audioop.ulaw2lin(data, 2)
+
+        # set the data format
+        if sys.byteorder == 'little':
+            fmt = linuxaudiodev.AFMT_S16_LE
+        else:
+            fmt = linuxaudiodev.AFMT_S16_BE
+
+        # set parameters based on .au file headers
+        self.dev.setparameters(rate, 16, nchannels, fmt)
+        self.dev.write(data)
+        self.dev.flush()
+
+    def test_errors(self):
+        size = 8
+        fmt = linuxaudiodev.AFMT_U8
+        rate = 8000
+        nchannels = 1
+        try:
+            self.dev.setparameters(-1, size, nchannels, fmt)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "expected rate >= 0, not -1")
+        try:
+            self.dev.setparameters(rate, -2, nchannels, fmt)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "expected sample size >= 0, not -2")
+        try:
+            self.dev.setparameters(rate, size, 3, fmt)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "nchannels must be 1 or 2, not 3")
+        try:
+            self.dev.setparameters(rate, size, nchannels, 177)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "unknown audio encoding: 177")
+        try:
+            self.dev.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "for linear unsigned 16-bit little-endian "
+                              "audio, expected sample size 16, not 8")
+        try:
+            self.dev.setparameters(rate, 16, nchannels, fmt)
+        except ValueError, err:
+            self.assertEquals(err.args[0], "for linear unsigned 8-bit audio, expected "
+                              "sample size 8, not 16")
+
+def test_main():
     try:
-        a = linuxaudiodev.open('w')
+        dsp = linuxaudiodev.open('w')
     except linuxaudiodev.error, msg:
-        if msg[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
-            raise TestSkipped, msg
-        raise TestFailed, msg
-
-    # convert the data to 16-bit signed
-    data = audioop.ulaw2lin(data, 2)
-
-    # set the data format
-    if sys.byteorder == 'little':
-        fmt = linuxaudiodev.AFMT_S16_LE
-    else:
-        fmt = linuxaudiodev.AFMT_S16_BE
-
-    # at least check that these methods can be invoked
-    a.bufsize()
-    a.obufcount()
-    a.obuffree()
-    a.getptr()
-    a.fileno()
-
-    # set parameters based on .au file headers
-    a.setparameters(rate, 16, nchannels, fmt)
-    a.write(data)
-    a.flush()
-    a.close()
-
-def test_errors():
-    a = linuxaudiodev.open("w")
-    size = 8
-    fmt = linuxaudiodev.AFMT_U8
-    rate = 8000
-    nchannels = 1
-    try:
-        a.setparameters(-1, size, nchannels, fmt)
-    except ValueError, msg:
-        print msg
-    try:
-        a.setparameters(rate, -2, nchannels, fmt)
-    except ValueError, msg:
-        print msg
-    try:
-        a.setparameters(rate, size, 3, fmt)
-    except ValueError, msg:
-        print msg
-    try:
-        a.setparameters(rate, size, nchannels, 177)
-    except ValueError, msg:
-        print msg
-    try:
-        a.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
-    except ValueError, msg:
-        print msg
-    try:
-        a.setparameters(rate, 16, nchannels, fmt)
-    except ValueError, msg:
-        print msg
-
-def test():
-    play_sound_file(findfile('audiotest.au'))
-    test_errors()
+        if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
+            raise TestSkipped(msg)
+        raise
+    dsp.close()
+    run_unittest(LinuxAudioDevTests)
 
-test()
+if __name__ == '__main__':
+    test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_macostools.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_macostools.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_macostools.py	Thu Sep  6 21:35:45 2007
@@ -52,7 +52,7 @@
     def test_touched(self):
         # This really only tests that nothing unforeseen happens.
         import warnings
-        with test_support.guard_warnings_filter():
+        with test_support.catch_warning():
             warnings.filterwarnings('ignore', 'macostools.touched*',
                                     DeprecationWarning)
             macostools.touched(test_support.TESTFN)

Modified: python/branches/bcannon-objcap/Lib/test/test_mailbox.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_mailbox.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_mailbox.py	Thu Sep  6 21:35:45 2007
@@ -686,7 +686,18 @@
         folder1_alias = box.get_folder('folder1')
         self.assert_(folder1_alias._factory is dummy_factory)
 
-
+    def test_directory_in_folder (self):
+        # Test that mailboxes still work if there's a stray extra directory
+        # in a folder.
+        for i in range(10):
+            self._box.add(mailbox.Message(_sample_message))
+
+        # Create a stray directory
+        os.mkdir(os.path.join(self._path, 'cur', 'stray-dir'))
+
+        # Check that looping still works with the directory present.
+        for msg in self._box:
+            pass
 
 class _TestMboxMMDF(TestMailbox):
 

Modified: python/branches/bcannon-objcap/Lib/test/test_math.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_math.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_math.py	Thu Sep  6 21:35:45 2007
@@ -12,7 +12,11 @@
 
     def ftest(self, name, value, expected):
         if abs(value-expected) > eps:
-            self.fail('%s returned %f, expected %f'%\
+            # Use %r instead of %f so the error message
+            # displays full precision. Otherwise discrepancies
+            # in the last few bits will lead to very confusing
+            # error messages
+            self.fail('%s returned %r, expected %r' %
                       (name, value, expected))
 
     def testConstants(self):
@@ -92,6 +96,10 @@
         self.ftest('floor(-0.5)', math.floor(-0.5), -1)
         self.ftest('floor(-1.0)', math.floor(-1.0), -1)
         self.ftest('floor(-1.5)', math.floor(-1.5), -2)
+        # pow() relies on floor() to check for integers
+        # This fails on some platforms - so check it here
+        self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
+        self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
 
     def testFmod(self):
         self.assertRaises(TypeError, math.fmod)

Modified: python/branches/bcannon-objcap/Lib/test/test_mmap.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_mmap.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_mmap.py	Thu Sep  6 21:35:45 2007
@@ -306,6 +306,40 @@
             m[x] = ch = chr(x & 255)
             self.assertEqual(m[x], ch)
 
+    def test_extended_getslice(self):
+        # Test extended slicing by comparing with list slicing.
+        s = "".join(chr(c) for c in reversed(range(256)))
+        m = mmap.mmap(-1, len(s))
+        m[:] = s
+        self.assertEqual(m[:], s)
+        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+        for start in indices:
+            for stop in indices:
+                # Skip step 0 (invalid)
+                for step in indices[1:]:
+                    self.assertEqual(m[start:stop:step],
+                                     s[start:stop:step])
+
+    def test_extended_set_del_slice(self):
+        # Test extended slicing by comparing with list slicing.
+        s = "".join(chr(c) for c in reversed(range(256)))
+        m = mmap.mmap(-1, len(s))
+        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+        for start in indices:
+            for stop in indices:
+                # Skip invalid step 0
+                for step in indices[1:]:
+                    m[:] = s
+                    self.assertEqual(m[:], s)
+                    L = list(s)
+                    # Make sure we have a slice of exactly the right length,
+                    # but with different data.
+                    data = L[start:stop:step]
+                    data = "".join(reversed(data))
+                    L[start:stop:step] = data
+                    m[start:stop:step] = data
+                    self.assertEquals(m[:], "".join(L))
+
 def test_main():
     run_unittest(MmapTests)
 

Modified: python/branches/bcannon-objcap/Lib/test/test_multibytecodec_support.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_multibytecodec_support.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_multibytecodec_support.py	Thu Sep  6 21:35:45 2007
@@ -5,7 +5,7 @@
 #
 
 import sys, codecs, os.path
-import unittest
+import unittest, re
 from test import test_support
 from StringIO import StringIO
 
@@ -272,6 +272,12 @@
         return test_support.open_urlresource(self.mapfileurl)
 
     def test_mapping_file(self):
+        if self.mapfileurl.endswith('.xml'):
+            self._test_mapping_file_ucm()
+        else:
+            self._test_mapping_file_plain()
+
+    def _test_mapping_file_plain(self):
         unichrs = lambda s: u''.join(map(unichr, map(eval, s.split('+'))))
         urt_wa = {}
 
@@ -303,6 +309,14 @@
 
             self._testpoint(csetch, unich)
 
+    def _test_mapping_file_ucm(self):
+        ucmdata = self.open_mapping_file().read()
+        uc = re.findall('<a u="([A-F0-9]{4})" b="([0-9A-F ]+)"/>', ucmdata)
+        for uni, coded in uc:
+            unich = unichr(int(uni, 16))
+            codech = ''.join(chr(int(c, 16)) for c in coded.split())
+            self._testpoint(codech, unich)
+
     def test_mapping_supplemental(self):
         for mapping in self.supmaps:
             self._testpoint(*mapping)

Modified: python/branches/bcannon-objcap/Lib/test/test_os.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_os.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_os.py	Thu Sep  6 21:35:45 2007
@@ -235,10 +235,20 @@
     # Restrict test to Win32, since there is no guarantee other
     # systems support centiseconds
     if sys.platform == 'win32':
-        def test_1565150(self):
-            t1 = 1159195039.25
-            os.utime(self.fname, (t1, t1))
-            self.assertEquals(os.stat(self.fname).st_mtime, t1)
+        def get_file_system(path):
+            import os
+            root = os.path.splitdrive(os.path.realpath("."))[0] + '\\'
+            import ctypes
+            kernel32 = ctypes.windll.kernel32
+            buf = ctypes.create_string_buffer("", 100)
+            if kernel32.GetVolumeInformationA(root, None, 0, None, None, None, buf, len(buf)):
+                return buf.value
+
+        if get_file_system(test_support.TESTFN) == "NTFS":
+            def test_1565150(self):
+                t1 = 1159195039.25
+                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

Modified: python/branches/bcannon-objcap/Lib/test/test_ossaudiodev.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_ossaudiodev.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_ossaudiodev.py	Thu Sep  6 21:35:45 2007
@@ -76,8 +76,7 @@
 
         # 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)
+        self.assertEquals("%.2f" % expected_time, "2.93")
         t1 = time.time()
         dsp.write(data)
         dsp.close()
@@ -119,7 +118,6 @@
                          "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
@@ -164,10 +162,11 @@
 def test_main():
     try:
         dsp = ossaudiodev.open('w')
-    except IOError, msg:
+    except (ossaudiodev.error, IOError), msg:
         if msg[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
             raise TestSkipped(msg)
         raise
+    dsp.close()
     test_support.run_unittest(__name__)
 
 if __name__ == "__main__":

Modified: python/branches/bcannon-objcap/Lib/test/test_parser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_parser.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_parser.py	Thu Sep  6 21:35:45 2007
@@ -474,6 +474,12 @@
         st = parser.suite('1 = 3 + 4')
         self.assertRaises(SyntaxError, parser.compilest, st)
 
+    def test_compile_badunicode(self):
+        st = parser.suite('a = u"\U12345678"')
+        self.assertRaises(SyntaxError, parser.compilest, st)
+        st = parser.suite('a = u"\u1"')
+        self.assertRaises(SyntaxError, parser.compilest, st)
+
 def test_main():
     test_support.run_unittest(
         RoundtripLegalSyntaxTestCase,

Modified: python/branches/bcannon-objcap/Lib/test/test_pep352.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_pep352.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_pep352.py	Thu Sep  6 21:35:45 2007
@@ -2,7 +2,7 @@
 import __builtin__
 import exceptions
 import warnings
-from test.test_support import run_unittest, guard_warnings_filter
+from test.test_support import run_unittest, catch_warning
 import os
 from platform import system as platform_system
 
@@ -22,7 +22,7 @@
         self.failUnless(issubclass(Exception, object))
 
     def verify_instance_interface(self, ins):
-        with guard_warnings_filter():
+        with catch_warning():
             ignore_message_warning()
             for attr in ("args", "message", "__str__", "__repr__",
                             "__getitem__"):
@@ -95,7 +95,7 @@
         # Make sure interface works properly when given a single argument
         arg = "spam"
         exc = Exception(arg)
-        with guard_warnings_filter():
+        with catch_warning():
             ignore_message_warning()
             results = ([len(exc.args), 1], [exc.args[0], arg],
                     [exc.message, arg],
@@ -109,7 +109,7 @@
         arg_count = 3
         args = tuple(range(arg_count))
         exc = Exception(*args)
-        with guard_warnings_filter():
+        with catch_warning():
             ignore_message_warning()
             results = ([len(exc.args), arg_count], [exc.args, args],
                     [exc.message, ''], [str(exc), str(args)],
@@ -121,7 +121,7 @@
     def test_interface_no_arg(self):
         # Make sure that with no args that interface is correct
         exc = Exception()
-        with guard_warnings_filter():
+        with catch_warning():
             ignore_message_warning()
             results = ([len(exc.args), 0], [exc.args, tuple()],
                     [exc.message, ''],
@@ -132,7 +132,7 @@
 
     def test_message_deprecation(self):
         # As of Python 2.6, BaseException.message is deprecated.
-        with guard_warnings_filter():
+        with catch_warning():
             warnings.resetwarnings()
             warnings.filterwarnings('error')
 
@@ -219,7 +219,7 @@
 
     def test_catch_string(self):
         # Catching a string should trigger a DeprecationWarning.
-        with guard_warnings_filter():
+        with catch_warning():
             warnings.resetwarnings()
             warnings.filterwarnings("error")
             str_exc = "spam"

Modified: python/branches/bcannon-objcap/Lib/test/test_pkg.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_pkg.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_pkg.py	Thu Sep  6 21:35:45 2007
@@ -1,33 +1,15 @@
 # Test packages (dotted-name import)
 
-import sys, os, tempfile, traceback
-from os import mkdir, rmdir, extsep          # Can't test if these fail
-del mkdir, rmdir
-from test.test_support import verify, verbose, TestFailed
+import sys
+import os
+import tempfile
+import textwrap
+import traceback
+import unittest
+from test import test_support
 
-# Helpers to create and destroy hierarchies.
 
-def mkhier(root, descr):
-    if not os.path.isdir(root):
-        mkdir(root)
-    for name, contents in descr:
-        comps = name.split()
-        fullname = root
-        for c in comps:
-            fullname = os.path.join(fullname, c)
-        if contents is None:
-            mkdir(fullname)
-        else:
-            if verbose: print "write", fullname
-            f = open(fullname, "w")
-            f.write(contents)
-            if contents and contents[-1] != '\n':
-                f.write('\n')
-            f.close()
-
-def mkdir(x):
-    if verbose: print "mkdir", x
-    os.mkdir(x)
+# Helpers to create and destroy hierarchies.
 
 def cleanout(root):
     names = os.listdir(root)
@@ -37,223 +19,252 @@
             cleanout(fullname)
         else:
             os.remove(fullname)
-    rmdir(root)
-
-def rmdir(x):
-    if verbose: print "rmdir", x
-    os.rmdir(x)
+    os.rmdir(root)
 
 def fixdir(lst):
-    try:
-        lst.remove('__builtins__')
-    except ValueError:
-        pass
+    if "__builtins__" in lst:
+        lst.remove("__builtins__")
     return lst
 
-# Helper to run a test
 
-def runtest(hier, code):
-    root = tempfile.mkdtemp()
-    mkhier(root, hier)
-    savepath = sys.path[:]
-    fd, fname = tempfile.mkstemp(text=True)
-    os.write(fd, code)
-    os.close(fd)
-    try:
+# XXX Things to test
+#
+# import package without __init__
+# import package with __init__
+# __init__ importing submodule
+# __init__ importing global module
+# __init__ defining variables
+# submodule importing other submodule
+# submodule importing global module
+# submodule import submodule via global name
+# from package import submodule
+# from package import subpackage
+# from package import variable (defined in __init__)
+# from package import * (defined in __init__)
+
+
+class Test(unittest.TestCase):
+
+    def setUp(self):
+        self.root = None
+        self.syspath = list(sys.path)
+
+    def tearDown(self):
+        sys.path[:] = self.syspath
+        cleanout(self.root)
+
+    def run_code(self, code):
+        exec(textwrap.dedent(code), globals(), {"self": self})
+
+    def mkhier(self, descr):
+        root = tempfile.mkdtemp()
         sys.path.insert(0, root)
-        if verbose: print "sys.path =", sys.path
-        try:
-            execfile(fname, globals(), {})
-        except:
-            traceback.print_exc(file=sys.stdout)
-    finally:
-        sys.path[:] = savepath
-        os.unlink(fname)
-        try:
-            cleanout(root)
-        except (os.error, IOError):
-            pass
-
-# Test descriptions
-
-tests = [
-    ("t1", [("t1", None), ("t1 __init__"+os.extsep+"py", "")], "import t1"),
-
-    ("t2", [
-    ("t2", None),
-    ("t2 __init__"+os.extsep+"py", "'doc for t2'; print __name__, 'loading'"),
-    ("t2 sub", None),
-    ("t2 sub __init__"+os.extsep+"py", ""),
-    ("t2 sub subsub", None),
-    ("t2 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
-    ],
-"""
-import t2
-print t2.__doc__
-import t2.sub
-import t2.sub.subsub
-print t2.__name__, t2.sub.__name__, t2.sub.subsub.__name__
-import t2
-from t2 import *
-print dir()
-from t2 import sub
-from t2.sub import subsub
-from t2.sub.subsub import spam
-print sub.__name__, subsub.__name__
-print sub.subsub.__name__
-print dir()
-import t2.sub
-import t2.sub.subsub
-print t2.__name__, t2.sub.__name__, t2.sub.subsub.__name__
-from t2 import *
-print dir()
-"""),
-
-    ("t3", [
-    ("t3", None),
-    ("t3 __init__"+os.extsep+"py", "print __name__, 'loading'"),
-    ("t3 sub", None),
-    ("t3 sub __init__"+os.extsep+"py", ""),
-    ("t3 sub subsub", None),
-    ("t3 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
-    ],
-"""
-import t3.sub.subsub
-print t3.__name__, t3.sub.__name__, t3.sub.subsub.__name__
-reload(t3)
-reload(t3.sub)
-reload(t3.sub.subsub)
-"""),
-
-    ("t4", [
-    ("t4"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (t4"+os.extsep+"py)'"),
-    ("t4", None),
-    ("t4 __init__"+os.extsep+"py", "print __name__, 'loading'"),
-    ("t4 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"),
-    ("t4 sub", None),
-    ("t4 sub __init__"+os.extsep+"py", ""),
-    ("t4 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"),
-    ("t4 sub subsub", None),
-    ("t4 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
-    ],
-"""
-from t4.sub.subsub import *
-print "t4.sub.subsub.spam =", spam
-"""),
-
-    ("t5", [
-    ("t5", None),
-    ("t5 __init__"+os.extsep+"py", "import t5.foo"),
-    ("t5 string"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
-    ("t5 foo"+os.extsep+"py",
-     "print __name__, 'loading'; import string; print string.spam"),
-     ],
-"""
-import t5
-from t5 import *
-print dir()
-import t5
-print fixdir(dir(t5))
-print fixdir(dir(t5.foo))
-print fixdir(dir(t5.string))
-"""),
-
-    ("t6", [
-    ("t6", None),
-    ("t6 __init__"+os.extsep+"py", "__all__ = ['spam', 'ham', 'eggs']"),
-    ("t6 spam"+os.extsep+"py", "print __name__, 'loading'"),
-    ("t6 ham"+os.extsep+"py", "print __name__, 'loading'"),
-    ("t6 eggs"+os.extsep+"py", "print __name__, 'loading'"),
-    ],
-"""
-import t6
-print fixdir(dir(t6))
-from t6 import *
-print fixdir(dir(t6))
-print dir()
-"""),
-
-    ("t7", [
-    ("t7"+os.extsep+"py", "print 'Importing t7"+os.extsep+"py'"),
-    ("t7", None),
-    ("t7 __init__"+os.extsep+"py", "print __name__, 'loading'"),
-    ("t7 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"),
-    ("t7 sub", None),
-    ("t7 sub __init__"+os.extsep+"py", ""),
-    ("t7 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"),
-    ("t7 sub subsub", None),
-    ("t7 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"),
-    ],
-"""
-t7, sub, subsub = None, None, None
-import t7 as tas
-print fixdir(dir(tas))
-verify(not t7)
-from t7 import sub as subpar
-print fixdir(dir(subpar))
-verify(not t7 and not sub)
-from t7.sub import subsub as subsubsub
-print fixdir(dir(subsubsub))
-verify(not t7 and not sub and not subsub)
-from t7.sub.subsub import spam as ham
-print "t7.sub.subsub.spam =", ham
-verify(not t7 and not sub and not subsub)
-"""),
-
-]
-
-nontests = [
-    ("x5", [], ("import a" + ".a"*400)),
-    ("x6", [], ("import a" + ".a"*499)),
-    ("x7", [], ("import a" + ".a"*500)),
-    ("x8", [], ("import a" + ".a"*1100)),
-    ("x9", [], ("import " + "a"*400)),
-    ("x10", [], ("import " + "a"*500)),
-    ("x11", [], ("import " + "a"*998)),
-    ("x12", [], ("import " + "a"*999)),
-    ("x13", [], ("import " + "a"*999)),
-    ("x14", [], ("import " + "a"*2000)),
-]
-
-"""XXX Things to test
-
-import package without __init__
-import package with __init__
-__init__ importing submodule
-__init__ importing global module
-__init__ defining variables
-submodule importing other submodule
-submodule importing global module
-submodule import submodule via global name
-from package import submodule
-from package import subpackage
-from package import variable (defined in __init__)
-from package import * (defined in __init__)
-"""
-
-# Run the tests
-
-args = []
-if __name__ == '__main__':
-    args = sys.argv[1:]
-    if args and args[0] == '-q':
-        verbose = 0
-        del args[0]
-
-for name, hier, code in tests:
-    if args and name not in args:
-        print "skipping test", name
-        continue
-    print "running test", name
-    runtest(hier, code)
+        if not os.path.isdir(root):
+            os.mkdir(root)
+        for name, contents in descr:
+            comps = name.split()
+            fullname = root
+            for c in comps:
+                fullname = os.path.join(fullname, c)
+            if contents is None:
+                os.mkdir(fullname)
+            else:
+                f = open(fullname, "w")
+                f.write(contents)
+                if contents and contents[-1] != '\n':
+                    f.write('\n')
+                f.close()
+        self.root = root
+
+    def test_1(self):
+        hier = [("t1", None), ("t1 __init__"+os.extsep+"py", "")]
+        self.mkhier(hier)
+        import t1
+
+    def test_2(self):
+        hier = [
+         ("t2", None),
+         ("t2 __init__"+os.extsep+"py", "'doc for t2'"),
+         ("t2 sub", None),
+         ("t2 sub __init__"+os.extsep+"py", ""),
+         ("t2 sub subsub", None),
+         ("t2 sub subsub __init__"+os.extsep+"py", "spam = 1"),
+        ]
+        self.mkhier(hier)
+
+        import t2
+        self.assertEqual(t2.__doc__, "doc for t2")
+
+        import t2.sub
+        import t2.sub.subsub
+        self.assertEqual(t2.__name__, "t2")
+        self.assertEqual(t2.sub.__name__, "t2.sub")
+        self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
+
+        # This exec crap is needed because Py3k forbids 'import *' outside
+        # of module-scope and __import__() is insufficient for what we need.
+        s = """
+            import t2
+            from t2 import *
+            self.assertEqual(dir(), ['self', 'sub', 't2'])
+            """
+        self.run_code(s)
+
+        from t2 import sub
+        from t2.sub import subsub
+        from t2.sub.subsub import spam
+        self.assertEqual(sub.__name__, "t2.sub")
+        self.assertEqual(subsub.__name__, "t2.sub.subsub")
+        self.assertEqual(sub.subsub.__name__, "t2.sub.subsub")
+        for name in ['spam', 'sub', 'subsub', 't2']:
+            self.failUnless(locals()["name"], "Failed to import %s" % name)
+
+        import t2.sub
+        import t2.sub.subsub
+        self.assertEqual(t2.__name__, "t2")
+        self.assertEqual(t2.sub.__name__, "t2.sub")
+        self.assertEqual(t2.sub.subsub.__name__, "t2.sub.subsub")
+
+        s = """
+            from t2 import *
+            self.failUnless(dir(), ['self', 'sub'])
+            """
+        self.run_code(s)
+
+    def test_3(self):
+        hier = [
+                ("t3", None),
+                ("t3 __init__"+os.extsep+"py", ""),
+                ("t3 sub", None),
+                ("t3 sub __init__"+os.extsep+"py", ""),
+                ("t3 sub subsub", None),
+                ("t3 sub subsub __init__"+os.extsep+"py", "spam = 1"),
+               ]
+        self.mkhier(hier)
+
+        import t3.sub.subsub
+        self.assertEqual(t3.__name__, "t3")
+        self.assertEqual(t3.sub.__name__, "t3.sub")
+        self.assertEqual(t3.sub.subsub.__name__, "t3.sub.subsub")
+
+    def test_4(self):
+        hier = [
+        ("t4.py", "raise RuntimeError('Shouldnt load t4.py')"),
+        ("t4", None),
+        ("t4 __init__"+os.extsep+"py", ""),
+        ("t4 sub.py", "raise RuntimeError('Shouldnt load sub.py')"),
+        ("t4 sub", None),
+        ("t4 sub __init__"+os.extsep+"py", ""),
+        ("t4 sub subsub"+os.extsep+"py",
+         "raise RuntimeError('Shouldnt load subsub.py')"),
+        ("t4 sub subsub", None),
+        ("t4 sub subsub __init__"+os.extsep+"py", "spam = 1"),
+               ]
+        self.mkhier(hier)
+
+        s = """
+            from t4.sub.subsub import *
+            self.assertEqual(spam, 1)
+            """
+        self.run_code(s)
+
+    def test_5(self):
+        hier = [
+        ("t5", None),
+        ("t5 __init__"+os.extsep+"py", "import t5.foo"),
+        ("t5 string"+os.extsep+"py", "spam = 1"),
+        ("t5 foo"+os.extsep+"py",
+         "from . import string; assert string.spam == 1"),
+         ]
+        self.mkhier(hier)
+
+        import t5
+        s = """
+            from t5 import *
+            self.assertEqual(dir(), ['foo', 'self', 'string', 't5'])
+            """
+        self.run_code(s)
+
+        import t5
+        self.assertEqual(fixdir(dir(t5)),
+                         ['__doc__', '__file__', '__name__',
+                          '__path__', 'foo', 'string', 't5'])
+        self.assertEqual(fixdir(dir(t5.foo)),
+                         ['__doc__', '__file__', '__name__', 'string'])
+        self.assertEqual(fixdir(dir(t5.string)),
+                         ['__doc__', '__file__', '__name__', 'spam'])
+
+    def test_6(self):
+        hier = [
+                ("t6", None),
+                ("t6 __init__"+os.extsep+"py",
+                 "__all__ = ['spam', 'ham', 'eggs']"),
+                ("t6 spam"+os.extsep+"py", ""),
+                ("t6 ham"+os.extsep+"py", ""),
+                ("t6 eggs"+os.extsep+"py", ""),
+               ]
+        self.mkhier(hier)
+
+        import t6
+        self.assertEqual(fixdir(dir(t6)),
+                         ['__all__', '__doc__', '__file__',
+                          '__name__', '__path__'])
+        s = """
+            import t6
+            from t6 import *
+            self.assertEqual(fixdir(dir(t6)),
+                             ['__all__', '__doc__', '__file__',
+                              '__name__', '__path__', 'eggs',
+                              'ham', 'spam'])
+            self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6'])
+            """
+        self.run_code(s)
+
+    def test_7(self):
+        hier = [
+                ("t7"+os.extsep+"py", ""),
+                ("t7", None),
+                ("t7 __init__"+os.extsep+"py", ""),
+                ("t7 sub"+os.extsep+"py",
+                 "raise RuntimeError('Shouldnt load sub.py')"),
+                ("t7 sub", None),
+                ("t7 sub __init__"+os.extsep+"py", ""),
+                ("t7 sub "+os.extsep+"py",
+                 "raise RuntimeError('Shouldnt load subsub.py')"),
+                ("t7 sub subsub", None),
+                ("t7 sub subsub __init__"+os.extsep+"py",
+                 "spam = 1"),
+               ]
+        self.mkhier(hier)
+
+
+        t7, sub, subsub = None, None, None
+        import t7 as tas
+        self.assertEqual(fixdir(dir(tas)),
+                         ['__doc__', '__file__', '__name__', '__path__'])
+        self.failIf(t7)
+        from t7 import sub as subpar
+        self.assertEqual(fixdir(dir(subpar)),
+                         ['__doc__', '__file__', '__name__', '__path__'])
+        self.failIf(t7)
+        self.failIf(sub)
+        from t7.sub import subsub as subsubsub
+        self.assertEqual(fixdir(dir(subsubsub)),
+                         ['__doc__', '__file__', '__name__', '__path__',
+                          'spam'])
+        self.failIf(t7)
+        self.failIf(sub)
+        self.failIf(subsub)
+        from t7.sub.subsub import spam as ham
+        self.assertEqual(ham, 1)
+        self.failIf(t7)
+        self.failIf(sub)
+        self.failIf(subsub)
 
-# Test
-import sys
-import imp
-try:
-    import sys.imp
-except ImportError:
-    # This is what we expect
-    pass
-else:
-    raise TestFailed, "No ImportError exception on 'import sys.imp'"
+
+def test_main():
+    test_support.run_unittest(__name__)
+
+
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_pow.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_pow.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_pow.py	Thu Sep  6 21:35:45 2007
@@ -106,6 +106,9 @@
         # platform pow() was buggy, and Python didn't worm around it.
         eq = self.assertEquals
         a = -1.0
+        # The next two tests can still fail if the platform floor()
+        # function doesn't treat all large inputs as integers
+        # test_math should also fail if that is happening
         eq(pow(a, 1.23e167), 1.0)
         eq(pow(a, -1.23e167), 1.0)
         for b in range(-10, 11):

Modified: python/branches/bcannon-objcap/Lib/test/test_random.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_random.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_random.py	Thu Sep  6 21:35:45 2007
@@ -178,7 +178,7 @@
 
     def test_bigrand(self):
         # Verify warnings are raised when randrange is too large for random()
-        with test_support.guard_warnings_filter():
+        with test_support.catch_warning():
             warnings.filterwarnings("error", "Underlying random")
             self.assertRaises(UserWarning, self.gen.randrange, 2**60)
 

Modified: python/branches/bcannon-objcap/Lib/test/test_re.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_re.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_re.py	Thu Sep  6 21:35:45 2007
@@ -1,7 +1,7 @@
 import sys
 sys.path = ['.'] + sys.path
 
-from test.test_support import verbose, run_unittest, guard_warnings_filter
+from test.test_support import verbose, run_unittest, catch_warning
 import re
 from re import Scanner
 import sys, os, traceback
@@ -416,7 +416,7 @@
         self.pickle_test(cPickle)
         # old pickles expect the _compile() reconstructor in sre module
         import warnings
-        with guard_warnings_filter():
+        with catch_warning():
             warnings.filterwarnings("ignore", "The sre module is deprecated",
                                     DeprecationWarning)
             from sre import _compile

Modified: python/branches/bcannon-objcap/Lib/test/test_resource.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_resource.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_resource.py	Thu Sep  6 21:35:45 2007
@@ -49,17 +49,24 @@
                 except ValueError:
                     limit_set = False
                 f = open(test_support.TESTFN, "wb")
-                f.write("X" * 1024)
                 try:
-                    f.write("Y")
-                    f.flush()
-                except IOError:
-                    if not limit_set:
-                        raise
-                f.close()
-                os.unlink(test_support.TESTFN)
+                    f.write("X" * 1024)
+                    try:
+                        f.write("Y")
+                        f.flush()
+                    except IOError:
+                        if not limit_set:
+                            raise
+                    if limit_set:
+                        # Close will attempt to flush the byte we wrote
+                        # Restore limit first to avoid getting a spurious error
+                        resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+                finally:
+                    f.close()
+                    os.unlink(test_support.TESTFN)
             finally:
-                resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
+                if limit_set:
+                    resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
 
     def test_fsize_toobig(self):
         # Be sure that setrlimit is checking for really large values

Modified: python/branches/bcannon-objcap/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_robotparser.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_robotparser.py	Thu Sep  6 21:35:45 2007
@@ -134,8 +134,19 @@
 
 RobotTest(7, doc, good, bad)
 
+class TestCase(unittest.TestCase):
+    def runTest(self):
+        test_support.requires('network')
+        # whole site is password-protected.
+        url = 'http://mueblesmoraleda.com'
+        parser = robotparser.RobotFileParser()
+        parser.set_url(url)
+        parser.read()
+        self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
+
 def test_main():
     test_support.run_unittest(tests)
+    TestCase().run()
 
 if __name__=='__main__':
     test_support.Verbose = 1

Modified: python/branches/bcannon-objcap/Lib/test/test_runpy.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_runpy.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_runpy.py	Thu Sep  6 21:35:45 2007
@@ -4,8 +4,8 @@
 import os.path
 import sys
 import tempfile
-from test.test_support import verbose, run_unittest
-from runpy import _run_module_code, run_module
+from test.test_support import verbose, run_unittest, forget
+from runpy import _run_code, _run_module_code, _run_module_as_main, run_module
 
 # Set up the test code and expected results
 
@@ -21,14 +21,24 @@
         "# Check the sys module\n"
         "import sys\n"
         "run_argv0 = sys.argv[0]\n"
-        "if __name__ in sys.modules:\n"
-        "    run_name = sys.modules[__name__].__name__\n"
+        "run_name_in_sys_modules = __name__ in sys.modules\n"
+        "if run_name_in_sys_modules:\n"
+        "   module_in_sys_modules = globals() is sys.modules[__name__].__dict__\n"
         "# Check nested operation\n"
         "import runpy\n"
-        "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
-        "                                          alter_sys=True)\n"
+        "nested = runpy._run_module_code('x=1\\n', mod_name='<run>')\n"
     )
 
+    def test_run_code(self):
+        saved_argv0 = sys.argv[0]
+        d = _run_code(self.test_source, {})
+        self.failUnless(d["result"] == self.expected_result)
+        self.failUnless(d["__name__"] is None)
+        self.failUnless(d["__file__"] is None)
+        self.failUnless(d["__loader__"] is None)
+        self.failUnless(d["run_argv0"] is saved_argv0)
+        self.failUnless("run_name" not in d)
+        self.failUnless(sys.argv[0] is saved_argv0)
 
     def test_run_module_code(self):
         initial = object()
@@ -41,30 +51,20 @@
                               d1,
                               name,
                               file,
-                              loader,
-                              True)
+                              loader)
         self.failUnless("result" not in d1)
         self.failUnless(d2["initial"] is initial)
         self.failUnless(d2["result"] == self.expected_result)
         self.failUnless(d2["nested"]["x"] == 1)
         self.failUnless(d2["__name__"] is name)
-        self.failUnless(d2["run_name"] is name)
+        self.failUnless(d2["run_name_in_sys_modules"])
+        self.failUnless(d2["module_in_sys_modules"])
         self.failUnless(d2["__file__"] is file)
         self.failUnless(d2["run_argv0"] is file)
         self.failUnless(d2["__loader__"] is loader)
         self.failUnless(sys.argv[0] is saved_argv0)
         self.failUnless(name not in sys.modules)
 
-    def test_run_module_code_defaults(self):
-        saved_argv0 = sys.argv[0]
-        d = _run_module_code(self.test_source)
-        self.failUnless(d["result"] == self.expected_result)
-        self.failUnless(d["__name__"] is None)
-        self.failUnless(d["__file__"] is None)
-        self.failUnless(d["__loader__"] is None)
-        self.failUnless(d["run_argv0"] is saved_argv0)
-        self.failUnless("run_name" not in d)
-        self.failUnless(sys.argv[0] is saved_argv0)
 
 class RunModuleTest(unittest.TestCase):
 
@@ -77,19 +77,29 @@
             self.fail("Expected import error for " + mod_name)
 
     def test_invalid_names(self):
+        # Builtin module
         self.expect_import_error("sys")
+        # Non-existent modules
         self.expect_import_error("sys.imp.eric")
         self.expect_import_error("os.path.half")
         self.expect_import_error("a.bee")
         self.expect_import_error(".howard")
         self.expect_import_error("..eaten")
+        # Package
+        self.expect_import_error("logging")
 
     def test_library_module(self):
         run_module("runpy")
 
+    def _add_pkg_dir(self, pkg_dir):
+        os.mkdir(pkg_dir)
+        pkg_fname = os.path.join(pkg_dir, "__init__"+os.extsep+"py")
+        pkg_file = open(pkg_fname, "w")
+        pkg_file.close()
+        return pkg_fname
+
     def _make_pkg(self, source, depth):
         pkg_name = "__runpy_pkg__"
-        init_fname = "__init__"+os.extsep+"py"
         test_fname = "runpy_test"+os.extsep+"py"
         pkg_dir = sub_dir = tempfile.mkdtemp()
         if verbose: print "  Package tree in:", sub_dir
@@ -97,11 +107,8 @@
         if verbose: print "  Updated sys.path:", sys.path[0]
         for i in range(depth):
             sub_dir = os.path.join(sub_dir, pkg_name)
-            os.mkdir(sub_dir)
+            pkg_fname = self._add_pkg_dir(sub_dir)
             if verbose: print "  Next level in:", sub_dir
-            pkg_fname = os.path.join(sub_dir, init_fname)
-            pkg_file = open(pkg_fname, "w")
-            pkg_file.close()
             if verbose: print "  Created:", pkg_fname
         mod_fname = os.path.join(sub_dir, test_fname)
         mod_file = open(mod_fname, "w")
@@ -112,13 +119,9 @@
         return pkg_dir, mod_fname, mod_name
 
     def _del_pkg(self, top, depth, mod_name):
-        for i in range(depth+1): # Don't forget the module itself
-            parts = mod_name.rsplit(".", i)
-            entry = parts[0]
-            try:
+        for entry in list(sys.modules):
+            if entry.startswith("__runpy_pkg__"):
                 del sys.modules[entry]
-            except KeyError, ex:
-                if verbose: print ex # Persist with cleaning up
         if verbose: print "  Removed sys.modules entries"
         del sys.path[0]
         if verbose: print "  Removed sys.path entry"
@@ -143,26 +146,85 @@
     def _check_module(self, depth):
         pkg_dir, mod_fname, mod_name = (
                self._make_pkg("x=1\n", depth))
+        forget(mod_name)
         try:
             if verbose: print "Running from source:", mod_name
             d1 = run_module(mod_name) # Read from source
+            self.failUnless("x" in d1)
             self.failUnless(d1["x"] == 1)
             del d1 # Ensure __loader__ entry doesn't keep file open
             __import__(mod_name)
             os.remove(mod_fname)
             if verbose: print "Running from compiled:", mod_name
             d2 = run_module(mod_name) # Read from bytecode
+            self.failUnless("x" in d2)
             self.failUnless(d2["x"] == 1)
             del d2 # Ensure __loader__ entry doesn't keep file open
         finally:
             self._del_pkg(pkg_dir, depth, mod_name)
         if verbose: print "Module executed successfully"
 
+    def _add_relative_modules(self, base_dir, depth):
+        if depth <= 1:
+            raise ValueError("Relative module test needs depth > 1")
+        pkg_name = "__runpy_pkg__"
+        module_dir = base_dir
+        for i in range(depth):
+            parent_dir = module_dir
+            module_dir = os.path.join(module_dir, pkg_name)
+        # Add sibling module
+        sibling_fname = os.path.join(module_dir, "sibling"+os.extsep+"py")
+        sibling_file = open(sibling_fname, "w")
+        sibling_file.close()
+        if verbose: print "  Added sibling module:", sibling_fname
+        # Add nephew module
+        uncle_dir = os.path.join(parent_dir, "uncle")
+        self._add_pkg_dir(uncle_dir)
+        if verbose: print "  Added uncle package:", uncle_dir
+        cousin_dir = os.path.join(uncle_dir, "cousin")
+        self._add_pkg_dir(cousin_dir)
+        if verbose: print "  Added cousin package:", cousin_dir
+        nephew_fname = os.path.join(cousin_dir, "nephew"+os.extsep+"py")
+        nephew_file = open(nephew_fname, "w")
+        nephew_file.close()
+        if verbose: print "  Added nephew module:", nephew_fname
+
+    def _check_relative_imports(self, depth, run_name=None):
+        contents = """\
+from __future__ import absolute_import
+from . import sibling
+from ..uncle.cousin import nephew
+"""
+        pkg_dir, mod_fname, mod_name = (
+               self._make_pkg(contents, depth))
+        try:
+            self._add_relative_modules(pkg_dir, depth)
+            if verbose: print "Running from source:", mod_name
+            d1 = run_module(mod_name) # Read from source
+            self.failUnless("sibling" in d1)
+            self.failUnless("nephew" in d1)
+            del d1 # Ensure __loader__ entry doesn't keep file open
+            __import__(mod_name)
+            os.remove(mod_fname)
+            if verbose: print "Running from compiled:", mod_name
+            d2 = run_module(mod_name) # Read from bytecode
+            self.failUnless("sibling" in d2)
+            self.failUnless("nephew" in d2)
+            del d2 # Ensure __loader__ entry doesn't keep file open
+        finally:
+            self._del_pkg(pkg_dir, depth, mod_name)
+        if verbose: print "Module executed successfully"
+
     def test_run_module(self):
         for depth in range(4):
             if verbose: print "Testing package depth:", depth
             self._check_module(depth)
 
+    def test_explicit_relative_import(self):
+        for depth in range(2, 5):
+            if verbose: print "Testing relative imports at depth:", depth
+            self._check_relative_imports(depth)
+
 
 def test_main():
     run_unittest(RunModuleCodeTest)

Modified: python/branches/bcannon-objcap/Lib/test/test_signal.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_signal.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_signal.py	Thu Sep  6 21:35:45 2007
@@ -1,167 +1,177 @@
-# Test the signal module
-from test.test_support import verbose, TestSkipped, TestFailed, vereq
+import unittest
+from test import test_support
 import signal
 import os, sys, time
 
-if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos':
-    raise TestSkipped, "Can't test signal on %s" % sys.platform
+class HandlerBCalled(Exception):
+    pass
 
-MAX_DURATION = 20   # Entire test should last at most 20 sec.
+class InterProcessSignalTests(unittest.TestCase):
+    MAX_DURATION = 20   # Entire test should last at most 20 sec.
 
-if verbose:
-    x = '-x'
-else:
-    x = '+x'
-
-pid = os.getpid()
-if verbose:
-    print "test runner's pid is", pid
-
-# Shell script that will send us asynchronous signals
-script = """
- (
-        set %(x)s
-        sleep 2
-        kill -HUP %(pid)d
-        sleep 2
-        kill -USR1 %(pid)d
-        sleep 2
-        kill -USR2 %(pid)d
- ) &
-""" % vars()
-
-a_called = b_called = False
-
-def handlerA(*args):
-    global a_called
-    a_called = True
-    if verbose:
-        print "handlerA invoked", args
+    # Set up a child to send signals to us (the parent) after waiting
+    # long enough to receive the alarm.  It seems we miss the alarm
+    # for some reason.  This will hopefully stop the hangs on
+    # Tru64/Alpha.  Alas, it doesn't.  Tru64 appears to miss all the
+    # signals at times, or seemingly random subsets of them, and
+    # nothing done in force_test_exit so far has actually helped.
+    def spawn_force_test_exit_process(self, parent_pid):
+        # Sigh, both imports seem necessary to avoid errors.
+        import os
+        fork_pid = os.fork()
+        if fork_pid:
+            # In parent.
+            return fork_pid
+
+        # In child.
+        import os, time
+        try:
+            # Wait 5 seconds longer than the expected alarm to give enough
+            # time for the normal sequence of events to occur.  This is
+            # just a stop-gap to try to prevent the test from hanging.
+            time.sleep(self.MAX_DURATION + 5)
+            print >> sys.__stdout__, "  child should not have to kill parent"
+            for signame in "SIGHUP", "SIGUSR1", "SIGUSR2", "SIGALRM":
+                os.kill(parent_pid, getattr(signal, signame))
+                print >> sys.__stdout__, "    child sent", signame, "to", \
+                      parent_pid
+                time.sleep(1)
+        finally:
+            os._exit(0)
+
+    def handlerA(self, *args):
+        self.a_called = True
+        if test_support.verbose:
+            print "handlerA invoked", args
+
+    def handlerB(self, *args):
+        self.b_called = True
+        if test_support.verbose:
+            print "handlerB invoked", args
+        raise HandlerBCalled(*args)
+
+    def test_main(self):
+        self.assertEquals(signal.getsignal(signal.SIGHUP), self.handlerA)
+        self.assertEquals(signal.getsignal(signal.SIGUSR1), self.handlerB)
+        self.assertEquals(signal.getsignal(signal.SIGUSR2), signal.SIG_IGN)
+        self.assertEquals(signal.getsignal(signal.SIGALRM),
+                          signal.default_int_handler)
+
+        # Launch an external script to send us signals.
+        # We expect the external script to:
+        #    send HUP, which invokes handlerA to set a_called
+        #    send USR1, which invokes handlerB to set b_called and raise
+        #               HandlerBCalled
+        #    send USR2, which is ignored
+        #
+        # Then we expect the alarm to go off, and its handler raises
+        # KeyboardInterrupt, finally getting us out of the loop.
+
+        if test_support.verbose:
+            verboseflag = '-x'
+        else:
+            verboseflag = '+x'
+
+        pid = self.pid
+        if test_support.verbose:
+            print "test runner's pid is", pid
+
+        # Shell script that will send us asynchronous signals
+        script = """
+         (
+                set %(verboseflag)s
+                sleep 2
+                kill -HUP %(pid)d
+                sleep 2
+                kill -USR1 %(pid)d
+                sleep 2
+                kill -USR2 %(pid)d
+         ) &
+        """ % vars()
+
+        signal.alarm(self.MAX_DURATION)
+
+        handler_b_exception_raised = False
+
+        os.system(script)
+        try:
+            if test_support.verbose:
+                print "starting pause() loop..."
+            while 1:
+                try:
+                    if test_support.verbose:
+                        print "call pause()..."
+                    signal.pause()
+                    if test_support.verbose:
+                        print "pause() returned"
+                except HandlerBCalled:
+                    handler_b_exception_raised = True
+                    if test_support.verbose:
+                        print "HandlerBCalled exception caught"
+
+        except KeyboardInterrupt:
+            if test_support.verbose:
+                print "KeyboardInterrupt (the alarm() went off)"
+
+        self.assert_(self.a_called)
+        self.assert_(self.b_called)
+        self.assert_(handler_b_exception_raised)
+
+    def setUp(self):
+        # Install handlers.
+        self.hup = signal.signal(signal.SIGHUP, self.handlerA)
+        self.usr1 = signal.signal(signal.SIGUSR1, self.handlerB)
+        self.usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN)
+        self.alrm = signal.signal(signal.SIGALRM,
+                                  signal.default_int_handler)
+        self.a_called = False
+        self.b_called = False
+        self.pid = os.getpid()
+        self.fork_pid = self.spawn_force_test_exit_process(self.pid)
+
+    def tearDown(self):
+        # Forcibly kill the child we created to ping us if there was a
+        # test error.
+        try:
+            # Make sure we don't kill ourself if there was a fork
+            # error.
+            if self.fork_pid > 0:
+                os.kill(self.fork_pid, signal.SIGKILL)
+        except:
+            # If the child killed us, it has probably exited.  Killing
+            # a non-existent process will raise an error which we
+            # don't care about.
+            pass
+
+        # Restore handlers.
+        signal.alarm(0) # cancel alarm in case we died early
+        signal.signal(signal.SIGHUP, self.hup)
+        signal.signal(signal.SIGUSR1, self.usr1)
+        signal.signal(signal.SIGUSR2, self.usr2)
+        signal.signal(signal.SIGALRM, self.alrm)
+
+
+class BasicSignalTests(unittest.TestCase):
+    def test_out_of_range_signal_number_raises_error(self):
+        self.assertRaises(ValueError, signal.getsignal, 4242)
+
+        def trivial_signal_handler(*args):
+            pass
+
+        self.assertRaises(ValueError, signal.signal, 4242,
+                          trivial_signal_handler)
+
+    def test_setting_signal_handler_to_none_raises_error(self):
+        self.assertRaises(TypeError, signal.signal,
+                          signal.SIGUSR1, None)
+
+def test_main():
+    if sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos':
+        raise test_support.TestSkipped("Can't test signal on %s" % \
+                                       sys.platform)
+
+    test_support.run_unittest(BasicSignalTests, InterProcessSignalTests)
 
-class HandlerBCalled(Exception):
-    pass
 
-def handlerB(*args):
-    global b_called
-    b_called = True
-    if verbose:
-        print "handlerB invoked", args
-    raise HandlerBCalled, args
-
-# Set up a child to send signals to us (the parent) after waiting long
-# enough to receive the alarm.  It seems we miss the alarm for some
-# reason.  This will hopefully stop the hangs on Tru64/Alpha.
-# Alas, it doesn't.  Tru64 appears to miss all the signals at times, or
-# seemingly random subsets of them, and nothing done in force_test_exit
-# so far has actually helped.
-def force_test_exit():
-    # Sigh, both imports seem necessary to avoid errors.
-    import os
-    fork_pid = os.fork()
-    if fork_pid:
-        # In parent.
-        return fork_pid
-
-    # In child.
-    import os, time
-    try:
-        # Wait 5 seconds longer than the expected alarm to give enough
-        # time for the normal sequence of events to occur.  This is
-        # just a stop-gap to try to prevent the test from hanging.
-        time.sleep(MAX_DURATION + 5)
-        print >> sys.__stdout__, '  child should not have to kill parent'
-        for signame in "SIGHUP", "SIGUSR1", "SIGUSR2", "SIGALRM":
-            os.kill(pid, getattr(signal, signame))
-            print >> sys.__stdout__, "    child sent", signame, "to", pid
-            time.sleep(1)
-    finally:
-        os._exit(0)
-
-# Install handlers.
-hup = signal.signal(signal.SIGHUP, handlerA)
-usr1 = signal.signal(signal.SIGUSR1, handlerB)
-usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN)
-alrm = signal.signal(signal.SIGALRM, signal.default_int_handler)
-
-try:
-
-    signal.alarm(MAX_DURATION)
-    vereq(signal.getsignal(signal.SIGHUP), handlerA)
-    vereq(signal.getsignal(signal.SIGUSR1), handlerB)
-    vereq(signal.getsignal(signal.SIGUSR2), signal.SIG_IGN)
-    vereq(signal.getsignal(signal.SIGALRM), signal.default_int_handler)
-
-    # Try to ensure this test exits even if there is some problem with alarm.
-    # Tru64/Alpha often hangs and is ultimately killed by the buildbot.
-    fork_pid = force_test_exit()
-
-    try:
-        signal.getsignal(4242)
-        raise TestFailed('expected ValueError for invalid signal # to '
-                         'getsignal()')
-    except ValueError:
-        pass
-
-    try:
-        signal.signal(4242, handlerB)
-        raise TestFailed('expected ValueError for invalid signal # to '
-                         'signal()')
-    except ValueError:
-        pass
-
-    try:
-        signal.signal(signal.SIGUSR1, None)
-        raise TestFailed('expected TypeError for non-callable')
-    except TypeError:
-        pass
-
-    # Launch an external script to send us signals.
-    # We expect the external script to:
-    #    send HUP, which invokes handlerA to set a_called
-    #    send USR1, which invokes handlerB to set b_called and raise
-    #               HandlerBCalled
-    #    send USR2, which is ignored
-    #
-    # Then we expect the alarm to go off, and its handler raises
-    # KeyboardInterrupt, finally getting us out of the loop.
-    os.system(script)
-    try:
-        print "starting pause() loop..."
-        while 1:
-            try:
-                if verbose:
-                    print "call pause()..."
-                signal.pause()
-                if verbose:
-                    print "pause() returned"
-            except HandlerBCalled:
-                if verbose:
-                    print "HandlerBCalled exception caught"
-
-    except KeyboardInterrupt:
-        if verbose:
-            print "KeyboardInterrupt (the alarm() went off)"
-
-    if not a_called:
-        print 'HandlerA not called'
-
-    if not b_called:
-        print 'HandlerB not called'
-
-finally:
-    # Forcibly kill the child we created to ping us if there was a test error.
-    try:
-        # Make sure we don't kill ourself if there was a fork error.
-        if fork_pid > 0:
-            os.kill(fork_pid, signal.SIGKILL)
-    except:
-        # If the child killed us, it has probably exited.  Killing a
-        # non-existent process will raise an error which we don't care about.
-        pass
-
-    # Restore handlers.
-    signal.alarm(0) # cancel alarm in case we died early
-    signal.signal(signal.SIGHUP, hup)
-    signal.signal(signal.SIGUSR1, usr1)
-    signal.signal(signal.SIGUSR2, usr2)
-    signal.signal(signal.SIGALRM, alrm)
+if __name__ == "__main__":
+    test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_smtplib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_smtplib.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_smtplib.py	Thu Sep  6 21:35:45 2007
@@ -1,53 +1,112 @@
+import asyncore
+import email.utils
 import socket
 import threading
+import smtpd
 import smtplib
+import StringIO
+import sys
 import time
+import select
 
 from unittest import TestCase
 from test import test_support
 
+# PORT is used to communicate the port number assigned to the server
+# to the test client
+HOST = "localhost"
+PORT = None
 
-def server(evt):
-    serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    serv.settimeout(3)
-    serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-    serv.bind(("", 9091))
-    serv.listen(5)
+def server(evt, buf):
     try:
+        serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        serv.settimeout(3)
+        serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        serv.bind(("", 0))
+        global PORT
+        PORT = serv.getsockname()[1]
+        serv.listen(5)
         conn, addr = serv.accept()
     except socket.timeout:
         pass
     else:
-        conn.send("220 Hola mundo\n")
+        n = 500
+        while buf and n > 0:
+            r, w, e = select.select([], [conn], [])
+            if w:
+                sent = conn.send(buf)
+                buf = buf[sent:]
+
+            n -= 1
+            time.sleep(0.01)
+
         conn.close()
     finally:
         serv.close()
+        PORT = None
         evt.set()
 
 class GeneralTests(TestCase):
 
     def setUp(self):
         self.evt = threading.Event()
-        threading.Thread(target=server, args=(self.evt,)).start()
-        time.sleep(.1)
+        servargs = (self.evt, "220 Hola mundo\n")
+        threading.Thread(target=server, args=servargs).start()
+
+        # wait until server thread has assigned a port number
+        n = 500
+        while PORT is None and n > 0:
+            time.sleep(0.01)
+            n -= 1
+
+        # wait a little longer (sometimes connections are refused
+        # on slow machines without this additional wait)
+        time.sleep(0.5)
 
     def tearDown(self):
         self.evt.wait()
 
-    def testBasic(self):
+    def testBasic1(self):
         # connects
-        smtp = smtplib.SMTP("localhost", 9091)
+        smtp = smtplib.SMTP(HOST, PORT)
+        smtp.sock.close()
+
+    def testBasic2(self):
+        # connects, include port in host name
+        smtp = smtplib.SMTP("%s:%s" % (HOST, PORT))
         smtp.sock.close()
 
+    def testNotConnected(self):
+        # Test various operations on an unconnected SMTP object that
+        # should raise exceptions (at present the attempt in SMTP.send
+        # to reference the nonexistent 'sock' attribute of the SMTP object
+        # causes an AttributeError)
+        smtp = smtplib.SMTP()
+        self.assertRaises(AttributeError, smtp.ehlo)
+        self.assertRaises(AttributeError, smtp.send, 'test msg')
+
+    def testLocalHostName(self):
+        # check that supplied local_hostname is used
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname="testhost")
+        self.assertEqual(smtp.local_hostname, "testhost")
+        smtp.sock.close()
+
+    def testNonnumericPort(self):
+        # check that non-numeric port raises socket.error
+        self.assertRaises(socket.error, smtplib.SMTP,
+                          "localhost", "bogus")
+        self.assertRaises(socket.error, smtplib.SMTP,
+                          "localhost:bogus")
+
     def testTimeoutDefault(self):
         # default
-        smtp = smtplib.SMTP("localhost", 9091)
+        smtp = smtplib.SMTP(HOST, PORT)
         self.assertTrue(smtp.sock.gettimeout() is None)
         smtp.sock.close()
 
     def testTimeoutValue(self):
         # a value
-        smtp = smtplib.SMTP("localhost", 9091, timeout=30)
+        smtp = smtplib.SMTP(HOST, PORT, timeout=30)
         self.assertEqual(smtp.sock.gettimeout(), 30)
         smtp.sock.close()
 
@@ -56,16 +115,318 @@
         previous = socket.getdefaulttimeout()
         socket.setdefaulttimeout(30)
         try:
-            smtp = smtplib.SMTP("localhost", 9091, timeout=None)
+            smtp = smtplib.SMTP(HOST, PORT, timeout=None)
         finally:
             socket.setdefaulttimeout(previous)
         self.assertEqual(smtp.sock.gettimeout(), 30)
         smtp.sock.close()
 
 
+# Test server thread using the specified SMTP server class
+def debugging_server(server_class, serv_evt, client_evt):
+    serv = server_class(("", 0), ('nowhere', -1))
+    global PORT
+    PORT = serv.getsockname()[1]
+
+    try:
+        if hasattr(select, 'poll'):
+            poll_fun = asyncore.poll2
+        else:
+            poll_fun = asyncore.poll
+
+        n = 1000
+        while asyncore.socket_map and n > 0:
+            poll_fun(0.01, asyncore.socket_map)
+
+            # when the client conversation is finished, it will
+            # set client_evt, and it's then ok to kill the server
+            if client_evt.isSet():
+                serv.close()
+                break
+
+            n -= 1
+
+    except socket.timeout:
+        pass
+    finally:
+        # allow some time for the client to read the result
+        time.sleep(0.5)
+        serv.close()
+        asyncore.close_all()
+        PORT = None
+        time.sleep(0.5)
+        serv_evt.set()
+
+MSG_BEGIN = '---------- MESSAGE FOLLOWS ----------\n'
+MSG_END = '------------ END MESSAGE ------------\n'
+
+# NOTE: Some SMTP objects in the tests below are created with a non-default
+# local_hostname argument to the constructor, since (on some systems) the FQDN
+# lookup caused by the default local_hostname sometimes takes so long that the
+# test server times out, causing the test to fail.
+
+# Test behavior of smtpd.DebuggingServer
+class DebuggingServerTests(TestCase):
+
+    def setUp(self):
+        # temporarily replace sys.stdout to capture DebuggingServer output
+        self.old_stdout = sys.stdout
+        self.output = StringIO.StringIO()
+        sys.stdout = self.output
+
+        self.serv_evt = threading.Event()
+        self.client_evt = threading.Event()
+        serv_args = (smtpd.DebuggingServer, self.serv_evt, self.client_evt)
+        threading.Thread(target=debugging_server, args=serv_args).start()
+
+        # wait until server thread has assigned a port number
+        n = 500
+        while PORT is None and n > 0:
+            time.sleep(0.01)
+            n -= 1
+
+        # wait a little longer (sometimes connections are refused
+        # on slow machines without this additional wait)
+        time.sleep(0.5)
+
+    def tearDown(self):
+        # indicate that the client is finished
+        self.client_evt.set()
+        # wait for the server thread to terminate
+        self.serv_evt.wait()
+        # restore sys.stdout
+        sys.stdout = self.old_stdout
+
+    def testBasic(self):
+        # connect
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        smtp.quit()
+
+    def testNOOP(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        expected = (250, 'Ok')
+        self.assertEqual(smtp.noop(), expected)
+        smtp.quit()
+
+    def testRSET(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        expected = (250, 'Ok')
+        self.assertEqual(smtp.rset(), expected)
+        smtp.quit()
+
+    def testNotImplemented(self):
+        # EHLO isn't implemented in DebuggingServer
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        expected = (502, 'Error: command "EHLO" not implemented')
+        self.assertEqual(smtp.ehlo(), expected)
+        smtp.quit()
+
+    def testVRFY(self):
+        # VRFY isn't implemented in DebuggingServer
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        expected = (502, 'Error: command "VRFY" not implemented')
+        self.assertEqual(smtp.vrfy('nobody at nowhere.com'), expected)
+        self.assertEqual(smtp.verify('nobody at nowhere.com'), expected)
+        smtp.quit()
+
+    def testSecondHELO(self):
+        # check that a second HELO returns a message that it's a duplicate
+        # (this behavior is specific to smtpd.SMTPChannel)
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        smtp.helo()
+        expected = (503, 'Duplicate HELO/EHLO')
+        self.assertEqual(smtp.helo(), expected)
+        smtp.quit()
+
+    def testHELP(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        self.assertEqual(smtp.help(), 'Error: command "HELP" not implemented')
+        smtp.quit()
+
+    def testSend(self):
+        # connect and send mail
+        m = 'A test message'
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        smtp.sendmail('John', 'Sally', m)
+        smtp.quit()
+
+        self.client_evt.set()
+        self.serv_evt.wait()
+        self.output.flush()
+        mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END)
+        self.assertEqual(self.output.getvalue(), mexpect)
+
+
+# test response of client to a non-successful HELO message
+class BadHELOServerTests(TestCase):
+
+    def setUp(self):
+        self.old_stdout = sys.stdout
+        self.output = StringIO.StringIO()
+        sys.stdout = self.output
+
+        self.evt = threading.Event()
+        servargs = (self.evt, "199 no hello for you!\n")
+        threading.Thread(target=server, args=servargs).start()
+
+        # wait until server thread has assigned a port number
+        n = 500
+        while PORT is None and n > 0:
+            time.sleep(0.01)
+            n -= 1
+
+        # wait a little longer (sometimes connections are refused
+        # on slow machines without this additional wait)
+        time.sleep(0.5)
+
+    def tearDown(self):
+        self.evt.wait()
+        sys.stdout = self.old_stdout
+
+    def testFailingHELO(self):
+        self.assertRaises(smtplib.SMTPConnectError, smtplib.SMTP,
+                            HOST, PORT, 'localhost', 3)
+
+
+sim_users = {'Mr.A at somewhere.com':'John A',
+             'Ms.B at somewhere.com':'Sally B',
+             'Mrs.C at somewhereesle.com':'Ruth C',
+            }
+
+sim_lists = {'list-1':['Mr.A at somewhere.com','Mrs.C at somewhereesle.com'],
+             'list-2':['Ms.B at somewhere.com',],
+            }
+
+# Simulated SMTP channel & server
+class SimSMTPChannel(smtpd.SMTPChannel):
+    def smtp_EHLO(self, arg):
+        resp = '250-testhost\r\n' \
+               '250-EXPN\r\n' \
+               '250-SIZE 20000000\r\n' \
+               '250-STARTTLS\r\n' \
+               '250-DELIVERBY\r\n' \
+               '250 HELP'
+        self.push(resp)
+
+    def smtp_VRFY(self, arg):
+#        print '\nsmtp_VRFY(%r)\n' % arg
+
+        raw_addr = email.utils.parseaddr(arg)[1]
+        quoted_addr = smtplib.quoteaddr(arg)
+        if raw_addr in sim_users:
+            self.push('250 %s %s' % (sim_users[raw_addr], quoted_addr))
+        else:
+            self.push('550 No such user: %s' % arg)
+
+    def smtp_EXPN(self, arg):
+#        print '\nsmtp_EXPN(%r)\n' % arg
+
+        list_name = email.utils.parseaddr(arg)[1].lower()
+        if list_name in sim_lists:
+            user_list = sim_lists[list_name]
+            for n, user_email in enumerate(user_list):
+                quoted_addr = smtplib.quoteaddr(user_email)
+                if n < len(user_list) - 1:
+                    self.push('250-%s %s' % (sim_users[user_email], quoted_addr))
+                else:
+                    self.push('250 %s %s' % (sim_users[user_email], quoted_addr))
+        else:
+            self.push('550 No access for you!')
+
+
+class SimSMTPServer(smtpd.SMTPServer):
+    def handle_accept(self):
+        conn, addr = self.accept()
+        channel = SimSMTPChannel(self, conn, addr)
+
+    def process_message(self, peer, mailfrom, rcpttos, data):
+        pass
+
+
+# Test various SMTP & ESMTP commands/behaviors that require a simulated server
+# (i.e., something with more features than DebuggingServer)
+class SMTPSimTests(TestCase):
+
+    def setUp(self):
+        self.serv_evt = threading.Event()
+        self.client_evt = threading.Event()
+        serv_args = (SimSMTPServer, self.serv_evt, self.client_evt)
+        threading.Thread(target=debugging_server, args=serv_args).start()
+
+        # wait until server thread has assigned a port number
+        n = 500
+        while PORT is None and n > 0:
+            time.sleep(0.01)
+            n -= 1
+
+        # wait a little longer (sometimes connections are refused
+        # on slow machines without this additional wait)
+        time.sleep(0.5)
+
+    def tearDown(self):
+        # indicate that the client is finished
+        self.client_evt.set()
+        # wait for the server thread to terminate
+        self.serv_evt.wait()
+
+    def testBasic(self):
+        # smoke test
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+        smtp.quit()
+
+    def testEHLO(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+
+        # no features should be present before the EHLO
+        self.assertEqual(smtp.esmtp_features, {})
+
+        # features expected from the test server
+        expected_features = {'expn':'',
+                             'size': '20000000',
+                             'starttls': '',
+                             'deliverby': '',
+                             'help': '',
+                             }
+
+        smtp.ehlo()
+        self.assertEqual(smtp.esmtp_features, expected_features)
+        for k in expected_features:
+            self.assertTrue(smtp.has_extn(k))
+        self.assertFalse(smtp.has_extn('unsupported-feature'))
+        smtp.quit()
+
+    def testVRFY(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+
+        for email, name in sim_users.items():
+            expected_known = (250, '%s %s' % (name, smtplib.quoteaddr(email)))
+            self.assertEqual(smtp.vrfy(email), expected_known)
+
+        u = 'nobody at nowhere.com'
+        expected_unknown = (550, 'No such user: %s' % smtplib.quoteaddr(u))
+        self.assertEqual(smtp.vrfy(u), expected_unknown)
+        smtp.quit()
+
+    def testEXPN(self):
+        smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3)
+
+        for listname, members in sim_lists.items():
+            users = []
+            for m in members:
+                users.append('%s %s' % (sim_users[m], smtplib.quoteaddr(m)))
+            expected_known = (250, '\n'.join(users))
+            self.assertEqual(smtp.expn(listname), expected_known)
+
+        u = 'PSU-Members-List'
+        expected_unknown = (550, 'No access for you!')
+        self.assertEqual(smtp.expn(u), expected_unknown)
+        smtp.quit()
+
+
 
 def test_main(verbose=None):
-    test_support.run_unittest(GeneralTests)
+    test_support.run_unittest(GeneralTests, DebuggingServerTests,
+                              BadHELOServerTests, SMTPSimTests)
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_socket_ssl.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_socket_ssl.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_socket_ssl.py	Thu Sep  6 21:35:45 2007
@@ -106,6 +106,25 @@
         connector()
         t.join()
 
+    def test_978833(self):
+        if test_support.verbose:
+            print "test_978833 ..."
+
+        import os, httplib, ssl
+        with test_support.transient_internet():
+            s = socket.socket(socket.AF_INET)
+            s.connect(("www.sf.net", 443))
+            fd = s._sock.fileno()
+            sock = ssl.sslsocket(s)
+            s = None
+            sock.close()
+            try:
+                os.fstat(fd)
+            except OSError:
+                pass
+            else:
+                raise test_support.TestFailed("Failed to close socket")
+
 class OpenSSLTests(unittest.TestCase):
 
     def testBasic(self):

Modified: python/branches/bcannon-objcap/Lib/test/test_socketserver.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_socketserver.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_socketserver.py	Thu Sep  6 21:35:45 2007
@@ -212,6 +212,7 @@
         # If the import lock is held, the threads will hang.
         raise TestSkipped("can't run when import lock is held")
 
+    reap_children()
     try:
         testall()
     finally:

Modified: python/branches/bcannon-objcap/Lib/test/test_struct.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_struct.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_struct.py	Thu Sep  6 21:35:45 2007
@@ -50,7 +50,7 @@
 
 def with_warning_restore(func):
     def _with_warning_restore(*args, **kw):
-        with test.test_support.guard_warnings_filter():
+        with test.test_support.catch_warning():
             # Grrr, we need this function to warn every time.  Without removing
             # the warningregistry, running test_tarfile then test_struct would fail
             # on 64-bit platforms.

Modified: python/branches/bcannon-objcap/Lib/test/test_structmembers.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_structmembers.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_structmembers.py	Thu Sep  6 21:35:45 2007
@@ -5,7 +5,7 @@
     LONG_MAX, LONG_MIN, ULONG_MAX, \
     LLONG_MAX, LLONG_MIN, ULLONG_MAX
 
-import warnings, exceptions, unittest
+import warnings, exceptions, unittest, sys
 from test import test_support
 
 ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
@@ -59,7 +59,7 @@
 
 class TestWarnings(unittest.TestCase):
     def has_warned(self, w):
-        self.assert_(w.category is RuntimeWarning)
+        self.assertEqual(w.category, RuntimeWarning)
 
     def test_byte_max(self):
         with test_support.catch_warning() as w:
@@ -94,10 +94,13 @@
 
 
 def test_main(verbose=None):
-    test_support.run_unittest(
-        ReadWriteTests,
-        TestWarnings
-        )
+    # Obscure hack so that this test passes after reloads or repeated calls
+    # to test_main (regrtest -R).
+    if '__warningregistry__' in globals():
+        del globals()['__warningregistry__']
+    if hasattr(sys, '__warningregistry__'):
+        del sys.__warningregistry__
+    test_support.run_unittest(__name__)
 
 if __name__ == "__main__":
     test_main(verbose=True)

Modified: python/branches/bcannon-objcap/Lib/test/test_structseq.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_structseq.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_structseq.py	Thu Sep  6 21:35:45 2007
@@ -97,6 +97,18 @@
         t = time.gmtime()
         x = t.__reduce__()
 
+    def test_extended_getslice(self):
+        # Test extended slicing by comparing with list slicing.
+        t = time.gmtime()
+        L = list(t)
+        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+        for start in indices:
+            for stop in indices:
+                # Skip step 0 (invalid)
+                for step in indices[1:]:
+                    self.assertEqual(list(t[start:stop:step]),
+                                     L[start:stop:step])
+
 def test_main():
     test_support.run_unittest(StructSeqTest)
 

Modified: python/branches/bcannon-objcap/Lib/test/test_sundry.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_sundry.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_sundry.py	Thu Sep  6 21:35:45 2007
@@ -1,10 +1,10 @@
 """Do a minimal test of all the modules that aren't otherwise tested."""
 
-from test.test_support import guard_warnings_filter
+from test.test_support import catch_warning
 import sys
 import warnings
 
-with guard_warnings_filter():
+with catch_warning():
     warnings.filterwarnings('ignore', r".*posixfile",
                             DeprecationWarning)
     warnings.filterwarnings('ignore', r".*mimify", DeprecationWarning)
@@ -89,7 +89,6 @@
     import opcode
     import os2emxpath
     import pdb
-    import pipes
     import posixfile
     import pstats
     import py_compile

Modified: python/branches/bcannon-objcap/Lib/test/test_support.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_support.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_support.py	Thu Sep  6 21:35:45 2007
@@ -271,14 +271,6 @@
     fn, _ = urllib.urlretrieve(url, filename)
     return open(fn)
 
- at contextlib.contextmanager
-def guard_warnings_filter():
-    """Guard the warnings filter from being permanently changed."""
-    original_filters = warnings.filters[:]
-    try:
-        yield
-    finally:
-        warnings.filters = original_filters
 
 class WarningMessage(object):
     "Holds the result of the latest showwarning() call"
@@ -302,7 +294,7 @@
 
     Use like this:
 
-        with catch_warning as w:
+        with catch_warning() as w:
             warnings.warn("foo")
             assert str(w.message) == "foo"
     """
@@ -382,6 +374,22 @@
     return contextlib.nested(time_out, socket_peer_reset, ioerror_peer_reset)
 
 
+ at contextlib.contextmanager
+def captured_stdout():
+    """Run the with statement body using a StringIO object as sys.stdout.
+    Example use::
+
+       with captured_stdout() as s:
+           print "hello"
+       assert s.getvalue() == "hello"
+    """
+    import StringIO
+    orig_stdout = sys.stdout
+    sys.stdout = StringIO.StringIO()
+    yield sys.stdout
+    sys.stdout = orig_stdout
+
+
 #=======================================================================
 # Decorator for running a function in a different locale, correctly resetting
 # it afterwards.

Modified: python/branches/bcannon-objcap/Lib/test/test_tarfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_tarfile.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_tarfile.py	Thu Sep  6 21:35:45 2007
@@ -141,11 +141,25 @@
 
 class MiscReadTest(ReadTest):
 
-    def test_no_filename(self):
+    def test_no_name_argument(self):
         fobj = open(self.tarname, "rb")
         tar = tarfile.open(fileobj=fobj, mode=self.mode)
         self.assertEqual(tar.name, os.path.abspath(fobj.name))
 
+    def test_no_name_attribute(self):
+        data = open(self.tarname, "rb").read()
+        fobj = StringIO.StringIO(data)
+        self.assertRaises(AttributeError, getattr, fobj, "name")
+        tar = tarfile.open(fileobj=fobj, mode=self.mode)
+        self.assertEqual(tar.name, None)
+
+    def test_empty_name_attribute(self):
+        data = open(self.tarname, "rb").read()
+        fobj = StringIO.StringIO(data)
+        fobj.name = ""
+        tar = tarfile.open(fileobj=fobj, mode=self.mode)
+        self.assertEqual(tar.name, None)
+
     def test_fail_comp(self):
         # For Gzip and Bz2 Tests: fail with a ReadError on an uncompressed file.
         if self.mode == "r:":

Modified: python/branches/bcannon-objcap/Lib/test/test_unicode.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_unicode.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_unicode.py	Thu Sep  6 21:35:45 2007
@@ -55,9 +55,9 @@
     def test_literals(self):
         self.assertEqual(u'\xff', u'\u00ff')
         self.assertEqual(u'\uffff', u'\U0000ffff')
-        self.assertRaises(UnicodeError, eval, 'u\'\\Ufffffffe\'')
-        self.assertRaises(UnicodeError, eval, 'u\'\\Uffffffff\'')
-        self.assertRaises(UnicodeError, eval, 'u\'\\U%08x\'' % 0x110000)
+        self.assertRaises(SyntaxError, eval, 'u\'\\Ufffffffe\'')
+        self.assertRaises(SyntaxError, eval, 'u\'\\Uffffffff\'')
+        self.assertRaises(SyntaxError, eval, 'u\'\\U%08x\'' % 0x110000)
 
     def test_repr(self):
         if not sys.platform.startswith('java'):

Modified: python/branches/bcannon-objcap/Lib/test/test_unicodedata.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_unicodedata.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_unicodedata.py	Thu Sep  6 21:35:45 2007
@@ -214,6 +214,9 @@
                 count += 1
         self.assert_(count >= 10) # should have tested at least the ASCII digits
 
+    def test_bug_1704793(self):
+        self.assertEquals(self.db.lookup("GOTHIC LETTER FAIHU"), u'\U00010346')
+
 def test_main():
     test.test_support.run_unittest(
         UnicodeMiscTest,

Modified: python/branches/bcannon-objcap/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_urllib2.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_urllib2.py	Thu Sep  6 21:35:45 2007
@@ -381,6 +381,12 @@
 
 class OpenerDirectorTests(unittest.TestCase):
 
+    def test_add_non_handler(self):
+        class NonHandler(object):
+            pass
+        self.assertRaises(TypeError,
+                          OpenerDirector().add_handler, NonHandler())
+
     def test_badly_named_methods(self):
         # test work-around for three methods that accidentally follow the
         # naming conventions for handler methods

Modified: python/branches/bcannon-objcap/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_urllib2_localnet.py	Thu Sep  6 21:35:45 2007
@@ -40,14 +40,16 @@
 class LoopbackHttpServerThread(threading.Thread):
     """Stoppable thread that runs a loopback http server."""
 
-    def __init__(self, port, RequestHandlerClass):
+    def __init__(self, request_handler):
         threading.Thread.__init__(self)
-        self._RequestHandlerClass = RequestHandlerClass
         self._stop = False
-        self._port = port
-        self._server_address = ('127.0.0.1', self._port)
         self.ready = threading.Event()
-        self.error = None
+        request_handler.protocol_version = "HTTP/1.0"
+        self.httpd = LoopbackHttpServer(('127.0.0.1', 0),
+                                        request_handler)
+        #print "Serving HTTP on %s port %s" % (self.httpd.server_name,
+        #                                      self.httpd.server_port)
+        self.port = self.httpd.server_port
 
     def stop(self):
         """Stops the webserver if it's currently running."""
@@ -58,24 +60,9 @@
         self.join()
 
     def run(self):
-        protocol = "HTTP/1.0"
-
-        try:
-            self._RequestHandlerClass.protocol_version = protocol
-            httpd = LoopbackHttpServer(self._server_address,
-                                       self._RequestHandlerClass)
-
-            sa = httpd.socket.getsockname()
-            #print "Serving HTTP on", sa[0], "port", sa[1], "..."
-        except:
-            # Fail "gracefully" if we are unable to start.
-            self.ready.set()
-            self.error = sys.exc_info()[1]
-            raise
-
         self.ready.set()
         while not self._stop:
-            httpd.handle_request()
+            self.httpd.handle_request()
 
 # Authentication infrastructure
 
@@ -232,26 +219,21 @@
 class ProxyAuthTests(unittest.TestCase):
     URL = "http://www.foo.com"
 
-    PORT = 8080
     USER = "tester"
     PASSWD = "test123"
     REALM = "TestRealm"
 
-    PROXY_URL = "http://127.0.0.1:%d" % PORT
-
     def setUp(self):
         FakeProxyHandler.digest_auth_handler.set_users({
             self.USER : self.PASSWD
             })
         FakeProxyHandler.digest_auth_handler.set_realm(self.REALM)
 
-        self.server = LoopbackHttpServerThread(self.PORT, FakeProxyHandler)
+        self.server = LoopbackHttpServerThread(FakeProxyHandler)
         self.server.start()
         self.server.ready.wait()
-        if self.server.error:
-            raise self.server.error
-
-        handler = urllib2.ProxyHandler({"http" : self.PROXY_URL})
+        proxy_url = "http://127.0.0.1:%d" % self.server.port
+        handler = urllib2.ProxyHandler({"http" : proxy_url})
         self._digest_auth_handler = urllib2.ProxyDigestAuthHandler()
         self.opener = urllib2.build_opener(handler, self._digest_auth_handler)
 

Modified: python/branches/bcannon-objcap/Lib/test/test_userstring.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_userstring.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_userstring.py	Thu Sep  6 21:35:45 2007
@@ -3,6 +3,7 @@
 # UserString instances should behave similar to builtin string objects.
 
 import unittest
+import string
 from test import test_support, string_tests
 
 from UserString import UserString, MutableString
@@ -88,6 +89,28 @@
         del s[-1:10]
         self.assertEqual(s, "fo")
 
+    def test_extended_set_del_slice(self):
+        indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+        orig = string.ascii_letters + string.digits
+        for start in indices:
+            for stop in indices:
+                # Use indices[1:] when MutableString can handle real
+                # extended slices
+                for step in (None, 1, -1):
+                    s = self.type2test(orig)
+                    L = list(orig)
+                    # Make sure we have a slice of exactly the right length,
+                    # but with (hopefully) different data.
+                    data = L[start:stop:step]
+                    data.reverse()
+                    L[start:stop:step] = data
+                    s[start:stop:step] = "".join(data)
+                    self.assertEquals(s, "".join(L))
+
+                    del L[start:stop:step]
+                    del s[start:stop:step]
+                    self.assertEquals(s, "".join(L))
+
     def test_immutable(self):
         s = self.type2test("foobar")
         s2 = s.immutable()

Modified: python/branches/bcannon-objcap/Lib/test/test_warnings.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_warnings.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_warnings.py	Thu Sep  6 21:35:45 2007
@@ -1,5 +1,6 @@
 import warnings
 import os
+import sys
 import unittest
 from test import test_support
 
@@ -61,7 +62,7 @@
     def test_options(self):
         # Uses the private _setoption() function to test the parsing
         # of command-line warning arguments
-        with test_support.guard_warnings_filter():
+        with test_support.catch_warning():
             self.assertRaises(warnings._OptionError,
                               warnings._setoption, '1:2:3:4:5:6')
             self.assertRaises(warnings._OptionError,
@@ -101,6 +102,10 @@
     # to test_main (regrtest -R).
     if '__warningregistry__' in globals():
         del globals()['__warningregistry__']
+    if hasattr(warning_tests, '__warningregistry__'):
+        del warning_tests.__warningregistry__
+    if hasattr(sys, '__warningregistry__'):
+        del sys.__warningregistry__
     test_support.run_unittest(TestModule)
 
 if __name__ == "__main__":

Modified: python/branches/bcannon-objcap/Lib/test/test_winreg.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_winreg.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_winreg.py	Thu Sep  6 21:35:45 2007
@@ -3,8 +3,9 @@
 
 from _winreg import *
 import os, sys
+import unittest
 
-from test.test_support import verify, have_unicode
+from test import test_support
 
 test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
 
@@ -17,140 +18,157 @@
     ("Big String",    "x"*(2**14-1),                           REG_SZ),
     ("Big Binary",    "x"*(2**14),                             REG_BINARY),
 ]
-if have_unicode:
-    test_data+=[
-    (unicode("Unicode Val"),  unicode("A Unicode value"),                      REG_SZ,),
-    ("UnicodeExpand", unicode("The path is %path%"),                   REG_EXPAND_SZ),
-    ("Multi-unicode", [unicode("Lots"), unicode("of"), unicode("unicode"), unicode("values")], REG_MULTI_SZ),
-    ("Multi-mixed",   [unicode("Unicode"), unicode("and"), "string", "values"],REG_MULTI_SZ),
+
+if test_support.have_unicode:
+    test_data += [
+        (unicode("Unicode Val"),  unicode("A Unicode value"), REG_SZ,),
+        ("UnicodeExpand", unicode("The path is %path%"), REG_EXPAND_SZ),
+        ("Multi-unicode", [unicode("Lots"), unicode("of"), unicode("unicode"),
+                           unicode("values")], REG_MULTI_SZ),
+        ("Multi-mixed",   [unicode("Unicode"), unicode("and"), "string",
+                           "values"], REG_MULTI_SZ),
     ]
 
-def WriteTestData(root_key):
-    # Set the default value for this key.
-    SetValue(root_key, test_key_name, REG_SZ, "Default value")
-    key = CreateKey(root_key, test_key_name)
-    # Create a sub-key
-    sub_key = CreateKey(key, "sub_key")
-    # Give the sub-key some named values
-
-    for value_name, value_data, value_type in test_data:
-        SetValueEx(sub_key, value_name, 0, value_type, value_data)
-
-    # Check we wrote as many items as we thought.
-    nkeys, nvalues, since_mod = QueryInfoKey(key)
-    verify(nkeys==1, "Not the correct number of sub keys")
-    verify(nvalues==1, "Not the correct number of values")
-    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
-    verify(nkeys==0, "Not the correct number of sub keys")
-    verify(nvalues==len(test_data), "Not the correct number of values")
-    # Close this key this way...
-    # (but before we do, copy the key as an integer - this allows
-    # us to test that the key really gets closed).
-    int_sub_key = int(sub_key)
-    CloseKey(sub_key)
-    try:
-        QueryInfoKey(int_sub_key)
-        raise RuntimeError, "It appears the CloseKey() function does not close the actual key!"
-    except EnvironmentError:
-        pass
-    # ... and close that key that way :-)
-    int_key = int(key)
-    key.Close()
-    try:
-        QueryInfoKey(int_key)
-        raise RuntimeError, "It appears the key.Close() function does not close the actual key!"
-    except EnvironmentError:
-        pass
-
-def ReadTestData(root_key):
-    # Check we can get default value for this key.
-    val = QueryValue(root_key, test_key_name)
-    verify(val=="Default value", "Registry didn't give back the correct value")
-
-    key = OpenKey(root_key, test_key_name)
-    # Read the sub-keys
-    sub_key = OpenKey(key, "sub_key")
-    # Check I can enumerate over the values.
-    index = 0
-    while 1:
+class WinregTests(unittest.TestCase):
+    remote_name = None
+
+    def WriteTestData(self, root_key):
+        # Set the default value for this key.
+        SetValue(root_key, test_key_name, REG_SZ, "Default value")
+        key = CreateKey(root_key, test_key_name)
+        # Create a sub-key
+        sub_key = CreateKey(key, "sub_key")
+        # Give the sub-key some named values
+
+        for value_name, value_data, value_type in test_data:
+            SetValueEx(sub_key, value_name, 0, value_type, value_data)
+
+        # Check we wrote as many items as we thought.
+        nkeys, nvalues, since_mod = QueryInfoKey(key)
+        self.assertEquals(nkeys, 1, "Not the correct number of sub keys")
+        self.assertEquals(nvalues, 1, "Not the correct number of values")
+        nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
+        self.assertEquals(nkeys, 0, "Not the correct number of sub keys")
+        self.assertEquals(nvalues, len(test_data),
+                          "Not the correct number of values")
+        # Close this key this way...
+        # (but before we do, copy the key as an integer - this allows
+        # us to test that the key really gets closed).
+        int_sub_key = int(sub_key)
+        CloseKey(sub_key)
         try:
-            data = EnumValue(sub_key, index)
+            QueryInfoKey(int_sub_key)
+            self.fail("It appears the CloseKey() function does "
+                      "not close the actual key!")
         except EnvironmentError:
-            break
-        verify(data in test_data, "Didn't read back the correct test data")
-        index = index + 1
-    verify(index==len(test_data), "Didn't read the correct number of items")
-    # Check I can directly access each item
-    for value_name, value_data, value_type in test_data:
-        read_val, read_typ = QueryValueEx(sub_key, value_name)
-        verify(read_val==value_data and read_typ == value_type, \
-               "Could not directly read the value" )
-    sub_key.Close()
-    # Enumerate our main key.
-    read_val = EnumKey(key, 0)
-    verify(read_val == "sub_key", "Read subkey value wrong")
-    try:
-        EnumKey(key, 1)
-        verify(0, "Was able to get a second key when I only have one!")
-    except EnvironmentError:
-        pass
-
-    key.Close()
-
-def DeleteTestData(root_key):
-    key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
-    sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
-    # It is not necessary to delete the values before deleting
-    # the key (although subkeys must not exist).  We delete them
-    # manually just to prove we can :-)
-    for value_name, value_data, value_type in test_data:
-        DeleteValue(sub_key, value_name)
-
-    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
-    verify(nkeys==0 and nvalues==0, "subkey not empty before delete")
-    sub_key.Close()
-    DeleteKey(key, "sub_key")
+            pass
+        # ... and close that key that way :-)
+        int_key = int(key)
+        key.Close()
+        try:
+            QueryInfoKey(int_key)
+            self.fail("It appears the key.Close() function "
+                      "does not close the actual key!")
+        except EnvironmentError:
+            pass
+
+    def ReadTestData(self, root_key):
+        # Check we can get default value for this key.
+        val = QueryValue(root_key, test_key_name)
+        self.assertEquals(val, "Default value",
+                          "Registry didn't give back the correct value")
 
-    try:
-        # Shouldnt be able to delete it twice!
-        DeleteKey(key, "sub_key")
-        verify(0, "Deleting the key twice succeeded")
-    except EnvironmentError:
-        pass
-    key.Close()
-    DeleteKey(root_key, test_key_name)
-    # Opening should now fail!
-    try:
         key = OpenKey(root_key, test_key_name)
-        verify(0, "Could open the non-existent key")
-    except WindowsError: # Use this error name this time
-        pass
-
-def TestAll(root_key):
-    WriteTestData(root_key)
-    ReadTestData(root_key)
-    DeleteTestData(root_key)
-
-# Test on my local machine.
-TestAll(HKEY_CURRENT_USER)
-print "Local registry tests worked"
-try:
-    remote_name = sys.argv[sys.argv.index("--remote")+1]
-except (IndexError, ValueError):
-    remote_name = None
+        # Read the sub-keys
+        sub_key = OpenKey(key, "sub_key")
+        # Check I can enumerate over the values.
+        index = 0
+        while 1:
+            try:
+                data = EnumValue(sub_key, index)
+            except EnvironmentError:
+                break
+            self.assertEquals(data in test_data, True,
+                              "Didn't read back the correct test data")
+            index = index + 1
+        self.assertEquals(index, len(test_data),
+                          "Didn't read the correct number of items")
+        # Check I can directly access each item
+        for value_name, value_data, value_type in test_data:
+            read_val, read_typ = QueryValueEx(sub_key, value_name)
+            self.assertEquals(read_val, value_data,
+                              "Could not directly read the value")
+            self.assertEquals(read_typ, value_type,
+                              "Could not directly read the value")
+        sub_key.Close()
+        # Enumerate our main key.
+        read_val = EnumKey(key, 0)
+        self.assertEquals(read_val, "sub_key", "Read subkey value wrong")
+        try:
+            EnumKey(key, 1)
+            self.fail("Was able to get a second key when I only have one!")
+        except EnvironmentError:
+            pass
 
-if remote_name is not None:
-    try:
-        remote_key = ConnectRegistry(remote_name, HKEY_CURRENT_USER)
-    except EnvironmentError, exc:
-        print "Could not connect to the remote machine -", exc.strerror
-        remote_key = None
-    if remote_key is not None:
-        TestAll(remote_key)
-        print "Remote registry tests worked"
-else:
-    print "Remote registry calls can be tested using",
-    print "'test_winreg.py --remote \\\\machine_name'"
-    # perform minimal ConnectRegistry test which just invokes it
-    h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
-    h.Close()
+        key.Close()
+
+    def DeleteTestData(self, root_key):
+        key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
+        sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
+        # It is not necessary to delete the values before deleting
+        # the key (although subkeys must not exist).  We delete them
+        # manually just to prove we can :-)
+        for value_name, value_data, value_type in test_data:
+            DeleteValue(sub_key, value_name)
+
+        nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
+        self.assertEquals(nkeys, 0, "subkey not empty before delete")
+        self.assertEquals(nvalues, 0, "subkey not empty before delete")
+        sub_key.Close()
+        DeleteKey(key, "sub_key")
+
+        try:
+            # Shouldnt be able to delete it twice!
+            DeleteKey(key, "sub_key")
+            self.fail("Deleting the key twice succeeded")
+        except EnvironmentError:
+            pass
+        key.Close()
+        DeleteKey(root_key, test_key_name)
+        # Opening should now fail!
+        try:
+            key = OpenKey(root_key, test_key_name)
+            self.fail("Could open the non-existent key")
+        except WindowsError: # Use this error name this time
+            pass
+
+    def TestAll(self, root_key):
+        self.WriteTestData(root_key)
+        self.ReadTestData(root_key)
+        self.DeleteTestData(root_key)
+
+    def testLocalMachineRegistryWorks(self):
+        self.TestAll(HKEY_CURRENT_USER)
+
+    def testConnectRegistryToLocalMachineWorks(self):
+        # perform minimal ConnectRegistry test which just invokes it
+        h = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
+        h.Close()
+
+    def testRemoteMachineRegistryWorks(self):
+        if not self.remote_name:
+            return # remote machine name not specified
+        remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER)
+        self.TestAll(remote_key)
+
+def test_main():
+    test_support.run_unittest(WinregTests)
+
+if __name__ == "__main__":
+    try:
+        WinregTests.remote_name = sys.argv[sys.argv.index("--remote")+1]
+    except (IndexError, ValueError):
+        print "Remote registry calls can be tested using",
+        print "'test_winreg.py --remote \\\\machine_name'"
+        WinregTests.remote_name = None
+    test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_xmlrpc.py	Thu Sep  6 21:35:45 2007
@@ -1,7 +1,12 @@
+import base64
 import datetime
 import sys
+import time
 import unittest
 import xmlrpclib
+import SimpleXMLRPCServer
+import threading
+import mimetools
 from test import test_support
 
 try:
@@ -25,6 +30,10 @@
                         (2005, 02, 10, 11, 41, 23, 0, 1, -1)),
           'datetime3': xmlrpclib.DateTime(
                         datetime.datetime(2005, 02, 10, 11, 41, 23)),
+          'datetime4': xmlrpclib.DateTime(
+                        datetime.date(2005, 02, 10)),
+          'datetime5': xmlrpclib.DateTime(
+                        datetime.time(11, 41, 23)),
           }]
 
 class XMLRPCTestCase(unittest.TestCase):
@@ -101,11 +110,37 @@
     def test_dump_bad_dict(self):
         self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},))
 
+    def test_dump_recursive_seq(self):
+        l = [1,2,3]
+        t = [3,4,5,l]
+        l.append(t)
+        self.assertRaises(TypeError, xmlrpclib.dumps, (l,))
+
+    def test_dump_recursive_dict(self):
+        d = {'1':1, '2':1}
+        t = {'3':3, 'd':d}
+        d['t'] = t
+        self.assertRaises(TypeError, xmlrpclib.dumps, (d,))
+
     def test_dump_big_int(self):
         if sys.maxint > 2L**31-1:
             self.assertRaises(OverflowError, xmlrpclib.dumps,
                               (int(2L**34),))
 
+        xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT))
+        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,))
+        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,))
+
+        def dummy_write(s):
+            pass
+
+        m = xmlrpclib.Marshaller()
+        m.dump_int(xmlrpclib.MAXINT, dummy_write)
+        m.dump_int(xmlrpclib.MININT, dummy_write)
+        self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MAXINT+1, dummy_write)
+        self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MININT-1, dummy_write)
+
+
     def test_dump_none(self):
         value = alist + [None]
         arg1 = (alist + [None],)
@@ -156,9 +191,354 @@
             self.assertEquals(s, "abc \xc2\x95")
             self.assertEquals(items, [("def \xc2\x96", "ghi \xc2\x97")])
 
+
+class HelperTestCase(unittest.TestCase):
+    def test_escape(self):
+        self.assertEqual(xmlrpclib.escape("a&b"), "a&amp;b")
+        self.assertEqual(xmlrpclib.escape("a<b"), "a&lt;b")
+        self.assertEqual(xmlrpclib.escape("a>b"), "a&gt;b")
+
+class FaultTestCase(unittest.TestCase):
+    def test_repr(self):
+        f = xmlrpclib.Fault(42, 'Test Fault')
+        self.assertEqual(repr(f), "<Fault 42: 'Test Fault'>")
+        self.assertEqual(repr(f), str(f))
+
+    def test_dump_fault(self):
+        f = xmlrpclib.Fault(42, 'Test Fault')
+        s = xmlrpclib.dumps((f,))
+        (newf,), m = xmlrpclib.loads(s)
+        self.assertEquals(newf, {'faultCode': 42, 'faultString': 'Test Fault'})
+        self.assertEquals(m, None)
+
+        s = xmlrpclib.Marshaller().dumps(f)
+        self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
+
+
+class DateTimeTestCase(unittest.TestCase):
+    def test_default(self):
+        t = xmlrpclib.DateTime()
+
+    def test_time(self):
+        d = 1181399930.036952
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d)))
+
+    def test_time_tuple(self):
+        d = (2007,6,9,10,38,50,5,160,0)
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t), '20070609T10:38:50')
+
+    def test_time_struct(self):
+        d = time.localtime(1181399930.036952)
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t),  time.strftime("%Y%m%dT%H:%M:%S", d))
+
+    def test_datetime_datetime(self):
+        d = datetime.datetime(2007,1,2,3,4,5)
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t), '20070102T03:04:05')
+
+    def test_datetime_date(self):
+        d = datetime.date(2007,9,8)
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t), '20070908T00:00:00')
+
+    def test_datetime_time(self):
+        d = datetime.time(13,17,19)
+        # allow for date rollover by checking today's or tomorrow's dates
+        dd1 = datetime.datetime.now().date()
+        dd2 = dd1 + datetime.timedelta(days=1)
+        vals = (dd1.strftime('%Y%m%dT13:17:19'),
+                dd2.strftime('%Y%m%dT13:17:19'))
+        t = xmlrpclib.DateTime(d)
+        self.assertEqual(str(t) in vals, True)
+
+    def test_repr(self):
+        d = datetime.datetime(2007,1,2,3,4,5)
+        t = xmlrpclib.DateTime(d)
+        val ="<DateTime '20070102T03:04:05' at %x>" % id(t)
+        self.assertEqual(repr(t), val)
+
+    def test_decode(self):
+        d = ' 20070908T07:11:13  '
+        t1 = xmlrpclib.DateTime()
+        t1.decode(d)
+        tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13))
+        self.assertEqual(t1, tref)
+
+        t2 = xmlrpclib._datetime(d)
+        self.assertEqual(t1, tref)
+
+class BinaryTestCase(unittest.TestCase):
+    def test_default(self):
+        t = xmlrpclib.Binary()
+        self.assertEqual(str(t), '')
+
+    def test_string(self):
+        d = '\x01\x02\x03abc123\xff\xfe'
+        t = xmlrpclib.Binary(d)
+        self.assertEqual(str(t), d)
+
+    def test_decode(self):
+        d = '\x01\x02\x03abc123\xff\xfe'
+        de = base64.encodestring(d)
+        t1 = xmlrpclib.Binary()
+        t1.decode(de)
+        self.assertEqual(str(t1), d)
+
+        t2 = xmlrpclib._binary(de)
+        self.assertEqual(str(t2), d)
+
+
+PORT = None
+
+def http_server(evt, numrequests):
+    class TestInstanceClass:
+        def div(self, x, y):
+            '''This is the div function'''
+            return x // y
+
+    try:
+        serv = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 0),
+                        logRequests=False, bind_and_activate=False)
+        serv.socket.settimeout(3)
+        serv.server_bind()
+        global PORT
+        PORT = serv.socket.getsockname()[1]
+        serv.server_activate()
+        serv.register_introspection_functions()
+        serv.register_multicall_functions()
+        serv.register_function(pow)
+        serv.register_function(lambda x,y: x+y, 'add')
+        serv.register_instance(TestInstanceClass())
+
+        # handle up to 'numrequests' requests
+        while numrequests > 0:
+            serv.handle_request()
+            numrequests -= 1
+
+    except socket.timeout:
+        pass
+    finally:
+        serv.socket.close()
+        PORT = None
+        evt.set()
+
+
+def is_unavailable_exception(e):
+    '''Returns True if the given ProtocolError is the product of a server-side
+       exception caused by the 'temporarily unavailable' response sometimes
+       given by operations on non-blocking sockets.'''
+    # sometimes we get a -1 error code and/or empty headers
+    if e.errcode == -1 or e.headers is None:
+        return True
+
+    exc_mess = e.headers.get('X-exception')
+    if exc_mess and 'temporarily unavailable' in exc_mess.lower():
+        return True
+
+    return False
+
+# NOTE: The tests in SimpleServerTestCase will ignore failures caused by
+# "temporarily unavailable" exceptions raised in SimpleXMLRPCServer.  This
+# condition occurs infrequently on some platforms, frequently on others, and
+# is apparently caused by using SimpleXMLRPCServer with a non-blocking socket.
+# If the server class is updated at some point in the future to handle this
+# situation more gracefully, these tests should be modified appropriately.
+
+class SimpleServerTestCase(unittest.TestCase):
+    def setUp(self):
+        # enable traceback reporting
+        SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True
+
+        self.evt = threading.Event()
+        # start server thread to handle requests
+        serv_args = (self.evt, 1)
+        threading.Thread(target=http_server, args=serv_args).start()
+
+        # wait for port to be assigned to server
+        n = 1000
+        while n > 0 and PORT is None:
+            time.sleep(0.001)
+            n -= 1
+
+        time.sleep(0.5)
+
+    def tearDown(self):
+        # wait on the server thread to terminate
+        self.evt.wait()
+
+        # disable traceback reporting
+        SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = False
+
+    def test_simple1(self):
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            self.assertEqual(p.pow(6,8), 6**8)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+    def test_introspection1(self):
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            meth = p.system.listMethods()
+            expected_methods = set(['pow', 'div', 'add', 'system.listMethods',
+                'system.methodHelp', 'system.methodSignature', 'system.multicall'])
+            self.assertEqual(set(meth), expected_methods)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+    def test_introspection2(self):
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            divhelp = p.system.methodHelp('div')
+            self.assertEqual(divhelp, 'This is the div function')
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+    def test_introspection3(self):
+        # the SimpleXMLRPCServer doesn't support signatures, but
+        # at least check that we can try making the call
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            divsig = p.system.methodSignature('div')
+            self.assertEqual(divsig, 'signatures not supported')
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+    def test_multicall(self):
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            multicall = xmlrpclib.MultiCall(p)
+            multicall.add(2,3)
+            multicall.pow(6,8)
+            multicall.div(127,42)
+            add_result, pow_result, div_result = multicall()
+            self.assertEqual(add_result, 2+3)
+            self.assertEqual(pow_result, 6**8)
+            self.assertEqual(div_result, 127//42)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+
+# This is a contrived way to make a failure occur on the server side
+# in order to test the _send_traceback_header flag on the server
+class FailingMessageClass(mimetools.Message):
+    def __getitem__(self, key):
+        key = key.lower()
+        if key == 'content-length':
+            return 'I am broken'
+        return mimetools.Message.__getitem__(self, key)
+
+
+class FailingServerTestCase(unittest.TestCase):
+    def setUp(self):
+        self.evt = threading.Event()
+        # start server thread to handle requests
+        serv_args = (self.evt, 2)
+        threading.Thread(target=http_server, args=serv_args).start()
+
+        # wait for port to be assigned to server
+        n = 1000
+        while n > 0 and PORT is None:
+            time.sleep(0.001)
+            n -= 1
+
+        time.sleep(0.5)
+
+    def tearDown(self):
+        # wait on the server thread to terminate
+        self.evt.wait()
+        # reset flag
+        SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = False
+        # reset message class
+        SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = mimetools.Message
+
+    def test_basic(self):
+        # check that flag is false by default
+        flagval = SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header
+        self.assertEqual(flagval, False)
+
+        # enable traceback reporting
+        SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True
+
+        # test a call that shouldn't fail just as a smoke test
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            self.assertEqual(p.pow(6,8), 6**8)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # protocol error; provide additional information in test output
+                self.fail("%s\n%s" % (e, e.headers))
+
+    def test_fail_no_info(self):
+        # use the broken message class
+        SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = FailingMessageClass
+
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            p.pow(6,8)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # The two server-side error headers shouldn't be sent back in this case
+                self.assertTrue(e.headers.get("X-exception") is None)
+                self.assertTrue(e.headers.get("X-traceback") is None)
+        else:
+            self.fail('ProtocolError not raised')
+
+    def test_fail_with_info(self):
+        # use the broken message class
+        SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.MessageClass = FailingMessageClass
+
+        # Check that errors in the server send back exception/traceback
+        # info when flag is set
+        SimpleXMLRPCServer.SimpleXMLRPCServer._send_traceback_header = True
+
+        try:
+            p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
+            p.pow(6,8)
+        except xmlrpclib.ProtocolError, e:
+            # ignore failures due to non-blocking socket 'unavailable' errors
+            if not is_unavailable_exception(e):
+                # We should get error info in the response
+                expected_err = "invalid literal for int() with base 10: 'I am broken'"
+                self.assertEqual(e.headers.get("x-exception"), expected_err)
+                self.assertTrue(e.headers.get("x-traceback") is not None)
+        else:
+            self.fail('ProtocolError not raised')
+
+
 def test_main():
-    test_support.run_unittest(XMLRPCTestCase)
+    xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase,
+         BinaryTestCase, FaultTestCase]
+
+    # The test cases against a SimpleXMLRPCServer raise a socket error
+    # 10035 (WSAEWOULDBLOCK) in the server thread handle_request call when
+    # run on Windows. This only happens on the first test to run, but it
+    # fails every time and so these tests are skipped on win32 platforms.
+    if sys.platform != 'win32':
+        xmlrpc_tests.append(SimpleServerTestCase)
+        xmlrpc_tests.append(FailingServerTestCase)
 
+    test_support.run_unittest(*xmlrpc_tests)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/bcannon-objcap/Lib/test/test_zipfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/test/test_zipfile.py	(original)
+++ python/branches/bcannon-objcap/Lib/test/test_zipfile.py	Thu Sep  6 21:35:45 2007
@@ -14,12 +14,12 @@
 from test.test_support import TESTFN, run_unittest
 
 TESTFN2 = TESTFN + "2"
-FIXEDTEST_SIZE = 10
+FIXEDTEST_SIZE = 1000
 
 class TestsWithSourceFile(unittest.TestCase):
     def setUp(self):
-        self.line_gen = ("Zipfile test line %d. random float: %f" % (i, random())
-                          for i in xrange(FIXEDTEST_SIZE))
+        self.line_gen = ["Zipfile test line %d. random float: %f" % (i, random())
+                          for i in xrange(FIXEDTEST_SIZE)]
         self.data = '\n'.join(self.line_gen) + '\n'
 
         # Make a source file with some lines
@@ -239,6 +239,63 @@
         self.assertEqual(zipfp.namelist(), ["absolute"])
         zipfp.close()
 
+    def testAppendToZipFile(self):
+        # Test appending to an existing zipfile
+        zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
+        zipfp.write(TESTFN, TESTFN)
+        zipfp.close()
+        zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED)
+        zipfp.writestr("strfile", self.data)
+        self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"])
+        zipfp.close()
+
+    def testAppendToNonZipFile(self):
+        # Test appending to an existing file that is not a zipfile
+        # NOTE: this test fails if len(d) < 22 because of the first
+        # line "fpin.seek(-22, 2)" in _EndRecData
+        d = 'I am not a ZipFile!'*10
+        f = file(TESTFN2, 'wb')
+        f.write(d)
+        f.close()
+        zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED)
+        zipfp.write(TESTFN, TESTFN)
+        zipfp.close()
+
+        f = file(TESTFN2, 'rb')
+        f.seek(len(d))
+        zipfp = zipfile.ZipFile(f, "r")
+        self.assertEqual(zipfp.namelist(), [TESTFN])
+        zipfp.close()
+        f.close()
+
+    def test_WriteDefaultName(self):
+        # Check that calling ZipFile.write without arcname specified produces the expected result
+        zipfp = zipfile.ZipFile(TESTFN2, "w")
+        zipfp.write(TESTFN)
+        self.assertEqual(zipfp.read(TESTFN), file(TESTFN).read())
+        zipfp.close()
+
+    def test_PerFileCompression(self):
+        # Check that files within a Zip archive can have different compression options
+        zipfp = zipfile.ZipFile(TESTFN2, "w")
+        zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED)
+        zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED)
+        sinfo = zipfp.getinfo('storeme')
+        dinfo = zipfp.getinfo('deflateme')
+        self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED)
+        self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED)
+        zipfp.close()
+
+    def test_WriteToReadonly(self):
+        # Check that trying to call write() on a readonly ZipFile object
+        # raises a RuntimeError
+        zipf = zipfile.ZipFile(TESTFN2, mode="w")
+        zipf.writestr("somefile.txt", "bogus")
+        zipf.close()
+        zipf = zipfile.ZipFile(TESTFN2, mode="r")
+        self.assertRaises(RuntimeError, zipf.write, TESTFN)
+        zipf.close()
+
     def tearDown(self):
         os.remove(TESTFN)
         os.remove(TESTFN2)
@@ -361,7 +418,6 @@
         self.assertEqual(zipfp.namelist(), ["absolute"])
         zipfp.close()
 
-
     def tearDown(self):
         zipfile.ZIP64_LIMIT = self._limit
         os.remove(TESTFN)
@@ -432,6 +488,11 @@
         finally:
             shutil.rmtree(TESTFN2)
 
+    def testWriteNonPyfile(self):
+        zipfp  = zipfile.PyZipFile(TemporaryFile(), "w")
+        file(TESTFN, 'w').write('most definitely not a python file')
+        self.assertRaises(RuntimeError, zipfp.writepy, TESTFN)
+        os.remove(TESTFN)
 
 
 class OtherTests(unittest.TestCase):
@@ -513,7 +574,56 @@
         # a RuntimeError, and so should calling .testzip.  An earlier
         # version of .testzip would swallow this exception (and any other)
         # and report that the first file in the archive was corrupt.
+        self.assertRaises(RuntimeError, zipf.read, "foo.txt")
+        self.assertRaises(RuntimeError, zipf.open, "foo.txt")
         self.assertRaises(RuntimeError, zipf.testzip)
+        self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus")
+        file(TESTFN, 'w').write('zipfile test data')
+        self.assertRaises(RuntimeError, zipf.write, TESTFN)
+
+    def test_BadConstructorMode(self):
+        # Check that bad modes passed to ZipFile constructor are caught
+        self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q")
+
+    def test_BadOpenMode(self):
+        # Check that bad modes passed to ZipFile.open are caught
+        zipf = zipfile.ZipFile(TESTFN, mode="w")
+        zipf.writestr("foo.txt", "O, for a Muse of Fire!")
+        zipf.close()
+        zipf = zipfile.ZipFile(TESTFN, mode="r")
+        # read the data to make sure the file is there
+        zipf.read("foo.txt")
+        self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q")
+        zipf.close()
+
+    def test_Read0(self):
+        # Check that calling read(0) on a ZipExtFile object returns an empty
+        # string and doesn't advance file pointer
+        zipf = zipfile.ZipFile(TESTFN, mode="w")
+        zipf.writestr("foo.txt", "O, for a Muse of Fire!")
+        # read the data to make sure the file is there
+        f = zipf.open("foo.txt")
+        for i in xrange(FIXEDTEST_SIZE):
+            self.assertEqual(f.read(0), '')
+
+        self.assertEqual(f.read(), "O, for a Muse of Fire!")
+        zipf.close()
+
+    def test_OpenNonexistentItem(self):
+        # Check that attempting to call open() for an item that doesn't
+        # exist in the archive raises a RuntimeError
+        zipf = zipfile.ZipFile(TESTFN, mode="w")
+        self.assertRaises(KeyError, zipf.open, "foo.txt", "r")
+
+    def test_BadCompressionMode(self):
+        # Check that bad compression methods passed to ZipFile.open are caught
+        self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
+
+    def test_NullByteInFilename(self):
+        # Check that a filename containing a null byte is properly terminated
+        zipf = zipfile.ZipFile(TESTFN, mode="w")
+        zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!")
+        self.assertEqual(zipf.namelist(), ['foo.txt'])
 
     def tearDown(self):
         support.unlink(TESTFN)

Modified: python/branches/bcannon-objcap/Lib/threading.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/threading.py	(original)
+++ python/branches/bcannon-objcap/Lib/threading.py	Thu Sep  6 21:35:45 2007
@@ -85,9 +85,10 @@
         self.__count = 0
 
     def __repr__(self):
+        owner = self.__owner
         return "<%s(%s, %d)>" % (
                 self.__class__.__name__,
-                self.__owner and self.__owner.getName(),
+                owner and owner.getName(),
                 self.__count)
 
     def acquire(self, blocking=1):
@@ -445,6 +446,26 @@
             self.__target(*self.__args, **self.__kwargs)
 
     def __bootstrap(self):
+        # Wrapper around the real bootstrap code that ignores
+        # exceptions during interpreter cleanup.  Those typically
+        # happen when a daemon thread wakes up at an unfortunate
+        # moment, finds the world around it destroyed, and raises some
+        # random exception *** while trying to report the exception in
+        # __bootstrap_inner() below ***.  Those random exceptions
+        # don't help anybody, and they confuse users, so we suppress
+        # them.  We suppress them only when it appears that the world
+        # indeed has already been destroyed, so that exceptions in
+        # __bootstrap_inner() during normal business hours are properly
+        # reported.  Also, we only suppress them for daemonic threads;
+        # if a non-daemonic encounters this, something else is wrong.
+        try:
+            self.__bootstrap_inner()
+        except:
+            if self.__daemonic and _sys is None:
+                return
+            raise
+
+    def __bootstrap_inner(self):
         try:
             self.__started = True
             _active_limbo_lock.acquire()

Modified: python/branches/bcannon-objcap/Lib/urllib.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/urllib.py	(original)
+++ python/branches/bcannon-objcap/Lib/urllib.py	Thu Sep  6 21:35:45 2007
@@ -91,6 +91,14 @@
     if _urlopener:
         _urlopener.cleanup()
 
+# check for SSL
+try:
+    import ssl
+except:
+    _have_ssl = False
+else:
+    _have_ssl = True
+
 # exception raised when downloaded size does not match content-length
 class ContentTooShortError(IOError):
     def __init__(self, message, content):
@@ -361,9 +369,10 @@
         fp.close()
         raise IOError, ('http error', errcode, errmsg, headers)
 
-    if hasattr(socket, "ssl"):
+    if _have_ssl:
         def open_https(self, url, data=None):
             """Use HTTPS protocol."""
+
             import httplib
             user_passwd = None
             proxy_passwd = None

Modified: python/branches/bcannon-objcap/Lib/urllib2.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/urllib2.py	(original)
+++ python/branches/bcannon-objcap/Lib/urllib2.py	Thu Sep  6 21:35:45 2007
@@ -295,6 +295,10 @@
         self.process_request = {}
 
     def add_handler(self, handler):
+        if not hasattr(handler, "add_parent"):
+            raise TypeError("expected BaseHandler instance, got %r" %
+                            type(handler))
+
         added = False
         for meth in dir(handler):
             if meth in ["redirect_request", "do_open", "proxy_open"]:

Modified: python/branches/bcannon-objcap/Lib/uuid.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/uuid.py	(original)
+++ python/branches/bcannon-objcap/Lib/uuid.py	Thu Sep  6 21:35:45 2007
@@ -393,7 +393,6 @@
 _uuid_generate_random = _uuid_generate_time = _UuidCreate = None
 try:
     import ctypes, ctypes.util
-    _buffer = ctypes.create_string_buffer(16)
 
     # The uuid_generate_* routines are provided by libuuid on at least
     # Linux and FreeBSD, and provided by libc on Mac OS X.
@@ -426,11 +425,13 @@
 
 def _unixdll_getnode():
     """Get the hardware address on Unix using ctypes."""
+    _buffer = ctypes.create_string_buffer(16)
     _uuid_generate_time(_buffer)
     return UUID(bytes=_buffer.raw).node
 
 def _windll_getnode():
     """Get the hardware address on Windows using ctypes."""
+    _buffer = ctypes.create_string_buffer(16)
     if _UuidCreate(_buffer) == 0:
         return UUID(bytes=_buffer.raw).node
 
@@ -478,6 +479,7 @@
 
     # When the system provides a version-1 UUID generator, use it (but don't
     # use UuidCreate here because its UUIDs don't conform to RFC 4122).
+    _buffer = ctypes.create_string_buffer(16)
     if _uuid_generate_time and node is clock_seq is None:
         _uuid_generate_time(_buffer)
         return UUID(bytes=_buffer.raw)
@@ -514,6 +516,7 @@
     """Generate a random UUID."""
 
     # When the system provides a version-4 UUID generator, use it.
+    _buffer = ctypes.create_string_buffer(16)
     if _uuid_generate_random:
         _uuid_generate_random(_buffer)
         return UUID(bytes=_buffer.raw)

Modified: python/branches/bcannon-objcap/Lib/webbrowser.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/webbrowser.py	(original)
+++ python/branches/bcannon-objcap/Lib/webbrowser.py	Thu Sep  6 21:35:45 2007
@@ -1,5 +1,6 @@
 #! /usr/bin/env python
 """Interfaces for launching and remotely controlling Web browsers."""
+# Maintained by Georg Brandl.
 
 import os
 import shlex
@@ -160,6 +161,7 @@
     def __init__(self, name):
         if isinstance(name, basestring):
             self.name = name
+            self.args = ["%s"]
         else:
             # name should be a list with arguments
             self.name = name[0]

Modified: python/branches/bcannon-objcap/Lib/zipfile.py
==============================================================================
--- python/branches/bcannon-objcap/Lib/zipfile.py	(original)
+++ python/branches/bcannon-objcap/Lib/zipfile.py	Thu Sep  6 21:35:45 2007
@@ -568,8 +568,9 @@
 
     def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
         """Open the ZIP file with mode read "r", write "w" or append "a"."""
-        self._allowZip64 = allowZip64
-        self._didModify = False
+        if mode not in ("r", "w", "a"):
+            raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
+
         if compression == ZIP_STORED:
             pass
         elif compression == ZIP_DEFLATED:
@@ -578,6 +579,9 @@
                       "Compression requires the (missing) zlib module"
         else:
             raise RuntimeError, "That compression method is not supported"
+
+        self._allowZip64 = allowZip64
+        self._didModify = False
         self.debug = 0  # Level of printing: 0 through 3
         self.NameToInfo = {}    # Find file info given name
         self.filelist = []      # List of ZipInfo instances for archive
@@ -720,7 +724,12 @@
 
     def getinfo(self, name):
         """Return the instance of ZipInfo given 'name'."""
-        return self.NameToInfo[name]
+        info = self.NameToInfo.get(name)
+        if info is None:
+            raise KeyError(
+                'There is no item named %r in the archive' % name)
+
+        return info
 
     def setpassword(self, pwd):
         """Set default password for encrypted files."""
@@ -824,6 +833,10 @@
     def write(self, filename, arcname=None, compress_type=None):
         """Put the bytes from filename into the archive under the name
         arcname."""
+        if not self.fp:
+            raise RuntimeError(
+                  "Attempt to write to ZIP archive that was already closed")
+
         st = os.stat(filename)
         mtime = time.localtime(st.st_mtime)
         date_time = mtime[0:6]
@@ -896,6 +909,11 @@
             zinfo.compress_type = self.compression
         else:
             zinfo = zinfo_or_arcname
+
+        if not self.fp:
+            raise RuntimeError(
+                  "Attempt to write to ZIP archive that was already closed")
+
         zinfo.file_size = len(bytes)            # Uncompressed size
         zinfo.header_offset = self.fp.tell()    # Start of header bytes
         self._writecheck(zinfo)

Modified: python/branches/bcannon-objcap/Makefile.pre.in
==============================================================================
--- python/branches/bcannon-objcap/Makefile.pre.in	(original)
+++ python/branches/bcannon-objcap/Makefile.pre.in	Thu Sep  6 21:35:45 2007
@@ -61,7 +61,7 @@
 # Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to
 # be able to build extension modules using the directories specified in the
 # environment variables
-CPPFLAGS=	-I. -I$(srcdir)/Include @CPPFLAGS@
+CPPFLAGS=	-I. -IInclude -I$(srcdir)/Include @CPPFLAGS@
 LDFLAGS=	@LDFLAGS@
 LDLAST=		@LDLAST@
 SGI_ABI=	@SGI_ABI@
@@ -392,7 +392,7 @@
 			-compatibility_version $(VERSION) \
 			-current_version $(VERSION); \
         else \
-		libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
+		/usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
 			@LIBTOOL_CRUFT@ ;\
 	fi
 	$(INSTALL) -d -m $(DIRMODE)  \
@@ -471,6 +471,7 @@
 
 
 $(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
+		-@ mkdir Include
 		-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
 
 $(PGEN):	$(PGENOBJS)
@@ -601,7 +602,11 @@
 
 
 # Like testall, but with a single pass only
+# run an optional script to include some information about the build environment
 buildbottest:	all platform
+		- at if which pybuildbot.identify >/dev/null 2>&1; then \
+			pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \
+		fi
 		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw
 
 QUICKTESTOPTS=	$(TESTOPTS) -x test_thread test_signal test_strftime \

Modified: python/branches/bcannon-objcap/Misc/ACKS
==============================================================================
--- python/branches/bcannon-objcap/Misc/ACKS	(original)
+++ python/branches/bcannon-objcap/Misc/ACKS	Thu Sep  6 21:35:45 2007
@@ -80,6 +80,7 @@
 Peter Bosch
 Eric Bouck
 Thierry Bousch
+Sebastian Boving
 Monty Brandenberg
 Georg Brandl
 Terrence Brannon
@@ -319,6 +320,7 @@
 Tony Ingraldi
 John Interrante
 Bob Ippolito
+Atsuo Ishimoto
 Ben Jackson
 Paul Jackson
 David Jacobs

Modified: python/branches/bcannon-objcap/Misc/BeOS-NOTES
==============================================================================
--- python/branches/bcannon-objcap/Misc/BeOS-NOTES	(original)
+++ python/branches/bcannon-objcap/Misc/BeOS-NOTES	Thu Sep  6 21:35:45 2007
@@ -39,4 +39,5 @@
    make install
 
 
-Maintainer: Mikael Jansson (mail at mikael.jansson.be)
+Maintainer: None (please volunteer if you would like to see this port continue
+to exist!)

Modified: python/branches/bcannon-objcap/Misc/NEWS
==============================================================================
--- python/branches/bcannon-objcap/Misc/NEWS	(original)
+++ python/branches/bcannon-objcap/Misc/NEWS	Thu Sep  6 21:35:45 2007
@@ -12,6 +12,18 @@
 Core and builtins
 -----------------
 
+- Patch #1031213: Decode source line in SyntaxErrors back to its original source
+  encoding.
+
+- Py_ssize_t fields work in structmember when HAVE_LONG_LONG is not defined.
+
+- PEP 3123: Provide forward compatibility with Python 3.0, while keeping
+  backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and
+  PyVarObject_HEAD_INIT.
+
+- Patch #1673759: add a missing overflow check when formatting floats
+  with %G.
+
 - Patch #1733960: Allow T_LONGLONG to accept ints.
 
 - T_PYSSIZET can now be used in PyMemberDef lists for Py_ssize_t members.
@@ -231,6 +243,42 @@
 Library
 -------
 
+- Bug #1709599: Run test_1565150 only if the file system is NTFS.
+
+- When encountering a password-protected robots.txt file the RobotFileParser
+  no longer prompts interactively for a username and password (bug 813986).
+
+- TarFile.__init__() no longer fails if no name argument is passed and
+  the fileobj argument has no usable name attribute (e.g. StringIO).
+
+- The functools module now provides 'reduce', for forward compatibility
+  with Python 3000.
+
+- Server-side SSL support and cert verification added, by Bill Janssen.
+
+- socket.ssl deprecated; use new ssl module instead.
+
+- uuid creation is now threadsafe.
+
+- EUC-KR codec now handles the cheot-ga-keut composed make-up hangul
+  syllables.
+
+- GB18030 codec now can encode additional two-byte characters that
+  are missing in GBK.
+
+- Add new codecs for UTF-32, UTF-32-LE and UTF-32-BE.
+
+- Bug #1704793: Return UTF-16 pair if unicodedata.lookup cannot
+  represent the result in a single character.
+
+- Bug #978833: Close https sockets by releasing the _ssl object.
+
+- Change location of the package index to pypi.python.org/pypi
+
+- Bug #1701409: Fix a segfault in printing ctypes.c_char_p and
+  ctypes.c_wchar_p when they point to an invalid location.  As a
+  sideeffect the representation of these instances has changed.
+
 - tarfile.py: Added "exclude" keyword argument to TarFile.add().
 
 - Bug #1734723: Fix repr.Repr() so it doesn't ignore the maxtuple attribute.
@@ -417,6 +465,10 @@
 
 - Patch #1481079: add support for HTTP_REFERER to CGIHTTPServer.
 
+- Patch #1675424: Added tests for uncovered code in the zipfile module. 
+  The KeyError raised by Zipfile.getinfo for nonexistent names now has 
+  a descriptive message.
+
 - Bug #1115886: os.path.splitext('.cshrc') gives now ('.cshrc', '').
 
 - unittest now verifies more of its assumptions. In particular, TestCase
@@ -697,6 +749,12 @@
 Extension Modules
 -----------------
 
+- Patch #1388440: Add set_completion_display_matches_hook and
+  get_completion_type to readline.
+
+- Bug #1649098: Avoid declaration of zero-sized array declaration in
+  structure.
+
 - Removed the rgbimg module; been deprecated since Python 2.5.
 
 - Bug #1721309: prevent bsddb module from freeing random memory.
@@ -752,10 +810,6 @@
 
 - Patch #1576166: Support os.utime for directories on Windows NT+.
 
-- Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode
-  arguments with the system default encoding just like the write()
-  method does, instead of converting it to a raw buffer.
-
 - Patch #1572724: fix typo ('=' instead of '==') in _msi.c.
 
 - Bug #1572832: fix a bug in ISO-2022 codecs which may cause segfault
@@ -790,17 +844,24 @@
 - fixed a bug with bsddb.DB.stat: the flags and txn keyword arguments
   were transposed.
 
-- Added support for linking the bsddb module against BerkeleyDB 4.5.x.
+- Added support for linking the bsddb module against BerkeleyDB 4.5.x
+  and 4.6.x.
 
 - Bug #1633621: if curses.resizeterm() or curses.resize_term() is called,
   update _curses.LINES, _curses.COLS, curses.LINES and curses.COLS.
 
 - Fix an off-by-one bug in locale.strxfrm().
 
+- Fix libffi configure for hppa*-*-linux* | parisc*-*-linux*.
+
 
 Tests
 -----
 
+- Make test_runpy reentrant by fixing _check_module to clear out any module
+  being tested.  Was causing an error by __import__ doing a reload on the
+  second run and thus suppressing bytecode recreation.
+
 - Capture socket connection resets and timeouts in test_socket_ssl and
   test_urllib2net and raise test.test_support.ResourceDenied.
 
@@ -816,10 +877,6 @@
   context manager so that one can temporarily set or unset environment
   variables.
 
-- Added guard_warnings_filter to test.test_support.  It returns a context
-  manager that protects the 'warnings' module's filter from being mutated
-  once the context has been exited.
-
 - Added some tests for modulefinder.
 
 - Converted test_imp to use unittest.
@@ -834,6 +891,9 @@
 Tools
 -----
 
+- Tools/18n/pygettext.py was added to the list of scripts installed by
+  Tools/scripts/setup.py (tracker item 642309).
+
 - Added IronPython and Jython support to pybench (part of which
   was patch #1563844)
 
@@ -844,10 +904,12 @@
   platform.python_implementation(); this will now be saved
   in the benchmark pickle
 
-
 Documentation
 -------------
 
+- Bug #1637365: add subsection about "__name__ == __main__" to the
+  Python tutorial.
+
 - Patch #1698768: updated the "using Python on the Mac" intro.
 
 - Bug #1569057: Document that calling file.next() when the file is open for
@@ -898,6 +960,15 @@
 Build
 -----
 
+- Patch #786737: Allow building in a tree of symlinks pointing to
+  a readonly source.
+
+- Bug #1737210: Change Manufacturer of Windows installer to PSF.
+
+- Bug #1746880: Correctly install DLLs into system32 folder on Win64.
+
+- Define _BSD_SOURCE, to get access to POSIX extensions on OpenBSD 4.1+.
+
 - Stop supporting AtheOS and cause a build error in configure for the platform.
 
 - Bug #1655392: don't add -L/usr/lib/pythonX.Y/config to the LDFLAGS
@@ -928,6 +999,10 @@
 
 - Fix the build of the library reference in info format.
 
+- Allow Emacs 22 for building the documentation in info format.
+
+- Makefile.pre.in(buildbottest): Run an optional script pybuildbot.identify
+  to include some information about the build environment.
 
 C API
 -----

Modified: python/branches/bcannon-objcap/Misc/build.sh
==============================================================================
--- python/branches/bcannon-objcap/Misc/build.sh	(original)
+++ python/branches/bcannon-objcap/Misc/build.sh	Thu Sep  6 21:35:45 2007
@@ -214,17 +214,22 @@
 cd $DIR/Doc
 F="make-doc.out"
 start=`current_time`
+# XXX(nnorwitz): For now, keep the code that checks for a conflicted file until
+# after the first release of 2.6a1 or 3.0a1.  At that point, it will be clear
+# if there will be a similar problem with the new doc system.
+
 # Doc/commontex/boilerplate.tex is expected to always have an outstanding
 # modification for the date.  When a release is cut, a conflict occurs.
 # This allows us to detect this problem and not try to build the docs
 # which will definitely fail with a conflict. 
-CONFLICTED_FILE=commontex/boilerplate.tex
-conflict_count=`grep -c "<<<" $CONFLICTED_FILE`
+#CONFLICTED_FILE=commontex/boilerplate.tex
+#conflict_count=`grep -c "<<<" $CONFLICTED_FILE`
+conflict_count=0
 if [ $conflict_count != 0 ]; then
     echo "Conflict detected in $CONFLICTED_FILE.  Doc build skipped." > ../build/$F
     err=1
 else
-    make >& ../build/$F
+    make update html >& ../build/$F
     err=$?
 fi
 update_status "Making doc" "$F" $start
@@ -238,6 +243,6 @@
 echo "</html>" >> $RESULT_FILE
 
 ## copy results
-rsync $RSYNC_OPTS html/* $REMOTE_SYSTEM:$REMOTE_DIR
+rsync $RSYNC_OPTS build/html/* $REMOTE_SYSTEM:$REMOTE_DIR
 cd ../build
 rsync $RSYNC_OPTS index.html *.out $REMOTE_SYSTEM:$REMOTE_DIR/results/

Modified: python/branches/bcannon-objcap/Misc/developers.txt
==============================================================================
--- python/branches/bcannon-objcap/Misc/developers.txt	(original)
+++ python/branches/bcannon-objcap/Misc/developers.txt	Thu Sep  6 21:35:45 2007
@@ -17,13 +17,17 @@
 Permissions History
 -------------------
 
-- Senthil Kumaran  was given SVN access on June 16 2007
-  by MvL, for his Summer-of-Code project, mentored by
-  Skip Montanaro.
-
-- Alexandre Vassalotti was given SVN access on May 21 2007
-  by MvL, for his Summer-of-Code project, mentored by
-  Brett Cannon.
+- Bill Janssen was given SVN access on 28 August 2007 by NCN,
+  for his work on the SSL module and other things related to (SSL) sockets.
+
+- Jeffrey Yasskin was given SVN access on 9 August 2007 by NCN,
+  for his work on PEPs and other general patches. 
+
+- Senthil Kumaran was given SVN access on 16 June 2007 by MvL,
+  for his Summer-of-Code project, mentored by Skip Montanaro.
+
+- Alexandre Vassalotti was given SVN access on 21 May 2007 by MvL,
+  for his Summer-of-Code project, mentored by Brett Cannon.
 
 - Travis Oliphant was given SVN access on 17 Apr 2007 by MvL,
   for implementing the extended buffer protocol.

Modified: python/branches/bcannon-objcap/Modules/_bsddb.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_bsddb.c	(original)
+++ python/branches/bcannon-objcap/Modules/_bsddb.c	Thu Sep  6 21:35:45 2007
@@ -300,13 +300,13 @@
 
 staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
 
-#define DBObject_Check(v)           ((v)->ob_type == &DB_Type)
-#define DBCursorObject_Check(v)     ((v)->ob_type == &DBCursor_Type)
-#define DBEnvObject_Check(v)        ((v)->ob_type == &DBEnv_Type)
-#define DBTxnObject_Check(v)        ((v)->ob_type == &DBTxn_Type)
-#define DBLockObject_Check(v)       ((v)->ob_type == &DBLock_Type)
+#define DBObject_Check(v)           (Py_Type(v) == &DB_Type)
+#define DBCursorObject_Check(v)     (Py_Type(v) == &DBCursor_Type)
+#define DBEnvObject_Check(v)        (Py_Type(v) == &DBEnv_Type)
+#define DBTxnObject_Check(v)        (Py_Type(v) == &DBTxn_Type)
+#define DBLockObject_Check(v)       (Py_Type(v) == &DBLock_Type)
 #if (DBVER >= 43)
-#define DBSequenceObject_Check(v)   ((v)->ob_type == &DBSequence_Type)
+#define DBSequenceObject_Check(v)   (Py_Type(v) == &DBSequence_Type)
 #endif
 
 
@@ -461,7 +461,7 @@
     else {
         PyErr_Format(PyExc_TypeError,
                      "String or Integer object expected for key, %s found",
-                     keyobj->ob_type->tp_name);
+                     Py_Type(keyobj)->tp_name);
         return 0;
     }
 
@@ -616,7 +616,7 @@
 static void makeTypeError(char* expected, PyObject* found)
 {
     PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
-                 expected, found->ob_type->tp_name);
+                 expected, Py_Type(found)->tp_name);
 }
 
 
@@ -5666,13 +5666,13 @@
 
     /* Initialize the type of the new type objects here; doing it here
        is required for portability to Windows without requiring C++. */
-    DB_Type.ob_type = &PyType_Type;
-    DBCursor_Type.ob_type = &PyType_Type;
-    DBEnv_Type.ob_type = &PyType_Type;
-    DBTxn_Type.ob_type = &PyType_Type;
-    DBLock_Type.ob_type = &PyType_Type;
+    Py_Type(&DB_Type) = &PyType_Type;
+    Py_Type(&DBCursor_Type) = &PyType_Type;
+    Py_Type(&DBEnv_Type) = &PyType_Type;
+    Py_Type(&DBTxn_Type) = &PyType_Type;
+    Py_Type(&DBLock_Type) = &PyType_Type;
 #if (DBVER >= 43)    
-    DBSequence_Type.ob_type = &PyType_Type;
+    Py_Type(&DBSequence_Type) = &PyType_Type;
 #endif    
 
 

Modified: python/branches/bcannon-objcap/Modules/_codecsmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_codecsmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_codecsmodule.c	Thu Sep  6 21:35:45 2007
@@ -10,7 +10,7 @@
 
      register(search_function) -> None
 
-     lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)
+     lookup(encoding) -> CodecInfo object
 
    The builtin Unicode codecs use the following interface:
 
@@ -45,7 +45,8 @@
 \n\
 Register a codec search function. Search functions are expected to take\n\
 one argument, the encoding name in all lower case letters, and return\n\
-a tuple of functions (encoder, decoder, stream_reader, stream_writer).");
+a tuple of functions (encoder, decoder, stream_reader, stream_writer)\n\
+(or a CodecInfo object).");
 
 static
 PyObject *codec_register(PyObject *self, PyObject *search_function)
@@ -57,10 +58,10 @@
 }
 
 PyDoc_STRVAR(lookup__doc__,
-"lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)\n\
+"lookup(encoding) -> CodecInfo\n\
 \n\
 Looks up a codec tuple in the Python codec registry and returns\n\
-a tuple of functions.");
+a tuple of function (or a CodecInfo object).");
 
 static
 PyObject *codec_lookup(PyObject *self, PyObject *args)
@@ -391,6 +392,126 @@
 }
 
 static PyObject *
+utf_32_decode(PyObject *self,
+	    PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 0;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_32_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+    if (size < 0) {
+	    PyErr_SetString(PyExc_ValueError, "negative argument");
+	    return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
+					    final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+}
+
+static PyObject *
+utf_32_le_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = -1;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_32_le_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+
+    if (size < 0) {
+          PyErr_SetString(PyExc_ValueError, "negative argument");
+          return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
+	&byteorder, final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+
+}
+
+static PyObject *
+utf_32_be_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 1;
+    int final = 0;
+    Py_ssize_t consumed;
+    PyObject *decoded = NULL;
+
+    if (!PyArg_ParseTuple(args, "t#|zi:utf_32_be_decode",
+			  &data, &size, &errors, &final))
+	return NULL;
+    if (size < 0) {
+          PyErr_SetString(PyExc_ValueError, "negative argument");
+          return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    decoded = PyUnicode_DecodeUTF32Stateful(data, size, errors,
+	&byteorder, final ? NULL : &consumed);
+    if (decoded == NULL)
+	return NULL;
+    return codec_tuple(decoded, consumed);
+}
+
+/* This non-standard version also provides access to the byteorder
+   parameter of the builtin UTF-32 codec.
+
+   It returns a tuple (unicode, bytesread, byteorder) with byteorder
+   being the value in effect at the end of data.
+
+*/
+
+static PyObject *
+utf_32_ex_decode(PyObject *self,
+		 PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = 0;
+    PyObject *unicode, *tuple;
+    int final = 0;
+    Py_ssize_t consumed;
+
+    if (!PyArg_ParseTuple(args, "t#|zii:utf_32_ex_decode",
+			  &data, &size, &errors, &byteorder, &final))
+	return NULL;
+    if (size < 0) {
+	    PyErr_SetString(PyExc_ValueError, "negative argument");
+	    return 0;
+    }
+    consumed = size; /* This is overwritten unless final is true. */
+    unicode = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder,
+					    final ? NULL : &consumed);
+    if (unicode == NULL)
+	return NULL;
+    tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
+    Py_DECREF(unicode);
+    return tuple;
+}
+
+static PyObject *
 unicode_escape_decode(PyObject *self,
 		     PyObject *args)
 {
@@ -682,6 +803,83 @@
     return v;
 }
 
+/* This version provides access to the byteorder parameter of the
+   builtin UTF-32 codecs as optional third argument. It defaults to 0
+   which means: use the native byte order and prepend the data with a
+   BOM mark.
+
+*/
+
+static PyObject *
+utf_32_encode(PyObject *self,
+	    PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+    int byteorder = 0;
+
+    if (!PyArg_ParseTuple(args, "O|zi:utf_32_encode",
+			  &str, &errors, &byteorder))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(str),
+					  PyUnicode_GET_SIZE(str),
+					  errors,
+					  byteorder),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+utf_32_le_encode(PyObject *self,
+		 PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_32_le_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(str),
+					     PyUnicode_GET_SIZE(str),
+					     errors,
+					     -1),
+		       PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
+static PyObject *
+utf_32_be_encode(PyObject *self,
+		 PyObject *args)
+{
+    PyObject *str, *v;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "O|z:utf_32_be_encode",
+			  &str, &errors))
+	return NULL;
+
+    str = PyUnicode_FromObject(str);
+    if (str == NULL)
+	return NULL;
+    v = codec_tuple(PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(str),
+					  PyUnicode_GET_SIZE(str),
+					  errors,
+					  +1),
+		    PyUnicode_GET_SIZE(str));
+    Py_DECREF(str);
+    return v;
+}
+
 static PyObject *
 unicode_escape_encode(PyObject *self,
 		     PyObject *args)
@@ -900,6 +1098,13 @@
     {"utf_16_le_decode",	utf_16_le_decode,		METH_VARARGS},
     {"utf_16_be_decode",	utf_16_be_decode,		METH_VARARGS},
     {"utf_16_ex_decode",	utf_16_ex_decode,		METH_VARARGS},
+    {"utf_32_encode",		utf_32_encode,			METH_VARARGS},
+    {"utf_32_le_encode",	utf_32_le_encode,		METH_VARARGS},
+    {"utf_32_be_encode",	utf_32_be_encode,		METH_VARARGS},
+    {"utf_32_decode",		utf_32_decode,			METH_VARARGS},
+    {"utf_32_le_decode",	utf_32_le_decode,		METH_VARARGS},
+    {"utf_32_be_decode",	utf_32_be_decode,		METH_VARARGS},
+    {"utf_32_ex_decode",	utf_32_ex_decode,		METH_VARARGS},
     {"unicode_escape_encode",	unicode_escape_encode,		METH_VARARGS},
     {"unicode_escape_decode",	unicode_escape_decode,		METH_VARARGS},
     {"unicode_internal_encode",	unicode_internal_encode,	METH_VARARGS},

Modified: python/branches/bcannon-objcap/Modules/_collectionsmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_collectionsmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_collectionsmodule.c	Thu Sep  6 21:35:45 2007
@@ -544,7 +544,7 @@
 	}
 	deque->leftblock = NULL;
 	deque->rightblock = NULL;
-	deque->ob_type->tp_free(deque);
+	Py_Type(deque)->tp_free(deque);
 }
 
 static int
@@ -579,7 +579,7 @@
 static PyObject *
 deque_copy(PyObject *deque)
 {
-	return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
+	return PyObject_CallFunctionObjArgs((PyObject *)(Py_Type(deque)),
 		deque, NULL);
 }
 
@@ -601,7 +601,7 @@
 		Py_DECREF(dict);
 		return NULL;
 	}
-	result = Py_BuildValue("O()ON", deque->ob_type, dict, it);
+	result = Py_BuildValue("O()ON", Py_Type(deque), dict, it);
 	Py_DECREF(dict);
 	return result;
 }
@@ -825,8 +825,7 @@
 Build an ordered collection accessible from endpoints only.");
 
 static PyTypeObject deque_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"collections.deque",		/* tp_name */
 	sizeof(dequeobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -903,7 +902,7 @@
 dequeiter_dealloc(dequeiterobject *dio)
 {
 	Py_XDECREF(dio->deque);
-	dio->ob_type->tp_free(dio);
+	Py_Type(dio)->tp_free(dio);
 }
 
 static PyObject *
@@ -948,8 +947,7 @@
 };
 
 PyTypeObject dequeiter_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"deque_iterator",			/* tp_name */
 	sizeof(dequeiterobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1031,8 +1029,7 @@
 }
 
 PyTypeObject dequereviter_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"deque_reverse_iterator",		/* tp_name */
 	sizeof(dequeiterobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1113,7 +1110,7 @@
 	   whose class constructor has the same signature.  Subclasses that
 	   define a different constructor signature must override copy().
 	*/
-	return PyObject_CallFunctionObjArgs((PyObject *)dd->dict.ob_type,
+	return PyObject_CallFunctionObjArgs(Py_Type(dd),
 					    dd->default_factory, dd, NULL);
 }
 
@@ -1156,7 +1153,7 @@
 		Py_DECREF(args);
 		return NULL;
 	}
-	result = PyTuple_Pack(5, dd->dict.ob_type, args,
+	result = PyTuple_Pack(5, Py_Type(dd), args,
 			      Py_None, Py_None, items);
 	Py_DECREF(items);
 	Py_DECREF(args);
@@ -1288,8 +1285,7 @@
 #define DEFERRED_ADDRESS(ADDR) 0
 
 static PyTypeObject defdict_type = {
-	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
 	"collections.defaultdict",	/* tp_name */
 	sizeof(defdictobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_csv.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_csv.c	(original)
+++ python/branches/bcannon-objcap/Modules/_csv.c	Thu Sep  6 21:35:45 2007
@@ -125,7 +125,7 @@
 
 staticforward PyTypeObject Reader_Type;
 
-#define ReaderObject_Check(v)   ((v)->ob_type == &Reader_Type)
+#define ReaderObject_Check(v)   (Py_Type(v) == &Reader_Type)
 
 typedef struct {
         PyObject_HEAD
@@ -310,7 +310,7 @@
 Dialect_dealloc(DialectObj *self)
 {
         Py_XDECREF(self->lineterminator);
-        self->ob_type->tp_free((PyObject *)self);
+        Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static char *dialect_kws[] = {
@@ -460,8 +460,7 @@
 "The Dialect type records CSV parsing and generation options.\n");
 
 static PyTypeObject Dialect_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,                                      /* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_csv.Dialect",                         /* tp_name */
 	sizeof(DialectObj),                     /* tp_basicsize */
 	0,                                      /* tp_itemsize */
@@ -869,8 +868,7 @@
 
 
 static PyTypeObject Reader_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,                                      /*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_csv.reader",                          /*tp_name*/
 	sizeof(ReaderObj),                      /*tp_basicsize*/
 	0,                                      /*tp_itemsize*/
@@ -1280,8 +1278,7 @@
 );
 
 static PyTypeObject Writer_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,                                      /*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_csv.writer",                          /*tp_name*/
 	sizeof(WriterObj),                      /*tp_basicsize*/
 	0,                                      /*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/_ctypes.c	Thu Sep  6 21:35:45 2007
@@ -333,7 +333,7 @@
 			Py_INCREF(value);
 			return value;
 		}
-		ob_name = (ob) ? ob->ob_type->tp_name : "???";
+		ob_name = (ob) ? Py_Type(ob)->tp_name : "???";
 		PyErr_Format(PyExc_TypeError,
 			     "expected %s instance instead of pointer to %s",
 			     ((PyTypeObject *)type)->tp_name, ob_name);
@@ -349,7 +349,7 @@
 	PyErr_Format(PyExc_TypeError,
 		     "expected %s instance instead of %s",
 		     ((PyTypeObject *)type)->tp_name,
-		     value->ob_type->tp_name);
+		     Py_Type(value)->tp_name);
 	return NULL;
 }
 
@@ -435,8 +435,7 @@
 
 
 PyTypeObject StructType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.StructType",			/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -478,8 +477,7 @@
 };
 
 static PyTypeObject UnionType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.UnionType",			/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -693,8 +691,7 @@
 };
 
 PyTypeObject PointerType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.PointerType",				/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -751,7 +748,7 @@
 	char *ptr;
 	Py_ssize_t size;
 	if (PyBuffer_Check(value)) {
-		size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
+		size = Py_Type(value)->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
 		if (size < 0)
 			return -1;
 	} else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
@@ -800,7 +797,7 @@
 	} else if (!PyString_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 			     "string expected instead of %s instance",
-			     value->ob_type->tp_name);
+			     Py_Type(value)->tp_name);
 		return -1;
 	} else
 		Py_INCREF(value);
@@ -855,7 +852,7 @@
 	} else if (!PyUnicode_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 				"unicode string expected instead of %s instance",
-				value->ob_type->tp_name);
+				Py_Type(value)->tp_name);
 		return -1;
 	} else
 		Py_INCREF(value);
@@ -1051,8 +1048,7 @@
 }
 
 PyTypeObject ArrayType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.ArrayType",			/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1684,8 +1680,7 @@
 };
 
 PyTypeObject SimpleType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.SimpleType",				/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1899,8 +1894,7 @@
 }
 
 PyTypeObject CFuncPtrType_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.CFuncPtrType",			/* tp_name */
 	0,					/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2076,7 +2070,7 @@
 CData_dealloc(PyObject *self)
 {
 	CData_clear((CDataObject *)self);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyMemberDef CData_members[] = {
@@ -2143,8 +2137,7 @@
 };
 
 PyTypeObject CData_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes._CData",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2350,7 +2343,7 @@
 			PyErr_Format(PyExc_TypeError,
 				     "expected %s instance, got %s",
 				     ((PyTypeObject *)type)->tp_name,
-				     value->ob_type->tp_name);
+				     Py_Type(value)->tp_name);
 			return NULL;
 		}
 	}
@@ -2381,7 +2374,7 @@
 		if (p1->proto != p2->proto) {
 			PyErr_Format(PyExc_TypeError,
 				     "incompatible types, %s instance instead of %s instance",
-				     value->ob_type->tp_name,
+				     Py_Type(value)->tp_name,
 				     ((PyTypeObject *)type)->tp_name);
 			return NULL;
 		}
@@ -2400,7 +2393,7 @@
 	}
 	PyErr_Format(PyExc_TypeError,
 		     "incompatible types, %s instance instead of %s instance",
-		     value->ob_type->tp_name,
+		     Py_Type(value)->tp_name,
 		     ((PyTypeObject *)type)->tp_name);
 	return NULL;
 }
@@ -2661,7 +2654,7 @@
 		     Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
 		     PyType_Check(arg) ?
 		     ((PyTypeObject *)arg)->tp_name :
-		     arg->ob_type->tp_name);
+		     Py_Type(arg)->tp_name);
 	return 0;
 }
 
@@ -3447,7 +3440,7 @@
 CFuncPtr_dealloc(CFuncPtrObject *self)
 {
 	CFuncPtr_clear(self);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static PyObject *
@@ -3457,17 +3450,16 @@
 	if (self->index)
 		return PyString_FromFormat("<COM method offset %d: %s at %p>",
 					   self->index - 0x1000,
-					   self->ob_type->tp_name,
+					   Py_Type(self)->tp_name,
 					   self);
 #endif
 	return PyString_FromFormat("<%s object at %p>",
-				   self->ob_type->tp_name,
+				   Py_Type(self)->tp_name,
 				   self);
 }
 
 PyTypeObject CFuncPtr_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.CFuncPtr",
 	sizeof(CFuncPtrObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3595,8 +3587,7 @@
 }
 
 static PyTypeObject Struct_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.Structure",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3638,8 +3629,7 @@
 };
 
 static PyTypeObject Union_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.Union",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3778,6 +3768,108 @@
 	return (PyObject *)np;
 }
 
+static PyObject *
+Array_subscript(PyObject *_self, PyObject *item)
+{
+	CDataObject *self = (CDataObject *)_self;
+
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += self->b_length;
+		return Array_item(_self, i);
+	}
+	else if PySlice_Check(item) {
+		StgDictObject *stgdict, *itemdict;
+		PyObject *proto;
+		PyObject *np;
+		Py_ssize_t start, stop, step, slicelen, cur, i;
+		
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 self->b_length, &start, &stop,
+					 &step, &slicelen) < 0) {
+			return NULL;
+		}
+		
+		stgdict = PyObject_stgdict((PyObject *)self);
+		assert(stgdict); /* Cannot be NULL for array object instances */
+		proto = stgdict->proto;
+		itemdict = PyType_stgdict(proto);
+		assert(itemdict); /* proto is the item type of the array, a
+				     ctypes type, so this cannot be NULL */
+
+		if (itemdict->getfunc == getentry("c")->getfunc) {
+			char *ptr = (char *)self->b_ptr;
+			char *dest;
+
+			if (slicelen <= 0)
+				return PyString_FromString("");
+			if (step == 1) {
+				return PyString_FromStringAndSize(ptr + start,
+								  slicelen);
+			}
+			dest = (char *)PyMem_Malloc(slicelen);
+
+			if (dest == NULL)
+				return PyErr_NoMemory();
+
+			for (cur = start, i = 0; i < slicelen;
+			     cur += step, i++) {
+				dest[i] = ptr[cur];
+			}
+
+			np = PyString_FromStringAndSize(dest, slicelen);
+			PyMem_Free(dest);
+			return np;
+		}
+#ifdef CTYPES_UNICODE
+		if (itemdict->getfunc == getentry("u")->getfunc) {
+			wchar_t *ptr = (wchar_t *)self->b_ptr;
+			wchar_t *dest;
+			
+			if (slicelen <= 0)
+				return PyUnicode_FromUnicode(NULL, 0);
+			if (step == 1) {
+				return PyUnicode_FromWideChar(ptr + start,
+							      slicelen);
+			}
+
+			dest = (wchar_t *)PyMem_Malloc(
+						slicelen * sizeof(wchar_t));
+			
+			for (cur = start, i = 0; i < slicelen;
+			     cur += step, i++) {
+				dest[i] = ptr[cur];
+			}
+			
+			np = PyUnicode_FromWideChar(dest, slicelen);
+			PyMem_Free(dest);
+			return np;
+		}
+#endif
+
+		np = PyList_New(slicelen);
+		if (np == NULL)
+			return NULL;
+
+		for (cur = start, i = 0; i < slicelen;
+		     cur += step, i++) {
+			PyObject *v = Array_item(_self, cur);
+			PyList_SET_ITEM(np, i, v);
+		}
+		return np;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError, 
+				"indices must be integers");
+		return NULL;
+	}
+
+}
+
 static int
 Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
 {
@@ -3849,6 +3941,63 @@
 	return 0;
 }
 
+static int
+Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
+{
+	CDataObject *self = (CDataObject *)_self;
+	
+	if (value == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+				"Array does not support item deletion");
+		return -1;
+	}
+
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += self->b_length;
+		return Array_ass_item(_self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
+		
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 self->b_length, &start, &stop,
+					 &step, &slicelen) < 0) {
+			return -1;
+		}
+		if ((step < 0 && start < stop) ||
+		    (step > 0 && start > stop))
+			stop = start;
+
+		otherlen = PySequence_Length(value);
+		if (otherlen != slicelen) {
+			PyErr_SetString(PyExc_ValueError,
+				"Can only assign sequence of same size");
+			return -1;
+		}
+		for (cur = start, i = 0; i < otherlen; cur += step, i++) {
+			PyObject *item = PySequence_GetItem(value, i);
+			int result;
+			if (item == NULL)
+				return -1;
+			result = Array_ass_item(_self, cur, item);
+			Py_DECREF(item);
+			if (result == -1)
+				return -1;
+		}
+		return 0;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"indices must be integer");
+		return -1;
+	}
+}
+
 static Py_ssize_t
 Array_length(PyObject *_self)
 {
@@ -3870,9 +4019,14 @@
 	0,					/* sq_inplace_repeat; */
 };
 
+static PyMappingMethods Array_as_mapping = {
+	Array_length,
+	Array_subscript,
+	Array_ass_subscript,
+};
+
 PyTypeObject Array_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.Array",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3884,7 +4038,7 @@
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
 	&Array_as_sequence,			/* tp_as_sequence */
-	0,					/* tp_as_mapping */
+	&Array_as_mapping,			/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
 	0,					/* tp_str */
@@ -4025,7 +4179,7 @@
 static PyObject *
 Simple_from_outparm(PyObject *self, PyObject *args)
 {
-	if (IsSimpleSubType((PyObject *)self->ob_type)) {
+	if (IsSimpleSubType((PyObject *)Py_Type(self))) {
 		Py_INCREF(self);
 		return self;
 	}
@@ -4090,9 +4244,9 @@
 	PyObject *val, *name, *args, *result;
 	static PyObject *format;
 
-	if (self->ob_type->tp_base != &Simple_Type) {
+	if (Py_Type(self)->tp_base != &Simple_Type) {
 		return PyString_FromFormat("<%s object at %p>",
-					   self->ob_type->tp_name, self);
+					   Py_Type(self)->tp_name, self);
 	}
 
 	if (format == NULL) {
@@ -4105,7 +4259,7 @@
 	if (val == NULL)
 		return NULL;
 
-	name = PyString_FromString(self->ob_type->tp_name);
+	name = PyString_FromString(Py_Type(self)->tp_name);
 	if (name == NULL) {
 		Py_DECREF(val);
 		return NULL;
@@ -4123,8 +4277,7 @@
 }
 
 static PyTypeObject Simple_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes._SimpleCData",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -4277,7 +4430,7 @@
 		PyErr_Format(PyExc_TypeError,
 			     "expected %s instead of %s",
 			     ((PyTypeObject *)(stgdict->proto))->tp_name,
-			     value->ob_type->tp_name);
+			     Py_Type(value)->tp_name);
 		return -1;
 	}
 
@@ -4371,6 +4524,139 @@
 	return (PyObject *)np;
 }
 
+static PyObject *
+Pointer_subscript(PyObject *_self, PyObject *item)
+{
+	CDataObject *self = (CDataObject *)_self;
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		return Pointer_item(_self, i);
+	}
+	else if (PySlice_Check(item)) {
+		PySliceObject *slice = (PySliceObject *)item;
+		Py_ssize_t start, stop, step;
+		PyObject *np;
+		StgDictObject *stgdict, *itemdict;
+		PyObject *proto;
+		Py_ssize_t i, len, cur;
+
+		/* Since pointers have no length, and we want to apply
+		   different semantics to negative indices than normal
+		   slicing, we have to dissect the slice object ourselves.*/
+		if (slice->step == Py_None) {
+			step = 1;
+		}
+		else {
+			step = PyNumber_AsSsize_t(slice->step,
+						  PyExc_ValueError);
+			if (step == -1 && PyErr_Occurred())
+				return NULL;
+			if (step == 0) {
+				PyErr_SetString(PyExc_ValueError,
+						"slice step cannot be zero");
+				return NULL;
+			}
+		}
+		if (slice->start == Py_None) {
+			if (step < 0) {
+				PyErr_SetString(PyExc_ValueError,
+						"slice start is required "
+						"for step < 0");
+				return NULL;
+			}
+			start = 0;
+		}
+		else {
+			start = PyNumber_AsSsize_t(slice->start,
+						   PyExc_ValueError);
+			if (start == -1 && PyErr_Occurred())
+				return NULL;
+		}
+		if (slice->stop == Py_None) {
+			PyErr_SetString(PyExc_ValueError,
+					"slice stop is required");
+			return NULL;
+		}
+		stop = PyNumber_AsSsize_t(slice->stop,
+					  PyExc_ValueError);
+		if (stop == -1 && PyErr_Occurred())
+			return NULL;
+		if ((step > 0 && start > stop) ||
+		    (step < 0 && start < stop))
+			len = 0;
+		else if (step > 0)
+			len = (stop - start - 1) / step + 1;
+		else
+			len = (stop - start + 1) / step + 1;
+
+		stgdict = PyObject_stgdict((PyObject *)self);
+		assert(stgdict); /* Cannot be NULL for pointer instances */
+		proto = stgdict->proto;
+		assert(proto);
+		itemdict = PyType_stgdict(proto);
+		assert(itemdict);
+		if (itemdict->getfunc == getentry("c")->getfunc) {
+			char *ptr = *(char **)self->b_ptr;
+			char *dest;
+			
+			if (len <= 0)
+                        	return PyString_FromString("");
+			if (step == 1) {
+				return PyString_FromStringAndSize(ptr + start,
+								  len);
+			}
+			dest = (char *)PyMem_Malloc(len);
+			if (dest == NULL)
+				return PyErr_NoMemory();
+			for (cur = start, i = 0; i < len; cur += step, i++) {
+				dest[i] = ptr[cur];
+			}
+			np = PyString_FromStringAndSize(dest, len);
+			PyMem_Free(dest);
+			return np;
+		}
+#ifdef CTYPES_UNICODE
+		if (itemdict->getfunc == getentry("u")->getfunc) {
+			wchar_t *ptr = *(wchar_t **)self->b_ptr;
+			wchar_t *dest;
+			
+			if (len <= 0)
+                        	return PyUnicode_FromUnicode(NULL, 0);
+			if (step == 1) {
+				return PyUnicode_FromWideChar(ptr + start,
+							      len);
+			}
+			dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
+			if (dest == NULL)
+				return PyErr_NoMemory();
+			for (cur = start, i = 0; i < len; cur += step, i++) {
+				dest[i] = ptr[cur];
+			}
+			np = PyUnicode_FromWideChar(dest, len);
+			PyMem_Free(dest);
+			return np;
+		}
+#endif
+
+		np = PyList_New(len);
+		if (np == NULL)
+			return NULL;
+
+		for (cur = start, i = 0; i < len; cur += step, i++) {
+			PyObject *v = Pointer_item(_self, cur);
+			PyList_SET_ITEM(np, i, v);
+		}
+		return np;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"Pointer indices must be integer");
+		return NULL;
+	}
+}
+
 static PySequenceMethods Pointer_as_sequence = {
 	0,					/* inquiry sq_length; */
 	0,					/* binaryfunc sq_concat; */
@@ -4385,6 +4671,11 @@
 	0,					/* intargfunc sq_inplace_repeat; */
 };
 
+static PyMappingMethods Pointer_as_mapping = {
+	0,
+	Pointer_subscript,
+};
+
 static int
 Pointer_nonzero(CDataObject *self)
 {
@@ -4406,8 +4697,7 @@
 };
 
 PyTypeObject Pointer_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes._Pointer",
 	sizeof(CDataObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -4419,7 +4709,7 @@
 	0,					/* tp_repr */
 	&Pointer_as_number,			/* tp_as_number */
 	&Pointer_as_sequence,			/* tp_as_sequence */
-	0,					/* tp_as_mapping */
+	&Pointer_as_mapping,			/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
 	0,					/* tp_str */
@@ -4520,11 +4810,6 @@
 	PyObject *s;
 	int status;
 
-	ComError = PyErr_NewException("_ctypes.COMError",
-				      NULL,
-				      dict);
-	if (ComError == NULL)
-		return -1;
 	while (methods->ml_name) {
 		/* get a wrapper for the built-in function */
 		PyObject *func = PyCFunction_New(methods, NULL);
@@ -4539,13 +4824,24 @@
 		Py_DECREF(meth);
 		++methods;
 	}
-	Py_INCREF(ComError);
+
 	s = PyString_FromString(comerror_doc);
 	if (s == NULL)
 		return -1;
 	status = PyDict_SetItemString(dict, "__doc__", s);
 	Py_DECREF(s);
-	return status;
+	if (status == -1) {
+		Py_DECREF(dict);
+		return -1;
+	}
+
+	ComError = PyErr_NewException("_ctypes.COMError",
+				      NULL,
+				      dict);
+	if (ComError == NULL)
+		return -1;
+
+	return 0;
 }
 
 #endif
@@ -4579,7 +4875,7 @@
 		     "cast() argument 2 must be a pointer type, not %s",
 		     PyType_Check(arg)
 		     ? ((PyTypeObject *)arg)->tp_name
-		     : arg->ob_type->tp_name);
+		     : Py_Type(arg)->tp_name);
 	return 0;
 }
 
@@ -4706,37 +5002,37 @@
 	if (PyType_Ready(&CData_Type) < 0)
 		return;
 
-	Struct_Type.ob_type = &StructType_Type;
+	Py_Type(&Struct_Type) = &StructType_Type;
 	Struct_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Struct_Type) < 0)
 		return;
 	PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
 
-	Union_Type.ob_type = &UnionType_Type;
+	Py_Type(&Union_Type) = &UnionType_Type;
 	Union_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Union_Type) < 0)
 		return;
 	PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
 
-	Pointer_Type.ob_type = &PointerType_Type;
+	Py_Type(&Pointer_Type) = &PointerType_Type;
 	Pointer_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Pointer_Type) < 0)
 		return;
 	PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
 
-	Array_Type.ob_type = &ArrayType_Type;
+	Py_Type(&Array_Type) = &ArrayType_Type;
 	Array_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Array_Type) < 0)
 		return;
 	PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
 
-	Simple_Type.ob_type = &SimpleType_Type;
+	Py_Type(&Simple_Type) = &SimpleType_Type;
 	Simple_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Simple_Type) < 0)
 		return;
 	PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
 
-	CFuncPtr_Type.ob_type = &CFuncPtrType_Type;
+	Py_Type(&CFuncPtr_Type) = &CFuncPtrType_Type;
 	CFuncPtr_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&CFuncPtr_Type) < 0)
 		return;

Modified: python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/callbacks.c	Thu Sep  6 21:35:45 2007
@@ -268,7 +268,7 @@
 	ffi_abi cc;
 
 	nArgs = PySequence_Size(converters);
-	p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
+	p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs));
 	if (p == NULL) {
 		PyErr_NoMemory();
 		return NULL;

Modified: python/branches/bcannon-objcap/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/callproc.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/callproc.c	Thu Sep  6 21:35:45 2007
@@ -381,8 +381,7 @@
 };
 
 PyTypeObject PyCArg_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"CArgObject",
 	sizeof(PyCArgObject),
 	0,
@@ -1180,7 +1179,7 @@
 	if (!CDataObject_Check(pcom) || (pcom->b_size != sizeof(void *))) {
 		PyErr_Format(PyExc_TypeError,
 			     "COM Pointer expected instead of %s instance",
-			     pcom->ob_type->tp_name);
+			     Py_Type(pcom)->tp_name);
 		return NULL;
 	}
 
@@ -1420,7 +1419,7 @@
 	if (!CDataObject_Check(obj)) {
 		PyErr_Format(PyExc_TypeError,
 			     "byref() argument must be a ctypes instance, not '%s'",
-			     obj->ob_type->tp_name);
+			     Py_Type(obj)->tp_name);
 		return NULL;
 	}
 

Modified: python/branches/bcannon-objcap/Modules/_ctypes/cfield.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/cfield.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/cfield.c	Thu Sep  6 21:35:45 2007
@@ -286,8 +286,7 @@
 }
 
 PyTypeObject CField_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_ctypes.CField",				/* tp_name */
 	sizeof(CFieldObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_ctypes/ctypes.h
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/ctypes.h	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/ctypes.h	Thu Sep  6 21:35:45 2007
@@ -75,7 +75,7 @@
 	PyObject *callable;
 	SETFUNC setfunc;
 	ffi_type *restype;
-	ffi_type *atypes[0];
+	ffi_type *atypes[1];
 } ffi_info;
 
 typedef struct {

Modified: python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure	Thu Sep  6 21:35:45 2007
@@ -3533,7 +3533,7 @@
 sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
 sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
 sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
-hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;;
+hppa*-*-linux* | parisc*-*-linux*) TARGET=PA; TARGETDIR=pa;;
 esac
 
 if test $TARGETDIR = unknown; then

Modified: python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure.ac
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure.ac	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/libffi/configure.ac	Thu Sep  6 21:35:45 2007
@@ -71,7 +71,7 @@
 sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
 sh-*-rtems*) TARGET=SH; TARGETDIR=sh;;
 sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
-hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;;
+hppa*-*-linux* | parisc*-*-linux*) TARGET=PA; TARGETDIR=pa;;
 esac
 
 if test $TARGETDIR = unknown; then

Modified: python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ctypes/stgdict.c	Thu Sep  6 21:35:45 2007
@@ -83,8 +83,7 @@
 }
 
 PyTypeObject StgDict_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"StgDict",
 	sizeof(StgDictObject),
 	0,
@@ -192,7 +191,7 @@
 			Py_DECREF(fieldlist);
 			return -1;
 		}
-		if (fdescr->ob_type != &CField_Type) {
+		if (Py_Type(fdescr) != &CField_Type) {
 			PyErr_SetString(PyExc_TypeError, "unexpected type");
 			Py_DECREF(fdescr);
 			Py_DECREF(fieldlist);
@@ -215,7 +214,7 @@
 			Py_DECREF(fieldlist);
 			return -1;
 		}
-		assert(new_descr->ob_type == &CField_Type);
+		assert(Py_Type(new_descr) == &CField_Type);
  		new_descr->size = fdescr->size;
  		new_descr->offset = fdescr->offset + offset;
  		new_descr->index = fdescr->index + index;
@@ -263,7 +262,7 @@
 			Py_DECREF(anon_names);
 			return -1;
 		}
-		assert(descr->ob_type == &CField_Type);
+		assert(Py_Type(descr) == &CField_Type);
 		descr->anonymous = 1;
 
 		/* descr is in the field descriptor. */
@@ -469,13 +468,11 @@
 
 		if (!prop) {
 			Py_DECREF(pair);
-			Py_DECREF((PyObject *)stgdict);
 			return -1;
 		}
 		if (-1 == PyDict_SetItem(realdict, name, prop)) {
 			Py_DECREF(prop);
 			Py_DECREF(pair);
-			Py_DECREF((PyObject *)stgdict);
 			return -1;
 		}
 		Py_DECREF(pair);

Modified: python/branches/bcannon-objcap/Modules/_curses_panel.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_curses_panel.c	(original)
+++ python/branches/bcannon-objcap/Modules/_curses_panel.c	Thu Sep  6 21:35:45 2007
@@ -56,7 +56,7 @@
 
 PyTypeObject PyCursesPanel_Type;
 
-#define PyCursesPanel_Check(v)	 ((v)->ob_type == &PyCursesPanel_Type)
+#define PyCursesPanel_Check(v)	 (Py_Type(v) == &PyCursesPanel_Type)
 
 /* Some helper functions. The problem is that there's always a window
    associated with a panel. To ensure that Python's GC doesn't pull
@@ -338,8 +338,7 @@
 /* -------------------------------------------------------*/
 
 PyTypeObject PyCursesPanel_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_curses_panel.curses panel",	/*tp_name*/
     sizeof(PyCursesPanelObject),	/*tp_basicsize*/
     0,			/*tp_itemsize*/
@@ -458,7 +457,7 @@
     PyObject *m, *d, *v;
 
     /* Initialize object type */
-    PyCursesPanel_Type.ob_type = &PyType_Type;
+    Py_Type(&PyCursesPanel_Type) = &PyType_Type;
 
     import_curses();
 

Modified: python/branches/bcannon-objcap/Modules/_cursesmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_cursesmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_cursesmodule.c	Thu Sep  6 21:35:45 2007
@@ -1566,8 +1566,7 @@
 /* -------------------------------------------------------*/
 
 PyTypeObject PyCursesWindow_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_curses.curses window",	/*tp_name*/
 	sizeof(PyCursesWindowObject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -2657,7 +2656,7 @@
 	static void *PyCurses_API[PyCurses_API_pointers];
 
 	/* Initialize object type */
-	PyCursesWindow_Type.ob_type = &PyType_Type;
+	Py_Type(&PyCursesWindow_Type) = &PyType_Type;
 
 	/* Initialize the C API pointer array */
 	PyCurses_API[0] = (void *)&PyCursesWindow_Type;

Modified: python/branches/bcannon-objcap/Modules/_elementtree.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_elementtree.c	(original)
+++ python/branches/bcannon-objcap/Modules/_elementtree.c	Thu Sep  6 21:35:45 2007
@@ -269,7 +269,7 @@
 
 staticforward PyTypeObject Element_Type;
 
-#define Element_CheckExact(op) ((op)->ob_type == &Element_Type)
+#define Element_CheckExact(op) (Py_Type(op) == &Element_Type)
 
 /* -------------------------------------------------------------------- */
 /* element constructor and destructor */
@@ -1207,7 +1207,7 @@
         /* FIXME: support arbitrary sequences? */
         PyErr_Format(
             PyExc_TypeError,
-            "expected list, not \"%.200s\"", item->ob_type->tp_name
+            "expected list, not \"%.200s\"", Py_Type(item)->tp_name
             );
         return -1;
     }
@@ -1440,7 +1440,7 @@
 
 staticforward PyTypeObject TreeBuilder_Type;
 
-#define TreeBuilder_CheckExact(op) ((op)->ob_type == &TreeBuilder_Type)
+#define TreeBuilder_CheckExact(op) (Py_Type(op) == &TreeBuilder_Type)
 
 /* -------------------------------------------------------------------- */
 /* constructor and destructor */
@@ -1607,7 +1607,7 @@
         Py_INCREF(data); self->data = data;
     } else {
         /* more than one item; use a list to collect items */
-        if (PyString_CheckExact(self->data) && self->data->ob_refcnt == 1 &&
+        if (PyString_CheckExact(self->data) && Py_Refcnt(self->data) == 1 &&
             PyString_CheckExact(data) && PyString_GET_SIZE(data) == 1) {
             /* expat often generates single character data sections; handle
                the most common case by resizing the existing string... */
@@ -2623,9 +2623,9 @@
 #endif
 
     /* Patch object type */
-    Element_Type.ob_type = TreeBuilder_Type.ob_type = &PyType_Type;
+    Py_Type(&Element_Type) = Py_Type(&TreeBuilder_Type) = &PyType_Type;
 #if defined(USE_EXPAT)
-    XMLParser_Type.ob_type = &PyType_Type;
+    Py_Type(&XMLParser_Type) = &PyType_Type;
 #endif
 
     m = Py_InitModule("_elementtree", _functions);

Modified: python/branches/bcannon-objcap/Modules/_functoolsmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_functoolsmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_functoolsmodule.c	Thu Sep  6 21:35:45 2007
@@ -81,7 +81,7 @@
 	Py_XDECREF(pto->args);
 	Py_XDECREF(pto->kw);
 	Py_XDECREF(pto->dict);
-	pto->ob_type->tp_free(pto);
+	Py_Type(pto)->tp_free(pto);
 }
 
 static PyObject *
@@ -197,8 +197,7 @@
 };
 
 static PyTypeObject partial_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"functools.partial",		/* tp_name */
 	sizeof(partialobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_hashopenssl.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_hashopenssl.c	(original)
+++ python/branches/bcannon-objcap/Modules/_hashopenssl.c	Thu Sep  6 21:35:45 2007
@@ -281,8 +281,7 @@
 digest_size -- number of bytes in this hashes output\n");
 
 static PyTypeObject EVPtype = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_hashlib.HASH",    /*tp_name*/
     sizeof(EVPobject),	/*tp_basicsize*/
     0,			/*tp_itemsize*/
@@ -464,7 +463,7 @@
      * but having some be unsupported.  Only init appropriate
      * constants. */
 
-    EVPtype.ob_type = &PyType_Type;
+    Py_Type(&EVPtype) = &PyType_Type;
     if (PyType_Ready(&EVPtype) < 0)
         return;
 

Modified: python/branches/bcannon-objcap/Modules/_hotshot.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_hotshot.c	(original)
+++ python/branches/bcannon-objcap/Modules/_hotshot.c	Thu Sep  6 21:35:45 2007
@@ -1220,8 +1220,7 @@
 "linetimings:  True if line events collect timing information.");
 
 static PyTypeObject ProfilerType = {
-    PyObject_HEAD_INIT(NULL)
-    0,					/* ob_size		*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_hotshot.ProfilerType",		/* tp_name		*/
     (int) sizeof(ProfilerObject),	/* tp_basicsize		*/
     0,					/* tp_itemsize		*/
@@ -1305,8 +1304,7 @@
 };
 
 static PyTypeObject LogReaderType = {
-    PyObject_HEAD_INIT(NULL)
-    0,					/* ob_size		*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_hotshot.LogReaderType",		/* tp_name		*/
     (int) sizeof(LogReaderObject),	/* tp_basicsize		*/
     0,					/* tp_itemsize		*/
@@ -1613,8 +1611,8 @@
 {
     PyObject *module;
 
-    LogReaderType.ob_type = &PyType_Type;
-    ProfilerType.ob_type = &PyType_Type;
+    Py_Type(&LogReaderType) = &PyType_Type;
+    Py_Type(&ProfilerType) = &PyType_Type;
     module = Py_InitModule("_hotshot", functions);
     if (module != NULL) {
         char *s = get_version_string();

Modified: python/branches/bcannon-objcap/Modules/_lsprof.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_lsprof.c	(original)
+++ python/branches/bcannon-objcap/Modules/_lsprof.c	Thu Sep  6 21:35:45 2007
@@ -120,7 +120,7 @@
 staticforward PyTypeObject PyProfiler_Type;
 
 #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type)
-#define PyProfiler_CheckExact(op) ((op)->ob_type == &PyProfiler_Type)
+#define PyProfiler_CheckExact(op) (Py_Type(op) == &PyProfiler_Type)
 
 /*** External Timers ***/
 
@@ -207,7 +207,7 @@
 		PyObject *self = fn->m_self;
 		PyObject *name = PyString_FromString(fn->m_ml->ml_name);
 		if (name != NULL) {
-			PyObject *mo = _PyType_Lookup(self->ob_type, name);
+			PyObject *mo = _PyType_Lookup(Py_Type(self), name);
 			Py_XINCREF(mo);
 			Py_DECREF(name);
 			if (mo != NULL) {
@@ -744,7 +744,7 @@
 	flush_unmatched(op);
 	clearEntries(op);
 	Py_XDECREF(op->externalTimer);
-	op->ob_type->tp_free(op);
+	Py_Type(op)->tp_free(op);
 }
 
 static int

Modified: python/branches/bcannon-objcap/Modules/_randommodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_randommodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_randommodule.c	Thu Sep  6 21:35:45 2007
@@ -84,7 +84,7 @@
 
 static PyTypeObject Random_Type;
 
-#define RandomObject_Check(v)	   ((v)->ob_type == &Random_Type)
+#define RandomObject_Check(v)	   (Py_Type(v) == &Random_Type)
 
 
 /* Random methods */
@@ -404,7 +404,7 @@
 	if (!PyInt_Check(n) && !PyLong_Check(n)) {
 		PyErr_Format(PyExc_TypeError, "jumpahead requires an "
 			     "integer, not '%s'",
-			     n->ob_type->tp_name);
+			     Py_Type(n)->tp_name);
 		return NULL;
 	}
 
@@ -518,8 +518,7 @@
 "Random() -> create a random number generator with its own internal state.");
 
 static PyTypeObject Random_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_random.Random",		/*tp_name*/
 	sizeof(RandomObject),		/*tp_basicsize*/
 	0,				/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/_sqlite/cache.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/cache.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/cache.c	Thu Sep  6 21:35:45 2007
@@ -51,7 +51,7 @@
     Py_DECREF(self->key);
     Py_DECREF(self->data);
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs)
@@ -109,7 +109,7 @@
     }
     Py_DECREF(self->mapping);
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args)
@@ -274,8 +274,7 @@
 };
 
 PyTypeObject pysqlite_NodeType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME "Node",                             /* tp_name */
         sizeof(pysqlite_Node),                          /* tp_basicsize */
         0,                                              /* tp_itemsize */
@@ -317,8 +316,7 @@
 };
 
 PyTypeObject pysqlite_CacheType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".Cache",                           /* tp_name */
         sizeof(pysqlite_Cache),                         /* tp_basicsize */
         0,                                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_sqlite/connection.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/connection.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/connection.c	Thu Sep  6 21:35:45 2007
@@ -205,7 +205,7 @@
     Py_XDECREF(self->collations);
     Py_XDECREF(self->statements);
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
@@ -1206,8 +1206,7 @@
 };
 
 PyTypeObject pysqlite_ConnectionType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".Connection",                      /* tp_name */
         sizeof(pysqlite_Connection),                    /* tp_basicsize */
         0,                                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_sqlite/cursor.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/cursor.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/cursor.c	Thu Sep  6 21:35:45 2007
@@ -134,7 +134,7 @@
     Py_XDECREF(self->row_factory);
     Py_XDECREF(self->next_row);
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 PyObject* _pysqlite_get_converter(PyObject* key)
@@ -1020,8 +1020,7 @@
 PyDoc_STR("SQLite database cursor class.");
 
 PyTypeObject pysqlite_CursorType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".Cursor",                          /* tp_name */
         sizeof(pysqlite_Cursor),                        /* tp_basicsize */
         0,                                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_sqlite/prepare_protocol.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/prepare_protocol.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/prepare_protocol.c	Thu Sep  6 21:35:45 2007
@@ -30,12 +30,11 @@
 
 void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self)
 {
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 PyTypeObject pysqlite_PrepareProtocolType= {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".PrepareProtocol",                 /* tp_name */
         sizeof(pysqlite_PrepareProtocol),               /* tp_basicsize */
         0,                                              /* tp_itemsize */
@@ -79,6 +78,6 @@
 extern int pysqlite_prepare_protocol_setup_types(void)
 {
     pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew;
-    pysqlite_PrepareProtocolType.ob_type= &PyType_Type;
+    Py_Type(&pysqlite_PrepareProtocolType)= &PyType_Type;
     return PyType_Ready(&pysqlite_PrepareProtocolType);
 }

Modified: python/branches/bcannon-objcap/Modules/_sqlite/row.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/row.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/row.c	Thu Sep  6 21:35:45 2007
@@ -30,7 +30,7 @@
     Py_XDECREF(self->data);
     Py_XDECREF(self->description);
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
@@ -183,8 +183,7 @@
 
 
 PyTypeObject pysqlite_RowType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".Row",                             /* tp_name */
         sizeof(pysqlite_Row),                           /* tp_basicsize */
         0,                                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_sqlite/statement.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sqlite/statement.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sqlite/statement.c	Thu Sep  6 21:35:45 2007
@@ -309,7 +309,7 @@
         PyObject_ClearWeakRefs((PyObject*)self);
     }
 
-    self->ob_type->tp_free((PyObject*)self);
+    Py_Type(self)->tp_free((PyObject*)self);
 }
 
 /*
@@ -383,8 +383,7 @@
 }
 
 PyTypeObject pysqlite_StatementType = {
-        PyObject_HEAD_INIT(NULL)
-        0,                                              /* ob_size */
+        PyVarObject_HEAD_INIT(NULL, 0)
         MODULE_NAME ".Statement",                       /* tp_name */
         sizeof(pysqlite_Statement),                     /* tp_basicsize */
         0,                                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_sre.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_sre.c	(original)
+++ python/branches/bcannon-objcap/Modules/_sre.c	Thu Sep  6 21:35:45 2007
@@ -1689,7 +1689,7 @@
 #endif
 
     /* get pointer to string buffer */
-    buffer = string->ob_type->tp_as_buffer;
+    buffer = Py_Type(string)->tp_as_buffer;
     if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||
         buffer->bf_getsegcount(string, NULL) != 1) {
         PyErr_SetString(PyExc_TypeError, "expected string or buffer");

Modified: python/branches/bcannon-objcap/Modules/_ssl.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_ssl.c	(original)
+++ python/branches/bcannon-objcap/Modules/_ssl.c	Thu Sep  6 21:35:45 2007
@@ -1,4 +1,4 @@
-/* SSL socket module 
+/* SSL socket module
 
    SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
 
@@ -8,25 +8,44 @@
 */
 
 #include "Python.h"
+
 enum py_ssl_error {
 	/* these mirror ssl.h */
-	PY_SSL_ERROR_NONE,                 
-	PY_SSL_ERROR_SSL,                   
-	PY_SSL_ERROR_WANT_READ,             
-	PY_SSL_ERROR_WANT_WRITE,            
-	PY_SSL_ERROR_WANT_X509_LOOKUP,      
+	PY_SSL_ERROR_NONE,
+	PY_SSL_ERROR_SSL,
+	PY_SSL_ERROR_WANT_READ,
+	PY_SSL_ERROR_WANT_WRITE,
+	PY_SSL_ERROR_WANT_X509_LOOKUP,
 	PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */
-	PY_SSL_ERROR_ZERO_RETURN,           
+	PY_SSL_ERROR_ZERO_RETURN,
 	PY_SSL_ERROR_WANT_CONNECT,
-	/* start of non ssl.h errorcodes */ 
+	/* start of non ssl.h errorcodes */
 	PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */
 	PY_SSL_ERROR_INVALID_ERROR_CODE
 };
 
+enum py_ssl_server_or_client {
+	PY_SSL_CLIENT,
+	PY_SSL_SERVER
+};
+
+enum py_ssl_cert_requirements {
+	PY_SSL_CERT_NONE,
+	PY_SSL_CERT_OPTIONAL,
+	PY_SSL_CERT_REQUIRED
+};
+
+enum py_ssl_version {
+	PY_SSL_VERSION_SSL2,
+	PY_SSL_VERSION_SSL3,
+	PY_SSL_VERSION_SSL23,
+	PY_SSL_VERSION_TLS1,
+};
+
 /* Include symbols from _socket module */
 #include "socketmodule.h"
 
-#if defined(HAVE_POLL_H) 
+#if defined(HAVE_POLL_H)
 #include <poll.h>
 #elif defined(HAVE_SYS_POLL_H)
 #include <sys/poll.h>
@@ -58,10 +77,10 @@
 typedef struct {
 	PyObject_HEAD
 	PySocketSockObject *Socket;	/* Socket on which we're layered */
-	SSL_CTX* 	ctx;
-	SSL*     	ssl;
-	X509*    	server_cert;
-	char    	server[X509_NAME_MAXLEN];
+	SSL_CTX*	ctx;
+	SSL*		ssl;
+	X509*		peer_cert;
+	char		server[X509_NAME_MAXLEN];
 	char		issuer[X509_NAME_MAXLEN];
 
 } PySSLObject;
@@ -69,10 +88,12 @@
 static PyTypeObject PySSL_Type;
 static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
 static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
-static int check_socket_and_wait_for_timeout(PySocketSockObject *s, 
+static int check_socket_and_wait_for_timeout(PySocketSockObject *s,
 					     int writing);
+static PyObject *PySSL_peercert(PySSLObject *self);
 
-#define PySSLObject_Check(v)	((v)->ob_type == &PySSL_Type)
+
+#define PySSLObject_Check(v)	(Py_Type(v) == &PySSL_Type)
 
 typedef enum {
 	SOCKET_IS_NONBLOCKING,
@@ -83,141 +104,181 @@
 	SOCKET_OPERATION_OK
 } timeout_state;
 
+/* Wrap error strings with filename and line # */
+#define STRINGIFY1(x) #x
+#define STRINGIFY2(x) STRINGIFY1(x)
+#define ERRSTR1(x,y,z) (x ":" y ": " z)
+#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x)
+
 /* XXX It might be helpful to augment the error message generated
    below with the name of the SSL function that generated the error.
    I expect it's obvious most of the time.
 */
 
 static PyObject *
-PySSL_SetError(PySSLObject *obj, int ret)
+PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno)
 {
-	PyObject *v, *n, *s;
+	PyObject *v;
+	char buf[2048];
 	char *errstr;
 	int err;
-	enum py_ssl_error p;
+	enum py_ssl_error p = PY_SSL_ERROR_NONE;
 
 	assert(ret <= 0);
-    
-	err = SSL_get_error(obj->ssl, ret);
 
-	switch (err) {
-	case SSL_ERROR_ZERO_RETURN:
-		errstr = "TLS/SSL connection has been closed";
-		p = PY_SSL_ERROR_ZERO_RETURN;
-		break;
-	case SSL_ERROR_WANT_READ:
-		errstr = "The operation did not complete (read)";
-		p = PY_SSL_ERROR_WANT_READ;
-		break;
-	case SSL_ERROR_WANT_WRITE:
-		p = PY_SSL_ERROR_WANT_WRITE;
-		errstr = "The operation did not complete (write)";
-		break;
-	case SSL_ERROR_WANT_X509_LOOKUP:
-		p = PY_SSL_ERROR_WANT_X509_LOOKUP;
-		errstr = "The operation did not complete (X509 lookup)";
-		break;
-	case SSL_ERROR_WANT_CONNECT:
-		p = PY_SSL_ERROR_WANT_CONNECT;
-		errstr = "The operation did not complete (connect)";
-		break;
-	case SSL_ERROR_SYSCALL:
-	{
-		unsigned long e = ERR_get_error();
-		if (e == 0) {
-			if (ret == 0 || !obj->Socket) {
-				p = PY_SSL_ERROR_EOF;
-				errstr = "EOF occurred in violation of protocol";
-			} else if (ret == -1) {
-				/* the underlying BIO reported an I/O error */
-				return obj->Socket->errorhandler();
-			} else {  /* possible? */
+	if ((obj != NULL) && (obj->ssl != NULL)) {
+		err = SSL_get_error(obj->ssl, ret);
+
+		switch (err) {
+		case SSL_ERROR_ZERO_RETURN:
+			errstr = "TLS/SSL connection has been closed";
+			p = PY_SSL_ERROR_ZERO_RETURN;
+			break;
+		case SSL_ERROR_WANT_READ:
+			errstr = "The operation did not complete (read)";
+			p = PY_SSL_ERROR_WANT_READ;
+			break;
+		case SSL_ERROR_WANT_WRITE:
+			p = PY_SSL_ERROR_WANT_WRITE;
+			errstr = "The operation did not complete (write)";
+			break;
+		case SSL_ERROR_WANT_X509_LOOKUP:
+			p = PY_SSL_ERROR_WANT_X509_LOOKUP;
+			errstr =
+                            "The operation did not complete (X509 lookup)";
+			break;
+		case SSL_ERROR_WANT_CONNECT:
+			p = PY_SSL_ERROR_WANT_CONNECT;
+			errstr = "The operation did not complete (connect)";
+			break;
+		case SSL_ERROR_SYSCALL:
+		{
+			unsigned long e = ERR_get_error();
+			if (e == 0) {
+				if (ret == 0 || !obj->Socket) {
+				  p = PY_SSL_ERROR_EOF;
+				  errstr =
+                                      "EOF occurred in violation of protocol";
+				} else if (ret == -1) {
+				  /* underlying BIO reported an I/O error */
+                                  return obj->Socket->errorhandler();
+				} else { /* possible? */
+                                  p = PY_SSL_ERROR_SYSCALL;
+                                  errstr = "Some I/O error occurred";
+				}
+			} else {
 				p = PY_SSL_ERROR_SYSCALL;
-				errstr = "Some I/O error occurred";
+				/* XXX Protected by global interpreter lock */
+				errstr = ERR_error_string(e, NULL);
 			}
-		} else {
-			p = PY_SSL_ERROR_SYSCALL;
-			/* XXX Protected by global interpreter lock */
-			errstr = ERR_error_string(e, NULL);
-		}
-		break;
-	}   
-	case SSL_ERROR_SSL:
-	{
-		unsigned long e = ERR_get_error();
-		p = PY_SSL_ERROR_SSL;
-		if (e != 0) 
-			/* XXX Protected by global interpreter lock */
-			errstr = ERR_error_string(e, NULL);
-		else { /* possible? */
-			errstr = "A failure in the SSL library occurred";
+			break;
 		}
-		break;
-	}
-	default:
-		p = PY_SSL_ERROR_INVALID_ERROR_CODE;
-		errstr = "Invalid error code";
-	}
-	n = PyInt_FromLong((long) p);
-	if (n == NULL)
-		return NULL;
-	v = PyTuple_New(2);
-	if (v == NULL) {
-		Py_DECREF(n);
-		return NULL;
+		case SSL_ERROR_SSL:
+		{
+			unsigned long e = ERR_get_error();
+			p = PY_SSL_ERROR_SSL;
+			if (e != 0)
+				/* XXX Protected by global interpreter lock */
+				errstr = ERR_error_string(e, NULL);
+			else {	/* possible? */
+				errstr =
+                                    "A failure in the SSL library occurred";
+			}
+			break;
+		}
+		default:
+			p = PY_SSL_ERROR_INVALID_ERROR_CODE;
+			errstr = "Invalid error code";
+		}
+	} else {
+		errstr = ERR_error_string(ERR_peek_last_error(), NULL);
 	}
-
-	s = PyString_FromString(errstr);
-	if (s == NULL) {
+	PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr);
+	v = Py_BuildValue("(is)", p, buf);
+	if (v != NULL) {
+		PyErr_SetObject(PySSLErrorObject, v);
 		Py_DECREF(v);
-		Py_DECREF(n);
 	}
-	PyTuple_SET_ITEM(v, 0, n);
-	PyTuple_SET_ITEM(v, 1, s);
-	PyErr_SetObject(PySSLErrorObject, v);
-	Py_DECREF(v);
 	return NULL;
 }
 
 static PySSLObject *
-newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
+newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
+	       enum py_ssl_server_or_client socket_type,
+	       enum py_ssl_cert_requirements certreq,
+	       enum py_ssl_version proto_version,
+	       char *cacerts_file)
 {
 	PySSLObject *self;
 	char *errstr = NULL;
 	int ret;
 	int err;
 	int sockstate;
+	int verification_mode;
 
 	self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
 	if (self == NULL)
 		return NULL;
 	memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
 	memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
-	self->server_cert = NULL;
+	self->peer_cert = NULL;
 	self->ssl = NULL;
 	self->ctx = NULL;
 	self->Socket = NULL;
 
 	if ((key_file && !cert_file) || (!key_file && cert_file)) {
-		errstr = "Both the key & certificate files must be specified";
+		errstr = ERRSTR("Both the key & certificate files "
+                                "must be specified");
+		goto fail;
+	}
+
+	if ((socket_type == PY_SSL_SERVER) &&
+	    ((key_file == NULL) || (cert_file == NULL))) {
+		errstr = ERRSTR("Both the key & certificate files "
+                                "must be specified for server-side operation");
 		goto fail;
 	}
 
 	Py_BEGIN_ALLOW_THREADS
-	self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
+	if (proto_version == PY_SSL_VERSION_TLS1)
+		self->ctx = SSL_CTX_new(TLSv1_method()); /* Set up context */
+	else if (proto_version == PY_SSL_VERSION_SSL3)
+		self->ctx = SSL_CTX_new(SSLv3_method()); /* Set up context */
+	else if (proto_version == PY_SSL_VERSION_SSL2)
+		self->ctx = SSL_CTX_new(SSLv2_method()); /* Set up context */
+	else
+		self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
 	Py_END_ALLOW_THREADS
+
 	if (self->ctx == NULL) {
-		errstr = "SSL_CTX_new error";
+		errstr = ERRSTR("Invalid SSL protocol variant specified.");
 		goto fail;
 	}
 
+	if (certreq != PY_SSL_CERT_NONE) {
+		if (cacerts_file == NULL) {
+			errstr = ERRSTR("No root certificates specified for "
+                                  "verification of other-side certificates.");
+			goto fail;
+		} else {
+			Py_BEGIN_ALLOW_THREADS
+			ret = SSL_CTX_load_verify_locations(self->ctx,
+							    cacerts_file,
+                                                            NULL);
+			Py_END_ALLOW_THREADS
+			if (ret != 1) {
+				PySSL_SetError(NULL, 0, __FILE__, __LINE__);
+				goto fail;
+			}
+		}
+	}
 	if (key_file) {
 		Py_BEGIN_ALLOW_THREADS
 		ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
-						SSL_FILETYPE_PEM);
+						  SSL_FILETYPE_PEM);
 		Py_END_ALLOW_THREADS
-		if (ret < 1) {
-			errstr = "SSL_CTX_use_PrivateKey_file error";
+		if (ret != 1) {
+			PySSL_SetError(NULL, 0, __FILE__, __LINE__);
 			goto fail;
 		}
 
@@ -225,16 +286,24 @@
 		ret = SSL_CTX_use_certificate_chain_file(self->ctx,
 						       cert_file);
 		Py_END_ALLOW_THREADS
-		SSL_CTX_set_options(self->ctx, SSL_OP_ALL); /* ssl compatibility */
-		if (ret < 1) {
-			errstr = "SSL_CTX_use_certificate_chain_file error";
+		if (ret != 1) {
+			PySSL_SetError(NULL, 0, __FILE__, __LINE__);
 			goto fail;
 		}
+                /* ssl compatibility */
+		SSL_CTX_set_options(self->ctx, SSL_OP_ALL);
 	}
 
+	verification_mode = SSL_VERIFY_NONE;
+	if (certreq == PY_SSL_CERT_OPTIONAL)
+		verification_mode = SSL_VERIFY_PEER;
+	else if (certreq == PY_SSL_CERT_REQUIRED)
+		verification_mode = (SSL_VERIFY_PEER |
+				     SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+	SSL_CTX_set_verify(self->ctx, verification_mode,
+			   NULL); /* set verify lvl */
+
 	Py_BEGIN_ALLOW_THREADS
-	SSL_CTX_set_verify(self->ctx,
-			   SSL_VERIFY_NONE, NULL); /* set verify lvl */
 	self->ssl = SSL_new(self->ctx); /* New ssl struct */
 	Py_END_ALLOW_THREADS
 	SSL_set_fd(self->ssl, Sock->sock_fd);	/* Set the socket for SSL */
@@ -249,7 +318,10 @@
 	}
 
 	Py_BEGIN_ALLOW_THREADS
-	SSL_set_connect_state(self->ssl);
+	if (socket_type == PY_SSL_CLIENT)
+		SSL_set_connect_state(self->ssl);
+	else
+		SSL_set_accept_state(self->ssl);
 	Py_END_ALLOW_THREADS
 
 	/* Actually negotiate SSL connection */
@@ -257,11 +329,14 @@
 	sockstate = 0;
 	do {
 		Py_BEGIN_ALLOW_THREADS
-		ret = SSL_connect(self->ssl);
+		if (socket_type == PY_SSL_CLIENT)
+			ret = SSL_connect(self->ssl);
+		else
+			ret = SSL_accept(self->ssl);
 		err = SSL_get_error(self->ssl, ret);
 		Py_END_ALLOW_THREADS
 		if(PyErr_CheckSignals()) {
-                        goto fail;
+			goto fail;
 		}
 		if (err == SSL_ERROR_WANT_READ) {
 			sockstate = check_socket_and_wait_for_timeout(Sock, 0);
@@ -270,30 +345,33 @@
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
-	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
-			PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
+		if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject,
+				ERRSTR("The connect operation timed out"));
 			goto fail;
 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
-			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+			PyErr_SetString(PySSLErrorObject,
+				ERRSTR("Underlying socket has been closed."));
 			goto fail;
 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
-			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+			PyErr_SetString(PySSLErrorObject,
+			  ERRSTR("Underlying socket too large for select()."));
 			goto fail;
 		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
 			break;
 		}
 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
-	if (ret <= 0) {
-		PySSL_SetError(self, ret);
+	if (ret < 1) {
+		PySSL_SetError(self, ret, __FILE__, __LINE__);
 		goto fail;
 	}
 	self->ssl->debug = 1;
 
 	Py_BEGIN_ALLOW_THREADS
-	if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
-		X509_NAME_oneline(X509_get_subject_name(self->server_cert),
+	if ((self->peer_cert = SSL_get_peer_certificate(self->ssl))) {
+		X509_NAME_oneline(X509_get_subject_name(self->peer_cert),
 				  self->server, X509_NAME_MAXLEN);
-		X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
+		X509_NAME_oneline(X509_get_issuer_name(self->peer_cert),
 				  self->issuer, X509_NAME_MAXLEN);
 	}
 	Py_END_ALLOW_THREADS
@@ -308,27 +386,41 @@
 }
 
 static PyObject *
-PySocket_ssl(PyObject *self, PyObject *args)
+PySSL_sslwrap(PyObject *self, PyObject *args)
 {
-	PySSLObject *rv;
 	PySocketSockObject *Sock;
+	int server_side = 0;
+	int verification_mode = PY_SSL_CERT_NONE;
+	int protocol = PY_SSL_VERSION_SSL23;
 	char *key_file = NULL;
 	char *cert_file = NULL;
+	char *cacerts_file = NULL;
 
-	if (!PyArg_ParseTuple(args, "O!|zz:ssl",
+	if (!PyArg_ParseTuple(args, "O!i|zziiz:sslwrap",
 			      PySocketModule.Sock_Type,
 			      &Sock,
-			      &key_file, &cert_file))
+			      &server_side,
+			      &key_file, &cert_file,
+			      &verification_mode, &protocol,
+			      &cacerts_file))
 		return NULL;
 
-	rv = newPySSLObject(Sock, key_file, cert_file);
-	if (rv == NULL)
-		return NULL;
-	return (PyObject *)rv;
+	/*
+	fprintf(stderr,
+		"server_side is %d, keyfile %p, certfile %p, verify_mode %d, "
+		"protocol %d, certs %p\n",
+		server_side, key_file, cert_file, verification_mode,
+		protocol, cacerts_file);
+	 */
+
+	return (PyObject *) newPySSLObject(Sock, key_file, cert_file,
+					   server_side, verification_mode,
+					   protocol, cacerts_file);
 }
 
 PyDoc_STRVAR(ssl_doc,
-"ssl(socket, [keyfile, certfile]) -> sslobject");
+"sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n"
+"                              cacertsfile]) -> sslobject");
 
 /* SSL object methods */
 
@@ -344,15 +436,168 @@
 	return PyString_FromString(self->issuer);
 }
 
+static PyObject *
+_create_tuple_for_X509_NAME (X509_NAME *xname)
+{
+	PyObject *pt = NULL;
+        PyObject *entry_tuple = NULL;
+        int entry_count = X509_NAME_entry_count(xname);
+	int index_counter;
+
+        pt = PyTuple_New(entry_count);
+	if (pt == NULL)
+		return NULL;
+
+	for (index_counter = 0;
+	     index_counter < X509_NAME_entry_count(xname);
+	     index_counter++)
+	{
+		char namebuf[X509_NAME_MAXLEN];
+		int buflen;
+		PyObject *name_obj;
+		ASN1_STRING *value;
+		PyObject *value_obj;
+		unsigned char *valuebuf = NULL;
+
+		X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname,
+							     index_counter);
+
+		ASN1_OBJECT *name = X509_NAME_ENTRY_get_object(entry);
+		buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0);
+		if (buflen < 0)
+			goto fail0;
+		name_obj = PyString_FromStringAndSize(namebuf, buflen);
+		if (name_obj == NULL)
+			goto fail0;
+
+		value = X509_NAME_ENTRY_get_data(entry);
+		buflen = ASN1_STRING_to_UTF8(&valuebuf, value);
+		if (buflen < 0) {
+			Py_DECREF(name_obj);
+			goto fail0;
+		}
+		value_obj = PyUnicode_DecodeUTF8((char *) valuebuf,
+						 buflen, "strict");
+		OPENSSL_free(valuebuf);
+		if (value_obj == NULL) {
+			Py_DECREF(name_obj);
+			goto fail0;
+		}
+                entry_tuple = PyTuple_New(2);
+                if (entry_tuple == NULL) {
+			Py_DECREF(name_obj);
+			Py_DECREF(value_obj);
+			goto fail0;
+		}
+                PyTuple_SET_ITEM(entry_tuple, 0, name_obj);
+                PyTuple_SET_ITEM(entry_tuple, 1, value_obj);
+                PyTuple_SET_ITEM(pt, index_counter, entry_tuple);
+	}
+	return pt;
+
+  fail0:
+	Py_XDECREF(pt);
+	return NULL;
+}
+
+static PyObject *
+PySSL_peercert(PySSLObject *self)
+{
+	PyObject *retval = NULL;
+	BIO *biobuf = NULL;
+	PyObject *peer;
+	PyObject *issuer;
+	PyObject *version;
+	char buf[2048];
+	int len;
+	ASN1_TIME *notBefore, *notAfter;
+	PyObject *pnotBefore, *pnotAfter;
+	int verification;
+
+	if (!self->peer_cert)
+		Py_RETURN_NONE;
+
+	retval = PyDict_New();
+	if (retval == NULL)
+		return NULL;
+
+	verification = SSL_CTX_get_verify_mode(self->ctx);
+	if ((verification & SSL_VERIFY_PEER) == 0)
+		return retval;
+
+	peer = _create_tuple_for_X509_NAME(
+		X509_get_subject_name(self->peer_cert));
+	if (peer == NULL)
+		goto fail0;
+	if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) {
+		Py_DECREF(peer);
+		goto fail0;
+	}
+	Py_DECREF(peer);
+
+	issuer = _create_tuple_for_X509_NAME(
+		X509_get_issuer_name(self->peer_cert));
+	if (issuer == NULL)
+		goto fail0;
+	if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) {
+		Py_DECREF(issuer);
+		goto fail0;
+	}
+	Py_DECREF(issuer);
+
+	version = PyInt_FromLong(X509_get_version(self->peer_cert));
+	if (PyDict_SetItemString(retval, "version", version) < 0) {
+		Py_DECREF(version);
+		goto fail0;
+	}
+	Py_DECREF(version);
+
+	/* get a memory buffer */
+	biobuf = BIO_new(BIO_s_mem());
+
+	notBefore = X509_get_notBefore(self->peer_cert);
+	ASN1_TIME_print(biobuf, notBefore);
+	len = BIO_gets(biobuf, buf, sizeof(buf)-1);
+	pnotBefore = PyString_FromStringAndSize(buf, len);
+	if (pnotBefore == NULL)
+		goto fail1;
+	if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {
+		Py_DECREF(pnotBefore);
+		goto fail1;
+	}
+	Py_DECREF(pnotBefore);
+
+	(void) BIO_reset(biobuf);
+	notAfter = X509_get_notAfter(self->peer_cert);
+	ASN1_TIME_print(biobuf, notAfter);
+	len = BIO_gets(biobuf, buf, sizeof(buf)-1);
+	BIO_free(biobuf);
+	pnotAfter = PyString_FromStringAndSize(buf, len);
+	if (pnotAfter == NULL)
+		goto fail0;
+	if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) {
+		Py_DECREF(pnotAfter);
+		goto fail0;
+	}
+	Py_DECREF(pnotAfter);
+	return retval;
+
+  fail1:
+	if (biobuf != NULL)
+		BIO_free(biobuf);
+  fail0:
+	Py_XDECREF(retval);
+	return NULL;
+}
 
 static void PySSL_dealloc(PySSLObject *self)
 {
-	if (self->server_cert)	/* Possible not to have one? */
-		X509_free (self->server_cert);
+	if (self->peer_cert)	/* Possible not to have one? */
+		X509_free (self->peer_cert);
 	if (self->ssl)
-	    SSL_free(self->ssl);
+		SSL_free(self->ssl);
 	if (self->ctx)
-	    SSL_CTX_free(self->ctx);
+		SSL_CTX_free(self->ctx);
 	Py_XDECREF(self->Socket);
 	PyObject_Del(self);
 }
@@ -438,13 +683,16 @@
 
 	sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
 	if (sockstate == SOCKET_HAS_TIMED_OUT) {
-		PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+		PyErr_SetString(PySSLErrorObject,
+                                "The write operation timed out");
 		return NULL;
 	} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
-		PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+		PyErr_SetString(PySSLErrorObject,
+                                "Underlying socket has been closed.");
 		return NULL;
 	} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
-		PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+		PyErr_SetString(PySSLErrorObject,
+                                "Underlying socket too large for select().");
 		return NULL;
 	}
 	do {
@@ -457,17 +705,21 @@
 			return NULL;
 		}
 		if (err == SSL_ERROR_WANT_READ) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+			sockstate =
+                            check_socket_and_wait_for_timeout(self->Socket, 0);
 		} else if (err == SSL_ERROR_WANT_WRITE) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+			sockstate =
+                            check_socket_and_wait_for_timeout(self->Socket, 1);
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
-	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
-			PyErr_SetString(PySSLErrorObject, "The write operation timed out");
+		if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject,
+                                        "The write operation timed out");
 			return NULL;
 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
-			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
+			PyErr_SetString(PySSLErrorObject,
+                                        "Underlying socket has been closed.");
 			return NULL;
 		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
 			break;
@@ -476,7 +728,7 @@
 	if (len > 0)
 		return PyInt_FromLong(len);
 	else
-		return PySSL_SetError(self, len);
+		return PySSL_SetError(self, len, __FILE__, __LINE__);
 }
 
 PyDoc_STRVAR(PySSL_SSLwrite_doc,
@@ -498,7 +750,7 @@
 
 	if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
 		return NULL;
-	
+
 	/* first check if there are bytes ready to be read */
 	Py_BEGIN_ALLOW_THREADS
 	count = SSL_pending(self->ssl);
@@ -507,12 +759,28 @@
 	if (!count) {
 		sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
-			PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+			PyErr_SetString(PySSLErrorObject,
+					"The read operation timed out");
 			Py_DECREF(buf);
 			return NULL;
 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
-			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
+			PyErr_SetString(PySSLErrorObject,
+				"Underlying socket too large for select().");
+			Py_DECREF(buf);
 			return NULL;
+		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
+			if (SSL_get_shutdown(self->ssl) !=
+			    SSL_RECEIVED_SHUTDOWN)
+			{
+                            Py_DECREF(buf);
+                            PyErr_SetString(PySSLErrorObject,
+                              "Socket closed without SSL shutdown handshake");
+				return NULL;
+			} else {
+				/* should contain a zero-length string */
+				_PyString_Resize(&buf, 0);
+				return buf;
+			}
 		}
 	}
 	do {
@@ -526,23 +794,32 @@
 			return NULL;
 		}
 		if (err == SSL_ERROR_WANT_READ) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+			sockstate =
+			  check_socket_and_wait_for_timeout(self->Socket, 0);
 		} else if (err == SSL_ERROR_WANT_WRITE) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+			sockstate =
+			  check_socket_and_wait_for_timeout(self->Socket, 1);
+		} else if ((err == SSL_ERROR_ZERO_RETURN) &&
+			   (SSL_get_shutdown(self->ssl) ==
+			    SSL_RECEIVED_SHUTDOWN))
+		{
+			_PyString_Resize(&buf, 0);
+			return buf;
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
-	        if (sockstate == SOCKET_HAS_TIMED_OUT) {
-			PyErr_SetString(PySSLErrorObject, "The read operation timed out");
+		if (sockstate == SOCKET_HAS_TIMED_OUT) {
+			PyErr_SetString(PySSLErrorObject,
+					"The read operation timed out");
 			Py_DECREF(buf);
 			return NULL;
 		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
 			break;
 		}
 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
- 	if (count <= 0) {
+	if (count <= 0) {
 		Py_DECREF(buf);
-		return PySSL_SetError(self, count);
+		return PySSL_SetError(self, count, __FILE__, __LINE__);
 	}
 	if (count != len)
 		_PyString_Resize(&buf, count);
@@ -554,13 +831,49 @@
 \n\
 Read up to len bytes from the SSL socket.");
 
+static PyObject *PySSL_SSLshutdown(PySSLObject *self, PyObject *args)
+{
+	int err;
+
+	/* Guard against closed socket */
+	if (self->Socket->sock_fd < 0) {
+		PyErr_SetString(PySSLErrorObject,
+				"Underlying socket has been closed.");
+		return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	err = SSL_shutdown(self->ssl);
+	if (err == 0) {
+		/* we need to call it again to finish the shutdown */
+		err = SSL_shutdown(self->ssl);
+	}
+	Py_END_ALLOW_THREADS
+
+	if (err < 0)
+		return PySSL_SetError(self, err, __FILE__, __LINE__);
+	else {
+		Py_INCREF(self->Socket);
+		return (PyObject *) (self->Socket);
+	}
+}
+
+PyDoc_STRVAR(PySSL_SSLshutdown_doc,
+"shutdown(s) -> socket\n\
+\n\
+Does the SSL shutdown handshake with the remote end, and returns\n\
+the underlying socket object.");
+
 static PyMethodDef PySSLMethods[] = {
 	{"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
-	          PySSL_SSLwrite_doc},
+		  PySSL_SSLwrite_doc},
 	{"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
-	          PySSL_SSLread_doc},
+		  PySSL_SSLread_doc},
 	{"server", (PyCFunction)PySSL_server, METH_NOARGS},
 	{"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
+	{"peer_certificate", (PyCFunction)PySSL_peercert, METH_NOARGS},
+	{"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS,
+         PySSL_SSLshutdown_doc},
 	{NULL, NULL}
 };
 
@@ -570,9 +883,8 @@
 }
 
 static PyTypeObject PySSL_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/*ob_size*/
-	"socket.SSL",			/*tp_name*/
+	PyVarObject_HEAD_INIT(NULL, 0)
+	"ssl.SSLContext",		/*tp_name*/
 	sizeof(PySSLObject),		/*tp_basicsize*/
 	0,				/*tp_itemsize*/
 	/* methods */
@@ -632,7 +944,7 @@
     if (!PyString_Check(arg))
 	return PyErr_Format(PyExc_TypeError,
 			    "RAND_egd() expected string, found %s",
-			    arg->ob_type->tp_name);
+			    Py_Type(arg)->tp_name);
     bytes = RAND_egd(PyString_AS_STRING(arg));
     if (bytes == -1) {
 	PyErr_SetString(PySSLErrorObject,
@@ -647,7 +959,7 @@
 "RAND_egd(path) -> bytes\n\
 \n\
 Queries the entropy gather daemon (EGD) on socket path.  Returns number\n\
-of bytes read.  Raises socket.sslerror if connection to EGD fails or\n\
+of bytes read.  Raises ssl.sslerror if connection to EGD fails or\n\
 if it does provide enough data to seed PRNG.");
 
 #endif
@@ -655,17 +967,17 @@
 /* List of functions exported by this module. */
 
 static PyMethodDef PySSL_methods[] = {
-	{"ssl",			PySocket_ssl,
-	 METH_VARARGS, ssl_doc},
+	{"sslwrap",             PySSL_sslwrap,
+         METH_VARARGS, ssl_doc},
 #ifdef HAVE_OPENSSL_RAND
-	{"RAND_add",            PySSL_RAND_add, METH_VARARGS, 
+	{"RAND_add",            PySSL_RAND_add, METH_VARARGS,
 	 PySSL_RAND_add_doc},
 	{"RAND_egd",            PySSL_RAND_egd, METH_O,
 	 PySSL_RAND_egd_doc},
 	{"RAND_status",         (PyCFunction)PySSL_RAND_status, METH_NOARGS,
 	 PySSL_RAND_status_doc},
 #endif
-	{NULL,			NULL}		 /* Sentinel */
+	{NULL,                  NULL}            /* Sentinel */
 };
 
 
@@ -678,7 +990,7 @@
 {
 	PyObject *m, *d;
 
-	PySSL_Type.ob_type = &PyType_Type;
+	Py_Type(&PySSL_Type) = &PyType_Type;
 
 	m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
 	if (m == NULL)
@@ -687,19 +999,20 @@
 
 	/* Load _socket module and its C API */
 	if (PySocketModule_ImportModuleAndAPI())
- 	    	return;
+		return;
 
 	/* Init OpenSSL */
 	SSL_load_error_strings();
 	SSLeay_add_ssl_algorithms();
 
 	/* Add symbols to module dict */
-	PySSLErrorObject = PyErr_NewException("socket.sslerror",
-                                               PySocketModule.error,
-                                               NULL);
+	PySSLErrorObject = PyErr_NewException("ssl.sslerror",
+					      PySocketModule.error,
+					      NULL);
 	if (PySSLErrorObject == NULL)
 		return;
-	PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
+	if (PyDict_SetItemString(d, "sslerror", PySSLErrorObject) != 0)
+		return;
 	if (PyDict_SetItemString(d, "SSLType",
 				 (PyObject *)&PySSL_Type) != 0)
 		return;
@@ -722,5 +1035,21 @@
 				PY_SSL_ERROR_EOF);
 	PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
 				PY_SSL_ERROR_INVALID_ERROR_CODE);
-
+	/* cert requirements */
+	PyModule_AddIntConstant(m, "CERT_NONE",
+				PY_SSL_CERT_NONE);
+	PyModule_AddIntConstant(m, "CERT_OPTIONAL",
+				PY_SSL_CERT_OPTIONAL);
+	PyModule_AddIntConstant(m, "CERT_REQUIRED",
+				PY_SSL_CERT_REQUIRED);
+
+	/* protocol versions */
+	PyModule_AddIntConstant(m, "PROTOCOL_SSLv2",
+				PY_SSL_VERSION_SSL2);
+	PyModule_AddIntConstant(m, "PROTOCOL_SSLv3",
+				PY_SSL_VERSION_SSL3);
+	PyModule_AddIntConstant(m, "PROTOCOL_SSLv23",
+				PY_SSL_VERSION_SSL23);
+	PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
+				PY_SSL_VERSION_TLS1);
 }

Modified: python/branches/bcannon-objcap/Modules/_struct.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_struct.c	(original)
+++ python/branches/bcannon-objcap/Modules/_struct.c	Thu Sep  6 21:35:45 2007
@@ -72,7 +72,7 @@
 
 
 #define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
-#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
+#define PyStruct_CheckExact(op) (Py_Type(op) == &PyStructType)
 
 
 /* Exception */
@@ -133,7 +133,7 @@
 		Py_INCREF(v);
 		return v;
 	}
-	m = v->ob_type->tp_as_number;
+	m = Py_Type(v)->tp_as_number;
 	if (m != NULL && m->nb_long != NULL) {
 		v = m->nb_long(v);
 		if (v == NULL)
@@ -1487,7 +1487,7 @@
 		PyMem_FREE(s->s_codes);
 	}
 	Py_XDECREF(s->s_format);
-	s->ob_type->tp_free((PyObject *)s);
+	Py_Type(s)->tp_free((PyObject *)s);
 }
 
 static PyObject *
@@ -1806,8 +1806,7 @@
 
 static
 PyTypeObject PyStructType = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"Struct",
 	sizeof(PyStructObject),
 	0,
@@ -1857,7 +1856,7 @@
 	if (m == NULL)
 		return;
 
-	PyStructType.ob_type = &PyType_Type;
+	Py_Type(&PyStructType) = &PyType_Type;
 	if (PyType_Ready(&PyStructType) < 0)
 		return;
 

Modified: python/branches/bcannon-objcap/Modules/_testcapimodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_testcapimodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_testcapimodule.c	Thu Sep  6 21:35:45 2007
@@ -839,8 +839,7 @@
 }
 
 static PyTypeObject test_structmembersType = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
 	"test_structmembersType",
 	sizeof(test_structmembers),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -890,7 +889,7 @@
 	if (m == NULL)
 		return;
 
-	test_structmembersType.ob_type=&PyType_Type;
+	Py_Type(&test_structmembersType)=&PyType_Type;
 	Py_INCREF(&test_structmembersType);
 	PyModule_AddObject(m, "test_structmembersType", (PyObject *)&test_structmembersType);
 

Modified: python/branches/bcannon-objcap/Modules/_tkinter.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_tkinter.c	(original)
+++ python/branches/bcannon-objcap/Modules/_tkinter.c	Thu Sep  6 21:35:45 2007
@@ -262,12 +262,12 @@
 	Tcl_ObjType *StringType;
 } TkappObject;
 
-#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Check(v) (Py_Type(v) == &Tkapp_Type)
 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
 
 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
-(void *) v, ((PyObject *) v)->ob_refcnt))
+(void *) v, Py_Refcnt(v)))
 
 
 
@@ -1285,6 +1285,12 @@
 	/* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
 	int flags = TCL_EVAL_DIRECT;
 
+	/* If args is a single tuple, replace with contents of tuple */
+	if (1 == PyTuple_Size(args)){
+		PyObject* item = PyTuple_GetItem(args, 0);
+		if (PyTuple_Check(item))
+			args = item;
+	}
 #ifdef WITH_THREAD
 	if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
 		/* We cannot call the command directly. Instead, we must
@@ -2022,7 +2028,9 @@
 
 	s = AsString(res, tmp);
 	if (s == NULL) {
-		rv = PythonCmd_Error(interp);
+		Py_DECREF(res);
+		Py_DECREF(tmp);
+		return PythonCmd_Error(interp);
 	}
 	else {
 		Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
@@ -2414,8 +2422,7 @@
 
 static PyTypeObject Tktt_Type =
 {
-	PyObject_HEAD_INIT(NULL)
-	0,				     /*ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"tktimertoken",			     /*tp_name */
 	sizeof(TkttObject),		     /*tp_basicsize */
 	0,				     /*tp_itemsize */
@@ -2759,8 +2766,7 @@
 
 static PyTypeObject Tkapp_Type =
 {
-	PyObject_HEAD_INIT(NULL)
-	0,				     /*ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"tkapp",			     /*tp_name */
 	sizeof(TkappObject),		     /*tp_basicsize */
 	0,				     /*tp_itemsize */
@@ -3099,7 +3105,7 @@
 {
 	PyObject *m, *d;
 
-	Tkapp_Type.ob_type = &PyType_Type;
+	Py_Type(&Tkapp_Type) = &PyType_Type;
 
 #ifdef WITH_THREAD
 	tcl_lock = PyThread_allocate_lock();
@@ -3127,10 +3133,10 @@
 
 	PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
 
-	Tktt_Type.ob_type = &PyType_Type;
+	Py_Type(&Tktt_Type) = &PyType_Type;
 	PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
 
-	PyTclObject_Type.ob_type = &PyType_Type;
+	Py_Type(&PyTclObject_Type) = &PyType_Type;
 	PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
 
 #ifdef TK_AQUA

Modified: python/branches/bcannon-objcap/Modules/_typesmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_typesmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/_typesmodule.c	Thu Sep  6 21:35:45 2007
@@ -33,8 +33,7 @@
 };
 
 static PyTypeObject HelperType = {
-    PyObject_HEAD_INIT(NULL)
-    0,						/* ob_size */
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_types.Helper",				/* tp_name */
     sizeof(Helper),                             /* tp_basicsize */
     0,						/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/_weakref.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/_weakref.c	(original)
+++ python/branches/bcannon-objcap/Modules/_weakref.c	Thu Sep  6 21:35:45 2007
@@ -14,7 +14,7 @@
 {
     PyObject *result = NULL;
 
-    if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+    if (PyType_SUPPORTS_WEAKREFS(Py_Type(object))) {
         PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
 
         result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list));
@@ -35,7 +35,7 @@
 {
     PyObject *result = NULL;
 
-    if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) {
+    if (PyType_SUPPORTS_WEAKREFS(Py_Type(object))) {
         PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
         Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
 

Modified: python/branches/bcannon-objcap/Modules/arraymodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/arraymodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/arraymodule.c	Thu Sep  6 21:35:45 2007
@@ -39,7 +39,7 @@
 static PyTypeObject Arraytype;
 
 #define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
-#define array_CheckExact(op) ((op)->ob_type == &Arraytype)
+#define array_CheckExact(op) (Py_Type(op) == &Arraytype)
 
 static int
 array_resize(arrayobject *self, Py_ssize_t newsize)
@@ -53,9 +53,9 @@
 	*/
 
 	if (self->allocated >= newsize &&
-	    self->ob_size < newsize + 16 &&
+	    Py_Size(self) < newsize + 16 &&
 	    self->ob_item != NULL) {
-		self->ob_size = newsize;
+		Py_Size(self) = newsize;
 		return 0;
 	}
 
@@ -71,7 +71,7 @@
 	 * memory critical.
 	 */
 
-	_new_size = (newsize >> 4) + (self->ob_size < 8 ? 3 : 7) + newsize;
+	_new_size = (newsize >> 4) + (Py_Size(self) < 8 ? 3 : 7) + newsize;
 	items = self->ob_item;
 	/* XXX The following multiplication and division does not optimize away 
 	   like it does for lists since the size is not known at compile time */
@@ -84,7 +84,7 @@
 		return -1;
 	}
 	self->ob_item = items;
-	self->ob_size = newsize;
+	Py_Size(self) = newsize;
 	self->allocated = _new_size;
 	return 0;
 }
@@ -432,7 +432,7 @@
 	if (op == NULL) {
 		return NULL;
 	}
-	op->ob_size = size;
+	Py_Size(op) = size;
 	if (size <= 0) {
 		op->ob_item = NULL;
 	}
@@ -455,7 +455,7 @@
 	register arrayobject *ap;
 	assert(array_Check(op));
 	ap = (arrayobject *)op;
-	assert(i>=0 && i<ap->ob_size);
+	assert(i>=0 && i<Py_Size(ap));
 	return (*ap->ob_descr->getitem)(ap, i);
 }
 
@@ -463,7 +463,7 @@
 ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
 {
 	char *items;
-	Py_ssize_t n = self->ob_size;
+	Py_ssize_t n = Py_Size(self);
 	if (v == NULL) {
 		PyErr_BadInternalCall();
 		return -1;
@@ -498,7 +498,7 @@
 		PyObject_ClearWeakRefs((PyObject *) op);
 	if (op->ob_item != NULL)
 		PyMem_DEL(op->ob_item);
-	op->ob_type->tp_free((PyObject *)op);
+	Py_Type(op)->tp_free((PyObject *)op);
 }
 
 static PyObject *
@@ -518,7 +518,7 @@
 	va = (arrayobject *)v;
 	wa = (arrayobject *)w;
 
-	if (va->ob_size != wa->ob_size && (op == Py_EQ || op == Py_NE)) {
+	if (Py_Size(va) != Py_Size(wa) && (op == Py_EQ || op == Py_NE)) {
 		/* Shortcut: if the lengths differ, the arrays differ */
 		if (op == Py_EQ)
 			res = Py_False;
@@ -530,7 +530,7 @@
 
 	/* Search for the first index where items are different */
 	k = 1;
-	for (i = 0; i < va->ob_size && i < wa->ob_size; i++) {
+	for (i = 0; i < Py_Size(va) && i < Py_Size(wa); i++) {
 		vi = getarrayitem(v, i);
 		wi = getarrayitem(w, i);
 		if (vi == NULL || wi == NULL) {
@@ -549,8 +549,8 @@
 
 	if (k) {
 		/* No more items to compare -- compare sizes */
-		Py_ssize_t vs = va->ob_size;
-		Py_ssize_t ws = wa->ob_size;
+		Py_ssize_t vs = Py_Size(va);
+		Py_ssize_t ws = Py_Size(wa);
 		int cmp;
 		switch (op) {
 		case Py_LT: cmp = vs <  ws; break;
@@ -590,13 +590,13 @@
 static Py_ssize_t
 array_length(arrayobject *a)
 {
-	return a->ob_size;
+	return Py_Size(a);
 }
 
 static PyObject *
 array_item(arrayobject *a, Py_ssize_t i)
 {
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		PyErr_SetString(PyExc_IndexError, "array index out of range");
 		return NULL;
 	}
@@ -609,14 +609,14 @@
 	arrayobject *np;
 	if (ilow < 0)
 		ilow = 0;
-	else if (ilow > a->ob_size)
-		ilow = a->ob_size;
+	else if (ilow > Py_Size(a))
+		ilow = Py_Size(a);
 	if (ihigh < 0)
 		ihigh = 0;
 	if (ihigh < ilow)
 		ihigh = ilow;
-	else if (ihigh > a->ob_size)
-		ihigh = a->ob_size;
+	else if (ihigh > Py_Size(a))
+		ihigh = Py_Size(a);
 	np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
 	if (np == NULL)
 		return NULL;
@@ -628,7 +628,7 @@
 static PyObject *
 array_copy(arrayobject *a, PyObject *unused)
 {
-	return array_slice(a, 0, a->ob_size);
+	return array_slice(a, 0, Py_Size(a));
 }
 
 PyDoc_STRVAR(copy_doc,
@@ -644,7 +644,7 @@
 	if (!array_Check(bb)) {
 		PyErr_Format(PyExc_TypeError,
 		     "can only append array (not \"%.200s\") to array",
-			     bb->ob_type->tp_name);
+			     Py_Type(bb)->tp_name);
 		return NULL;
 	}
 #define b ((arrayobject *)bb)
@@ -652,14 +652,14 @@
 		PyErr_BadArgument();
 		return NULL;
 	}
-	size = a->ob_size + b->ob_size;
+	size = Py_Size(a) + Py_Size(b);
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL) {
 		return NULL;
 	}
-	memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
-	memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
-	       b->ob_item, b->ob_size*b->ob_descr->itemsize);
+	memcpy(np->ob_item, a->ob_item, Py_Size(a)*a->ob_descr->itemsize);
+	memcpy(np->ob_item + Py_Size(a)*a->ob_descr->itemsize,
+	       b->ob_item, Py_Size(b)*b->ob_descr->itemsize);
 	return (PyObject *)np;
 #undef b
 }
@@ -674,12 +674,12 @@
 	Py_ssize_t nbytes;
 	if (n < 0)
 		n = 0;
-	size = a->ob_size * n;
+	size = Py_Size(a) * n;
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL)
 		return NULL;
 	p = np->ob_item;
-	nbytes = a->ob_size * a->ob_descr->itemsize;
+	nbytes = Py_Size(a) * a->ob_descr->itemsize;
 	for (i = 0; i < n; i++) {
 		memcpy(p, a->ob_item, nbytes);
 		p += nbytes;
@@ -697,7 +697,7 @@
 	if (v == NULL)
 		n = 0;
 	else if (array_Check(v)) {
-		n = b->ob_size;
+		n = Py_Size(b);
 		if (a == b) {
 			/* Special case "a[i:j] = a" -- copy b first */
 			int ret;
@@ -716,44 +716,44 @@
 	else {
 		PyErr_Format(PyExc_TypeError,
 	     "can only assign array (not \"%.200s\") to array slice",
-			     v->ob_type->tp_name);
+			     Py_Type(v)->tp_name);
 		return -1;
 	}
 	if (ilow < 0)
 		ilow = 0;
-	else if (ilow > a->ob_size)
-		ilow = a->ob_size;
+	else if (ilow > Py_Size(a))
+		ilow = Py_Size(a);
 	if (ihigh < 0)
 		ihigh = 0;
 	if (ihigh < ilow)
 		ihigh = ilow;
-	else if (ihigh > a->ob_size)
-		ihigh = a->ob_size;
+	else if (ihigh > Py_Size(a))
+		ihigh = Py_Size(a);
 	item = a->ob_item;
 	d = n - (ihigh-ilow);
 	if (d < 0) { /* Delete -d items */
 		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
 			item + ihigh*a->ob_descr->itemsize,
-			(a->ob_size-ihigh)*a->ob_descr->itemsize);
-		a->ob_size += d;
-		PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
+			(Py_Size(a)-ihigh)*a->ob_descr->itemsize);
+		Py_Size(a) += d;
+		PyMem_RESIZE(item, char, Py_Size(a)*a->ob_descr->itemsize);
 						/* Can't fail */
 		a->ob_item = item;
-		a->allocated = a->ob_size;
+		a->allocated = Py_Size(a);
 	}
 	else if (d > 0) { /* Insert d items */
 		PyMem_RESIZE(item, char,
-			     (a->ob_size + d)*a->ob_descr->itemsize);
+			     (Py_Size(a) + d)*a->ob_descr->itemsize);
 		if (item == NULL) {
 			PyErr_NoMemory();
 			return -1;
 		}
 		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
 			item + ihigh*a->ob_descr->itemsize,
-			(a->ob_size-ihigh)*a->ob_descr->itemsize);
+			(Py_Size(a)-ihigh)*a->ob_descr->itemsize);
 		a->ob_item = item;
-		a->ob_size += d;
-		a->allocated = a->ob_size;
+		Py_Size(a) += d;
+		a->allocated = Py_Size(a);
 	}
 	if (n > 0)
 		memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
@@ -765,7 +765,7 @@
 static int
 array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
 {
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		PyErr_SetString(PyExc_IndexError,
 			         "array assignment index out of range");
 		return -1;
@@ -792,7 +792,7 @@
 		return -1;
 
 	while ((v = PyIter_Next(it)) != NULL) {
-		if (ins1(self, (int) self->ob_size, v) != 0) {
+		if (ins1(self, (int) Py_Size(self), v) != 0) {
 			Py_DECREF(v);
 			Py_DECREF(it);
 			return -1;
@@ -818,16 +818,16 @@
 			     "can only extend with array of same kind");
 		return -1;
 	}
-	size = self->ob_size + b->ob_size;
+	size = Py_Size(self) + Py_Size(b);
         PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
         if (self->ob_item == NULL) {
                 PyObject_Del(self);
                 PyErr_NoMemory();
 		return -1;
         }
-	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
-               b->ob_item, b->ob_size*b->ob_descr->itemsize);
-	self->ob_size = size;
+	memcpy(self->ob_item + Py_Size(self)*self->ob_descr->itemsize,
+               b->ob_item, Py_Size(b)*b->ob_descr->itemsize);
+	Py_Size(self) = size;
 	self->allocated = size;
 
 	return 0;
@@ -840,7 +840,7 @@
 	if (!array_Check(bb)) {
 		PyErr_Format(PyExc_TypeError,
 			"can only extend array with array (not \"%.200s\")",
-			bb->ob_type->tp_name);
+			Py_Type(bb)->tp_name);
 		return NULL;
 	}
 	if (array_do_extend(self, bb) == -1)
@@ -855,15 +855,15 @@
 	char *items, *p;
 	Py_ssize_t size, i;
 
-	if (self->ob_size > 0) {
+	if (Py_Size(self) > 0) {
 		if (n < 0)
 			n = 0;
 		items = self->ob_item;
-		size = self->ob_size * self->ob_descr->itemsize;
+		size = Py_Size(self) * self->ob_descr->itemsize;
 		if (n == 0) {
 			PyMem_FREE(items);
 			self->ob_item = NULL;
-			self->ob_size = 0;
+			Py_Size(self) = 0;
 			self->allocated = 0;
 		}
 		else {
@@ -876,8 +876,8 @@
 				memcpy(p, items, size);
 			}
 			self->ob_item = items;
-			self->ob_size *= n;
-			self->allocated = self->ob_size;
+			Py_Size(self) *= n;
+			self->allocated = Py_Size(self);
 		}
 	}
 	Py_INCREF(self);
@@ -900,7 +900,7 @@
 	Py_ssize_t count = 0;
 	Py_ssize_t i;
 
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		PyObject *selfi = getarrayitem((PyObject *)self, i);
 		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
 		Py_DECREF(selfi);
@@ -922,7 +922,7 @@
 {
 	Py_ssize_t i;
 
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		PyObject *selfi = getarrayitem((PyObject *)self, i);
 		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
 		Py_DECREF(selfi);
@@ -947,7 +947,7 @@
 	Py_ssize_t i;
 	int cmp;
 
-	for (i = 0, cmp = 0 ; cmp == 0 && i < self->ob_size; i++) {
+	for (i = 0, cmp = 0 ; cmp == 0 && i < Py_Size(self); i++) {
 		PyObject *selfi = getarrayitem((PyObject *)self, i);
 		cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
 		Py_DECREF(selfi);
@@ -960,7 +960,7 @@
 {
 	int i;
 
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		PyObject *selfi = getarrayitem((PyObject *)self,i);
 		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
 		Py_DECREF(selfi);
@@ -990,14 +990,14 @@
 	PyObject *v;
 	if (!PyArg_ParseTuple(args, "|n:pop", &i))
 		return NULL;
-	if (self->ob_size == 0) {
+	if (Py_Size(self) == 0) {
 		/* Special-case most common failure cause */
 		PyErr_SetString(PyExc_IndexError, "pop from empty array");
 		return NULL;
 	}
 	if (i < 0)
-		i += self->ob_size;
-	if (i < 0 || i >= self->ob_size) {
+		i += Py_Size(self);
+	if (i < 0 || i >= Py_Size(self)) {
 		PyErr_SetString(PyExc_IndexError, "pop index out of range");
 		return NULL;
 	}
@@ -1053,7 +1053,7 @@
 		return NULL;
 
 	PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
-	PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
+	PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(Py_Size(self))));
 
 	return retval;
 }
@@ -1070,7 +1070,7 @@
 static PyObject *
 array_append(arrayobject *self, PyObject *v)
 {
-	return ins(self, (int) self->ob_size, v);
+	return ins(self, (int) Py_Size(self), v);
 }
 
 PyDoc_STRVAR(append_doc,
@@ -1089,14 +1089,14 @@
 	case 1:
 		break;
 	case 2:
-		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
+		for (p = self->ob_item, i = Py_Size(self); --i >= 0; p += 2) {
 			char p0 = p[0];
 			p[0] = p[1];
 			p[1] = p0;
 		}
 		break;
 	case 4:
-		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
+		for (p = self->ob_item, i = Py_Size(self); --i >= 0; p += 4) {
 			char p0 = p[0];
 			char p1 = p[1];
 			p[0] = p[3];
@@ -1106,7 +1106,7 @@
 		}
 		break;
 	case 8:
-		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
+		for (p = self->ob_item, i = Py_Size(self); --i >= 0; p += 8) {
 			char p0 = p[0];
 			char p1 = p[1];
 			char p2 = p[2];
@@ -1147,16 +1147,16 @@
 		dict = Py_None;
 		Py_INCREF(dict);
 	}
-	if (array->ob_size > 0) {
+	if (Py_Size(array) > 0) {
 		result = Py_BuildValue("O(cs#)O", 
-			array->ob_type, 
+			Py_Type(array), 
 			array->ob_descr->typecode,
 			array->ob_item,
-			array->ob_size * array->ob_descr->itemsize,
+			Py_Size(array) * array->ob_descr->itemsize,
 			dict);
 	} else {
 		result = Py_BuildValue("O(c)O", 
-			array->ob_type, 
+			Py_Type(array), 
 			array->ob_descr->typecode,
 			dict);
 	}
@@ -1175,9 +1175,9 @@
 	char tmp[256];	/* 8 is probably enough -- but why skimp */
 	assert((size_t)itemsize <= sizeof(tmp));
 
-	if (self->ob_size > 1) {
+	if (Py_Size(self) > 1) {
 		for (p = self->ob_item,
-		     q = self->ob_item + (self->ob_size - 1)*itemsize;
+		     q = self->ob_item + (Py_Size(self) - 1)*itemsize;
 		     p < q;
 		     p += itemsize, q -= itemsize) {
 			/* memory areas guaranteed disjoint, so memcpy
@@ -1218,7 +1218,7 @@
 		Py_ssize_t newlength;
 		size_t newbytes;
 		/* Be careful here about overflow */
-		if ((newlength = self->ob_size + n) <= 0 ||
+		if ((newlength = Py_Size(self) + n) <= 0 ||
 		    (newbytes = newlength * itemsize) / itemsize !=
 		    (size_t)newlength)
 			goto nomem;
@@ -1229,15 +1229,15 @@
 			return NULL;
 		}
 		self->ob_item = item;
-		self->ob_size += n;
-		self->allocated = self->ob_size;
-		nread = fread(item + (self->ob_size - n) * itemsize,
+		Py_Size(self) += n;
+		self->allocated = Py_Size(self);
+		nread = fread(item + (Py_Size(self) - n) * itemsize,
 			      itemsize, n, fp);
 		if (nread < (size_t)n) {
-		  self->ob_size -= (n - nread);
-			PyMem_RESIZE(item, char, self->ob_size*itemsize);
+		  Py_Size(self) -= (n - nread);
+			PyMem_RESIZE(item, char, Py_Size(self)*itemsize);
 			self->ob_item = item;
-			self->allocated = self->ob_size;
+			self->allocated = Py_Size(self);
 			PyErr_SetString(PyExc_EOFError,
 				         "not enough items in file");
 			return NULL;
@@ -1297,23 +1297,23 @@
 	if (n > 0) {
 		char *item = self->ob_item;
 		Py_ssize_t i;
-		PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+		PyMem_RESIZE(item, char, (Py_Size(self) + n) * itemsize);
 		if (item == NULL) {
 			PyErr_NoMemory();
 			return NULL;
 		}
 		self->ob_item = item;
-		self->ob_size += n;
-		self->allocated = self->ob_size;
+		Py_Size(self) += n;
+		self->allocated = Py_Size(self);
 		for (i = 0; i < n; i++) {
 			PyObject *v = PyList_GetItem(list, i);
 			if ((*self->ob_descr->setitem)(self,
-					self->ob_size - n + i, v) != 0) {
-				self->ob_size -= n;
+					Py_Size(self) - n + i, v) != 0) {
+				Py_Size(self) -= n;
 				PyMem_RESIZE(item, char,
-					          self->ob_size * itemsize);
+					          Py_Size(self) * itemsize);
 				self->ob_item = item;
-				self->allocated = self->ob_size;
+				self->allocated = Py_Size(self);
 				return NULL;
 			}
 		}
@@ -1331,12 +1331,12 @@
 static PyObject *
 array_tolist(arrayobject *self, PyObject *unused)
 {
-	PyObject *list = PyList_New(self->ob_size);
+	PyObject *list = PyList_New(Py_Size(self));
 	Py_ssize_t i;
 
 	if (list == NULL)
 		return NULL;
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		PyObject *v = getarrayitem((PyObject *)self, i);
 		if (v == NULL) {
 			Py_DECREF(list);
@@ -1369,15 +1369,15 @@
 	n = n / itemsize;
 	if (n > 0) {
 		char *item = self->ob_item;
-		PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
+		PyMem_RESIZE(item, char, (Py_Size(self) + n) * itemsize);
 		if (item == NULL) {
 			PyErr_NoMemory();
 			return NULL;
 		}
 		self->ob_item = item;
-		self->ob_size += n;
-		self->allocated = self->ob_size;
-		memcpy(item + (self->ob_size - n) * itemsize,
+		Py_Size(self) += n;
+		self->allocated = Py_Size(self);
+		memcpy(item + (Py_Size(self) - n) * itemsize,
 		       str, itemsize*n);
 	}
 	Py_INCREF(Py_None);
@@ -1395,7 +1395,7 @@
 array_tostring(arrayobject *self, PyObject *unused)
 {
 	return PyString_FromStringAndSize(self->ob_item,
-				    self->ob_size * self->ob_descr->itemsize);
+				    Py_Size(self) * self->ob_descr->itemsize);
 }
 
 PyDoc_STRVAR(tostring_doc,
@@ -1423,15 +1423,15 @@
 	}
 	if (n > 0) {
 		Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
-		PyMem_RESIZE(item, Py_UNICODE, self->ob_size + n);
+		PyMem_RESIZE(item, Py_UNICODE, Py_Size(self) + n);
 		if (item == NULL) {
 			PyErr_NoMemory();
 			return NULL;
 		}
 		self->ob_item = (char *) item;
-		self->ob_size += n;
-		self->allocated = self->ob_size;
-		memcpy(item + self->ob_size - n,
+		Py_Size(self) += n;
+		self->allocated = Py_Size(self);
+		memcpy(item + Py_Size(self) - n,
 		       ustr, n * sizeof(Py_UNICODE));
 	}
 
@@ -1456,7 +1456,7 @@
 			"tounicode() may only be called on type 'u' arrays");
 		return NULL;
 	}
-	return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, self->ob_size);
+	return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_Size(self));
 }
 
 PyDoc_STRVAR(tounicode_doc,
@@ -1554,7 +1554,7 @@
 	PyObject *s, *t, *v = NULL;
 	Py_ssize_t len;
 
-	len = a->ob_size;
+	len = Py_Size(a);
 	typecode = a->ob_descr->typecode;
 	if (len == 0) {
 		PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
@@ -1588,7 +1588,7 @@
 			return NULL;
 		}
 		if (i < 0)
-			i += self->ob_size;
+			i += Py_Size(self);
 		return array_item(self, i);
 	}
 	else if (PySlice_Check(item)) {
@@ -1597,7 +1597,7 @@
 		arrayobject* ar;
 		int itemsize = self->ob_descr->itemsize;
 
-		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+		if (PySlice_GetIndicesEx((PySliceObject*)item, Py_Size(self),
 				 &start, &stop, &step, &slicelength) < 0) {
 			return NULL;
 		}
@@ -1605,6 +1605,16 @@
 		if (slicelength <= 0) {
 			return newarrayobject(&Arraytype, 0, self->ob_descr);
 		}
+		else if (step == 1) {
+			PyObject *result = newarrayobject(&Arraytype,
+						slicelength, self->ob_descr);
+			if (result == NULL)
+				return NULL;
+			memcpy(((arrayobject *)result)->ob_item,
+			       self->ob_item + start * itemsize,
+			       slicelength * itemsize);
+			return result;
+		}
 		else {
 			result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
 			if (!result) return NULL;
@@ -1623,7 +1633,7 @@
 	}
 	else {
 		PyErr_SetString(PyExc_TypeError, 
-				"list indices must be integers");
+				"array indices must be integers");
 		return NULL;
 	}
 }
@@ -1631,112 +1641,146 @@
 static int
 array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
 {
+	Py_ssize_t start, stop, step, slicelength, needed;
+	arrayobject* other;
+	int itemsize;
+
 	if (PyIndex_Check(item)) {
 		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
-		if (i==-1 && PyErr_Occurred()) 
+		
+		if (i == -1 && PyErr_Occurred())
 			return -1;
 		if (i < 0)
-			i += self->ob_size;
-		return array_ass_item(self, i, value);
-	}
-	else if (PySlice_Check(item)) {
-		Py_ssize_t start, stop, step, slicelength;
-		int itemsize = self->ob_descr->itemsize;
-
-		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
-				 &start, &stop, &step, &slicelength) < 0) {
+			i += Py_Size(self);
+		if (i < 0 || i >= Py_Size(self)) {
+			PyErr_SetString(PyExc_IndexError,
+				"array assignment index out of range");
 			return -1;
 		}
-
-		/* treat A[slice(a,b)] = v _exactly_ like A[a:b] = v */
-		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
-			return array_ass_slice(self, start, stop, value);
-
 		if (value == NULL) {
-			/* delete slice */
-			Py_ssize_t cur, i, extra;
-			
-			if (slicelength <= 0)
-				return 0;
-
-			if (step < 0) {
-				stop = start + 1;
-				start = stop + step*(slicelength - 1) - 1;
-				step = -step;
-			}
-
-			for (cur = start, i = 0; i < slicelength - 1;
-			     cur += step, i++) {
-				memmove(self->ob_item + (cur - i)*itemsize,
-					self->ob_item + (cur + 1)*itemsize,
-					(step - 1) * itemsize);
-			}
-			extra = self->ob_size - (cur + 1);
-			if (extra > 0) {
-				memmove(self->ob_item + (cur - i)*itemsize,
-					self->ob_item + (cur + 1)*itemsize,
-					extra*itemsize);
-			}
-
-			self->ob_size -= slicelength;
-			self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
-							      itemsize*self->ob_size);
-			self->allocated = self->ob_size;
-
-			return 0;
+			/* Fall through to slice assignment */
+			start = i;
+			stop = i + 1;
+			step = 1;
+			slicelength = 1;
 		}
-		else {
-			/* assign slice */
-			Py_ssize_t cur, i;
-			arrayobject* av;
-
-			if (!array_Check(value)) {
-				PyErr_Format(PyExc_TypeError,
-			     "must assign array (not \"%.200s\") to slice",
-					     value->ob_type->tp_name);
-				return -1;
-			}
-
-			av = (arrayobject*)value;
-
-			if (av->ob_size != slicelength) {
-				PyErr_Format(PyExc_ValueError,
-            "attempt to assign array of size %ld to extended slice of size %ld",
-					     /*XXX*/(long)av->ob_size, /*XXX*/(long)slicelength);
+		else
+			return (*self->ob_descr->setitem)(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 Py_Size(self), &start, &stop,
+					 &step, &slicelength) < 0) {
+			return -1;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"array indices must be integer");
+		return -1;
+	}
+	if (value == NULL) {
+		other = NULL;
+		needed = 0;
+	}
+	else if (array_Check(value)) {
+		other = (arrayobject *)value;
+		needed = Py_Size(other);
+		if (self == other) {
+			/* Special case "self[i:j] = self" -- copy self first */
+			int ret;
+			value = array_slice(other, 0, needed);
+			if (value == NULL)
 				return -1;
-			}
-
-			if (!slicelength)
-				return 0;
-
-			/* protect against a[::-1] = a */
-			if (self == av) { 
-				value = array_slice(av, 0, av->ob_size);
-				av = (arrayobject*)value;
-				if (!av)
-					return -1;
-			} 
-			else {
-				Py_INCREF(value);
-			}
-
-			for (cur = start, i = 0; i < slicelength; 
-			     cur += step, i++) {
-				memcpy(self->ob_item + cur*itemsize,
-				       av->ob_item + i*itemsize,
-				       itemsize);
-			}
-
+			ret = array_ass_subscr(self, item, value);
 			Py_DECREF(value);
-			
-			return 0;
+			return ret;
+		}
+		if (other->ob_descr != self->ob_descr) {
+			PyErr_BadArgument();
+			return -1;
 		}
-	} 
+	}
 	else {
-		PyErr_SetString(PyExc_TypeError, 
-				"list indices must be integers");
+		PyErr_Format(PyExc_TypeError,
+	     "can only assign array (not \"%.200s\") to array slice",
+			     Py_Type(value)->tp_name);
 		return -1;
 	}
+	itemsize = self->ob_descr->itemsize;
+	/* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
+	if ((step > 0 && stop < start) ||
+	    (step < 0 && stop > start))
+		stop = start;
+	if (step == 1) {
+		if (slicelength > needed) {
+			memmove(self->ob_item + (start + needed) * itemsize,
+				self->ob_item + stop * itemsize,
+				(Py_Size(self) - stop) * itemsize);
+			if (array_resize(self, Py_Size(self) +
+					 needed - slicelength) < 0)
+				return -1;
+		}
+		else if (slicelength < needed) {
+			if (array_resize(self, Py_Size(self) +
+					 needed - slicelength) < 0)
+				return -1;
+			memmove(self->ob_item + (start + needed) * itemsize,
+				self->ob_item + stop * itemsize,
+				(Py_Size(self) - start - needed) * itemsize);
+		}
+		if (needed > 0)
+			memcpy(self->ob_item + start * itemsize,
+			       other->ob_item, needed * itemsize);
+		return 0;
+	}
+	else if (needed == 0) {
+		/* Delete slice */
+		Py_ssize_t cur, i;
+		
+		if (step < 0) {
+			stop = start + 1;
+			start = stop + step * (slicelength - 1) - 1;
+			step = -step;
+		}
+		for (cur = start, i = 0; i < slicelength;
+		     cur += step, i++) {
+			Py_ssize_t lim = step - 1;
+
+			if (cur + step >= Py_Size(self))
+				lim = Py_Size(self) - cur - 1;
+			memmove(self->ob_item + (cur - i) * itemsize,
+				self->ob_item + (cur + 1) * itemsize,
+				lim * itemsize);
+		}
+		cur = start + slicelength * step;
+		if (cur < Py_Size(self)) {
+			memmove(self->ob_item + (cur-slicelength) * itemsize,
+				self->ob_item + cur * itemsize,
+				(Py_Size(self) - cur) * itemsize);
+		}
+		if (array_resize(self, Py_Size(self) - slicelength) < 0)
+			return -1;
+		return 0;
+	}
+	else {
+		Py_ssize_t cur, i;
+
+		if (needed != slicelength) {
+			PyErr_Format(PyExc_ValueError,
+				"attempt to assign array of size %zd "
+				"to extended slice of size %zd",
+				needed, slicelength);
+			return -1;
+		}
+		for (cur = start, i = 0; i < slicelength;
+		     cur += step, i++) {
+			memcpy(self->ob_item + cur * itemsize,
+			       other->ob_item + i * itemsize,
+			       itemsize);
+		}
+		return 0;
+	}
 }
 
 static PyMappingMethods array_as_mapping = {
@@ -1758,7 +1802,7 @@
 	*ptr = (void *)self->ob_item;
 	if (*ptr == NULL)
 		*ptr = emptybuf;
-	return self->ob_size*self->ob_descr->itemsize;
+	return Py_Size(self)*self->ob_descr->itemsize;
 }
 
 static Py_ssize_t
@@ -1772,14 +1816,14 @@
 	*ptr = (void *)self->ob_item;
 	if (*ptr == NULL)
 		*ptr = emptybuf;
-	return self->ob_size*self->ob_descr->itemsize;
+	return Py_Size(self)*self->ob_descr->itemsize;
 }
 
 static Py_ssize_t
 array_buffer_getsegcount(arrayobject *self, Py_ssize_t *lenp)
 {
 	if ( lenp )
-		*lenp = self->ob_size*self->ob_descr->itemsize;
+		*lenp = Py_Size(self)*self->ob_descr->itemsize;
 	return 1;
 }
 
@@ -1888,9 +1932,9 @@
 						return NULL;
 					}
 					self->ob_item = item;
-					self->ob_size = n / sizeof(Py_UNICODE);
+					Py_Size(self) = n / sizeof(Py_UNICODE);
 					memcpy(item, PyUnicode_AS_DATA(initial), n);
-					self->allocated = self->ob_size;
+					self->allocated = Py_Size(self);
 				}
 #endif
 			}
@@ -1978,8 +2022,7 @@
 static PyObject *array_iter(arrayobject *ao);
 
 static PyTypeObject Arraytype = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"array.array",
 	sizeof(arrayobject),
 	0,
@@ -2060,7 +2103,7 @@
 arrayiter_next(arrayiterobject *it)
 {
 	assert(PyArrayIter_Check(it));
-	if (it->index < it->ao->ob_size)
+	if (it->index < Py_Size(it->ao))
 		return (*it->getitem)(it->ao, it->index++);
 	return NULL;
 }
@@ -2081,8 +2124,7 @@
 }
 
 static PyTypeObject PyArrayIter_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,                                      /* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"arrayiterator",                        /* tp_name */
 	sizeof(arrayiterobject),                /* tp_basicsize */
 	0,                                      /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/bz2module.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/bz2module.c	(original)
+++ python/branches/bcannon-objcap/Modules/bz2module.c	Thu Sep  6 21:35:45 2007
@@ -41,7 +41,7 @@
 #define MODE_READ_EOF 2
 #define MODE_WRITE    3
 
-#define BZ2FileObject_Check(v)	((v)->ob_type == &BZ2File_Type)
+#define BZ2FileObject_Check(v)	(Py_Type(v) == &BZ2File_Type)
 
 
 #ifdef BZ_CONFIG_ERROR
@@ -1431,7 +1431,7 @@
 	}
 	Util_DropReadAhead(self);
 	Py_XDECREF(self->file);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 /* This is a hacked version of Python's fileobject.c:file_getiter(). */
@@ -1493,8 +1493,7 @@
 ;
 
 static PyTypeObject BZ2File_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"bz2.BZ2File",		/*tp_name*/
 	sizeof(BZ2FileObject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -1748,7 +1747,7 @@
 		PyThread_free_lock(self->lock);
 #endif
 	BZ2_bzCompressEnd(&self->bzs);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 
@@ -1765,8 +1764,7 @@
 ");
 
 static PyTypeObject BZ2Comp_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"bz2.BZ2Compressor",	/*tp_name*/
 	sizeof(BZ2CompObject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -1971,7 +1969,7 @@
 #endif
 	Py_XDECREF(self->unused_data);
 	BZ2_bzDecompressEnd(&self->bzs);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 
@@ -1987,8 +1985,7 @@
 ");
 
 static PyTypeObject BZ2Decomp_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"bz2.BZ2Decompressor",	/*tp_name*/
 	sizeof(BZ2DecompObject), /*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -2222,9 +2219,9 @@
 {
 	PyObject *m;
 
-	BZ2File_Type.ob_type = &PyType_Type;
-	BZ2Comp_Type.ob_type = &PyType_Type;
-	BZ2Decomp_Type.ob_type = &PyType_Type;
+	Py_Type(&BZ2File_Type) = &PyType_Type;
+	Py_Type(&BZ2Comp_Type) = &PyType_Type;
+	Py_Type(&BZ2Decomp_Type) = &PyType_Type;
 
 	m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
 	if (m == NULL)

Modified: python/branches/bcannon-objcap/Modules/cPickle.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/cPickle.c	(original)
+++ python/branches/bcannon-objcap/Modules/cPickle.c	Thu Sep  6 21:35:45 2007
@@ -151,12 +151,12 @@
 }
 
 static PyTypeObject PdataType = {
-	PyObject_HEAD_INIT(NULL) 0, "cPickle.Pdata", sizeof(Pdata), 0,
+	PyVarObject_HEAD_INIT(NULL, 0) "cPickle.Pdata", sizeof(Pdata), 0,
 	(destructor)Pdata_dealloc,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L,0L,0L,0L, ""
 };
 
-#define Pdata_Check(O) ((O)->ob_type == &PdataType)
+#define Pdata_Check(O) (Py_Type(O) == &PdataType)
 
 static PyObject *
 Pdata_New(void)
@@ -316,7 +316,7 @@
 }
 
 #define FREE_ARG_TUP(self) {                        \
-    if (self->arg->ob_refcnt > 1) {                 \
+    if (Py_Refcnt(self->arg) > 1) {                 \
       Py_DECREF(self->arg);                         \
       self->arg=NULL;                               \
     }                                               \
@@ -752,7 +752,7 @@
 static int
 put(Picklerobject *self, PyObject *ob)
 {
-	if (ob->ob_refcnt < 2 || self->fast)
+	if (Py_Refcnt(ob) < 2 || self->fast)
 		return 0;
 
 	return put2(self, ob);
@@ -916,7 +916,7 @@
 			PyErr_Format(PyExc_ValueError,
 				     "fast mode: can't pickle cyclic objects "
 				     "including object type %s at %p",
-				     obj->ob_type->tp_name, obj);
+				     Py_Type(obj)->tp_name, obj);
 			self->fast_container = -1;
 			return 0;
 		}
@@ -2320,7 +2320,7 @@
 		goto finally;
 	}
 
-	type = args->ob_type;
+	type = Py_Type(args);
 
 	switch (type->tp_name[0]) {
 	case 'b':
@@ -2372,7 +2372,7 @@
 #endif
 	}
 
-	if (args->ob_refcnt > 1) {
+	if (Py_Refcnt(args) > 1) {
 		if (!( py_ob_id = PyLong_FromVoidPtr(args)))
 			goto finally;
 
@@ -2913,7 +2913,7 @@
 	Py_XDECREF(self->inst_pers_func);
 	Py_XDECREF(self->dispatch_table);
 	PyMem_Free(self->write_buf);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -3037,8 +3037,7 @@
 "Objects that know how to pickle objects\n");
 
 static PyTypeObject Picklertype = {
-    PyObject_HEAD_INIT(NULL)
-    0,                            /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "cPickle.Pickler",            /*tp_name*/
     sizeof(Picklerobject),              /*tp_basicsize*/
     0,
@@ -5254,7 +5253,7 @@
 		free(self->buf);
 	}
 
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -5483,8 +5482,7 @@
 "Objects that know how to unpickle");
 
 static PyTypeObject Unpicklertype = {
-    PyObject_HEAD_INIT(NULL)
-    0,                          	 /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "cPickle.Unpickler", 	         /*tp_name*/
     sizeof(Unpicklerobject),             /*tp_basicsize*/
     0,
@@ -5708,9 +5706,9 @@
 	PyObject *format_version;
 	PyObject *compatible_formats;
 
-	Picklertype.ob_type = &PyType_Type;
-	Unpicklertype.ob_type = &PyType_Type;
-	PdataType.ob_type = &PyType_Type;
+	Py_Type(&Picklertype) = &PyType_Type;
+	Py_Type(&Unpicklertype) = &PyType_Type;
+	Py_Type(&PdataType) = &PyType_Type;
 
 	/* Initialize some pieces. We need to do this before module creation,
 	 * so we're forced to use a temporary dictionary. :(

Modified: python/branches/bcannon-objcap/Modules/cStringIO.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/cStringIO.c	(original)
+++ python/branches/bcannon-objcap/Modules/cStringIO.c	Thu Sep  6 21:35:45 2007
@@ -514,8 +514,7 @@
 PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
 
 static PyTypeObject Otype = {
-  PyObject_HEAD_INIT(NULL)
-  0,	       			/*ob_size*/
+  PyVarObject_HEAD_INIT(NULL, 0)
   "cStringIO.StringO",   	/*tp_name*/
   sizeof(Oobject),       	/*tp_basicsize*/
   0,	       			/*tp_itemsize*/
@@ -635,8 +634,7 @@
 "Simple type for treating strings as input file streams");
 
 static PyTypeObject Itype = {
-  PyObject_HEAD_INIT(NULL)
-  0,					/*ob_size*/
+  PyVarObject_HEAD_INIT(NULL, 0)
   "cStringIO.StringI",			/*tp_name*/
   sizeof(Iobject),			/*tp_basicsize*/
   0,					/*tp_itemsize*/
@@ -675,8 +673,11 @@
   char *buf;
   Py_ssize_t size;
 
-  if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
-      return NULL;
+  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
+    PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
+                 s->ob_type->tp_name);
+    return NULL;
+  }
 
   self = PyObject_New(Iobject, &Itype);
   if (!self) return NULL;
@@ -746,8 +747,8 @@
   d = PyModule_GetDict(m);
   
   /* Export C API */
-  Itype.ob_type=&PyType_Type;
-  Otype.ob_type=&PyType_Type;
+  Py_Type(&Itype)=&PyType_Type;
+  Py_Type(&Otype)=&PyType_Type;
   if (PyType_Ready(&Otype) < 0) return;
   if (PyType_Ready(&Itype) < 0) return;
   PyDict_SetItemString(d,"cStringIO_CAPI",

Modified: python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_cn.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_cn.c	(original)
+++ python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_cn.c	Thu Sep  6 21:35:45 2007
@@ -197,6 +197,7 @@
 		REQUIRE_OUTBUF(2)
 
 		GBK_ENCODE(c, code)
+		else TRYMAP_ENC(gb18030ext, code, c);
 		else {
 			const struct _gb18030_to_unibmp_ranges *utrrange;
 

Modified: python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_kr.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_kr.c	(original)
+++ python/branches/bcannon-objcap/Modules/cjkcodecs/_codecs_kr.c	Thu Sep  6 21:35:45 2007
@@ -11,6 +11,26 @@
  * EUC-KR codec
  */
 
+#define EUCKR_JAMO_FIRSTBYTE	0xA4
+#define EUCKR_JAMO_FILLER	0xD4
+
+static const unsigned char u2cgk_choseong[19] = {
+	0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2,
+	0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
+	0xbc, 0xbd, 0xbe
+};
+static const unsigned char u2cgk_jungseong[21] = {
+	0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
+	0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
+	0xcf, 0xd0, 0xd1, 0xd2, 0xd3
+};
+static const unsigned char u2cgk_jongseong[28] = {
+	0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+	0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xba,
+	0xbb, 0xbc, 0xbd, 0xbe
+};
+
 ENCODER(euc_kr)
 {
 	while (inleft > 0) {
@@ -28,17 +48,57 @@
 		TRYMAP_ENC(cp949, code, c);
 		else return 1;
 
-		if (code & 0x8000) /* MSB set: CP949 */
-			return 1;
+		if ((code & 0x8000) == 0) {
+			/* KS X 1001 coded character */
+			OUT1((code >> 8) | 0x80)
+			OUT2((code & 0xFF) | 0x80)
+			NEXT(1, 2)
+		}
+		else {	/* Mapping is found in CP949 extension,
+			 * but we encode it in KS X 1001:1998 Annex 3,
+			 * make-up sequence for EUC-KR. */
+
+			REQUIRE_OUTBUF(8)
+
+			/* syllable composition precedence */
+			OUT1(EUCKR_JAMO_FIRSTBYTE)
+			OUT2(EUCKR_JAMO_FILLER)
+
+			/* All codepoints in CP949 extension are in unicode
+			 * Hangul Syllable area. */
+			assert(0xac00 <= c && c <= 0xd7a3);
+			c -= 0xac00;
 
-		OUT1((code >> 8) | 0x80)
-		OUT2((code & 0xFF) | 0x80)
-		NEXT(1, 2)
+			OUT3(EUCKR_JAMO_FIRSTBYTE)
+			OUT4(u2cgk_choseong[c / 588])
+			NEXT_OUT(4)
+
+			OUT1(EUCKR_JAMO_FIRSTBYTE)
+			OUT2(u2cgk_jungseong[(c / 28) % 21])
+			OUT3(EUCKR_JAMO_FIRSTBYTE)
+			OUT4(u2cgk_jongseong[c % 28])
+			NEXT(1, 4)
+		}
 	}
 
 	return 0;
 }
 
+#define NONE	127
+
+static const unsigned char cgk2u_choseong[] = { /* [A1, BE] */
+	   0,    1, NONE,    2, NONE, NONE,    3,    4,
+	   5, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
+	   6,    7,    8, NONE,    9,   10,   11,   12,
+	  13,   14,   15,   16,   17,   18
+};
+static const unsigned char cgk2u_jongseong[] = { /* [A1, BE] */
+	   1,    2,    3,    4,    5,    6,    7, NONE,
+	   8,    9,   10,   11,   12,   13,   14,   15,
+	  16,   17, NONE,   18,   19,   20,   21,   22,
+	NONE,   23,   24,   25,   26,   27
+};
+
 DECODER(euc_kr)
 {
 	while (inleft > 0) {
@@ -54,13 +114,50 @@
 
 		REQUIRE_INBUF(2)
 
-		TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
+		if (c == EUCKR_JAMO_FIRSTBYTE &&
+		    IN2 == EUCKR_JAMO_FILLER) {
+			/* KS X 1001:1998 Annex 3 make-up sequence */
+			DBCHAR cho, jung, jong;
+
+			REQUIRE_INBUF(8)
+			if ((*inbuf)[2] != EUCKR_JAMO_FIRSTBYTE ||
+			    (*inbuf)[4] != EUCKR_JAMO_FIRSTBYTE ||
+			    (*inbuf)[6] != EUCKR_JAMO_FIRSTBYTE)
+				return 8;
+
+			c = (*inbuf)[3];
+			if (0xa1 <= c && c <= 0xbe)
+				cho = cgk2u_choseong[c - 0xa1];
+			else
+				cho = NONE;
+
+			c = (*inbuf)[5];
+			jung = (0xbf <= c && c <= 0xd3) ? c - 0xbf : NONE;
+
+			c = (*inbuf)[7];
+			if (c == EUCKR_JAMO_FILLER)
+				jong = 0;
+			else if (0xa1 <= c && c <= 0xbe)
+				jong = cgk2u_jongseong[c - 0xa1];
+			else
+				jong = NONE;
+
+			if (cho == NONE || jung == NONE || jong == NONE)
+				return 8;
+
+			OUT1(0xac00 + cho*588 + jung*28 + jong);
+			NEXT(8, 1)
+		}
+		else TRYMAP_DEC(ksx1001, **outbuf, c ^ 0x80, IN2 ^ 0x80) {
 			NEXT(2, 1)
-		} else return 2;
+		}
+		else
+			return 2;
 	}
 
 	return 0;
 }
+#undef NONE
 
 
 /*

Modified: python/branches/bcannon-objcap/Modules/cjkcodecs/multibytecodec.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/cjkcodecs/multibytecodec.c	(original)
+++ python/branches/bcannon-objcap/Modules/cjkcodecs/multibytecodec.c	Thu Sep  6 21:35:45 2007
@@ -670,8 +670,7 @@
 }
 
 static PyTypeObject MultibyteCodec_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"MultibyteCodec",		/* tp_name */
 	sizeof(MultibyteCodecObject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -946,12 +945,11 @@
 {
 	PyObject_GC_UnTrack(self);
 	ERROR_DECREF(self->errors);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyTypeObject MultibyteIncrementalEncoder_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"MultibyteIncrementalEncoder",	/* tp_name */
 	sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1147,12 +1145,11 @@
 {
 	PyObject_GC_UnTrack(self);
 	ERROR_DECREF(self->errors);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyTypeObject MultibyteIncrementalDecoder_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"MultibyteIncrementalDecoder",	/* tp_name */
 	sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1464,12 +1461,11 @@
 	PyObject_GC_UnTrack(self);
 	ERROR_DECREF(self->errors);
 	Py_DECREF(self->stream);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyTypeObject MultibyteStreamReader_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"MultibyteStreamReader",	/* tp_name */
 	sizeof(MultibyteStreamReaderObject), /* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1667,7 +1663,7 @@
 	PyObject_GC_UnTrack(self);
 	ERROR_DECREF(self->errors);
 	Py_DECREF(self->stream);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static struct PyMethodDef mbstreamwriter_methods[] = {
@@ -1688,8 +1684,7 @@
 };
 
 static PyTypeObject MultibyteStreamWriter_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"MultibyteStreamWriter",	/* tp_name */
 	sizeof(MultibyteStreamWriterObject), /* tp_basicsize */
 	0,				/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/datetimemodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/datetimemodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/datetimemodule.c	Thu Sep  6 21:35:45 2007
@@ -764,7 +764,7 @@
 	PyErr_Format(PyExc_TypeError,
 		     "tzinfo argument must be None or of a tzinfo subclass, "
 		     "not type '%s'",
-		     p->ob_type->tp_name);
+		     Py_Type(p)->tp_name);
 	return -1;
 }
 
@@ -855,7 +855,7 @@
 		PyErr_Format(PyExc_TypeError,
 			     "tzinfo.%s() must return None or "
 			     "timedelta, not '%s'",
-			     name, u->ob_type->tp_name);
+			     name, Py_Type(u)->tp_name);
 	}
 
 	Py_DECREF(u);
@@ -948,7 +948,7 @@
 	if (result != NULL && result != Py_None && ! PyString_Check(result)) {
 		PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
 			     "return None or a string, not '%s'",
-			     result->ob_type->tp_name);
+			     Py_Type(result)->tp_name);
 		Py_DECREF(result);
 		result = NULL;
 	}
@@ -1421,7 +1421,7 @@
 {
 	PyErr_Format(PyExc_TypeError,
 		     "can't compare %s to %s",
-		     a->ob_type->tp_name, b->ob_type->tp_name);
+		     Py_Type(a)->tp_name, Py_Type(b)->tp_name);
 	return NULL;
 }
 
@@ -1876,7 +1876,7 @@
 
 	PyErr_Format(PyExc_TypeError,
 		     "unsupported type for timedelta %s component: %s",
-		     tag, num->ob_type->tp_name);
+		     tag, Py_Type(num)->tp_name);
 	return NULL;
 }
 
@@ -1980,18 +1980,18 @@
 {
 	if (GET_TD_MICROSECONDS(self) != 0)
 		return PyString_FromFormat("%s(%d, %d, %d)",
-					   self->ob_type->tp_name,
+					   Py_Type(self)->tp_name,
 					   GET_TD_DAYS(self),
 					   GET_TD_SECONDS(self),
 					   GET_TD_MICROSECONDS(self));
 	if (GET_TD_SECONDS(self) != 0)
 		return PyString_FromFormat("%s(%d, %d)",
-					   self->ob_type->tp_name,
+					   Py_Type(self)->tp_name,
 					   GET_TD_DAYS(self),
 					   GET_TD_SECONDS(self));
 
 	return PyString_FromFormat("%s(%d)",
-				   self->ob_type->tp_name,
+				   Py_Type(self)->tp_name,
 				   GET_TD_DAYS(self));
 }
 
@@ -2055,7 +2055,7 @@
 static PyObject *
 delta_reduce(PyDateTime_Delta* self)
 {
-	return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
+	return Py_BuildValue("ON", Py_Type(self), delta_getstate(self));
 }
 
 #define OFFSET(field)  offsetof(PyDateTime_Delta, field)
@@ -2125,8 +2125,7 @@
 };
 
 static PyTypeObject PyDateTime_DeltaType = {
-	PyObject_HEAD_INIT(NULL)
-	0,						/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"datetime.timedelta",				/* tp_name */
 	sizeof(PyDateTime_Delta),			/* tp_basicsize */
 	0,						/* tp_itemsize */
@@ -2415,7 +2414,7 @@
 	char buffer[1028];
 	const char *type_name;
 
-	type_name = self->ob_type->tp_name;
+	type_name = Py_Type(self)->tp_name;
 	PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
 		      type_name,
 		      GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
@@ -2555,7 +2554,7 @@
 	tuple = Py_BuildValue("iii", year, month, day);
 	if (tuple == NULL)
 		return NULL;
-	clone = date_new(self->ob_type, tuple, NULL);
+	clone = date_new(Py_Type(self), tuple, NULL);
 	Py_DECREF(tuple);
 	return clone;
 }
@@ -2605,7 +2604,7 @@
 static PyObject *
 date_reduce(PyDateTime_Date *self, PyObject *arg)
 {
-	return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
+	return Py_BuildValue("(ON)", Py_Type(self), date_getstate(self));
 }
 
 static PyMethodDef date_methods[] = {
@@ -2683,8 +2682,7 @@
 };
 
 static PyTypeObject PyDateTime_DateType = {
-	PyObject_HEAD_INIT(NULL)
-	0,						/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"datetime.date",				/* tp_name */
 	sizeof(PyDateTime_Date),			/* tp_basicsize */
 	0,						/* tp_itemsize */
@@ -2908,10 +2906,10 @@
 
 	if (state == Py_None) {
 		Py_DECREF(state);
-		return Py_BuildValue("(ON)", self->ob_type, args);
+		return Py_BuildValue("(ON)", Py_Type(self), args);
 	}
 	else
-		return Py_BuildValue("(ONN)", self->ob_type, args, state);
+		return Py_BuildValue("(ONN)", Py_Type(self), args, state);
 }
 
 static PyMethodDef tzinfo_methods[] = {
@@ -3106,7 +3104,7 @@
 	if (HASTZINFO(self)) {
 		Py_XDECREF(self->tzinfo);
 	}
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 /*
@@ -3140,7 +3138,7 @@
 time_repr(PyDateTime_Time *self)
 {
 	char buffer[100];
-	const char *type_name = self->ob_type->tp_name;
+	const char *type_name = Py_Type(self)->tp_name;
 	int h = TIME_GET_HOUR(self);
 	int m = TIME_GET_MINUTE(self);
 	int s = TIME_GET_SECOND(self);
@@ -3354,7 +3352,7 @@
 	tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
 	if (tuple == NULL)
 		return NULL;
-	clone = time_new(self->ob_type, tuple, NULL);
+	clone = time_new(Py_Type(self), tuple, NULL);
 	Py_DECREF(tuple);
 	return clone;
 }
@@ -3408,7 +3406,7 @@
 static PyObject *
 time_reduce(PyDateTime_Time *self, PyObject *arg)
 {
-	return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
+	return Py_BuildValue("(ON)", Py_Type(self), time_getstate(self));
 }
 
 static PyMethodDef time_methods[] = {
@@ -3902,7 +3900,7 @@
 	if (HASTZINFO(self)) {
 		Py_XDECREF(self->tzinfo);
 	}
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 /*
@@ -4051,7 +4049,7 @@
 datetime_repr(PyDateTime_DateTime *self)
 {
 	char buffer[1000];
-	const char *type_name = self->ob_type->tp_name;
+	const char *type_name = Py_Type(self)->tp_name;
 	PyObject *baserepr;
 
 	if (DATE_GET_MICROSECOND(self)) {
@@ -4272,7 +4270,7 @@
 	tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
 	if (tuple == NULL)
 		return NULL;
-	clone = datetime_new(self->ob_type, tuple, NULL);
+	clone = datetime_new(Py_Type(self), tuple, NULL);
 	Py_DECREF(tuple);
 	return clone;
 }
@@ -4460,7 +4458,7 @@
 static PyObject *
 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
 {
-	return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
+	return Py_BuildValue("(ON)", Py_Type(self), datetime_getstate(self));
 }
 
 static PyMethodDef datetime_methods[] = {

Modified: python/branches/bcannon-objcap/Modules/dbmmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/dbmmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/dbmmodule.c	Thu Sep  6 21:35:45 2007
@@ -36,7 +36,7 @@
 
 static PyTypeObject Dbmtype;
 
-#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define is_dbmobject(v) (Py_Type(v) == &Dbmtype)
 #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
                { PyErr_SetString(DbmError, "DBM object has already been closed"); \
                  return NULL; }
@@ -302,8 +302,7 @@
 }
 
 static PyTypeObject Dbmtype = {
-	PyObject_HEAD_INIT(NULL)
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"dbm.dbm",
 	sizeof(dbmobject),
 	0,

Modified: python/branches/bcannon-objcap/Modules/dlmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/dlmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/dlmodule.c	Thu Sep  6 21:35:45 2007
@@ -62,7 +62,7 @@
 		name = PyString_AS_STRING(args);
 	} else {
 		PyErr_Format(PyExc_TypeError, "expected string, found %.200s",
-			     args->ob_type->tp_name);
+			     Py_Type(args)->tp_name);
 		return NULL;
 	}
 	func = dlsym(xp->dl_handle, name);
@@ -141,8 +141,7 @@
 
 
 static PyTypeObject Dltype = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"dl.dl",		/*tp_name*/
 	sizeof(dlobject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -237,7 +236,7 @@
 	PyObject *m, *d, *x;
 
 	/* Initialize object type */
-	Dltype.ob_type = &PyType_Type;
+	Py_Type(&Dltype) = &PyType_Type;
 
 	/* Create the module and add the functions */
 	m = Py_InitModule("dl", dl_methods);

Modified: python/branches/bcannon-objcap/Modules/gcmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/gcmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/gcmodule.c	Thu Sep  6 21:35:45 2007
@@ -239,7 +239,7 @@
 	PyGC_Head *gc = containers->gc.gc_next;
 	for (; gc != containers; gc = gc->gc.gc_next) {
 		assert(gc->gc.gc_refs == GC_REACHABLE);
-		gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt;
+		gc->gc.gc_refs = Py_Refcnt(FROM_GC(gc));
 		/* Python's cyclic gc should never see an incoming refcount
 		 * of 0:  if something decref'ed to 0, it should have been
 		 * deallocated immediately at that time.
@@ -291,7 +291,7 @@
 	traverseproc traverse;
 	PyGC_Head *gc = containers->gc.gc_next;
 	for (; gc != containers; gc=gc->gc.gc_next) {
-		traverse = FROM_GC(gc)->ob_type->tp_traverse;
+		traverse = Py_Type(FROM_GC(gc))->tp_traverse;
 		(void) traverse(FROM_GC(gc),
 			       (visitproc)visit_decref,
 			       NULL);
@@ -376,7 +376,7 @@
                          * the next object to visit.
                          */
                         PyObject *op = FROM_GC(gc);
-                        traverseproc traverse = op->ob_type->tp_traverse;
+                        traverseproc traverse = Py_Type(op)->tp_traverse;
                         assert(gc->gc.gc_refs > 0);
                         gc->gc.gc_refs = GC_REACHABLE;
                         (void) traverse(op,
@@ -472,7 +472,7 @@
 	PyGC_Head *gc = finalizers->gc.gc_next;
 	for (; gc != finalizers; gc = gc->gc.gc_next) {
 		/* Note that the finalizers list may grow during this. */
-		traverse = FROM_GC(gc)->ob_type->tp_traverse;
+		traverse = Py_Type(FROM_GC(gc))->tp_traverse;
 		(void) traverse(FROM_GC(gc),
 				(visitproc)visit_move,
 				(void *)finalizers);
@@ -517,7 +517,7 @@
 		assert(IS_TENTATIVELY_UNREACHABLE(op));
 		next = gc->gc.gc_next;
 
-		if (! PyType_SUPPORTS_WEAKREFS(op->ob_type))
+		if (! PyType_SUPPORTS_WEAKREFS(Py_Type(op)))
 			continue;
 
 		/* It supports weakrefs.  Does it have any? */
@@ -654,7 +654,7 @@
 	}
 	else if (debug & DEBUG_OBJECTS) {
 		PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
-				  msg, op->ob_type->tp_name, op);
+				  msg, Py_Type(op)->tp_name, op);
 	}
 }
 
@@ -708,7 +708,7 @@
 			PyList_Append(garbage, op);
 		}
 		else {
-			if ((clear = op->ob_type->tp_clear) != NULL) {
+			if ((clear = Py_Type(op)->tp_clear) != NULL) {
 				Py_INCREF(op);
 				clear(op);
 				Py_DECREF(op);
@@ -1079,7 +1079,7 @@
 	traverseproc traverse;
 	for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
 		obj = FROM_GC(gc);
-		traverse = obj->ob_type->tp_traverse;
+		traverse = Py_Type(obj)->tp_traverse;
 		if (obj == objs || obj == resultlist)
 			continue;
 		if (traverse(obj, (visitproc)referrersvisit, objs)) {
@@ -1136,7 +1136,7 @@
 
 		if (! PyObject_IS_GC(obj))
 			continue;
-		traverse = obj->ob_type->tp_traverse;
+		traverse = Py_Type(obj)->tp_traverse;
 		if (! traverse)
 			continue;
 		if (traverse(obj, (visitproc)referentsvisit, result)) {
@@ -1359,13 +1359,13 @@
 PyVarObject *
 _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
 {
-	const size_t basicsize = _PyObject_VAR_SIZE(op->ob_type, nitems);
+	const size_t basicsize = _PyObject_VAR_SIZE(Py_Type(op), nitems);
 	PyGC_Head *g = AS_GC(op);
 	g = (PyGC_Head *)PyObject_REALLOC(g,  sizeof(PyGC_Head) + basicsize);
 	if (g == NULL)
 		return (PyVarObject *)PyErr_NoMemory();
 	op = (PyVarObject *) FROM_GC(g);
-	op->ob_size = nitems;
+	Py_Size(op) = nitems;
 	return op;
 }
 

Modified: python/branches/bcannon-objcap/Modules/gdbmmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/gdbmmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/gdbmmodule.c	Thu Sep  6 21:35:45 2007
@@ -36,7 +36,7 @@
 
 static PyTypeObject Dbmtype;
 
-#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
+#define is_dbmobject(v) (Py_Type(v) == &Dbmtype)
 #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
     { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
       return NULL; }
@@ -370,8 +370,7 @@
 }
 
 static PyTypeObject Dbmtype = {
-    PyObject_HEAD_INIT(0)
-    0,
+    PyVarObject_HEAD_INIT(0, 0)
     "gdbm.gdbm",
     sizeof(dbmobject),
     0,

Modified: python/branches/bcannon-objcap/Modules/itertoolsmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/itertoolsmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/itertoolsmodule.c	Thu Sep  6 21:35:45 2007
@@ -59,7 +59,7 @@
 	Py_XDECREF(gbo->tgtkey);
 	Py_XDECREF(gbo->currkey);
 	Py_XDECREF(gbo->currvalue);
-	gbo->ob_type->tp_free(gbo);
+	Py_Type(gbo)->tp_free(gbo);
 }
 
 static int
@@ -139,8 +139,7 @@
 (key, sub-iterator) grouped by each value of key(value).\n");
 
 static PyTypeObject groupby_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.groupby",		/* tp_name */
 	sizeof(groupbyobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -261,8 +260,7 @@
 }
 
 static PyTypeObject _grouper_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools._grouper",		/* tp_name */
 	sizeof(_grouperobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -415,8 +413,7 @@
 PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
 
 static PyTypeObject teedataobject_type = {
-	PyObject_HEAD_INIT(0)	/* Must fill in type value later */
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(0, 0)	/* Must fill in type value later */
 	"itertools.tee_dataobject",		/* tp_name */
 	sizeof(teedataobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -572,8 +569,7 @@
 };
 
 static PyTypeObject tee_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.tee",		/* tp_name */
 	sizeof(teeobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -718,7 +714,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->saved);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -768,8 +764,7 @@
 Then repeat the sequence indefinitely.");
 
 static PyTypeObject cycle_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.cycle",		/* tp_name */
 	sizeof(cycleobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -862,7 +857,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->func);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -882,7 +877,7 @@
 	PyObject *(*iternext)(PyObject *);
 
 	assert(PyIter_Check(it));
-	iternext = *it->ob_type->tp_iternext;
+	iternext = *Py_Type(it)->tp_iternext;
 	for (;;) {
 		item = iternext(it);
 		if (item == NULL)
@@ -912,8 +907,7 @@
 Afterwards, return every element until the iterable is exhausted.");
 
 static PyTypeObject dropwhile_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.dropwhile",		/* tp_name */
 	sizeof(dropwhileobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1006,7 +1000,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->func);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1028,7 +1022,7 @@
 		return NULL;
 
 	assert(PyIter_Check(it));
-	item = (*it->ob_type->tp_iternext)(it);
+	item = (*Py_Type(it)->tp_iternext)(it);
 	if (item == NULL)
 		return NULL;
 
@@ -1053,8 +1047,7 @@
 predicate evaluates to true for each entry.");
 
 static PyTypeObject takewhile_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.takewhile",		/* tp_name */
 	sizeof(takewhileobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1197,7 +1190,7 @@
 {
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1216,7 +1209,7 @@
 	PyObject *(*iternext)(PyObject *);
 
 	assert(PyIter_Check(it));
-	iternext = *it->ob_type->tp_iternext;
+	iternext = *Py_Type(it)->tp_iternext;
 	while (lz->cnt < lz->next) {
 		item = iternext(it);
 		if (item == NULL)
@@ -1249,8 +1242,7 @@
 but returns an iterator.");
 
 static PyTypeObject islice_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.islice",		/* tp_name */
 	sizeof(isliceobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1341,7 +1333,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->func);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1360,7 +1352,7 @@
 	PyObject *it = lz->it;
 
 	assert(PyIter_Check(it));
-	args = (*it->ob_type->tp_iternext)(it);
+	args = (*Py_Type(it)->tp_iternext)(it);
 	if (args == NULL)
 		return NULL;
 	if (!PyTuple_CheckExact(args)) {
@@ -1381,8 +1373,7 @@
 with a argument tuple taken from the given sequence.");
 
 static PyTypeObject starmap_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.starmap",		/* tp_name */
 	sizeof(starmapobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1487,7 +1478,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->iters);
 	Py_XDECREF(lz->func);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1561,8 +1552,7 @@
 iterables.");
 
 static PyTypeObject imap_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.imap",		/* tp_name */
 	sizeof(imapobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1666,7 +1656,7 @@
 {
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->ittuple);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1706,8 +1696,7 @@
 iterable, until all of the iterables are exhausted.");
 
 static PyTypeObject chain_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.chain",		/* tp_name */
 	sizeof(chainobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1798,7 +1787,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->func);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1818,7 +1807,7 @@
 	PyObject *(*iternext)(PyObject *);
 
 	assert(PyIter_Check(it));
-	iternext = *it->ob_type->tp_iternext;
+	iternext = *Py_Type(it)->tp_iternext;
 	for (;;) {
 		item = iternext(it);
 		if (item == NULL)
@@ -1850,8 +1839,7 @@
 If function is None, return the items that are true.");
 
 static PyTypeObject ifilter_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.ifilter",		/* tp_name */
 	sizeof(ifilterobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -1943,7 +1931,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->func);
 	Py_XDECREF(lz->it);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -1963,7 +1951,7 @@
 	PyObject *(*iternext)(PyObject *);
 
 	assert(PyIter_Check(it));
-	iternext = *it->ob_type->tp_iternext;
+	iternext = *Py_Type(it)->tp_iternext;
 	for (;;) {
 		item = iternext(it);
 		if (item == NULL)
@@ -1995,8 +1983,7 @@
 If function is None, return the items that are false.");
 
 static PyTypeObject ifilterfalse_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.ifilterfalse",	/* tp_name */
 	sizeof(ifilterfalseobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2094,8 +2081,7 @@
 integers starting from zero or, if specified, from firstval.");
 
 static PyTypeObject count_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.count",		/* tp_name */
 	sizeof(countobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2214,7 +2200,7 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->ittuple);
 	Py_XDECREF(lz->result);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -2237,12 +2223,12 @@
 
 	if (tuplesize == 0)
 		return NULL;
-	if (result->ob_refcnt == 1) {
+	if (Py_Refcnt(result) == 1) {
 		Py_INCREF(result);
 		for (i=0 ; i < tuplesize ; i++) {
 			it = PyTuple_GET_ITEM(lz->ittuple, i);
 			assert(PyIter_Check(it));
-			item = (*it->ob_type->tp_iternext)(it);
+			item = (*Py_Type(it)->tp_iternext)(it);
 			if (item == NULL) {
 				Py_DECREF(result);
 				return NULL;
@@ -2258,7 +2244,7 @@
 		for (i=0 ; i < tuplesize ; i++) {
 			it = PyTuple_GET_ITEM(lz->ittuple, i);
 			assert(PyIter_Check(it));
-			item = (*it->ob_type->tp_iternext)(it);
+			item = (*Py_Type(it)->tp_iternext)(it);
 			if (item == NULL) {
 				Py_DECREF(result);
 				return NULL;
@@ -2280,8 +2266,7 @@
 a list.");
 
 static PyTypeObject izip_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.izip",		/* tp_name */
 	sizeof(izipobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2365,7 +2350,7 @@
 {
 	PyObject_GC_UnTrack(ro);
 	Py_XDECREF(ro->element);
-	ro->ob_type->tp_free(ro);
+	Py_Type(ro)->tp_free(ro);
 }
 
 static int
@@ -2428,8 +2413,7 @@
 endlessly.");
 
 static PyTypeObject repeat_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.repeat",		/* tp_name */
 	sizeof(repeatobject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2561,7 +2545,7 @@
 	Py_XDECREF(lz->ittuple);
 	Py_XDECREF(lz->result);
 	Py_XDECREF(lz->fillvalue);
-	lz->ob_type->tp_free(lz);
+	Py_Type(lz)->tp_free(lz);
 }
 
 static int
@@ -2587,7 +2571,7 @@
 		return NULL;
         if (lz->numactive == 0)
                 return NULL;
-	if (result->ob_refcnt == 1) {
+	if (Py_Refcnt(result) == 1) {
 		Py_INCREF(result);
 		for (i=0 ; i < tuplesize ; i++) {
 			it = PyTuple_GET_ITEM(lz->ittuple, i);
@@ -2596,7 +2580,7 @@
                                 item = lz->fillvalue;
                         } else {
                                 assert(PyIter_Check(it));
-                                item = (*it->ob_type->tp_iternext)(it);
+                                item = (*Py_Type(it)->tp_iternext)(it);
                                 if (item == NULL) {
                                         lz->numactive -= 1;      
                                         if (lz->numactive == 0) {
@@ -2625,7 +2609,7 @@
                                 item = lz->fillvalue;
                         } else {
                                 assert(PyIter_Check(it));
-                                item = (*it->ob_type->tp_iternext)(it);
+                                item = (*Py_Type(it)->tp_iternext)(it);
                                 if (item == NULL) {
                                         lz->numactive -= 1;      
                                         if (lz->numactive == 0) {
@@ -2657,8 +2641,7 @@
 ");
 
 static PyTypeObject iziplongest_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"itertools.izip_longest",	/* tp_name */
 	sizeof(iziplongestobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2757,7 +2740,7 @@
 		NULL
 	};
 
-	teedataobject_type.ob_type = &PyType_Type;
+	Py_Type(&teedataobject_type) = &PyType_Type;
 	m = Py_InitModule3("itertools", module_methods, module_doc);
 	if (m == NULL)
 		return;

Modified: python/branches/bcannon-objcap/Modules/linuxaudiodev.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/linuxaudiodev.c	(original)
+++ python/branches/bcannon-objcap/Modules/linuxaudiodev.c	Thu Sep  6 21:35:45 2007
@@ -441,8 +441,7 @@
 }
 
 static PyTypeObject Ladtype = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,				/*ob_size*/
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "linuxaudiodev.linux_audio_device", /*tp_name*/
     sizeof(lad_t),		/*tp_size*/
     0,				/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/main.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/main.c	(original)
+++ python/branches/bcannon-objcap/Modules/main.c	Thu Sep  6 21:35:45 2007
@@ -149,17 +149,16 @@
 		fprintf(stderr, "Could not import runpy module\n");
 		return -1;
 	}
-	runmodule = PyObject_GetAttrString(runpy, "run_module");
+	runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
 	if (runmodule == NULL) {
-		fprintf(stderr, "Could not access runpy.run_module\n");
+		fprintf(stderr, "Could not access runpy._run_module_as_main\n");
 		Py_DECREF(runpy);
 		return -1;
 	}
-	runargs = Py_BuildValue("sOsO", module,
-							Py_None, "__main__", Py_True);
+	runargs = Py_BuildValue("(s)", module);
 	if (runargs == NULL) {
 		fprintf(stderr,
-				"Could not create arguments for runpy.run_module\n");
+			"Could not create arguments for runpy._run_module_as_main\n");
 		Py_DECREF(runpy);
 		Py_DECREF(runmodule);
 		return -1;

Modified: python/branches/bcannon-objcap/Modules/makesetup
==============================================================================
--- python/branches/bcannon-objcap/Modules/makesetup	(original)
+++ python/branches/bcannon-objcap/Modules/makesetup	Thu Sep  6 21:35:45 2007
@@ -238,7 +238,7 @@
 			no)	SHAREDMODS="$SHAREDMODS $file";;
 			esac
 			rule="$file: $objs"
-			rule="$rule; \$(LDSHARED) $objs $libs $ExtraLibs -o $file"
+			rule="$rule; \$(BLDSHARED) $objs $libs $ExtraLibs -o $file"
 			echo "$rule" >>$rulesf
 		done
 	done

Modified: python/branches/bcannon-objcap/Modules/md5module.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/md5module.c	(original)
+++ python/branches/bcannon-objcap/Modules/md5module.c	Thu Sep  6 21:35:45 2007
@@ -221,8 +221,7 @@
 copy() -- return a copy of the current md5 object");
 
 static PyTypeObject MD5type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			  /*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_md5.md5",		  /*tp_name*/
 	sizeof(md5object),	  /*tp_size*/
 	0,			  /*tp_itemsize*/
@@ -299,7 +298,7 @@
 {
 	PyObject *m, *d;
 
-        MD5type.ob_type = &PyType_Type;
+        Py_Type(&MD5type) = &PyType_Type;
         if (PyType_Ready(&MD5type) < 0)
             return;
 	m = Py_InitModule3("_md5", md5_functions, module_doc);

Modified: python/branches/bcannon-objcap/Modules/mmapmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/mmapmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/mmapmodule.c	Thu Sep  6 21:35:45 2007
@@ -681,6 +681,60 @@
 }
 
 static PyObject *
+mmap_subscript(mmap_object *self, PyObject *item)
+{
+	CHECK_VALID(NULL);
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += self->size;
+		if (i < 0 || i > self->size) {
+			PyErr_SetString(PyExc_IndexError,
+				"mmap index out of range");
+			return NULL;
+		}
+		return PyString_FromStringAndSize(self->data + i, 1);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelen;
+
+		if (PySlice_GetIndicesEx((PySliceObject *)item, self->size,
+				 &start, &stop, &step, &slicelen) < 0) {
+			return NULL;
+		}
+		
+		if (slicelen <= 0)
+			return PyString_FromStringAndSize("", 0);
+		else if (step == 1)
+			return PyString_FromStringAndSize(self->data + start,
+							  slicelen);
+		else {
+			char *result_buf = (char *)PyMem_Malloc(slicelen);
+			Py_ssize_t cur, i;
+			PyObject *result;
+
+			if (result_buf == NULL)
+				return PyErr_NoMemory();
+			for (cur = start, i = 0; i < slicelen;
+			     cur += step, i++) {
+			     	result_buf[i] = self->data[cur];
+			}
+			result = PyString_FromStringAndSize(result_buf,
+							    slicelen);
+			PyMem_Free(result_buf);
+			return result;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"mmap indices must be integers");
+		return NULL;
+	}
+}
+
+static PyObject *
 mmap_concat(mmap_object *self, PyObject *bb)
 {
 	CHECK_VALID(NULL);
@@ -764,6 +818,96 @@
 	return 0;
 }
 
+static int
+mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value)
+{
+	CHECK_VALID(-1);
+
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		const char *buf;
+
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += self->size;
+		if (i < 0 || i > self->size) {
+			PyErr_SetString(PyExc_IndexError,
+				"mmap index out of range");
+			return -1;
+		}
+		if (value == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+				"mmap object doesn't support item deletion");
+			return -1;
+		}
+		if (!PyString_Check(value) || PyString_Size(value) != 1) {
+			PyErr_SetString(PyExc_IndexError,
+		          "mmap assignment must be single-character string");
+			return -1;
+		}
+		if (!is_writeable(self))
+			return -1;
+		buf = PyString_AsString(value);
+		self->data[i] = buf[0];
+		return 0;
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelen;
+		
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 self->size, &start, &stop,
+					 &step, &slicelen) < 0) {
+			return -1;
+		}
+		if (value == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+				"mmap object doesn't support slice deletion");
+			return -1;
+		}
+		if (!PyString_Check(value)) {
+			PyErr_SetString(PyExc_IndexError,
+				"mmap slice assignment must be a string");
+			return -1;
+		}
+		if (PyString_Size(value) != slicelen) {
+			PyErr_SetString(PyExc_IndexError,
+				"mmap slice assignment is wrong size");
+			return -1;
+		}
+		if (!is_writeable(self))
+			return -1;
+
+		if (slicelen == 0)
+			return 0;
+		else if (step == 1) {
+			const char *buf = PyString_AsString(value);
+
+			if (buf == NULL)
+				return -1;
+			memcpy(self->data + start, buf, slicelen);
+			return 0;
+		}
+		else {
+			Py_ssize_t cur, i;
+			const char *buf = PyString_AsString(value);
+			
+			if (buf == NULL)
+				return -1;
+			for (cur = start, i = 0; i < slicelen;
+			     cur += step, i++) {
+				self->data[cur] = buf[i];
+			}
+			return 0;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"mmap indices must be integer");
+		return -1;
+	}
+}
+
 static PySequenceMethods mmap_as_sequence = {
 	(lenfunc)mmap_length,		       /*sq_length*/
 	(binaryfunc)mmap_concat,	       /*sq_concat*/
@@ -774,6 +918,12 @@
 	(ssizessizeobjargproc)mmap_ass_slice,      /*sq_ass_slice*/
 };
 
+static PyMappingMethods mmap_as_mapping = {
+	(lenfunc)mmap_length,
+	(binaryfunc)mmap_subscript,
+	(objobjargproc)mmap_ass_subscript,
+};
+
 static PyBufferProcs mmap_as_buffer = {
 	(readbufferproc)mmap_buffer_getreadbuf,
 	(writebufferproc)mmap_buffer_getwritebuf,
@@ -782,8 +932,7 @@
 };
 
 static PyTypeObject mmap_object_type = {
-	PyObject_HEAD_INIT(0) /* patched in module init */
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(0, 0) /* patched in module init */
 	"mmap.mmap",				/* tp_name */
 	sizeof(mmap_object),			/* tp_size */
 	0,					/* tp_itemsize */
@@ -796,7 +945,7 @@
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
 	&mmap_as_sequence,			/*tp_as_sequence*/
-	0,					/*tp_as_mapping*/
+	&mmap_as_mapping,			/*tp_as_mapping*/
 	0,					/*tp_hash*/
 	0,					/*tp_call*/
 	0,					/*tp_str*/
@@ -1141,7 +1290,7 @@
 	PyObject *dict, *module;
 
 	/* Patch the object type */
-	mmap_object_type.ob_type = &PyType_Type;
+	Py_Type(&mmap_object_type) = &PyType_Type;
 
 	module = Py_InitModule("mmap", mmap_functions);
 	if (module == NULL)

Modified: python/branches/bcannon-objcap/Modules/operator.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/operator.c	(original)
+++ python/branches/bcannon-objcap/Modules/operator.c	Thu Sep  6 21:35:45 2007
@@ -397,8 +397,7 @@
 After, g=itemgetter(2,5,3), the call g(r) returns (r[2], r[5], r[3])");
 
 static PyTypeObject itemgetter_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"operator.itemgetter",		/* tp_name */
 	sizeof(itemgetterobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -535,8 +534,7 @@
 After, g=attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).");
 
 static PyTypeObject attrgetter_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"operator.attrgetter",		/* tp_name */
 	sizeof(attrgetterobject),	/* tp_basicsize */
 	0,				/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/ossaudiodev.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/ossaudiodev.c	(original)
+++ python/branches/bcannon-objcap/Modules/ossaudiodev.c	Thu Sep  6 21:35:45 2007
@@ -841,8 +841,7 @@
 }
 
 static PyTypeObject OSSAudioType = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,                          /*ob_size*/
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "ossaudiodev.oss_audio_device", /*tp_name*/
     sizeof(oss_audio_t),        /*tp_size*/
     0,                          /*tp_itemsize*/
@@ -856,8 +855,7 @@
 };
 
 static PyTypeObject OSSMixerType = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,                              /*ob_size*/
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "ossaudiodev.oss_mixer_device", /*tp_name*/
     sizeof(oss_mixer_t),            /*tp_size*/
     0,                              /*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/parsermodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/parsermodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/parsermodule.c	Thu Sep  6 21:35:45 2007
@@ -166,8 +166,7 @@
 
 static
 PyTypeObject PyST_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+    PyVarObject_HEAD_INIT(NULL, 0)
     "parser.st",                        /* tp_name              */
     (int) sizeof(PyST_Object),          /* tp_basicsize         */
     0,                                  /* tp_itemsize          */
@@ -694,7 +693,7 @@
                 PyErr_Format(parser_error,
                              "second item in terminal node must be a string,"
                              " found %s",
-                             temp->ob_type->tp_name);
+                             Py_Type(temp)->tp_name);
                 Py_DECREF(temp);
                 return 0;
             }
@@ -707,7 +706,7 @@
                         PyErr_Format(parser_error,
                                      "third item in terminal node must be an"
                                      " integer, found %s",
-				     temp->ob_type->tp_name);
+				     Py_Type(temp)->tp_name);
                         Py_DECREF(o);
                         Py_DECREF(temp);
                         return 0;
@@ -3233,7 +3232,7 @@
 {
     PyObject *module, *copyreg;
 
-    PyST_Type.ob_type = &PyType_Type;
+    Py_Type(&PyST_Type) = &PyType_Type;
     module = Py_InitModule("parser", parser_functions);
     if (module == NULL)
     	return;

Modified: python/branches/bcannon-objcap/Modules/posixmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/posixmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/posixmodule.c	Thu Sep  6 21:35:45 2007
@@ -2593,7 +2593,7 @@
 	long intval;
 	if (PyFloat_Check(t)) {
 		double tval = PyFloat_AsDouble(t);
-		PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
+		PyObject *intobj = Py_Type(t)->tp_as_number->nb_int(t);
 		if (!intobj)
 			return -1;
 		intval = PyInt_AsLong(intobj);
@@ -5783,7 +5783,10 @@
 		return NULL;
 #ifdef Py_USING_UNICODE
 	v = PySequence_GetItem(args, 0);
-	if (v == NULL) return NULL;
+	if (v == NULL) {
+		PyMem_Free(path);
+		return NULL;
+	}
 
 	if (PyUnicode_Check(v)) {
 		arg_is_unicode = 1;
@@ -5795,8 +5798,9 @@
 	n = readlink(path, buf, (int) sizeof buf);
 	Py_END_ALLOW_THREADS
 	if (n < 0)
-		return posix_error_with_filename(path);
+		return posix_error_with_allocated_filename(path);
 
+	PyMem_Free(path);
 	v = PyString_FromStringAndSize(buf, n);
 #ifdef Py_USING_UNICODE
 	if (arg_is_unicode) {
@@ -8070,6 +8074,8 @@
               BYTE *pbBuffer );
 
 static CRYPTGENRANDOM pCryptGenRandom = NULL;
+/* This handle is never explicitly released. Instead, the operating
+   system will release it when the process terminates. */
 static HCRYPTPROV hCryptProv = 0;
 
 static PyObject*

Modified: python/branches/bcannon-objcap/Modules/pyexpat.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/pyexpat.c	(original)
+++ python/branches/bcannon-objcap/Modules/pyexpat.c	Thu Sep  6 21:35:45 2007
@@ -974,7 +974,7 @@
     if (!PyString_Check(str)) {
         PyErr_Format(PyExc_TypeError,
                      "read() did not return a string object (type=%.400s)",
-                     str->ob_type->tp_name);
+                     Py_Type(str)->tp_name);
         goto finally;
     }
     len = PyString_GET_SIZE(str);
@@ -1687,8 +1687,7 @@
 PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
 
 static PyTypeObject Xmlparsetype = {
-	PyObject_HEAD_INIT(NULL)
-	0,				/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"pyexpat.xmlparser",		/*tp_name*/
 	sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
 	0,				/*tp_itemsize*/
@@ -1860,7 +1859,7 @@
     if (modelmod_name == NULL)
         return;
 
-    Xmlparsetype.ob_type = &PyType_Type;
+    Py_Type(&Xmlparsetype) = &PyType_Type;
 
     /* Create the module and add the functions */
     m = Py_InitModule3(MODULE_NAME, pyexpat_methods,

Modified: python/branches/bcannon-objcap/Modules/readline.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/readline.c	(original)
+++ python/branches/bcannon-objcap/Modules/readline.c	Thu Sep  6 21:35:45 2007
@@ -198,6 +198,7 @@
 
 /* Exported functions to specify hook functions in Python */
 
+static PyObject *completion_display_matches_hook = NULL;
 static PyObject *startup_hook = NULL;
 
 #ifdef HAVE_RL_PRE_INPUT_HOOK
@@ -205,6 +206,20 @@
 #endif
 
 static PyObject *
+set_completion_display_matches_hook(PyObject *self, PyObject *args)
+{
+	return set_hook("completion_display_matches_hook",
+			&completion_display_matches_hook, args);
+}
+
+PyDoc_STRVAR(doc_set_completion_display_matches_hook,
+"set_completion_display_matches_hook([function]) -> None\n\
+Set or remove the completion display function.\n\
+The function is called as\n\
+  function(substitution, [matches], longest_match_length)\n\
+once each time matches need to be displayed.");
+
+static PyObject *
 set_startup_hook(PyObject *self, PyObject *args)
 {
 	return set_hook("startup_hook", &startup_hook, args);
@@ -245,6 +260,18 @@
 static PyObject *endidx = NULL;
 
 
+/* Get the completion type for the scope of the tab-completion */
+static PyObject *
+get_completion_type(PyObject *self, PyObject *noarg)
+{
+  return PyInt_FromLong(rl_completion_type);
+}
+
+PyDoc_STRVAR(doc_get_completion_type,
+"get_completion_type() -> int\n\
+Get the type of completion being attempted.");
+
+
 /* Get the beginning index for the scope of the tab-completion */
 
 static PyObject *
@@ -557,6 +584,8 @@
 	 METH_NOARGS, get_history_length_doc},
 	{"set_completer", set_completer, METH_VARARGS, doc_set_completer},
 	{"get_completer", get_completer, METH_NOARGS, doc_get_completer},
+	{"get_completion_type", get_completion_type,
+	 METH_NOARGS, doc_get_completion_type},
 	{"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx},
 	{"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
 
@@ -568,6 +597,8 @@
 	{"get_completer_delims", get_completer_delims,
 	 METH_NOARGS, doc_get_completer_delims},
 
+	{"set_completion_display_matches_hook", set_completion_display_matches_hook,
+	 METH_VARARGS, doc_set_completion_display_matches_hook},
 	{"set_startup_hook", set_startup_hook,
 	 METH_VARARGS, doc_set_startup_hook},
 #ifdef HAVE_RL_PRE_INPUT_HOOK
@@ -631,6 +662,48 @@
 #endif
 
 
+/* C function to call the Python completion_display_matches */
+
+static void
+on_completion_display_matches_hook(char **matches,
+				   int num_matches, int max_length)
+{
+	if (completion_display_matches_hook != NULL) {
+	        int i;
+	        PyObject *m, *s;
+	        PyObject *r;
+#ifdef WITH_THREAD	      
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
+		m = PyList_New(num_matches);
+		for (i = 0; i < num_matches; i++) {
+		  s = PyString_FromString(matches[i+1]);
+		  PyList_SetItem(m, i, s);
+		}
+
+		r = PyObject_CallFunction(completion_display_matches_hook,
+					  "sOi", matches[0], m, max_length);
+
+		Py_DECREF(m);
+
+		if (r == NULL ||
+		    (r != Py_None && PyInt_AsLong(r) == -1 && PyErr_Occurred())) {
+		  goto error;
+		}
+
+		Py_DECREF(r);
+		goto done;
+	  error:
+		PyErr_Clear();
+		Py_XDECREF(r);
+	  done:
+#ifdef WITH_THREAD	      
+		PyGILState_Release(gilstate);
+#endif
+	}
+}
+
+
 /* C function to call the Python completer. */
 
 static char *
@@ -708,6 +781,10 @@
 	rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
 	rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
 	/* Set our hook functions */
+#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
+	rl_completion_display_matches_hook =
+	  (rl_compdisp_func_t *)on_completion_display_matches_hook;
+#endif
 	rl_startup_hook = (Function *)on_startup_hook;
 #ifdef HAVE_RL_PRE_INPUT_HOOK
 	rl_pre_input_hook = (Function *)on_pre_input_hook;

Modified: python/branches/bcannon-objcap/Modules/selectmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/selectmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/selectmodule.c	Thu Sep  6 21:35:45 2007
@@ -587,8 +587,7 @@
 static PyTypeObject poll_Type = {
 	/* The ob_type field must be initialized in the module init function
 	 * to be portable to Windows without using C++. */
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"select.poll",		/*tp_name*/
 	sizeof(pollObject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -706,7 +705,7 @@
 #else
 	{
 #endif
-		poll_Type.ob_type = &PyType_Type;
+		Py_Type(&poll_Type) = &PyType_Type;
 		PyModule_AddIntConstant(m, "POLLIN", POLLIN);
 		PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
 		PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);

Modified: python/branches/bcannon-objcap/Modules/sha256module.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/sha256module.c	(original)
+++ python/branches/bcannon-objcap/Modules/sha256module.c	Thu Sep  6 21:35:45 2007
@@ -409,7 +409,7 @@
 {
     SHAobject *newobj;
 
-    if (((PyObject*)self)->ob_type == &SHA256type) {
+    if (Py_Type(self) == &SHA256type) {
         if ( (newobj = newSHA256object())==NULL)
             return NULL;
     } else {
@@ -536,8 +536,7 @@
 };
 
 static PyTypeObject SHA224type = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_sha256.sha224",	/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
@@ -571,8 +570,7 @@
 };
 
 static PyTypeObject SHA256type = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_sha256.sha256",	/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
@@ -689,10 +687,10 @@
 {
     PyObject *m;
 
-    SHA224type.ob_type = &PyType_Type;
+    Py_Type(&SHA224type) = &PyType_Type;
     if (PyType_Ready(&SHA224type) < 0)
         return;
-    SHA256type.ob_type = &PyType_Type;
+    Py_Type(&SHA256type) = &PyType_Type;
     if (PyType_Ready(&SHA256type) < 0)
         return;
     m = Py_InitModule("_sha256", SHA_functions);

Modified: python/branches/bcannon-objcap/Modules/sha512module.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/sha512module.c	(original)
+++ python/branches/bcannon-objcap/Modules/sha512module.c	Thu Sep  6 21:35:45 2007
@@ -602,8 +602,7 @@
 };
 
 static PyTypeObject SHA384type = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_sha512.sha384",	/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
@@ -637,8 +636,7 @@
 };
 
 static PyTypeObject SHA512type = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_sha512.sha512",	/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
@@ -755,10 +753,10 @@
 {
     PyObject *m;
 
-    SHA384type.ob_type = &PyType_Type;
+    Py_Type(&SHA384type) = &PyType_Type;
     if (PyType_Ready(&SHA384type) < 0)
         return;
-    SHA512type.ob_type = &PyType_Type;
+    Py_Type(&SHA512type) = &PyType_Type;
     if (PyType_Ready(&SHA512type) < 0)
         return;
     m = Py_InitModule("_sha512", SHA_functions);

Modified: python/branches/bcannon-objcap/Modules/shamodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/shamodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/shamodule.c	Thu Sep  6 21:35:45 2007
@@ -489,8 +489,7 @@
 };
 
 static PyTypeObject SHAtype = {
-    PyObject_HEAD_INIT(NULL)
-    0,			/*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_sha.sha",		/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
@@ -577,7 +576,7 @@
 {
     PyObject *m;
 
-    SHAtype.ob_type = &PyType_Type;
+    Py_Type(&SHAtype) = &PyType_Type;
     if (PyType_Ready(&SHAtype) < 0)
         return;
     m = Py_InitModule("_sha", SHA_functions);

Modified: python/branches/bcannon-objcap/Modules/socketmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/socketmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/socketmodule.c	Thu Sep  6 21:35:45 2007
@@ -1245,7 +1245,7 @@
 				PyExc_TypeError,
 				"getsockaddrarg: "
 				"AF_NETLINK address must be tuple, not %.500s",
-				args->ob_type->tp_name);
+				Py_Type(args)->tp_name);
 			return 0;
 		}
 		if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &pid, &groups))
@@ -1268,7 +1268,7 @@
 				PyExc_TypeError,
 				"getsockaddrarg: "
 				"AF_INET address must be tuple, not %.500s",
-				args->ob_type->tp_name);
+				Py_Type(args)->tp_name);
 			return 0;
 		}
 		if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
@@ -1298,7 +1298,7 @@
 				PyExc_TypeError,
 				"getsockaddrarg: "
 				"AF_INET6 address must be tuple, not %.500s",
-				args->ob_type->tp_name);
+				Py_Type(args)->tp_name);
 			return 0;
 		}
 		if (!PyArg_ParseTuple(args, "eti|ii",
@@ -1420,7 +1420,7 @@
 				PyExc_TypeError,
 				"getsockaddrarg: "
 				"AF_PACKET address must be tuple, not %.500s",
-				args->ob_type->tp_name);
+				Py_Type(args)->tp_name);
 			return 0;
 		}
 		if (!PyArg_ParseTuple(args, "si|iis#", &interfaceName,
@@ -2843,7 +2843,7 @@
 {
 	if (s->sock_fd != -1)
 		(void) SOCKETCLOSE(s->sock_fd);
-	s->ob_type->tp_free((PyObject *)s);
+	Py_Type(s)->tp_free((PyObject *)s);
 }
 
 
@@ -2928,8 +2928,7 @@
 /* Type object for socket objects. */
 
 static PyTypeObject sock_type = {
-	PyObject_HEAD_INIT(0)	/* Must fill in type value later */
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(0, 0)	/* Must fill in type value later */
 	"_socket.socket",			/* tp_name */
 	sizeof(PySocketSockObject),		/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3555,7 +3554,7 @@
 	else
 		return PyErr_Format(PyExc_TypeError,
 				    "expected int/long, %s found",
-				    arg->ob_type->tp_name);
+				    Py_Type(arg)->tp_name);
 	if (x == (unsigned long) -1 && PyErr_Occurred())
 		return NULL;
 	return PyLong_FromUnsignedLong(ntohl(x));
@@ -3624,7 +3623,7 @@
 	else
 		return PyErr_Format(PyExc_TypeError,
 				    "expected int/long, %s found",
-				    arg->ob_type->tp_name);
+				    Py_Type(arg)->tp_name);
 	return PyLong_FromUnsignedLong(htonl((unsigned long)x));
 }
 
@@ -4274,7 +4273,7 @@
 	if (!os_init())
 		return;
 
-	sock_type.ob_type = &PyType_Type;
+	Py_Type(&sock_type) = &PyType_Type;
 	m = Py_InitModule3(PySocket_MODULE_NAME,
 			   socket_methods,
 			   socket_doc);

Modified: python/branches/bcannon-objcap/Modules/sunaudiodev.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/sunaudiodev.c	(original)
+++ python/branches/bcannon-objcap/Modules/sunaudiodev.c	Thu Sep  6 21:35:45 2007
@@ -42,8 +42,8 @@
 
 static PyObject *SunAudioError;
 
-#define is_sadobject(v)		((v)->ob_type == &Sadtype)
-#define is_sadstatusobject(v)	((v)->ob_type == &Sadstatustype)
+#define is_sadobject(v)		(Py_Type(v) == &Sadtype)
+#define is_sadstatusobject(v)	(Py_Type(v) == &Sadstatustype)
 
 
 static sadobject *
@@ -409,8 +409,7 @@
 
 
 static PyTypeObject Sadtype = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/*ob_size*/
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"sunaudiodev.sun_audio_device",	/*tp_name*/
 	sizeof(sadobject),		/*tp_size*/
 	0,				/*tp_itemsize*/
@@ -424,8 +423,7 @@
 };
 
 static PyTypeObject Sadstatustype = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/*ob_size*/
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"sunaudiodev.sun_audio_device_status", /*tp_name*/
 	sizeof(sadstatusobject),	/*tp_size*/
 	0,				/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/threadmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/threadmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/threadmodule.c	Thu Sep  6 21:35:45 2007
@@ -126,8 +126,7 @@
 }
 
 static PyTypeObject Locktype = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/*ob_size*/
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"thread.lock",			/*tp_name*/
 	sizeof(lockobject),		/*tp_size*/
 	0,				/*tp_itemsize*/
@@ -251,7 +250,7 @@
 	}
 
 	local_clear(self);
-	self->ob_type->tp_free((PyObject*)self);
+	Py_Type(self)->tp_free((PyObject*)self);
 }
 
 static PyObject *
@@ -283,8 +282,8 @@
 		Py_INCREF(ldict);
 		self->dict = ldict; /* still borrowed */
 
-		if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
-		    self->ob_type->tp_init((PyObject*)self, 
+		if (Py_Type(self)->tp_init != PyBaseObject_Type.tp_init &&
+		    Py_Type(self)->tp_init((PyObject*)self, 
 					   self->args, self->kw) < 0) {
 			/* we need to get rid of ldict from thread so
 			   we create a new one the next time we do an attr
@@ -336,8 +335,7 @@
 static PyObject *local_getattro(localobject *, PyObject *);
 
 static PyTypeObject localtype = {
-	PyObject_HEAD_INIT(NULL)
-	/* ob_size           */ 0,
+	PyVarObject_HEAD_INIT(NULL, 0)
 	/* tp_name           */ "thread._local",
 	/* tp_basicsize      */ sizeof(localobject),
 	/* tp_itemsize       */ 0,
@@ -388,7 +386,7 @@
 	if (ldict == NULL) 
 		return NULL;
 
-	if (self->ob_type != &localtype)
+	if (Py_Type(self) != &localtype)
 		/* use generic lookup for subtypes */
 		return PyObject_GenericGetAttr((PyObject *)self, name);
 

Modified: python/branches/bcannon-objcap/Modules/unicodedata.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/unicodedata.c	(original)
+++ python/branches/bcannon-objcap/Modules/unicodedata.c	Thu Sep  6 21:35:45 2007
@@ -1077,8 +1077,7 @@
 unicodedata_lookup(PyObject* self, PyObject* args)
 {
     Py_UCS4 code;
-    Py_UNICODE str[1];
-    char errbuf[256];
+    Py_UNICODE str[2];
 
     char* name;
     int namelen;
@@ -1086,24 +1085,20 @@
         return NULL;
 
     if (!_getcode(self, name, namelen, &code)) {
-	/* XXX(nnorwitz): why are we allocating for the error msg?
-		Why not always use snprintf? */
-        char fmt[] = "undefined character name '%s'";
-        char *buf = PyMem_MALLOC(sizeof(fmt) + namelen);
-        if (buf)
-            sprintf(buf, fmt, name);
-        else {
-            buf = errbuf;
-            PyOS_snprintf(buf, sizeof(errbuf), fmt, name);
-        }
-        PyErr_SetString(PyExc_KeyError, buf);
-        if (buf != errbuf)
-        	PyMem_FREE(buf);
+        PyErr_Format(PyExc_KeyError, "undefined character name '%s'",
+                     name);
         return NULL;
     }
 
+#ifndef Py_UNICODE_WIDE
+    if (code >= 0x10000) {
+        str[0] = 0xd800 + ((code - 0x10000) >> 10);
+        str[1] = 0xdc00 + ((code - 0x10000) & 0x3ff);
+        return PyUnicode_FromUnicode(str, 2);
+    }
+#endif
     str[0] = (Py_UNICODE) code;
-    return PyUnicode_FromUnicode(str, 1);
+    return PyUnicode_FromUnicode(str, 1);    
 }
 
 /* XXX Add doc strings. */
@@ -1134,8 +1129,7 @@
 static PyTypeObject UCD_Type = {
 	/* The ob_type field must be initialized in the module init function
 	 * to be portable to Windows without using C++. */
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"unicodedata.UCD",		/*tp_name*/
 	sizeof(PreviousDBVersion),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -1193,7 +1187,7 @@
 {
     PyObject *m, *v;
 
-    UCD_Type.ob_type = &PyType_Type;
+    Py_Type(&UCD_Type) = &PyType_Type;
 
     m = Py_InitModule3(
         "unicodedata", unicodedata_functions, unicodedata_docstring);

Modified: python/branches/bcannon-objcap/Modules/xxmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/xxmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/xxmodule.c	Thu Sep  6 21:35:45 2007
@@ -25,7 +25,7 @@
 
 static PyTypeObject Xxo_Type;
 
-#define XxoObject_Check(v)	((v)->ob_type == &Xxo_Type)
+#define XxoObject_Check(v)	(Py_Type(v) == &Xxo_Type)
 
 static XxoObject *
 newXxoObject(PyObject *arg)
@@ -97,8 +97,7 @@
 static PyTypeObject Xxo_Type = {
 	/* The ob_type field must be initialized in the module init function
 	 * to be portable to Windows without using C++. */
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"xxmodule.Xxo",		/*tp_name*/
 	sizeof(XxoObject),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -216,8 +215,7 @@
 static PyTypeObject Str_Type = {
 	/* The ob_type field must be initialized in the module init function
 	 * to be portable to Windows without using C++. */
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"xxmodule.Str",		/*tp_name*/
 	0,			/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -272,8 +270,7 @@
 static PyTypeObject Null_Type = {
 	/* The ob_type field must be initialized in the module init function
 	 * to be portable to Windows without using C++. */
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"xxmodule.Null",	/*tp_name*/
 	0,			/*tp_basicsize*/
 	0,			/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Modules/xxsubtype.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/xxsubtype.c	(original)
+++ python/branches/bcannon-objcap/Modules/xxsubtype.c	Thu Sep  6 21:35:45 2007
@@ -101,8 +101,7 @@
 };
 
 static PyTypeObject spamlist_type = {
-	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
-	0,
+	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
 	"xxsubtype.spamlist",
 	sizeof(spamlistobject),
 	0,
@@ -193,8 +192,7 @@
 };
 
 static PyTypeObject spamdict_type = {
-	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
-	0,
+	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
 	"xxsubtype.spamdict",
 	sizeof(spamdictobject),
 	0,

Modified: python/branches/bcannon-objcap/Modules/zipimport.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/zipimport.c	(original)
+++ python/branches/bcannon-objcap/Modules/zipimport.c	Thu Sep  6 21:35:45 2007
@@ -181,7 +181,7 @@
 	Py_XDECREF(self->archive);
 	Py_XDECREF(self->prefix);
 	Py_XDECREF(self->files);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static PyObject *
@@ -561,8 +561,7 @@
 #define DEFERRED_ADDRESS(ADDR) 0
 
 static PyTypeObject ZipImporter_Type = {
-	PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
-	0,
+	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
 	"zipimport.zipimporter",
 	sizeof(ZipImporter),
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Modules/zlibmodule.c
==============================================================================
--- python/branches/bcannon-objcap/Modules/zlibmodule.c	(original)
+++ python/branches/bcannon-objcap/Modules/zlibmodule.c	Thu Sep  6 21:35:45 2007
@@ -935,8 +935,7 @@
 };
 
 static PyTypeObject Comptype = {
-    PyObject_HEAD_INIT(0)
-    0,
+    PyVarObject_HEAD_INIT(0, 0)
     "zlib.Compress",
     sizeof(compobject),
     0,
@@ -952,8 +951,7 @@
 };
 
 static PyTypeObject Decomptype = {
-    PyObject_HEAD_INIT(0)
-    0,
+    PyVarObject_HEAD_INIT(0, 0)
     "zlib.Decompress",
     sizeof(compobject),
     0,
@@ -987,8 +985,8 @@
 PyInit_zlib(void)
 {
     PyObject *m, *ver;
-    Comptype.ob_type = &PyType_Type;
-    Decomptype.ob_type = &PyType_Type;
+    Py_Type(&Comptype) = &PyType_Type;
+    Py_Type(&Decomptype) = &PyType_Type;
     m = Py_InitModule4("zlib", zlib_methods,
 		       zlib_module_documentation,
 		       (PyObject*)NULL,PYTHON_API_VERSION);

Modified: python/branches/bcannon-objcap/Objects/boolobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/boolobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/boolobject.c	Thu Sep  6 21:35:45 2007
@@ -146,8 +146,7 @@
 /* The type object for bool.  Note that this cannot be subclassed! */
 
 PyTypeObject PyBool_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"bool",
 	sizeof(PyIntObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/bufferobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/bufferobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/bufferobject.c	Thu Sep  6 21:35:45 2007
@@ -472,6 +472,61 @@
 					  right - left);
 }
 
+static PyObject *
+buffer_subscript(PyBufferObject *self, PyObject *item)
+{
+	void *p;
+	Py_ssize_t size;
+	
+	if (!get_buf(self, &p, &size, ANY_BUFFER))
+		return NULL;
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += size;
+		return buffer_item(self, i);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength, cur, i;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, size,
+				 &start, &stop, &step, &slicelength) < 0) {
+			return NULL;
+		}
+
+		if (slicelength <= 0)
+			return PyString_FromStringAndSize("", 0);
+		else if (step == 1)
+			return PyString_FromStringAndSize((char *)p + start,
+							  stop - start);
+		else {
+			PyObject *result;
+			char *source_buf = (char *)p;
+			char *result_buf = (char *)PyMem_Malloc(slicelength);
+
+			if (result_buf == NULL)
+				return PyErr_NoMemory();
+
+			for (cur = start, i = 0; i < slicelength;
+			     cur += step, i++) {
+				result_buf[i] = source_buf[cur];
+			}
+
+			result = PyString_FromStringAndSize(result_buf,
+							    slicelength);
+			PyMem_Free(result_buf);
+			return result;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"sequence index must be integer");
+		return NULL;
+	}
+}
+
 static int
 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
 {
@@ -581,6 +636,98 @@
 	return 0;
 }
 
+static int
+buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
+{
+	PyBufferProcs *pb;
+	void *ptr1, *ptr2;
+	Py_ssize_t selfsize;
+	Py_ssize_t othersize;
+
+	if ( self->b_readonly ) {
+		PyErr_SetString(PyExc_TypeError,
+				"buffer is read-only");
+		return -1;
+	}
+
+	pb = value ? value->ob_type->tp_as_buffer : NULL;
+	if ( pb == NULL ||
+	     pb->bf_getreadbuffer == NULL ||
+	     pb->bf_getsegcount == NULL )
+	{
+		PyErr_BadArgument();
+		return -1;
+	}
+	if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
+	{
+		/* ### use a different exception type/message? */
+		PyErr_SetString(PyExc_TypeError,
+				"single-segment buffer object expected");
+		return -1;
+	}
+	if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
+		return -1;
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += selfsize;
+		return buffer_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+		
+		if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
+				&start, &stop, &step, &slicelength) < 0)
+			return -1;
+
+		pb = value ? value->ob_type->tp_as_buffer : NULL;
+		if (pb == NULL ||
+		    pb->bf_getreadbuffer == NULL ||
+		    pb->bf_getsegcount == NULL) {
+			PyErr_BadArgument();
+			return -1;
+		}
+		if ((*pb->bf_getsegcount)(value, NULL) != 1) {
+			/* ### use a different exception type/message? */
+			PyErr_SetString(PyExc_TypeError,
+					"single-segment buffer object expected");
+			return -1;
+		}
+		if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
+			return -1;
+
+		if (othersize != slicelength) {
+			PyErr_SetString(
+				PyExc_TypeError,
+				"right operand length must match slice length");
+			return -1;
+		}
+
+		if (slicelength == 0)
+			return 0;
+		else if (step == 1) {
+			memcpy((char *)ptr1 + start, ptr2, slicelength);
+			return 0;
+		}
+		else {
+			Py_ssize_t cur, i;
+			
+			for (cur = start, i = 0; i < slicelength;
+			     cur += step, i++) {
+				((char *)ptr1)[cur] = ((char *)ptr2)[i];
+			}
+
+			return 0;
+		}
+	} else {
+		PyErr_SetString(PyExc_TypeError,
+				"buffer indices must be integers");
+		return -1;
+	}
+}
+
 /* Buffer methods */
 
 static Py_ssize_t
@@ -656,6 +803,12 @@
 	(ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
 };
 
+static PyMappingMethods buffer_as_mapping = {
+	(lenfunc)buffer_length,
+	(binaryfunc)buffer_subscript,
+	(objobjargproc)buffer_ass_subscript,
+};
+
 static PyBufferProcs buffer_as_buffer = {
 	(readbufferproc)buffer_getreadbuf,
 	(writebufferproc)buffer_getwritebuf,
@@ -664,8 +817,7 @@
 };
 
 PyTypeObject PyBuffer_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"buffer",
 	sizeof(PyBufferObject),
 	0,
@@ -677,7 +829,7 @@
 	(reprfunc)buffer_repr,			/* tp_repr */
 	0,					/* tp_as_number */
 	&buffer_as_sequence,			/* tp_as_sequence */
-	0,					/* tp_as_mapping */
+	&buffer_as_mapping,			/* tp_as_mapping */
 	(hashfunc)buffer_hash,			/* tp_hash */
 	0,					/* tp_call */
 	(reprfunc)buffer_str,			/* tp_str */

Modified: python/branches/bcannon-objcap/Objects/cellobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/cellobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/cellobject.c	Thu Sep  6 21:35:45 2007
@@ -99,8 +99,7 @@
 };
 
 PyTypeObject PyCell_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"cell",
 	sizeof(PyCellObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/cobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/cobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/cobject.c	Thu Sep  6 21:35:45 2007
@@ -135,8 +135,7 @@
 mechanism to link to one another.");
 
 PyTypeObject PyCObject_Type = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,				/*ob_size*/
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "PyCObject",		/*tp_name*/
     sizeof(PyCObject),		/*tp_basicsize*/
     0,				/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Objects/codeobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/codeobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/codeobject.c	Thu Sep  6 21:35:45 2007
@@ -233,8 +233,7 @@
 /* XXX code objects need to participate in GC? */
 
 PyTypeObject PyCode_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"code",
 	sizeof(PyCodeObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/complexobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/complexobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/complexobject.c	Thu Sep  6 21:35:45 2007
@@ -1074,8 +1074,7 @@
 };
 
 PyTypeObject PyComplex_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"complex",
 	sizeof(PyComplexObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/descrobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/descrobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/descrobject.c	Thu Sep  6 21:35:45 2007
@@ -382,8 +382,7 @@
 }
 
 static PyTypeObject PyMethodDescr_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"method_descriptor",
 	sizeof(PyMethodDescrObject),
 	0,
@@ -421,8 +420,7 @@
 
 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
 static PyTypeObject PyClassMethodDescr_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"classmethod_descriptor",
 	sizeof(PyMethodDescrObject),
 	0,
@@ -459,8 +457,7 @@
 };
 
 static PyTypeObject PyMemberDescr_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"member_descriptor",
 	sizeof(PyMemberDescrObject),
 	0,
@@ -497,8 +494,7 @@
 };
 
 static PyTypeObject PyGetSetDescr_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"getset_descriptor",
 	sizeof(PyGetSetDescrObject),
 	0,
@@ -535,8 +531,7 @@
 };
 
 PyTypeObject PyWrapperDescr_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"wrapper_descriptor",
 	sizeof(PyWrapperDescrObject),
 	0,
@@ -825,8 +820,7 @@
 }
 
 static PyTypeObject proxytype = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"dictproxy",				/* tp_name */
 	sizeof(proxyobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1007,8 +1001,7 @@
 }
 
 static PyTypeObject wrappertype = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"method-wrapper",			/* tp_name */
 	sizeof(wrapperobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1238,8 +1231,7 @@
 }
 
 PyTypeObject PyProperty_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"property",				/* tp_name */
 	sizeof(propertyobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/dictobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/dictobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/dictobject.c	Thu Sep  6 21:35:45 2007
@@ -204,7 +204,7 @@
 	if (num_free_dicts) {
 		mp = free_dicts[--num_free_dicts];
 		assert (mp != NULL);
-		assert (mp->ob_type == &PyDict_Type);
+		assert (Py_Type(mp) == &PyDict_Type);
 		_Py_NewReference((PyObject *)mp);
 		if (mp->ma_fill) {
 			EMPTY_TO_MINSIZE(mp);
@@ -849,10 +849,10 @@
 	}
 	if (mp->ma_table != mp->ma_smalltable)
 		PyMem_DEL(mp->ma_table);
-	if (num_free_dicts < MAXFREEDICTS && mp->ob_type == &PyDict_Type)
+	if (num_free_dicts < MAXFREEDICTS && Py_Type(mp) == &PyDict_Type)
 		free_dicts[num_free_dicts++] = mp;
 	else
-		mp->ob_type->tp_free((PyObject *)mp);
+		Py_Type(mp)->tp_free((PyObject *)mp);
 	Py_TRASHCAN_SAFE_END(mp)
 }
 
@@ -1011,7 +1011,7 @@
 			if (missing_str == NULL)
 				missing_str =
 				  PyString_InternFromString("__missing__");
-			missing = _PyType_Lookup(mp->ob_type, missing_str);
+			missing = _PyType_Lookup(Py_Type(mp), missing_str);
 			if (missing != NULL)
 				return PyObject_CallFunctionObjArgs(missing,
 					(PyObject *)mp, key, NULL);
@@ -2119,8 +2119,7 @@
 "    in the keyword argument list.  For example:  dict(one=1, two=2)");
 
 PyTypeObject PyDict_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"dict",
 	sizeof(dictobject),
 	0,
@@ -2302,8 +2301,7 @@
 }
 
 PyTypeObject PyDictIterKey_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"dictionary-keyiterator",		/* tp_name */
 	sizeof(dictiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2375,8 +2373,7 @@
 }
 
 PyTypeObject PyDictIterValue_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"dictionary-valueiterator",		/* tp_name */
 	sizeof(dictiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2462,8 +2459,7 @@
 }
 
 PyTypeObject PyDictIterItem_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"dictionary-itemiterator",		/* tp_name */
 	sizeof(dictiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/enumobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/enumobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/enumobject.c	Thu Sep  6 21:35:45 2007
@@ -43,7 +43,7 @@
 	PyObject_GC_UnTrack(en);
 	Py_XDECREF(en->en_sit);
 	Py_XDECREF(en->en_result);
-	en->ob_type->tp_free(en);
+	Py_Type(en)->tp_free(en);
 }
 
 static int
@@ -68,7 +68,7 @@
 		return NULL;         
 	}
 
-	next_item = (*it->ob_type->tp_iternext)(it);
+	next_item = (*Py_Type(it)->tp_iternext)(it);
 	if (next_item == NULL)
 		return NULL;
 
@@ -105,8 +105,7 @@
 "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
 
 PyTypeObject PyEnum_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,                              /* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"enumerate",                    /* tp_name */
 	sizeof(enumobject),             /* tp_basicsize */
 	0,                              /* tp_itemsize */
@@ -195,7 +194,7 @@
 {
 	PyObject_GC_UnTrack(ro);
 	Py_XDECREF(ro->seq);
-	ro->ob_type->tp_free(ro);
+	Py_Type(ro)->tp_free(ro);
 }
 
 static int
@@ -253,8 +252,7 @@
 };
 
 PyTypeObject PyReversed_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,                              /* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"reversed",                     /* tp_name */
 	sizeof(reversedobject),         /* tp_basicsize */
 	0,                              /* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/exceptions.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/exceptions.c	(original)
+++ python/branches/bcannon-objcap/Objects/exceptions.c	Thu Sep  6 21:35:45 2007
@@ -56,7 +56,7 @@
 static int
 BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
 {
-    if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
+    if (!_PyArg_NoKeywords(Py_Type(self)->tp_name, kwds))
         return -1;
 
     Py_DECREF(self->args);
@@ -85,7 +85,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     BaseException_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -129,7 +129,7 @@
     if (!repr_suffix)
         return NULL;
 
-    name = (char *)self->ob_type->tp_name;
+    name = (char *)Py_Type(self)->tp_name;
     dot = strrchr(name, '.');
     if (dot != NULL) name = dot+1;
 
@@ -148,9 +148,9 @@
 BaseException_reduce(PyBaseExceptionObject *self)
 {
     if (self->args && self->dict)
-        return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
+        return PyTuple_Pack(3, Py_Type(self), self->args, self->dict);
     else
-        return PyTuple_Pack(2, self->ob_type, self->args);
+        return PyTuple_Pack(2, Py_Type(self), self->args);
 }
 
 /*
@@ -478,7 +478,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     SystemExit_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -583,7 +583,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     EnvironmentError_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -725,9 +725,9 @@
         Py_INCREF(args);
 
     if (self->dict)
-        res = PyTuple_Pack(3, self->ob_type, args, self->dict);
+        res = PyTuple_Pack(3, Py_Type(self), args, self->dict);
     else
-        res = PyTuple_Pack(2, self->ob_type, args);
+        res = PyTuple_Pack(2, Py_Type(self), args);
     Py_DECREF(args);
     return res;
 }
@@ -780,7 +780,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     WindowsError_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -1054,7 +1054,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     SyntaxError_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int
@@ -1532,7 +1532,7 @@
 {
     _PyObject_GC_UNTRACK(self);
     UnicodeError_clear(self);
-    self->ob_type->tp_free((PyObject *)self);
+    Py_Type(self)->tp_free((PyObject *)self);
 }
 
 static int

Modified: python/branches/bcannon-objcap/Objects/fileobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/fileobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/fileobject.c	Thu Sep  6 21:35:45 2007
@@ -406,7 +406,7 @@
 	Py_XDECREF(f->f_mode);
 	Py_XDECREF(f->f_encoding);
 	drop_readahead(f);
-	f->ob_type->tp_free((PyObject *)f);
+	Py_Type(f)->tp_free((PyObject *)f);
 }
 
 static PyObject *
@@ -2079,8 +2079,7 @@
 );
 
 PyTypeObject PyFile_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"file",
 	sizeof(PyFileObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/floatobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/floatobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/floatobject.c	Thu Sep  6 21:35:45 2007
@@ -41,8 +41,8 @@
 	p = &((PyFloatBlock *)p)->objects[0];
 	q = p + N_FLOATOBJECTS;
 	while (--q > p)
-		q->ob_type = (struct _typeobject *)(q-1);
-	q->ob_type = NULL;
+		Py_Type(q) = (struct _typeobject *)(q-1);
+	Py_Type(q) = NULL;
 	return p + N_FLOATOBJECTS - 1;
 }
 
@@ -56,7 +56,7 @@
 	}
 	/* Inline PyObject_New */
 	op = free_list;
-	free_list = (PyFloatObject *)op->ob_type;
+	free_list = (PyFloatObject *)Py_Type(op);
 	PyObject_INIT(op, &PyFloat_Type);
 	op->ob_fval = fval;
 	return (PyObject *) op;
@@ -175,11 +175,11 @@
 float_dealloc(PyFloatObject *op)
 {
 	if (PyFloat_CheckExact(op)) {
-		op->ob_type = (struct _typeobject *)free_list;
+		Py_Type(op) = (struct _typeobject *)free_list;
 		free_list = op;
 	}
 	else
-		op->ob_type->tp_free((PyObject *)op);
+		Py_Type(op)->tp_free((PyObject *)op);
 }
 
 double
@@ -197,7 +197,7 @@
 		return -1;
 	}
 
-	if ((nb = op->ob_type->tp_as_number) == NULL || nb->nb_float == NULL) {
+	if ((nb = Py_Type(op)->tp_as_number) == NULL || nb->nb_float == NULL) {
 		PyErr_SetString(PyExc_TypeError, "a float is required");
 		return -1;
 	}
@@ -986,7 +986,7 @@
 	if (!PyString_Check(arg)) {
 		PyErr_Format(PyExc_TypeError,
 	     "__getformat__() argument must be string, not %.500s",
-			     arg->ob_type->tp_name);
+			     Py_Type(arg)->tp_name);
 		return NULL;
 	}
 	s = PyString_AS_STRING(arg);
@@ -1152,8 +1152,7 @@
 };
 
 PyTypeObject PyFloat_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"float",
 	sizeof(PyFloatObject),
 	0,
@@ -1265,7 +1264,7 @@
 		for (i = 0, p = &list->objects[0];
 		     i < N_FLOATOBJECTS;
 		     i++, p++) {
-			if (PyFloat_CheckExact(p) && p->ob_refcnt != 0)
+			if (PyFloat_CheckExact(p) && Py_Refcnt(p) != 0)
 				frem++;
 		}
 		next = list->next;
@@ -1276,8 +1275,8 @@
 			     i < N_FLOATOBJECTS;
 			     i++, p++) {
 				if (!PyFloat_CheckExact(p) ||
-				    p->ob_refcnt == 0) {
-					p->ob_type = (struct _typeobject *)
+				    Py_Refcnt(p) == 0) {
+					Py_Type(p) = (struct _typeobject *)
 						free_list;
 					free_list = p;
 				}
@@ -1309,7 +1308,7 @@
 			     i < N_FLOATOBJECTS;
 			     i++, p++) {
 				if (PyFloat_CheckExact(p) &&
-				    p->ob_refcnt != 0) {
+				    Py_Refcnt(p) != 0) {
 					char buf[100];
 					PyFloat_AsString(buf, p);
 					/* XXX(twouters) cast refcount to
@@ -1318,7 +1317,7 @@
 					 */
 					fprintf(stderr,
 			     "#   <float at %p, refcnt=%ld, val=%s>\n",
-						p, (long)p->ob_refcnt, buf);
+						p, (long)Py_Refcnt(p), buf);
 				}
 			}
 			list = list->next;

Modified: python/branches/bcannon-objcap/Objects/frameobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/frameobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/frameobject.c	Thu Sep  6 21:35:45 2007
@@ -509,8 +509,7 @@
 
 
 PyTypeObject PyFrame_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"frame",
 	sizeof(PyFrameObject),
 	sizeof(PyObject *),
@@ -623,7 +622,7 @@
 		    --numfree;
 		    f = free_list;
 		    free_list = free_list->f_back;
-		    if (f->ob_size < extras) {
+		    if (Py_Size(f) < extras) {
 			    f = PyObject_GC_Resize(PyFrameObject, f, extras);
 			    if (f == NULL) {
 				    Py_DECREF(builtins);

Modified: python/branches/bcannon-objcap/Objects/funcobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/funcobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/funcobject.c	Thu Sep  6 21:35:45 2007
@@ -544,8 +544,7 @@
 }
 
 PyTypeObject PyFunction_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"function",
 	sizeof(PyFunctionObject),
 	0,
@@ -615,7 +614,7 @@
 {
 	_PyObject_GC_UNTRACK((PyObject *)cm);
 	Py_XDECREF(cm->cm_callable);
-	cm->ob_type->tp_free((PyObject *)cm);
+	Py_Type(cm)->tp_free((PyObject *)cm);
 }
 
 static int
@@ -644,9 +643,9 @@
 		return NULL;
 	}
 	if (type == NULL)
-		type = (PyObject *)(obj->ob_type);
+		type = (PyObject *)(Py_Type(obj));
  	return PyMethod_New(cm->cm_callable,
-			    type, (PyObject *)(type->ob_type));
+			    type, (PyObject *)(Py_Type(type)));
 }
 
 static int
@@ -692,8 +691,7 @@
 If you want those, see the staticmethod builtin.");
 
 PyTypeObject PyClassMethod_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"classmethod",
 	sizeof(classmethod),
 	0,
@@ -773,7 +771,7 @@
 {
 	_PyObject_GC_UNTRACK((PyObject *)sm);
 	Py_XDECREF(sm->sm_callable);
-	sm->ob_type->tp_free((PyObject *)sm);
+	Py_Type(sm)->tp_free((PyObject *)sm);
 }
 
 static int
@@ -840,8 +838,7 @@
 For a more advanced concept, see the classmethod builtin.");
 
 PyTypeObject PyStaticMethod_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"staticmethod",
 	sizeof(staticmethod),
 	0,

Modified: python/branches/bcannon-objcap/Objects/genobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/genobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/genobject.c	Thu Sep  6 21:35:45 2007
@@ -28,7 +28,7 @@
 
 	if (gen->gi_frame != NULL && gen->gi_frame->f_stacktop != NULL) {
 		/* Generator is paused, so we need to close */
-		gen->ob_type->tp_del(self);
+		Py_Type(gen)->tp_del(self);
 		if (self->ob_refcnt > 0)
 			return;		/* resurrected.  :( */
 	}
@@ -296,8 +296,7 @@
 };
 
 PyTypeObject PyGen_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"generator",				/* tp_name */
 	sizeof(PyGenObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/intobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/intobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/intobject.c	Thu Sep  6 21:35:45 2007
@@ -56,8 +56,8 @@
 	p = &((PyIntBlock *)p)->objects[0];
 	q = p + N_INTOBJECTS;
 	while (--q > p)
-		q->ob_type = (struct _typeobject *)(q-1);
-	q->ob_type = NULL;
+		Py_Type(q) = (struct _typeobject *)(q-1);
+	Py_Type(q) = NULL;
 	return p + N_INTOBJECTS - 1;
 }
 
@@ -102,7 +102,7 @@
 	}
 	/* Inline PyObject_New */
 	v = free_list;
-	free_list = (PyIntObject *)v->ob_type;
+	free_list = (PyIntObject *)Py_Type(v);
 	PyObject_INIT(v, &PyInt_Type);
 	v->ob_ival = ival;
 	return (PyObject *) v;
@@ -128,17 +128,17 @@
 int_dealloc(PyIntObject *v)
 {
 	if (PyInt_CheckExact(v)) {
-		v->ob_type = (struct _typeobject *)free_list;
+		Py_Type(v) = (struct _typeobject *)free_list;
 		free_list = v;
 	}
 	else
-		v->ob_type->tp_free((PyObject *)v);
+		Py_Type(v)->tp_free((PyObject *)v);
 }
 
 static void
 int_free(PyIntObject *v)
 {
-	v->ob_type = (struct _typeobject *)free_list;
+	Py_Type(v) = (struct _typeobject *)free_list;
 	free_list = v;
 }
 
@@ -152,7 +152,7 @@
 	if (op && PyInt_Check(op))
 		return PyInt_AS_LONG((PyIntObject*) op);
 
-	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	if (op == NULL || (nb = Py_Type(op)->tp_as_number) == NULL ||
 	    nb->nb_int == NULL) {
 		PyErr_SetString(PyExc_TypeError, "an integer is required");
 		return -1;
@@ -207,7 +207,7 @@
 	return PyInt_AsLong(op);
 #else
 
-	if ((nb = op->ob_type->tp_as_number) == NULL ||
+	if ((nb = Py_Type(op)->tp_as_number) == NULL ||
 	    (nb->nb_int == NULL && nb->nb_long == 0)) {
 		PyErr_SetString(PyExc_TypeError, "an integer is required");
 		return -1;
@@ -256,7 +256,7 @@
 	if (op && PyLong_Check(op))
 		return PyLong_AsUnsignedLongMask(op);
 
-	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	if (op == NULL || (nb = Py_Type(op)->tp_as_number) == NULL ||
 	    nb->nb_int == NULL) {
 		PyErr_SetString(PyExc_TypeError, "an integer is required");
 		return (unsigned long)-1;
@@ -301,7 +301,7 @@
 	if (op && PyLong_Check(op))
 		return PyLong_AsUnsignedLongLongMask(op);
 
-	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
+	if (op == NULL || (nb = Py_Type(op)->tp_as_number) == NULL ||
 	    nb->nb_int == NULL) {
 		PyErr_SetString(PyExc_TypeError, "an integer is required");
 		return (unsigned PY_LONG_LONG)-1;
@@ -1116,8 +1116,7 @@
 };
 
 PyTypeObject PyInt_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"int",
 	sizeof(PyIntObject),
 	0,
@@ -1170,7 +1169,7 @@
 			return 0;
 		/* PyObject_New is inlined */
 		v = free_list;
-		free_list = (PyIntObject *)v->ob_type;
+		free_list = (PyIntObject *)Py_Type(v);
 		PyObject_INIT(v, &PyInt_Type);
 		v->ob_ival = ival;
 		small_ints[ival + NSMALLNEGINTS] = v;
@@ -1223,7 +1222,7 @@
 			     ctr++, p++) {
 				if (!PyInt_CheckExact(p) ||
 				    p->ob_refcnt == 0) {
-					p->ob_type = (struct _typeobject *)
+					Py_Type(p) = (struct _typeobject *)
 						free_list;
 					free_list = p;
 				}

Modified: python/branches/bcannon-objcap/Objects/iterobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/iterobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/iterobject.c	Thu Sep  6 21:35:45 2007
@@ -94,8 +94,7 @@
 };
 
 PyTypeObject PySeqIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"iterator",				/* tp_name */
 	sizeof(seqiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -199,8 +198,7 @@
 }
 
 PyTypeObject PyCallIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"callable-iterator",			/* tp_name */
 	sizeof(calliterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/listobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/listobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/listobject.c	Thu Sep  6 21:35:45 2007
@@ -34,7 +34,7 @@
 	*/
 	if (allocated >= newsize && newsize >= (allocated >> 1)) {
 		assert(self->ob_item != NULL || newsize == 0);
-		self->ob_size = newsize;
+		Py_Size(self) = newsize;
 		return 0;
 	}
 
@@ -58,7 +58,7 @@
 		return -1;
 	}
 	self->ob_item = items;
-	self->ob_size = newsize;
+	Py_Size(self) = newsize;
 	self->allocated = new_allocated;
 	return 0;
 }
@@ -114,7 +114,7 @@
 		}
 		memset(op->ob_item, 0, nbytes);
 	}
-	op->ob_size = size;
+	Py_Size(op) = size;
 	op->allocated = size;
 	_PyObject_GC_TRACK(op);
 	return (PyObject *) op;
@@ -128,7 +128,7 @@
 		return -1;
 	}
 	else
-		return ((PyListObject *)op) -> ob_size;
+		return Py_Size(op);
 }
 
 static PyObject *indexerr = NULL;
@@ -140,7 +140,7 @@
 		PyErr_BadInternalCall();
 		return NULL;
 	}
-	if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
+	if (i < 0 || i >= Py_Size(op)) {
 		if (indexerr == NULL)
 			indexerr = PyString_FromString(
 				"list index out of range");
@@ -161,7 +161,7 @@
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
+	if (i < 0 || i >= Py_Size(op)) {
 		Py_XDECREF(newitem);
 		PyErr_SetString(PyExc_IndexError,
 				"list assignment index out of range");
@@ -177,7 +177,7 @@
 static int
 ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
 {
-	Py_ssize_t i, n = self->ob_size;
+	Py_ssize_t i, n = Py_Size(self);
 	PyObject **items;
 	if (v == NULL) {
 		PyErr_BadInternalCall();
@@ -259,7 +259,7 @@
 		   There's a simple test case where somehow this reduces
 		   thrashing when a *very* large list is created and
 		   immediately deleted. */
-		i = op->ob_size;
+		i = Py_Size(op);
 		while (--i >= 0) {
 			Py_XDECREF(op->ob_item[i]);
 		}
@@ -268,7 +268,7 @@
 	if (num_free_lists < MAXFREELISTS && PyList_CheckExact(op))
 		free_lists[num_free_lists++] = op;
 	else
-		op->ob_type->tp_free((PyObject *)op);
+		Py_Type(op)->tp_free((PyObject *)op);
 	Py_TRASHCAN_SAFE_END(op)
 }
 
@@ -286,7 +286,7 @@
 		return 0;
 	}
 	fprintf(fp, "[");
-	for (i = 0; i < op->ob_size; i++) {
+	for (i = 0; i < Py_Size(op); i++) {
 		if (i > 0)
 			fprintf(fp, ", ");
 		if (PyObject_Print(op->ob_item[i], fp, 0) != 0) {
@@ -311,7 +311,7 @@
 		return i > 0 ? PyString_FromString("[...]") : NULL;
 	}
 
-	if (v->ob_size == 0) {
+	if (Py_Size(v) == 0) {
 		result = PyString_FromString("[]");
 		goto Done;
 	}
@@ -322,7 +322,7 @@
 
 	/* Do repr() on each element.  Note that this may mutate the list,
 	   so must refetch the list size on each iteration. */
-	for (i = 0; i < v->ob_size; ++i) {
+	for (i = 0; i < Py_Size(v); ++i) {
 		int status;
 		s = PyObject_Repr(v->ob_item[i]);
 		if (s == NULL)
@@ -369,7 +369,7 @@
 static Py_ssize_t
 list_length(PyListObject *a)
 {
-	return a->ob_size;
+	return Py_Size(a);
 }
 
 static int
@@ -378,7 +378,7 @@
 	Py_ssize_t i;
 	int cmp;
 
-	for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
+	for (i = 0, cmp = 0 ; cmp == 0 && i < Py_Size(a); ++i)
 		cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
 						   Py_EQ);
 	return cmp;
@@ -387,7 +387,7 @@
 static PyObject *
 list_item(PyListObject *a, Py_ssize_t i)
 {
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		if (indexerr == NULL)
 			indexerr = PyString_FromString(
 				"list index out of range");
@@ -406,12 +406,12 @@
 	Py_ssize_t i, len;
 	if (ilow < 0)
 		ilow = 0;
-	else if (ilow > a->ob_size)
-		ilow = a->ob_size;
+	else if (ilow > Py_Size(a))
+		ilow = Py_Size(a);
 	if (ihigh < ilow)
 		ihigh = ilow;
-	else if (ihigh > a->ob_size)
-		ihigh = a->ob_size;
+	else if (ihigh > Py_Size(a))
+		ihigh = Py_Size(a);
 	len = ihigh - ilow;
 	np = (PyListObject *) PyList_New(len);
 	if (np == NULL)
@@ -451,7 +451,7 @@
 		return NULL;
 	}
 #define b ((PyListObject *)bb)
-	size = a->ob_size + b->ob_size;
+	size = Py_Size(a) + Py_Size(b);
 	if (size < 0)
 		return PyErr_NoMemory();
 	np = (PyListObject *) PyList_New(size);
@@ -460,14 +460,14 @@
 	}
 	src = a->ob_item;
 	dest = np->ob_item;
-	for (i = 0; i < a->ob_size; i++) {
+	for (i = 0; i < Py_Size(a); i++) {
 		PyObject *v = src[i];
 		Py_INCREF(v);
 		dest[i] = v;
 	}
 	src = b->ob_item;
-	dest = np->ob_item + a->ob_size;
-	for (i = 0; i < b->ob_size; i++) {
+	dest = np->ob_item + Py_Size(a);
+	for (i = 0; i < Py_Size(b); i++) {
 		PyObject *v = src[i];
 		Py_INCREF(v);
 		dest[i] = v;
@@ -486,17 +486,17 @@
 	PyObject *elem;
 	if (n < 0)
 		n = 0;
-	size = a->ob_size * n;
+	size = Py_Size(a) * n;
 	if (size == 0)
               return PyList_New(0);
-	if (n && size/n != a->ob_size)
+	if (n && size/n != Py_Size(a))
 		return PyErr_NoMemory();
 	np = (PyListObject *) PyList_New(size);
 	if (np == NULL)
 		return NULL;
 
 	items = np->ob_item;
-	if (a->ob_size == 1) {
+	if (Py_Size(a) == 1) {
 		elem = a->ob_item[0];
 		for (i = 0; i < n; i++) {
 			items[i] = elem;
@@ -507,7 +507,7 @@
 	p = np->ob_item;
 	items = a->ob_item;
 	for (i = 0; i < n; i++) {
-		for (j = 0; j < a->ob_size; j++) {
+		for (j = 0; j < Py_Size(a); j++) {
 			*p = items[j];
 			Py_INCREF(*p);
 			p++;
@@ -524,8 +524,8 @@
 	if (item != NULL) {
 		/* Because XDECREF can recursively invoke operations on
 		   this list, we make it empty first. */
-		i = a->ob_size;
-		a->ob_size = 0;
+		i = Py_Size(a);
+		Py_Size(a) = 0;
 		a->ob_item = NULL;
 		a->allocated = 0;
 		while (--i >= 0) {
@@ -571,7 +571,7 @@
 	else {
 		if (a == b) {
 			/* Special case "a[i:j] = a" -- copy b first */
-			v = list_slice(b, 0, b->ob_size);
+			v = list_slice(b, 0, Py_Size(b));
 			if (v == NULL)
 				return result;
 			result = list_ass_slice(a, ilow, ihigh, v);
@@ -586,18 +586,18 @@
 	}
 	if (ilow < 0)
 		ilow = 0;
-	else if (ilow > a->ob_size)
-		ilow = a->ob_size;
+	else if (ilow > Py_Size(a))
+		ilow = Py_Size(a);
 
 	if (ihigh < ilow)
 		ihigh = ilow;
-	else if (ihigh > a->ob_size)
-		ihigh = a->ob_size;
+	else if (ihigh > Py_Size(a))
+		ihigh = Py_Size(a);
 
 	norig = ihigh - ilow;
 	assert(norig >= 0);
 	d = n - norig;
-	if (a->ob_size + d == 0) {
+	if (Py_Size(a) + d == 0) {
 		Py_XDECREF(v_as_SF);
 		return list_clear(a);
 	}
@@ -615,12 +615,12 @@
 
 	if (d < 0) { /* Delete -d items */
 		memmove(&item[ihigh+d], &item[ihigh],
-			(a->ob_size - ihigh)*sizeof(PyObject *));
-		list_resize(a, a->ob_size + d);
+			(Py_Size(a) - ihigh)*sizeof(PyObject *));
+		list_resize(a, Py_Size(a) + d);
 		item = a->ob_item;
 	}
 	else if (d > 0) { /* Insert d items */
-		k = a->ob_size;
+		k = Py_Size(a);
 		if (list_resize(a, k+d) < 0)
 			goto Error;
 		item = a->ob_item;
@@ -692,7 +692,7 @@
 list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
 {
 	PyObject *old_value;
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		PyErr_SetString(PyExc_IndexError,
 				"list assignment index out of range");
 		return -1;
@@ -751,7 +751,7 @@
 			Py_DECREF(b);
 			Py_RETURN_NONE;
 		}
-		m = self->ob_size;
+		m = Py_Size(self);
 		if (list_resize(self, m + n) == -1) {
 			Py_DECREF(b);
 			return NULL;
@@ -789,14 +789,14 @@
 		PyErr_Clear();
 		n = 8;	/* arbitrary */
 	}
-	m = self->ob_size;
+	m = Py_Size(self);
 	mn = m + n;
 	if (mn >= m) {
 		/* Make room. */
 		if (list_resize(self, mn) == -1)
 			goto error;
 		/* Make the list sane again. */
-		self->ob_size = m;
+		Py_Size(self) = m;
 	}
 	/* Else m + n overflowed; on the chance that n lied, and there really
 	 * is enough room, ignore it.  If n was telling the truth, we'll
@@ -815,10 +815,10 @@
 			}
 			break;
 		}
-		if (self->ob_size < self->allocated) {
+		if (Py_Size(self) < self->allocated) {
 			/* steals ref */
-			PyList_SET_ITEM(self, self->ob_size, item);
-			++self->ob_size;
+			PyList_SET_ITEM(self, Py_Size(self), item);
+			++Py_Size(self);
 		}
 		else {
 			int status = app1(self, item);
@@ -829,8 +829,8 @@
 	}
 
 	/* Cut back result list if initial guess was too large. */
-	if (self->ob_size < self->allocated)
-		list_resize(self, self->ob_size);  /* shrinking can't fail */
+	if (Py_Size(self) < self->allocated)
+		list_resize(self, Py_Size(self));  /* shrinking can't fail */
 
 	Py_DECREF(it);
 	Py_RETURN_NONE;
@@ -869,20 +869,20 @@
 	if (!PyArg_ParseTuple(args, "|n:pop", &i))
 		return NULL;
 
-	if (self->ob_size == 0) {
+	if (Py_Size(self) == 0) {
 		/* Special-case most common failure cause */
 		PyErr_SetString(PyExc_IndexError, "pop from empty list");
 		return NULL;
 	}
 	if (i < 0)
-		i += self->ob_size;
-	if (i < 0 || i >= self->ob_size) {
+		i += Py_Size(self);
+	if (i < 0 || i >= Py_Size(self)) {
 		PyErr_SetString(PyExc_IndexError, "pop index out of range");
 		return NULL;
 	}
 	v = self->ob_item[i];
-	if (i == self->ob_size - 1) {
-		status = list_resize(self, self->ob_size - 1);
+	if (i == Py_Size(self) - 1) {
+		status = list_resize(self, Py_Size(self) - 1);
 		assert(status >= 0);
 		return v; /* and v now owns the reference the list had */
 	}
@@ -1812,8 +1812,7 @@
 sortwrapper_dealloc(sortwrapperobject *);
 
 static PyTypeObject sortwrapper_type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"sortwrapper",				/* tp_name */
 	sizeof(sortwrapperobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -1930,8 +1929,7 @@
 PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");
 
 static PyTypeObject cmpwrapper_type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"cmpwrapper",				/* tp_name */
 	sizeof(cmpwrapperobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2014,10 +2012,10 @@
 	 * sorting (allowing mutations during sorting is a core-dump
 	 * factory, since ob_item may change).
 	 */
-	saved_ob_size = self->ob_size;
+	saved_ob_size = Py_Size(self);
 	saved_ob_item = self->ob_item;
 	saved_allocated = self->allocated;
-	self->ob_size = 0;
+	Py_Size(self) = 0;
 	self->ob_item = NULL;
 	self->allocated = -1; /* any operation will reset it to >= 0 */
 
@@ -2123,8 +2121,8 @@
 
 dsu_fail:
 	final_ob_item = self->ob_item;
-	i = self->ob_size;
-	self->ob_size = saved_ob_size;
+	i = Py_Size(self);
+	Py_Size(self) = saved_ob_size;
 	self->ob_item = saved_ob_item;
 	self->allocated = saved_allocated;
 	if (final_ob_item != NULL) {
@@ -2159,8 +2157,8 @@
 static PyObject *
 listreverse(PyListObject *self)
 {
-	if (self->ob_size > 1)
-		reverse_slice(self->ob_item, self->ob_item + self->ob_size);
+	if (Py_Size(self) > 1)
+		reverse_slice(self->ob_item, self->ob_item + Py_Size(self));
 	Py_RETURN_NONE;
 }
 
@@ -2173,8 +2171,8 @@
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	if (self->ob_size > 1)
-		reverse_slice(self->ob_item, self->ob_item + self->ob_size);
+	if (Py_Size(self) > 1)
+		reverse_slice(self->ob_item, self->ob_item + Py_Size(self));
 	return 0;
 }
 
@@ -2188,7 +2186,7 @@
 		PyErr_BadInternalCall();
 		return NULL;
 	}
-	n = ((PyListObject *)v)->ob_size;
+	n = Py_Size(v);
 	w = PyTuple_New(n);
 	if (w == NULL)
 		return NULL;
@@ -2206,7 +2204,7 @@
 static PyObject *
 listindex(PyListObject *self, PyObject *args)
 {
-	Py_ssize_t i, start=0, stop=self->ob_size;
+	Py_ssize_t i, start=0, stop=Py_Size(self);
 	PyObject *v;
 
 	if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
@@ -2214,16 +2212,16 @@
 	                            _PyEval_SliceIndex, &stop))
 		return NULL;
 	if (start < 0) {
-		start += self->ob_size;
+		start += Py_Size(self);
 		if (start < 0)
 			start = 0;
 	}
 	if (stop < 0) {
-		stop += self->ob_size;
+		stop += Py_Size(self);
 		if (stop < 0)
 			stop = 0;
 	}
-	for (i = start; i < stop && i < self->ob_size; i++) {
+	for (i = start; i < stop && i < Py_Size(self); i++) {
 		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
 		if (cmp > 0)
 			return PyInt_FromSsize_t(i);
@@ -2240,7 +2238,7 @@
 	Py_ssize_t count = 0;
 	Py_ssize_t i;
 
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
 		if (cmp > 0)
 			count++;
@@ -2255,7 +2253,7 @@
 {
 	Py_ssize_t i;
 
-	for (i = 0; i < self->ob_size; i++) {
+	for (i = 0; i < Py_Size(self); i++) {
 		int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
 		if (cmp > 0) {
 			if (list_ass_slice(self, i, i+1,
@@ -2275,7 +2273,7 @@
 {
 	Py_ssize_t i;
 
-	for (i = o->ob_size; --i >= 0; )
+	for (i = Py_Size(o); --i >= 0; )
 		Py_VISIT(o->ob_item[i]);
 	return 0;
 }
@@ -2294,7 +2292,7 @@
 	vl = (PyListObject *)v;
 	wl = (PyListObject *)w;
 
-	if (vl->ob_size != wl->ob_size && (op == Py_EQ || op == Py_NE)) {
+	if (Py_Size(vl) != Py_Size(wl) && (op == Py_EQ || op == Py_NE)) {
 		/* Shortcut: if the lengths differ, the lists differ */
 		PyObject *res;
 		if (op == Py_EQ)
@@ -2306,7 +2304,7 @@
 	}
 
 	/* Search for the first index where items are different */
-	for (i = 0; i < vl->ob_size && i < wl->ob_size; i++) {
+	for (i = 0; i < Py_Size(vl) && i < Py_Size(wl); i++) {
 		int k = PyObject_RichCompareBool(vl->ob_item[i],
 						 wl->ob_item[i], Py_EQ);
 		if (k < 0)
@@ -2315,10 +2313,10 @@
 			break;
 	}
 
-	if (i >= vl->ob_size || i >= wl->ob_size) {
+	if (i >= Py_Size(vl) || i >= Py_Size(wl)) {
 		/* No more items to compare -- compare sizes */
-		Py_ssize_t vs = vl->ob_size;
-		Py_ssize_t ws = wl->ob_size;
+		Py_ssize_t vs = Py_Size(vl);
+		Py_ssize_t ws = Py_Size(wl);
 		int cmp;
 		PyObject *res;
 		switch (op) {
@@ -2362,8 +2360,8 @@
 		return -1;
 
 	/* Verify list invariants established by PyType_GenericAlloc() */
-	assert(0 <= self->ob_size);
-	assert(self->ob_size <= self->allocated || self->allocated == -1);
+	assert(0 <= Py_Size(self));
+	assert(Py_Size(self) <= self->allocated || self->allocated == -1);
 	assert(self->ob_item != NULL ||
 	       self->allocated == 0 || self->allocated == -1);
 
@@ -2467,7 +2465,7 @@
 		PyObject* it;
 		PyObject **src, **dest;
 
-		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+		if (PySlice_GetIndicesEx((PySliceObject*)item, Py_Size(self),
 				 &start, &stop, &step, &slicelength) < 0) {
 			return NULL;
 		}
@@ -2475,6 +2473,9 @@
 		if (slicelength <= 0) {
 			return PyList_New(0);
 		}
+		else if (step == 1) {
+			return list_slice(self, start, stop);
+		}
 		else {
 			result = PyList_New(slicelength);
 			if (!result) return NULL;
@@ -2513,15 +2514,20 @@
 	else if (PySlice_Check(item)) {
 		Py_ssize_t start, stop, step, slicelength;
 
-		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+		if (PySlice_GetIndicesEx((PySliceObject*)item, Py_Size(self),
 				 &start, &stop, &step, &slicelength) < 0) {
 			return -1;
 		}
 
-		/* treat L[slice(a,b)] = v _exactly_ like L[a:b] = v */
-		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
+		if (step == 1)
 			return list_ass_slice(self, start, stop, value);
 
+		/* Make sure s[5:2] = [..] inserts at the right place:
+		   before 5, not before 2. */
+		if ((step < 0 && start < stop) ||
+		    (step > 0 && start > stop))
+			stop = start;
+
 		if (value == NULL) {
 			/* delete slice */
 			PyObject **garbage;
@@ -2543,32 +2549,37 @@
 				return -1;
 			}
 
-			/* drawing pictures might help
-			   understand these for loops */
+			/* drawing pictures might help understand these for
+			   loops. Basically, we memmove the parts of the
+			   list that are *not* part of the slice: step-1
+			   items for each item that is part of the slice,
+			   and then tail end of the list that was not
+			   covered by the slice */
 			for (cur = start, i = 0;
 			     cur < stop;
 			     cur += step, i++) {
-				Py_ssize_t lim = step;
+				Py_ssize_t lim = step - 1;
 
 				garbage[i] = PyList_GET_ITEM(self, cur);
 
-				if (cur + step >= self->ob_size) {
-					lim = self->ob_size - cur - 1;
+				if (cur + step >= Py_Size(self)) {
+					lim = Py_Size(self) - cur - 1;
 				}
 
 				memmove(self->ob_item + cur - i,
 					self->ob_item + cur + 1,
 					lim * sizeof(PyObject *));
 			}
-
-			for (cur = start + slicelength*step + 1;
-			     cur < self->ob_size; cur++) {
-				PyList_SET_ITEM(self, cur - slicelength,
-						PyList_GET_ITEM(self, cur));
+			cur = start + slicelength*step;
+			if (cur < Py_Size(self)) {
+				memmove(self->ob_item + cur - slicelength,
+					self->ob_item + cur,
+					(Py_Size(self) - cur) * 
+					 sizeof(PyObject *));
 			}
 
-			self->ob_size -= slicelength;
-			list_resize(self, self->ob_size);
+			Py_Size(self) -= slicelength;
+			list_resize(self, Py_Size(self));
 
 			for (i = 0; i < slicelength; i++) {
 				Py_DECREF(garbage[i]);
@@ -2579,7 +2590,8 @@
 		}
 		else {
 			/* assign slice */
-			PyObject **garbage, *ins, *seq, **seqitems, **selfitems;
+			PyObject *ins, *seq;
+			PyObject **garbage, **seqitems, **selfitems;
 			Py_ssize_t cur, i;
 
 			/* protect against a[::-1] = a */
@@ -2589,14 +2601,17 @@
 			}
 			else {
 				seq = PySequence_Fast(value,
-					"must assign iterable to extended slice");
+						      "must assign iterable "
+						      "to extended slice");
 			}
 			if (!seq)
 				return -1;
 
 			if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
 				PyErr_Format(PyExc_ValueError,
-            "attempt to assign sequence of size %zd to extended slice of size %zd",
+					"attempt to assign sequence of "
+					"size %zd to extended slice of "
+					"size %zd",
 					     PySequence_Fast_GET_SIZE(seq),
 					     slicelength);
 				Py_DECREF(seq);
@@ -2651,8 +2666,7 @@
 };
 
 PyTypeObject PyList_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"list",
 	sizeof(PyListObject),
 	0,
@@ -2717,8 +2731,7 @@
 };
 
 PyTypeObject PyListIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"listiterator",				/* tp_name */
 	sizeof(listiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -2840,8 +2853,7 @@
 };
 
 PyTypeObject PyListRevIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"listreverseiterator",			/* tp_name */
 	sizeof(listreviterobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/longobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/longobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/longobject.c	Thu Sep  6 21:35:45 2007
@@ -50,13 +50,13 @@
 static PyLongObject *
 long_normalize(register PyLongObject *v)
 {
-	Py_ssize_t j = ABS(v->ob_size);
+	Py_ssize_t j = ABS(Py_Size(v));
 	Py_ssize_t i = j;
 
 	while (i > 0 && v->ob_digit[i-1] == 0)
 		--i;
 	if (i != j)
-		v->ob_size = (v->ob_size < 0) ? -(i) : i;
+		Py_Size(v) = (Py_Size(v) < 0) ? -(i) : i;
 	return v;
 }
 
@@ -147,7 +147,7 @@
 	v = _PyLong_New(ndigits);
 	if (v != NULL) {
 		digit *p = v->ob_digit;
-		v->ob_size = ndigits;
+		Py_Size(v) = ndigits;
 		while (ival) {
 			*p++ = (digit)(ival & MASK);
 			ival >>= SHIFT;
@@ -189,7 +189,7 @@
 		frac = ldexp(frac, SHIFT);
 	}
 	if (neg)
-		v->ob_size = -(v->ob_size);
+		Py_Size(v) = -(Py_Size(v));
 	return (PyObject *)v;
 }
 
@@ -323,7 +323,7 @@
 		return (unsigned long) -1;
 	}
 	v = (PyLongObject *)vv;
-	i = v->ob_size;
+	i = Py_Size(v);
 	x = 0;
 	if (i < 0) {
 		PyErr_SetString(PyExc_OverflowError,
@@ -381,7 +381,7 @@
 	assert(v != NULL);
 	assert(PyLong_Check(v));
 
-	return v->ob_size == 0 ? 0 : (v->ob_size < 0 ? -1 : 1);
+	return Py_Size(v) == 0 ? 0 : (Py_Size(v) < 0 ? -1 : 1);
 }
 
 size_t
@@ -393,7 +393,7 @@
 
 	assert(v != NULL);
 	assert(PyLong_Check(v));
-	ndigits = ABS(v->ob_size);
+	ndigits = ABS(Py_Size(v));
 	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
 	if (ndigits > 0) {
 		digit msd = v->ob_digit[ndigits - 1];
@@ -519,7 +519,7 @@
 		}
 	}
 
-	v->ob_size = is_signed ? -idigit : idigit;
+	Py_Size(v) = is_signed ? -idigit : idigit;
 	return (PyObject *)long_normalize(v);
 }
 
@@ -540,8 +540,8 @@
 
 	assert(v != NULL && PyLong_Check(v));
 
-	if (v->ob_size < 0) {
-		ndigits = -(v->ob_size);
+	if (Py_Size(v) < 0) {
+		ndigits = -(Py_Size(v));
 		if (!is_signed) {
 			PyErr_SetString(PyExc_TypeError,
 				"can't convert negative long to unsigned");
@@ -550,7 +550,7 @@
 		do_twos_comp = 1;
 	}
 	else {
-		ndigits = v->ob_size;
+		ndigits = Py_Size(v);
 		do_twos_comp = 0;
 	}
 
@@ -686,7 +686,7 @@
 		return -1;
 	}
 	v = (PyLongObject *)vv;
-	i = v->ob_size;
+	i = Py_Size(v);
 	sign = 1;
 	if (i < 0) {
 		sign = -1;
@@ -847,7 +847,7 @@
 	v = _PyLong_New(ndigits);
 	if (v != NULL) {
 		digit *p = v->ob_digit;
-		v->ob_size = negative ? -ndigits : ndigits;
+		Py_Size(v) = negative ? -ndigits : ndigits;
 		t = (unsigned PY_LONG_LONG)ival;
 		while (t) {
 			*p++ = (digit)(t & MASK);
@@ -875,7 +875,7 @@
 	v = _PyLong_New(ndigits);
 	if (v != NULL) {
 		digit *p = v->ob_digit;
-		v->ob_size = ndigits;
+		Py_Size(v) = ndigits;
 		while (ival) {
 			*p++ = (digit)(ival & MASK);
 			ival >>= SHIFT;
@@ -1117,7 +1117,7 @@
 static PyLongObject *
 muladd1(PyLongObject *a, wdigit n, wdigit extra)
 {
-	Py_ssize_t size_a = ABS(a->ob_size);
+	Py_ssize_t size_a = ABS(Py_Size(a));
 	PyLongObject *z = _PyLong_New(size_a+1);
 	twodigits carry = extra;
 	Py_ssize_t i;
@@ -1163,7 +1163,7 @@
 static PyLongObject *
 divrem1(PyLongObject *a, digit n, digit *prem)
 {
-	const Py_ssize_t size = ABS(a->ob_size);
+	const Py_ssize_t size = ABS(Py_Size(a));
 	PyLongObject *z;
 
 	assert(n > 0 && n <= MASK);
@@ -1194,7 +1194,7 @@
 		return NULL;
 	}
 	assert(base >= 2 && base <= 36);
-	size_a = ABS(a->ob_size);
+	size_a = ABS(Py_Size(a));
 
 	/* Compute a rough upper bound for the length of the string */
 	i = base;
@@ -1597,7 +1597,7 @@
 		z = _PyLong_New(size_z);
 		if (z == NULL)
 			return NULL;
-		z->ob_size = 0;
+		Py_Size(z) = 0;
 
 		/* `convwidth` consecutive input digits are treated as a single
 		 * digit in base `convmultmax`.
@@ -1627,7 +1627,7 @@
 
 			/* Multiply z by convmult, and add c. */
 			pz = z->ob_digit;
-			pzstop = pz + z->ob_size;
+			pzstop = pz + Py_Size(z);
 			for (; pz < pzstop; ++pz) {
 				c += (twodigits)*pz * convmult;
 				*pz = (digit)(c & MASK);
@@ -1636,14 +1636,14 @@
 			/* carry off the current end? */
 			if (c) {
 				assert(c < BASE);
-				if (z->ob_size < size_z) {
+				if (Py_Size(z) < size_z) {
 					*pz = (digit)c;
-					++z->ob_size;
+					++Py_Size(z);
 				}
 				else {
 					PyLongObject *tmp;
 					/* Extremely rare.  Get more space. */
-					assert(z->ob_size == size_z);
+					assert(Py_Size(z) == size_z);
 					tmp = _PyLong_New(size_z + 1);
 					if (tmp == NULL) {
 						Py_DECREF(z);
@@ -1665,7 +1665,7 @@
 	if (str == start)
 		goto onError;
 	if (sign < 0)
-		z->ob_size = -(z->ob_size);
+		Py_Size(z) = -(Py_Size(z));
 	if (*str == 'L' || *str == 'l')
 		str++;
 	while (*str && isspace(Py_CHARMASK(*str)))
@@ -1726,7 +1726,7 @@
 long_divrem(PyLongObject *a, PyLongObject *b,
 	    PyLongObject **pdiv, PyLongObject **prem)
 {
-	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	Py_ssize_t size_a = ABS(Py_Size(a)), size_b = ABS(Py_Size(b));
 	PyLongObject *z;
 
 	if (size_b == 0) {
@@ -1778,7 +1778,7 @@
 static PyLongObject *
 x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
 {
-	Py_ssize_t size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
+	Py_ssize_t size_v = ABS(Py_Size(v1)), size_w = ABS(Py_Size(w1));
 	digit d = (digit) ((twodigits)BASE / (w1->ob_digit[size_w-1] + 1));
 	PyLongObject *v = mul1(v1, d);
 	PyLongObject *w = mul1(w1, d);
@@ -1792,10 +1792,10 @@
 	}
 
 	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
-	assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
-	assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
+	assert(Py_Refcnt(v) == 1); /* Since v will be used as accumulator! */
+	assert(size_w == ABS(Py_Size(w))); /* That's how d was calculated */
 
-	size_v = ABS(v->ob_size);
+	size_v = ABS(Py_Size(v));
 	k = size_v - size_w;
 	a = _PyLong_New(k + 1);
 
@@ -1878,7 +1878,7 @@
 static void
 long_dealloc(PyObject *v)
 {
-	v->ob_type->tp_free(v);
+	Py_Type(v)->tp_free(v);
 }
 
 static PyObject *
@@ -1898,21 +1898,21 @@
 {
 	Py_ssize_t sign;
 
-	if (a->ob_size != b->ob_size) {
-		if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
+	if (Py_Size(a) != Py_Size(b)) {
+		if (ABS(Py_Size(a)) == 0 && ABS(Py_Size(b)) == 0)
 			sign = 0;
 		else
-			sign = a->ob_size - b->ob_size;
+			sign = Py_Size(a) - Py_Size(b);
 	}
 	else {
-		Py_ssize_t i = ABS(a->ob_size);
+		Py_ssize_t i = ABS(Py_Size(a));
 		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
 			;
 		if (i < 0)
 			sign = 0;
 		else {
 			sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
-			if (a->ob_size < 0)
+			if (Py_Size(a) < 0)
 				sign = -sign;
 		}
 	}
@@ -1955,7 +1955,7 @@
 static PyLongObject *
 x_add(PyLongObject *a, PyLongObject *b)
 {
-	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	Py_ssize_t size_a = ABS(Py_Size(a)), size_b = ABS(Py_Size(b));
 	PyLongObject *z;
 	int i;
 	digit carry = 0;
@@ -1989,7 +1989,7 @@
 static PyLongObject *
 x_sub(PyLongObject *a, PyLongObject *b)
 {
-	Py_ssize_t size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
+	Py_ssize_t size_a = ABS(Py_Size(a)), size_b = ABS(Py_Size(b));
 	PyLongObject *z;
 	Py_ssize_t i;
 	int sign = 1;
@@ -2099,15 +2099,15 @@
 x_mul(PyLongObject *a, PyLongObject *b)
 {
 	PyLongObject *z;
-	Py_ssize_t size_a = ABS(a->ob_size);
-	Py_ssize_t size_b = ABS(b->ob_size);
+	Py_ssize_t size_a = ABS(Py_Size(a));
+	Py_ssize_t size_b = ABS(Py_Size(b));
 	Py_ssize_t i;
 
      	z = _PyLong_New(size_a + size_b);
 	if (z == NULL)
 		return NULL;
 
-	memset(z->ob_digit, 0, z->ob_size * sizeof(digit));
+	memset(z->ob_digit, 0, Py_Size(z) * sizeof(digit));
 	if (a == b) {
 		/* Efficient squaring per HAC, Algorithm 14.16:
 		 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
@@ -2191,7 +2191,7 @@
 {
 	PyLongObject *hi, *lo;
 	Py_ssize_t size_lo, size_hi;
-	const Py_ssize_t size_n = ABS(n->ob_size);
+	const Py_ssize_t size_n = ABS(Py_Size(n));
 
 	size_lo = MIN(size_n, size);
 	size_hi = size_n - size_lo;
@@ -2220,8 +2220,8 @@
 static PyLongObject *
 k_mul(PyLongObject *a, PyLongObject *b)
 {
-	Py_ssize_t asize = ABS(a->ob_size);
-	Py_ssize_t bsize = ABS(b->ob_size);
+	Py_ssize_t asize = ABS(Py_Size(a));
+	Py_ssize_t bsize = ABS(Py_Size(b));
 	PyLongObject *ah = NULL;
 	PyLongObject *al = NULL;
 	PyLongObject *bh = NULL;
@@ -2273,7 +2273,7 @@
 	/* Split a & b into hi & lo pieces. */
 	shift = bsize >> 1;
 	if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
-	assert(ah->ob_size > 0);	/* the split isn't degenerate */
+	assert(Py_Size(ah) > 0);	/* the split isn't degenerate */
 
 	if (a == b) {
 		bh = ah;
@@ -2304,20 +2304,20 @@
 	if (ret == NULL) goto fail;
 #ifdef Py_DEBUG
 	/* Fill with trash, to catch reference to uninitialized digits. */
-	memset(ret->ob_digit, 0xDF, ret->ob_size * sizeof(digit));
+	memset(ret->ob_digit, 0xDF, Py_Size(ret) * sizeof(digit));
 #endif
 
 	/* 2. t1 <- ah*bh, and copy into high digits of result. */
 	if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
-	assert(t1->ob_size >= 0);
-	assert(2*shift + t1->ob_size <= ret->ob_size);
+	assert(Py_Size(t1) >= 0);
+	assert(2*shift + Py_Size(t1) <= Py_Size(ret));
 	memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
-	       t1->ob_size * sizeof(digit));
+	       Py_Size(t1) * sizeof(digit));
 
 	/* Zero-out the digits higher than the ah*bh copy. */
-	i = ret->ob_size - 2*shift - t1->ob_size;
+	i = Py_Size(ret) - 2*shift - Py_Size(t1);
 	if (i)
-		memset(ret->ob_digit + 2*shift + t1->ob_size, 0,
+		memset(ret->ob_digit + 2*shift + Py_Size(t1), 0,
 		       i * sizeof(digit));
 
 	/* 3. t2 <- al*bl, and copy into the low digits. */
@@ -2325,23 +2325,23 @@
 		Py_DECREF(t1);
 		goto fail;
 	}
-	assert(t2->ob_size >= 0);
-	assert(t2->ob_size <= 2*shift); /* no overlap with high digits */
-	memcpy(ret->ob_digit, t2->ob_digit, t2->ob_size * sizeof(digit));
+	assert(Py_Size(t2) >= 0);
+	assert(Py_Size(t2) <= 2*shift); /* no overlap with high digits */
+	memcpy(ret->ob_digit, t2->ob_digit, Py_Size(t2) * sizeof(digit));
 
 	/* Zero out remaining digits. */
-	i = 2*shift - t2->ob_size;	/* number of uninitialized digits */
+	i = 2*shift - Py_Size(t2);	/* number of uninitialized digits */
 	if (i)
-		memset(ret->ob_digit + t2->ob_size, 0, i * sizeof(digit));
+		memset(ret->ob_digit + Py_Size(t2), 0, i * sizeof(digit));
 
 	/* 4 & 5. Subtract ah*bh (t1) and al*bl (t2).  We do al*bl first
 	 * because it's fresher in cache.
 	 */
-	i = ret->ob_size - shift;  /* # digits after shift */
-	(void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, t2->ob_size);
+	i = Py_Size(ret) - shift;  /* # digits after shift */
+	(void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_Size(t2));
 	Py_DECREF(t2);
 
-	(void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, t1->ob_size);
+	(void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_Size(t1));
 	Py_DECREF(t1);
 
 	/* 6. t3 <- (ah+al)(bh+bl), and add into result. */
@@ -2366,12 +2366,12 @@
 	Py_DECREF(t1);
 	Py_DECREF(t2);
 	if (t3 == NULL) goto fail;
-	assert(t3->ob_size >= 0);
+	assert(Py_Size(t3) >= 0);
 
 	/* Add t3.  It's not obvious why we can't run out of room here.
 	 * See the (*) comment after this function.
 	 */
-	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, t3->ob_size);
+	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_Size(t3));
 	Py_DECREF(t3);
 
 	return long_normalize(ret);
@@ -2441,8 +2441,8 @@
 static PyLongObject *
 k_lopsided_mul(PyLongObject *a, PyLongObject *b)
 {
-	const Py_ssize_t asize = ABS(a->ob_size);
-	Py_ssize_t bsize = ABS(b->ob_size);
+	const Py_ssize_t asize = ABS(Py_Size(a));
+	Py_ssize_t bsize = ABS(Py_Size(b));
 	Py_ssize_t nbdone;	/* # of b digits already multiplied */
 	PyLongObject *ret;
 	PyLongObject *bslice = NULL;
@@ -2454,7 +2454,7 @@
 	ret = _PyLong_New(asize + bsize);
 	if (ret == NULL)
 		return NULL;
-	memset(ret->ob_digit, 0, ret->ob_size * sizeof(digit));
+	memset(ret->ob_digit, 0, Py_Size(ret) * sizeof(digit));
 
 	/* Successive slices of b are copied into bslice. */
 	bslice = _PyLong_New(asize);
@@ -2469,14 +2469,14 @@
 		/* Multiply the next slice of b by a. */
 		memcpy(bslice->ob_digit, b->ob_digit + nbdone,
 		       nbtouse * sizeof(digit));
-		bslice->ob_size = nbtouse;
+		Py_Size(bslice) = nbtouse;
 		product = k_mul(a, bslice);
 		if (product == NULL)
 			goto fail;
 
 		/* Add into result. */
-		(void)v_iadd(ret->ob_digit + nbdone, ret->ob_size - nbdone,
-			     product->ob_digit, product->ob_size);
+		(void)v_iadd(ret->ob_digit + nbdone, Py_Size(ret) - nbdone,
+			     product->ob_digit, Py_Size(product));
 		Py_DECREF(product);
 
 		bsize -= nbtouse;
@@ -2540,8 +2540,8 @@
 
 	if (long_divrem(v, w, &div, &mod) < 0)
 		return -1;
-	if ((mod->ob_size < 0 && w->ob_size > 0) ||
-	    (mod->ob_size > 0 && w->ob_size < 0)) {
+	if ((Py_Size(mod) < 0 && Py_Size(w) > 0) ||
+	    (Py_Size(mod) > 0 && Py_Size(w) < 0)) {
 		PyLongObject *temp;
 		PyLongObject *one;
 		temp = (PyLongObject *) long_add(mod, w);
@@ -2729,7 +2729,7 @@
 		return Py_NotImplemented;
 	}
 
-	if (b->ob_size < 0) {  /* if exponent is negative */
+	if (Py_Size(b) < 0) {  /* if exponent is negative */
 		if (c) {
 			PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
 			    "cannot be negative when 3rd argument specified");
@@ -2748,7 +2748,7 @@
 	if (c) {
 		/* if modulus == 0:
 		       raise ValueError() */
-		if (c->ob_size == 0) {
+		if (Py_Size(c) == 0) {
 			PyErr_SetString(PyExc_ValueError,
 					"pow() 3rd argument cannot be 0");
 			goto Error;
@@ -2757,7 +2757,7 @@
 		/* if modulus < 0:
 		       negativeOutput = True
 		       modulus = -modulus */
-		if (c->ob_size < 0) {
+		if (Py_Size(c) < 0) {
 			negativeOutput = 1;
 			temp = (PyLongObject *)_PyLong_Copy(c);
 			if (temp == NULL)
@@ -2770,7 +2770,7 @@
 
 		/* if modulus == 1:
 		       return 0 */
-		if ((c->ob_size == 1) && (c->ob_digit[0] == 1)) {
+		if ((Py_Size(c) == 1) && (c->ob_digit[0] == 1)) {
 			z = (PyLongObject *)PyLong_FromLong(0L);
 			goto Done;
 		}
@@ -2778,7 +2778,7 @@
 		/* if base < 0:
 		       base = base % modulus
 		   Having the base positive just makes things easier. */
-		if (a->ob_size < 0) {
+		if (Py_Size(a) < 0) {
 			if (l_divmod(a, c, NULL, &temp) < 0)
 				goto Error;
 			Py_DECREF(a);
@@ -2819,10 +2819,10 @@
 	REDUCE(result)					\
 }
 
-	if (b->ob_size <= FIVEARY_CUTOFF) {
+	if (Py_Size(b) <= FIVEARY_CUTOFF) {
 		/* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
 		/* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */
-		for (i = b->ob_size - 1; i >= 0; --i) {
+		for (i = Py_Size(b) - 1; i >= 0; --i) {
 			digit bi = b->ob_digit[i];
 
 			for (j = 1 << (SHIFT-1); j != 0; j >>= 1) {
@@ -2839,7 +2839,7 @@
 		for (i = 1; i < 32; ++i)
 			MULT(table[i-1], a, table[i])
 
-		for (i = b->ob_size - 1; i >= 0; --i) {
+		for (i = Py_Size(b) - 1; i >= 0; --i) {
 			const digit bi = b->ob_digit[i];
 
 			for (j = SHIFT - 5; j >= 0; j -= 5) {
@@ -2852,7 +2852,7 @@
 		}
 	}
 
-	if (negativeOutput && (z->ob_size != 0)) {
+	if (negativeOutput && (Py_Size(z) != 0)) {
 		temp = (PyLongObject *)long_sub(z, c);
 		if (temp == NULL)
 			goto Error;
@@ -2869,7 +2869,7 @@
  	}
 	/* fall through */
  Done:
-	if (b->ob_size > FIVEARY_CUTOFF) {
+	if (Py_Size(b) > FIVEARY_CUTOFF) {
 		for (i = 0; i < 32; ++i)
 			Py_XDECREF(table[i]);
 	}
@@ -2893,7 +2893,7 @@
 	Py_DECREF(w);
 	if (x == NULL)
 		return NULL;
-	x->ob_size = -(x->ob_size);
+	Py_Size(x) = -(Py_Size(x));
 	return (PyObject *)x;
 }
 
@@ -2935,7 +2935,7 @@
 static int
 long_nonzero(PyLongObject *v)
 {
-	return ABS(v->ob_size) != 0;
+	return ABS(Py_Size(v)) != 0;
 }
 
 static PyObject *
@@ -2949,7 +2949,7 @@
 
 	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
 
-	if (a->ob_size < 0) {
+	if (Py_Size(a) < 0) {
 		/* Right shifting negative numbers is harder */
 		PyLongObject *a1, *a2;
 		a1 = (PyLongObject *) long_invert(a);
@@ -2973,7 +2973,7 @@
 			goto rshift_error;
 		}
 		wordshift = shiftby / SHIFT;
-		newsize = ABS(a->ob_size) - wordshift;
+		newsize = ABS(Py_Size(a)) - wordshift;
 		if (newsize <= 0) {
 			z = _PyLong_New(0);
 			Py_DECREF(a);
@@ -2987,8 +2987,8 @@
 		z = _PyLong_New(newsize);
 		if (z == NULL)
 			goto rshift_error;
-		if (a->ob_size < 0)
-			z->ob_size = -(z->ob_size);
+		if (Py_Size(a) < 0)
+			Py_Size(z) = -(Py_Size(z));
 		for (i = 0, j = wordshift; i < newsize; i++, j++) {
 			z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
 			if (i+1 < newsize)
@@ -3076,7 +3076,7 @@
 	digit diga, digb;
 	PyObject *v;
 
-	if (a->ob_size < 0) {
+	if (Py_Size(a) < 0) {
 		a = (PyLongObject *) long_invert(a);
 		if (a == NULL)
 			return NULL;
@@ -3086,7 +3086,7 @@
 		Py_INCREF(a);
 		maska = 0;
 	}
-	if (b->ob_size < 0) {
+	if (Py_Size(b) < 0) {
 		b = (PyLongObject *) long_invert(b);
 		if (b == NULL) {
 			Py_DECREF(a);
@@ -3135,8 +3135,8 @@
 	   whose length should be ignored.
 	*/
 
-	size_a = a->ob_size;
-	size_b = b->ob_size;
+	size_a = Py_Size(a);
+	size_b = Py_Size(b);
 	size_z = op == '&'
 		? (maska
 		   ? size_b
@@ -3343,7 +3343,7 @@
 	if (tmp == NULL)
 		return NULL;
 	assert(PyLong_CheckExact(tmp));
-	n = tmp->ob_size;
+	n = Py_Size(tmp);
 	if (n < 0)
 		n = -n;
 	newobj = (PyLongObject *)type->tp_alloc(type, n);
@@ -3352,7 +3352,7 @@
 		return NULL;
 	}
 	assert(PyLong_Check(newobj));
-	newobj->ob_size = tmp->ob_size;
+	Py_Size(newobj) = Py_Size(tmp);
 	for (i = 0; i < n; i++)
 		newobj->ob_digit[i] = tmp->ob_digit[i];
 	Py_DECREF(tmp);

Modified: python/branches/bcannon-objcap/Objects/methodobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/methodobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/methodobject.c	Thu Sep  6 21:35:45 2007
@@ -231,8 +231,7 @@
 
 
 PyTypeObject PyCFunction_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"builtin_function_or_method",
 	sizeof(PyCFunctionObject),
 	0,

Modified: python/branches/bcannon-objcap/Objects/moduleobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/moduleobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/moduleobject.c	Thu Sep  6 21:35:45 2007
@@ -186,7 +186,7 @@
 		_PyModule_Clear((PyObject *)m);
 		Py_DECREF(m->md_dict);
 	}
-	m->ob_type->tp_free((PyObject *)m);
+	Py_Type(m)->tp_free((PyObject *)m);
 }
 
 static PyObject *
@@ -225,8 +225,7 @@
 The name must be a string; the optional doc argument can have any type.");
 
 PyTypeObject PyModule_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"module",				/* tp_name */
 	sizeof(PyModuleObject),			/* tp_size */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/object.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/object.c	(original)
+++ python/branches/bcannon-objcap/Objects/object.c	Thu Sep  6 21:35:45 2007
@@ -214,7 +214,7 @@
 	if (op == NULL)
 		return PyErr_NoMemory();
 	/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
-	op->ob_type = tp;
+	Py_Type(op) = tp;
 	_Py_NewReference(op);
 	return op;
 }
@@ -226,7 +226,7 @@
 		return (PyVarObject *) PyErr_NoMemory();
 	/* Any changes should be reflected in PyObject_INIT_VAR */
 	op->ob_size = size;
-	op->ob_type = tp;
+	Py_Type(op) = tp;
 	_Py_NewReference((PyObject *)op);
 	return op;
 }
@@ -287,7 +287,7 @@
 			   universally available */
 			fprintf(fp, "<refcnt %ld at %p>",
 				(long)op->ob_refcnt, op);
-		else if (op->ob_type->tp_print == NULL) {
+		else if (Py_Type(op)->tp_print == NULL) {
 			PyObject *s;
 			if (flags & Py_PRINT_RAW)
 				s = PyObject_Str(op);
@@ -302,7 +302,7 @@
 			Py_XDECREF(s);
 		}
 		else
-			ret = (*op->ob_type->tp_print)(op, fp, flags);
+			ret = (*Py_Type(op)->tp_print)(op, fp, flags);
 	}
 	if (ret == 0) {
 		if (ferror(fp)) {
@@ -335,7 +335,7 @@
 			"type    : %s\n"
 			"refcount: %ld\n"
 			"address : %p\n",
-			op->ob_type==NULL ? "NULL" : op->ob_type->tp_name,
+			Py_Type(op)==NULL ? "NULL" : Py_Type(op)->tp_name,
 			(long)op->ob_refcnt,
 			op);
 	}
@@ -354,12 +354,12 @@
 #endif
 	if (v == NULL)
 		return PyString_FromString("<NULL>");
-	else if (v->ob_type->tp_repr == NULL)
+	else if (Py_Type(v)->tp_repr == NULL)
 		return PyString_FromFormat("<%s object at %p>",
-					   v->ob_type->tp_name, v);
+					   Py_Type(v)->tp_name, v);
 	else {
 		PyObject *res;
-		res = (*v->ob_type->tp_repr)(v);
+		res = (*Py_Type(v)->tp_repr)(v);
 		if (res == NULL)
 			return NULL;
 #ifdef Py_USING_UNICODE
@@ -376,7 +376,7 @@
 		if (!PyString_Check(res)) {
 			PyErr_Format(PyExc_TypeError,
 				     "__repr__ returned non-string (type %.200s)",
-				     res->ob_type->tp_name);
+				     Py_Type(res)->tp_name);
 			Py_DECREF(res);
 			return NULL;
 		}
@@ -401,10 +401,10 @@
 		return v;
 	}
 #endif
-	if (v->ob_type->tp_str == NULL)
+	if (Py_Type(v)->tp_str == NULL)
 		return PyObject_Repr(v);
 
-	res = (*v->ob_type->tp_str)(v);
+	res = (*Py_Type(v)->tp_str)(v);
 	if (res == NULL)
 		return NULL;
 	type_ok = PyString_Check(res);
@@ -414,7 +414,7 @@
 	if (!type_ok) {
 		PyErr_Format(PyExc_TypeError,
 			     "__str__ returned non-string (type %.200s)",
-			     res->ob_type->tp_name);
+			     Py_Type(res)->tp_name);
 		Py_DECREF(res);
 		return NULL;
 	}
@@ -488,8 +488,8 @@
 			res = v;
 		}
 		else {
-			if (v->ob_type->tp_str != NULL)
-				res = (*v->ob_type->tp_str)(v);
+			if (Py_Type(v)->tp_str != NULL)
+				res = (*Py_Type(v)->tp_str)(v);
 			else
 				res = PyObject_Repr(v);
 		}
@@ -1062,8 +1062,8 @@
 {
 	PyObject *w, *res;
 
-	if (v->ob_type->tp_getattr != NULL)
-		return (*v->ob_type->tp_getattr)(v, (char*)name);
+	if (Py_Type(v)->tp_getattr != NULL)
+		return (*Py_Type(v)->tp_getattr)(v, (char*)name);
 	w = PyString_InternFromString(name);
 	if (w == NULL)
 		return NULL;
@@ -1090,8 +1090,8 @@
 	PyObject *s;
 	int res;
 
-	if (v->ob_type->tp_setattr != NULL)
-		return (*v->ob_type->tp_setattr)(v, (char*)name, w);
+	if (Py_Type(v)->tp_setattr != NULL)
+		return (*Py_Type(v)->tp_setattr)(v, (char*)name, w);
 	s = PyString_InternFromString(name);
 	if (s == NULL)
 		return -1;
@@ -1103,7 +1103,7 @@
 PyObject *
 PyObject_GetAttr(PyObject *v, PyObject *name)
 {
-	PyTypeObject *tp = v->ob_type;
+	PyTypeObject *tp = Py_Type(v);
 
 	if (!PyString_Check(name)) {
 #ifdef Py_USING_UNICODE
@@ -1120,7 +1120,7 @@
 		{
 			PyErr_Format(PyExc_TypeError,
 				     "attribute name must be string, not '%.200s'",
-				     name->ob_type->tp_name);
+				     Py_Type(name)->tp_name);
 			return NULL;
 		}
 	}
@@ -1149,7 +1149,7 @@
 int
 PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 {
-	PyTypeObject *tp = v->ob_type;
+	PyTypeObject *tp = Py_Type(v);
 	int err;
 
 	if (!PyString_Check(name)){
@@ -1167,7 +1167,7 @@
 		{
 			PyErr_Format(PyExc_TypeError,
 				     "attribute name must be string, not '%.200s'",
-				     name->ob_type->tp_name);
+				     Py_Type(name)->tp_name);
 			return -1;
 		}
 	}
@@ -1209,7 +1209,7 @@
 _PyObject_GetDictPtr(PyObject *obj)
 {
 	Py_ssize_t dictoffset;
-	PyTypeObject *tp = obj->ob_type;
+	PyTypeObject *tp = Py_Type(obj);
 
 	if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
 		return NULL;
@@ -1244,7 +1244,7 @@
 PyObject *
 PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
 {
-	PyTypeObject *tp = obj->ob_type;
+	PyTypeObject *tp = Py_Type(obj);
 	PyObject *descr = NULL;
 	PyObject *res = NULL;
 	descrgetfunc f;
@@ -1266,7 +1266,7 @@
 		{
 			PyErr_Format(PyExc_TypeError,
 				     "attribute name must be string, not '%.200s'",
-				     name->ob_type->tp_name);
+				     Py_Type(name)->tp_name);
 			return NULL;
 		}
 	}
@@ -1346,7 +1346,7 @@
 	}
 
 	if (f != NULL) {
-		res = f(descr, obj, (PyObject *)obj->ob_type);
+		res = f(descr, obj, (PyObject *)Py_Type(obj));
 		Py_DECREF(descr);
 		goto done;
 	}
@@ -1368,7 +1368,7 @@
 int
 PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
 {
-	PyTypeObject *tp = obj->ob_type;
+	PyTypeObject *tp = Py_Type(obj);
 	PyObject *descr;
 	descrsetfunc f;
 	PyObject **dictptr;
@@ -1389,7 +1389,7 @@
 		{
 			PyErr_Format(PyExc_TypeError,
 				     "attribute name must be string, not '%.200s'",
-				     name->ob_type->tp_name);
+				     Py_Type(name)->tp_name);
 			return -1;
 		}
 	}
@@ -1683,7 +1683,7 @@
 	if (!PyList_Check(names)) {
 		PyErr_Format(PyExc_TypeError,
 			"dir(): expected keys() of locals to be a list, "
-			"not '%.200s'", names->ob_type->tp_name);
+			"not '%.200s'", Py_Type(names)->tp_name);
 		Py_DECREF(names);
 		return NULL;
 	}
@@ -1818,7 +1818,7 @@
 		if (!PyList_Check(result)) {
 			PyErr_Format(PyExc_TypeError,
 				     "__dir__() must return a list, not %.200s",
-				     result->ob_type->tp_name);
+				     Py_Type(result)->tp_name);
 			Py_DECREF(result);
 			result = NULL;
 		}
@@ -1880,8 +1880,7 @@
 
 
 static PyTypeObject PyNone_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"NoneType",
 	0,
 	0,
@@ -1898,7 +1897,8 @@
 };
 
 PyObject _Py_NoneStruct = {
-	PyObject_HEAD_INIT(&PyNone_Type)
+  _PyObject_EXTRA_INIT
+  1, &PyNone_Type
 };
 
 /* NotImplemented is an object that can be used to signal that an
@@ -1911,8 +1911,7 @@
 }
 
 static PyTypeObject PyNotImplemented_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"NotImplementedType",
 	0,
 	0,
@@ -1929,7 +1928,8 @@
 };
 
 PyObject _Py_NotImplementedStruct = {
-	PyObject_HEAD_INIT(&PyNotImplemented_Type)
+	_PyObject_EXTRA_INIT
+	1, &PyNotImplemented_Type
 };
 
 void
@@ -1997,7 +1997,7 @@
 void
 _Py_Dealloc(PyObject *op)
 {
-	destructor dealloc = op->ob_type->tp_dealloc;
+	destructor dealloc = Py_Type(op)->tp_dealloc;
 	_Py_ForgetReference(op);
 	(*dealloc)(op);
 }
@@ -2028,7 +2028,7 @@
 	fprintf(fp, "Remaining object addresses:\n");
 	for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
 		fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", op,
-			op->ob_refcnt, op->ob_type->tp_name);
+			op->ob_refcnt, Py_Type(op)->tp_name);
 }
 
 PyObject *
@@ -2046,7 +2046,7 @@
 		return NULL;
 	for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
 		while (op == self || op == args || op == res || op == t ||
-		       (t != NULL && op->ob_type != (PyTypeObject *) t)) {
+		       (t != NULL && Py_Type(op) != (PyTypeObject *) t)) {
 			op = op->_ob_next;
 			if (op == &refchain)
 				return res;
@@ -2189,7 +2189,7 @@
 {
 	while (_PyTrash_delete_later) {
 		PyObject *op = _PyTrash_delete_later;
-		destructor dealloc = op->ob_type->tp_dealloc;
+		destructor dealloc = Py_Type(op)->tp_dealloc;
 
 		_PyTrash_delete_later =
 			(PyObject*) _Py_AS_GC(op)->gc.gc_prev;

Modified: python/branches/bcannon-objcap/Objects/obmalloc.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/obmalloc.c	(original)
+++ python/branches/bcannon-objcap/Objects/obmalloc.c	Thu Sep  6 21:35:45 2007
@@ -675,8 +675,8 @@
 /* This is only useful when running memory debuggers such as
  * Purify or Valgrind.  Uncomment to use.
  *
-#define Py_USING_MEMORY_DEBUGGER
  */
+#define Py_USING_MEMORY_DEBUGGER
 
 #ifdef Py_USING_MEMORY_DEBUGGER
 

Modified: python/branches/bcannon-objcap/Objects/setobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/setobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/setobject.c	Thu Sep  6 21:35:45 2007
@@ -3,7 +3,7 @@
    Written and maintained by Raymond D. Hettinger <python at rcn.com>
    Derived from Lib/sets.py and Objects/dictobject.c.
 
-   Copyright (c) 2003-6 Python Software Foundation.
+   Copyright (c) 2003-2007 Python Software Foundation.
    All rights reserved.
 */
 
@@ -561,7 +561,7 @@
 	if (num_free_sets < MAXFREESETS && PyAnySet_CheckExact(so))
 		free_sets[num_free_sets++] = so;
 	else 
-		so->ob_type->tp_free(so);
+		Py_Type(so)->tp_free(so);
 	Py_TRASHCAN_SAFE_END(so)
 }
 
@@ -860,8 +860,7 @@
 }
 
 static PyTypeObject PySetIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"setiterator",				/* tp_name */
 	sizeof(setiterobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -987,7 +986,7 @@
 	    (type == &PySet_Type  ||  type == &PyFrozenSet_Type)) {
 		so = free_sets[--num_free_sets];
 		assert (so != NULL && PyAnySet_CheckExact(so));
-		so->ob_type = type;
+		Py_Type(so) = type;
 		_Py_NewReference((PyObject *)so);
 		EMPTY_TO_MINSIZE(so);
 		PyObject_GC_Track(so);
@@ -1113,8 +1112,8 @@
 		memcpy(b->smalltable, tab, sizeof(tab));
 	}
 
-	if (PyType_IsSubtype(a->ob_type, &PyFrozenSet_Type)  &&
-	    PyType_IsSubtype(b->ob_type, &PyFrozenSet_Type)) {
+	if (PyType_IsSubtype(Py_Type(a), &PyFrozenSet_Type)  &&
+	    PyType_IsSubtype(Py_Type(b), &PyFrozenSet_Type)) {
 		h = a->hash;     a->hash = b->hash;  b->hash = h;
 	} else {
 		a->hash = -1;
@@ -1125,7 +1124,7 @@
 static PyObject *
 set_copy(PySetObject *so)
 {
-	return make_new_set(so->ob_type, (PyObject *)so);
+	return make_new_set(Py_Type(so), (PyObject *)so);
 }
 
 static PyObject *
@@ -1203,7 +1202,7 @@
 	if ((PyObject *)so == other)
 		return set_copy(so);
 
-	result = (PySetObject *)make_new_set(so->ob_type, NULL);
+	result = (PySetObject *)make_new_set(Py_Type(so), NULL);
 	if (result == NULL)
 		return NULL;
 
@@ -1390,7 +1389,7 @@
 		return NULL;
 	}
 	
-	result = make_new_set(so->ob_type, NULL);
+	result = make_new_set(Py_Type(so), NULL);
 	if (result == NULL)
 		return NULL;
 
@@ -1491,7 +1490,7 @@
 		Py_INCREF(other);
 		otherset = (PySetObject *)other;
 	} else {
-		otherset = (PySetObject *)make_new_set(so->ob_type, other);
+		otherset = (PySetObject *)make_new_set(Py_Type(so), other);
 		if (otherset == NULL)
 			return NULL;
 	}
@@ -1522,7 +1521,7 @@
 	PyObject *rv;
 	PySetObject *otherset;
 
-	otherset = (PySetObject *)make_new_set(so->ob_type, other);
+	otherset = (PySetObject *)make_new_set(Py_Type(so), other);
 	if (otherset == NULL)
 		return NULL;
 	rv = set_symmetric_difference_update(otherset, (PyObject *)so);
@@ -1789,7 +1788,7 @@
 		dict = Py_None;
 		Py_INCREF(dict);
 	}
-	result = PyTuple_Pack(3, so->ob_type, args, dict);
+	result = PyTuple_Pack(3, Py_Type(so), args, dict);
 done:
 	Py_XDECREF(args);
 	Py_XDECREF(keys);
@@ -1806,7 +1805,7 @@
 
 	if (!PyAnySet_Check(self))
 		return -1;
-	if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable))
+	if (!PyArg_UnpackTuple(args, Py_Type(self)->tp_name, 0, 1, &iterable))
 		return -1;
 	set_clear_internal(self);
 	self->hash = -1;
@@ -1922,8 +1921,7 @@
 Build an unordered collection of unique elements.");
 
 PyTypeObject PySet_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"set",				/* tp_name */
 	sizeof(PySetObject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2017,8 +2015,7 @@
 Build an immutable unordered collection of unique elements.");
 
 PyTypeObject PyFrozenSet_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"frozenset",			/* tp_name */
 	sizeof(PySetObject),		/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -2099,7 +2096,7 @@
 int
 PySet_Clear(PyObject *set)
 {
-	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+	if (!PyType_IsSubtype(Py_Type(set), &PySet_Type)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2119,7 +2116,7 @@
 int
 PySet_Discard(PyObject *set, PyObject *key)
 {
-	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+	if (!PyType_IsSubtype(Py_Type(set), &PySet_Type)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2129,7 +2126,7 @@
 int
 PySet_Add(PyObject *set, PyObject *key)
 {
-	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+	if (!PyType_IsSubtype(Py_Type(set), &PySet_Type)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2170,7 +2167,7 @@
 PyObject *
 PySet_Pop(PyObject *set)
 {
-	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+	if (!PyType_IsSubtype(Py_Type(set), &PySet_Type)) {
 		PyErr_BadInternalCall();
 		return NULL;
 	}
@@ -2180,7 +2177,7 @@
 int
 _PySet_Update(PyObject *set, PyObject *iterable)
 {
-	if (!PyType_IsSubtype(set->ob_type, &PySet_Type)) {
+	if (!PyType_IsSubtype(Py_Type(set), &PySet_Type)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}

Modified: python/branches/bcannon-objcap/Objects/sliceobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/sliceobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/sliceobject.c	Thu Sep  6 21:35:45 2007
@@ -23,8 +23,7 @@
 }
 
 static PyTypeObject PyEllipsis_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,				/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"ellipsis",			/* tp_name */
 	0,				/* tp_basicsize */
 	0,				/* tp_itemsize */
@@ -47,7 +46,8 @@
 };
 
 PyObject _Py_EllipsisObject = {
-	PyObject_HEAD_INIT(&PyEllipsis_Type)
+	_PyObject_EXTRA_INIT
+	1, &PyEllipsis_Type
 };
 
 
@@ -277,7 +277,7 @@
 static PyObject *
 slice_reduce(PySliceObject* self)
 {
-	return Py_BuildValue("O(OOO)", self->ob_type, self->start, self->stop, self->step);
+	return Py_BuildValue("O(OOO)", Py_Type(self), self->start, self->stop, self->step);
 }
 
 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
@@ -319,8 +319,7 @@
 }
 
 PyTypeObject PySlice_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,			/* Number of items for varobject */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"slice",		/* Name of this type */
 	sizeof(PySliceObject),	/* Basic object size */
 	0,			/* Item size for varobject */

Modified: python/branches/bcannon-objcap/Objects/stringobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/stringobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/stringobject.c	Thu Sep  6 21:35:45 2007
@@ -421,7 +421,7 @@
     if (!PyString_Check(v)) {
         PyErr_Format(PyExc_TypeError,
                      "decoder did not return a string object (type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         goto onError;
     }
@@ -501,7 +501,7 @@
     if (!PyString_Check(v)) {
         PyErr_Format(PyExc_TypeError,
                      "encoder did not return a string object (type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         goto onError;
     }
@@ -521,7 +521,7 @@
 
 		case SSTATE_INTERNED_MORTAL:
 			/* revive dead object temporarily for DelItem */
-			op->ob_refcnt = 3;
+			Py_Refcnt(op) = 3;
 			if (PyDict_DelItem(interned, op) != 0)
 				Py_FatalError(
 					"deletion of interned string failed");
@@ -533,7 +533,7 @@
 		default:
 			Py_FatalError("Inconsistent interned string state.");
 	}
-	op->ob_type->tp_free(op);
+	Py_Type(op)->tp_free(op);
 }
 
 /* Unescape a backslash-escaped string. If unicode is non-zero,
@@ -717,7 +717,7 @@
 {
 	if (!PyString_Check(op))
 		return string_getsize(op);
-	return ((PyStringObject *)op) -> ob_size;
+	return Py_Size(op);
 }
 
 /*const*/ char *
@@ -750,7 +750,7 @@
 		{
 			PyErr_Format(PyExc_TypeError,
 				     "expected string or Unicode object, "
-				     "%.200s found", obj->ob_type->tp_name);
+				     "%.200s found", Py_Type(obj)->tp_name);
 			return -1;
 		}
 	}
@@ -805,7 +805,7 @@
 	}
 	if (flags & Py_PRINT_RAW) {
 		char *data = op->ob_sval;
-		Py_ssize_t size = op->ob_size;
+		Py_ssize_t size = Py_Size(op);
 		while (size > INT_MAX) {
 			/* Very long strings cannot be written atomically.
 			 * But don't write exactly INT_MAX bytes at a time
@@ -826,12 +826,12 @@
 
 	/* figure out which quote to use; single is preferred */
 	quote = '\'';
-	if (memchr(op->ob_sval, '\'', op->ob_size) &&
-	    !memchr(op->ob_sval, '"', op->ob_size))
+	if (memchr(op->ob_sval, '\'', Py_Size(op)) &&
+	    !memchr(op->ob_sval, '"', Py_Size(op)))
 		quote = '"';
 
 	fputc(quote, fp);
-	for (i = 0; i < op->ob_size; i++) {
+	for (i = 0; i < Py_Size(op); i++) {
 		c = op->ob_sval[i];
 		if (c == quote || c == '\\')
 			fprintf(fp, "\\%c", c);
@@ -854,9 +854,9 @@
 PyString_Repr(PyObject *obj, int smartquotes)
 {
 	register PyStringObject* op = (PyStringObject*) obj;
-	size_t newsize = 2 + 4 * op->ob_size;
+	size_t newsize = 2 + 4 * Py_Size(op);
 	PyObject *v;
-	if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {
+	if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_Size(op)) {
 		PyErr_SetString(PyExc_OverflowError,
 			"string is too large to make repr");
 	}
@@ -873,13 +873,13 @@
 		/* figure out which quote to use; single is preferred */
 		quote = '\'';
 		if (smartquotes &&
-		    memchr(op->ob_sval, '\'', op->ob_size) &&
-		    !memchr(op->ob_sval, '"', op->ob_size))
+		    memchr(op->ob_sval, '\'', Py_Size(op)) &&
+		    !memchr(op->ob_sval, '"', Py_Size(op)))
 			quote = '"';
 
 		p = PyString_AS_STRING(v);
 		*p++ = quote;
-		for (i = 0; i < op->ob_size; i++) {
+		for (i = 0; i < Py_Size(op); i++) {
 			/* There's at least enough room for a hex escape
 			   and a closing quote. */
 			assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
@@ -928,14 +928,14 @@
 	else {
 		/* Subtype -- return genuine string with the same value. */
 		PyStringObject *t = (PyStringObject *) s;
-		return PyString_FromStringAndSize(t->ob_sval, t->ob_size);
+		return PyString_FromStringAndSize(t->ob_sval, Py_Size(t));
 	}
 }
 
 static Py_ssize_t
 string_length(PyStringObject *a)
 {
-	return a->ob_size;
+	return Py_Size(a);
 }
 
 static PyObject *
@@ -950,21 +950,21 @@
 #endif
 		PyErr_Format(PyExc_TypeError,
 			     "cannot concatenate 'str' and '%.200s' objects",
-			     bb->ob_type->tp_name);
+			     Py_Type(bb)->tp_name);
 		return NULL;
 	}
 #define b ((PyStringObject *)bb)
 	/* Optimize cases with empty left or right operand */
-	if ((a->ob_size == 0 || b->ob_size == 0) &&
+	if ((Py_Size(a) == 0 || Py_Size(b) == 0) &&
 	    PyString_CheckExact(a) && PyString_CheckExact(b)) {
-		if (a->ob_size == 0) {
+		if (Py_Size(a) == 0) {
 			Py_INCREF(bb);
 			return bb;
 		}
 		Py_INCREF(a);
 		return (PyObject *)a;
 	}
-	size = a->ob_size + b->ob_size;
+	size = Py_Size(a) + Py_Size(b);
 	if (size < 0) {
 		PyErr_SetString(PyExc_OverflowError,
 				"strings are too large to concat");
@@ -978,8 +978,8 @@
 	PyObject_INIT_VAR(op, &PyString_Type, size);
 	op->ob_shash = -1;
 	op->ob_sstate = SSTATE_NOT_INTERNED;
-	Py_MEMCPY(op->ob_sval, a->ob_sval, a->ob_size);
-	Py_MEMCPY(op->ob_sval + a->ob_size, b->ob_sval, b->ob_size);
+	Py_MEMCPY(op->ob_sval, a->ob_sval, Py_Size(a));
+	Py_MEMCPY(op->ob_sval + Py_Size(a), b->ob_sval, Py_Size(b));
 	op->ob_sval[size] = '\0';
 	return (PyObject *) op;
 #undef b
@@ -998,13 +998,13 @@
 	/* watch out for overflows:  the size can overflow int,
 	 * and the # of bytes needed can overflow size_t
 	 */
-	size = a->ob_size * n;
-	if (n && size / n != a->ob_size) {
+	size = Py_Size(a) * n;
+	if (n && size / n != Py_Size(a)) {
 		PyErr_SetString(PyExc_OverflowError,
 			"repeated string is too long");
 		return NULL;
 	}
-	if (size == a->ob_size && PyString_CheckExact(a)) {
+	if (size == Py_Size(a) && PyString_CheckExact(a)) {
 		Py_INCREF(a);
 		return (PyObject *)a;
 	}
@@ -1022,14 +1022,14 @@
 	op->ob_shash = -1;
 	op->ob_sstate = SSTATE_NOT_INTERNED;
 	op->ob_sval[size] = '\0';
-	if (a->ob_size == 1 && n > 0) {
+	if (Py_Size(a) == 1 && n > 0) {
 		memset(op->ob_sval, a->ob_sval[0] , n);
 		return (PyObject *) op;
 	}
 	i = 0;
 	if (i < size) {
-		Py_MEMCPY(op->ob_sval, a->ob_sval, a->ob_size);
-		i = a->ob_size;
+		Py_MEMCPY(op->ob_sval, a->ob_sval, Py_Size(a));
+		i = Py_Size(a);
 	}
 	while (i < size) {
 		j = (i <= size-i)  ?  i  :  size-i;
@@ -1050,9 +1050,9 @@
 		i = 0;
 	if (j < 0)
 		j = 0; /* Avoid signed/unsigned bug in next line */
-	if (j > a->ob_size)
-		j = a->ob_size;
-	if (i == 0 && j == a->ob_size && PyString_CheckExact(a)) {
+	if (j > Py_Size(a))
+		j = Py_Size(a);
+	if (i == 0 && j == Py_Size(a) && PyString_CheckExact(a)) {
 		/* It's the same as a */
 		Py_INCREF(a);
 		return (PyObject *)a;
@@ -1073,7 +1073,7 @@
 		if (!PyString_Check(sub_obj)) {
 			PyErr_Format(PyExc_TypeError,
 			    "'in <string>' requires string as left operand, "
-			    "not %.200s", sub_obj->ob_type->tp_name);
+			    "not %.200s", Py_Type(sub_obj)->tp_name);
 			return -1;
 		}
 	}
@@ -1086,7 +1086,7 @@
 {
 	char pchar;
 	PyObject *v;
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		PyErr_SetString(PyExc_IndexError, "string index out of range");
 		return NULL;
 	}
@@ -1129,16 +1129,16 @@
 	if (op == Py_EQ) {
 		/* Supporting Py_NE here as well does not save
 		   much time, since Py_NE is rarely used.  */
-		if (a->ob_size == b->ob_size
+		if (Py_Size(a) == Py_Size(b)
 		    && (a->ob_sval[0] == b->ob_sval[0]
-			&& memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0)) {
+			&& memcmp(a->ob_sval, b->ob_sval, Py_Size(a)) == 0)) {
 			result = Py_True;
 		} else {
 			result = Py_False;
 		}
 		goto out;
 	}
-	len_a = a->ob_size; len_b = b->ob_size;
+	len_a = Py_Size(a); len_b = Py_Size(b);
 	min_len = (len_a < len_b) ? len_a : len_b;
 	if (min_len > 0) {
 		c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
@@ -1170,9 +1170,9 @@
 {
 	PyStringObject *a = (PyStringObject*) o1;
 	PyStringObject *b = (PyStringObject*) o2;
-        return a->ob_size == b->ob_size
+        return Py_Size(a) == Py_Size(b)
           && *a->ob_sval == *b->ob_sval
-          && memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0;
+          && memcmp(a->ob_sval, b->ob_sval, Py_Size(a)) == 0;
 }
 
 static long
@@ -1184,12 +1184,12 @@
 
 	if (a->ob_shash != -1)
 		return a->ob_shash;
-	len = a->ob_size;
+	len = Py_Size(a);
 	p = (unsigned char *) a->ob_sval;
 	x = *p << 7;
 	while (--len >= 0)
 		x = (1000003*x) ^ *p++;
-	x ^= a->ob_size;
+	x ^= Py_Size(a);
 	if (x == -1)
 		x = -2;
 	a->ob_shash = x;
@@ -1222,6 +1222,17 @@
 		if (slicelength <= 0) {
 			return PyString_FromStringAndSize("", 0);
 		}
+		else if (start == 0 && step == 1 &&
+			 slicelength == PyString_GET_SIZE(self) &&
+			 PyString_CheckExact(self)) {
+			Py_INCREF(self);
+			return (PyObject *)self;
+		}
+		else if (step == 1) {
+			return PyString_FromStringAndSize(
+				PyString_AS_STRING(self) + start,
+				slicelength);
+		}
 		else {
 			source_buf = PyString_AsString((PyObject*)self);
 			result_buf = (char *)PyMem_Malloc(slicelength);
@@ -1242,7 +1253,7 @@
 	else {
 		PyErr_Format(PyExc_TypeError,
 			     "string indices must be integers, not %.200s",
-			     item->ob_type->tp_name);
+			     Py_Type(item)->tp_name);
 		return NULL;
 	}
 }
@@ -1256,7 +1267,7 @@
 		return -1;
 	}
 	*ptr = (void *)self->ob_sval;
-	return self->ob_size;
+	return Py_Size(self);
 }
 
 static Py_ssize_t
@@ -1271,7 +1282,7 @@
 string_buffer_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
 {
 	if ( lenp )
-		*lenp = self->ob_size;
+		*lenp = Py_Size(self);
 	return 1;
 }
 
@@ -1284,7 +1295,7 @@
 		return -1;
 	}
 	*ptr = self->ob_sval;
-	return self->ob_size;
+	return Py_Size(self);
 }
 
 static PySequenceMethods string_as_sequence = {
@@ -1373,7 +1384,7 @@
 	count++; }
 
 /* Always force the list to the expected size. */
-#define FIX_PREALLOC_SIZE(list) ((PyListObject *)list)->ob_size = count
+#define FIX_PREALLOC_SIZE(list) Py_Size(list) = count
 
 #define SKIP_SPACE(s, i, len)    { while (i<len &&  isspace(Py_CHARMASK(s[i]))) i++; }
 #define SKIP_NONSPACE(s, i, len) { while (i<len && !isspace(Py_CHARMASK(s[i]))) i++; }
@@ -1788,7 +1799,7 @@
 			PyErr_Format(PyExc_TypeError,
 				     "sequence item %zd: expected string,"
 				     " %.80s found",
-				     i, item->ob_type->tp_name);
+				     i, Py_Type(item)->tp_name);
 			Py_DECREF(seq);
 			return NULL;
 		}
@@ -1891,7 +1902,7 @@
 "S.find(sub [,start [,end]]) -> int\n\
 \n\
 Return the lowest index in S where substring sub is found,\n\
-such that sub is contained within s[start,end].  Optional\n\
+such that sub is contained within s[start:end].  Optional\n\
 arguments start and end are interpreted as in slice notation.\n\
 \n\
 Return -1 on failure.");
@@ -1930,7 +1941,7 @@
 "S.rfind(sub [,start [,end]]) -> int\n\
 \n\
 Return the highest index in S where substring sub is found,\n\
-such that sub is contained within s[start,end].  Optional\n\
+such that sub is contained within s[start:end].  Optional\n\
 arguments start and end are interpreted as in slice notation.\n\
 \n\
 Return -1 on failure.");
@@ -3248,7 +3259,7 @@
         PyErr_Format(PyExc_TypeError,
                      "encoder did not return a string/unicode object "
                      "(type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         return NULL;
     }
@@ -3285,7 +3296,7 @@
         PyErr_Format(PyExc_TypeError,
                      "decoder did not return a string/unicode object "
                      "(type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         return NULL;
     }
@@ -3843,7 +3854,7 @@
 static PyObject *
 string_getnewargs(PyStringObject *v)
 {
-	return Py_BuildValue("(s#)", v->ob_sval, v->ob_size);
+	return Py_BuildValue("(s#)", v->ob_sval, Py_Size(v));
 }
 
 
@@ -3972,8 +3983,7 @@
 
 
 PyTypeObject PyBaseString_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"basestring",
 	0,
 	0,
@@ -4021,8 +4031,7 @@
 If the argument is a string, the return value is the same object.");
 
 PyTypeObject PyString_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"str",
 	sizeof(PyStringObject),
 	sizeof(char),
@@ -4108,7 +4117,7 @@
 	register PyObject *v;
 	register PyStringObject *sv;
 	v = *pv;
-	if (!PyString_Check(v) || v->ob_refcnt != 1 || newsize < 0 ||
+	if (!PyString_Check(v) || Py_Refcnt(v) != 1 || newsize < 0 ||
 	    PyString_CHECK_INTERNED(v)) {
 		*pv = 0;
 		Py_DECREF(v);
@@ -4127,7 +4136,7 @@
 	}
 	_Py_NewReference(*pv);
 	sv = (PyStringObject *) *pv;
-	sv->ob_size = newsize;
+	Py_Size(sv) = newsize;
 	sv->ob_sval[newsize] = '\0';
 	sv->ob_shash = -1;	/* invalidate cached hash value */
 	return 0;
@@ -4175,7 +4184,7 @@
 	x = PyFloat_AsDouble(v);
 	if (x == -1.0 && PyErr_Occurred()) {
 		PyErr_Format(PyExc_TypeError, "float argument required, "
-			     "not %.200s", v->ob_type->tp_name);
+			     "not %.200s", Py_Type(v)->tp_name);
 		return -1;
 	}
 	if (prec < 0)
@@ -4198,7 +4207,8 @@
 	   always given), therefore increase the length by one.
 
 	*/
-	if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) ||
+	if (((type == 'g' || type == 'G') &&
+              buflen <= (size_t)10 + (size_t)prec) ||
 	    (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
 		PyErr_SetString(PyExc_OverflowError,
 			"formatted float is too long (precision too large?)");
@@ -4248,15 +4258,15 @@
 	switch (type) {
 	case 'd':
 	case 'u':
-		result = val->ob_type->tp_str(val);
+		result = Py_Type(val)->tp_str(val);
 		break;
 	case 'o':
-		result = val->ob_type->tp_as_number->nb_oct(val);
+		result = Py_Type(val)->tp_as_number->nb_oct(val);
 		break;
 	case 'x':
 	case 'X':
 		numnondigits = 2;
-		result = val->ob_type->tp_as_number->nb_hex(val);
+		result = Py_Type(val)->tp_as_number->nb_hex(val);
 		break;
 	default:
 		assert(!"'type' not in [duoxX]");
@@ -4271,7 +4281,7 @@
 	}
 
 	/* To modify the string in-place, there can only be one reference. */
-	if (result->ob_refcnt != 1) {
+	if (Py_Refcnt(result) != 1) {
 		PyErr_BadInternalCall();
 		return NULL;
 	}
@@ -4371,7 +4381,7 @@
 	x = PyInt_AsLong(v);
 	if (x == -1 && PyErr_Occurred()) {
 		PyErr_Format(PyExc_TypeError, "int argument required, not %.200s",
-			     v->ob_type->tp_name);
+			     Py_Type(v)->tp_name);
 		return -1;
 	}
 	if (x < 0 && type == 'u') {
@@ -4488,7 +4498,7 @@
 		arglen = -1;
 		argidx = -2;
 	}
-	if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) &&
+	if (Py_Type(args)->tp_as_mapping && !PyTuple_Check(args) &&
 	    !PyObject_TypeCheck(args, &PyBaseString_Type))
 		dict = args;
 	while (--fmtcnt >= 0) {
@@ -4955,7 +4965,7 @@
 	}
 	/* The two references in interned are not counted by refcnt.
 	   The string deallocator will take care of this */
-	s->ob_refcnt -= 2;
+	Py_Refcnt(s) -= 2;
 	PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;
 }
 
@@ -5022,12 +5032,12 @@
 			/* XXX Shouldn't happen */
 			break;
 		case SSTATE_INTERNED_IMMORTAL:
-			s->ob_refcnt += 1;
-			immortal_size += s->ob_size;
+			Py_Refcnt(s) += 1;
+			immortal_size += Py_Size(s);
 			break;
 		case SSTATE_INTERNED_MORTAL:
-			s->ob_refcnt += 2;
-			mortal_size += s->ob_size;
+			Py_Refcnt(s) += 2;
+			mortal_size += Py_Size(s);
 			break;
 		default:
 			Py_FatalError("Inconsistent interned string state.");

Modified: python/branches/bcannon-objcap/Objects/structseq.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/structseq.c	(original)
+++ python/branches/bcannon-objcap/Objects/structseq.c	Thu Sep  6 21:35:45 2007
@@ -13,17 +13,17 @@
    They are only allowed for indices < n_visible_fields. */
 char *PyStructSequence_UnnamedField = "unnamed field";
 
-#define VISIBLE_SIZE(op) ((op)->ob_size)
+#define VISIBLE_SIZE(op) Py_Size(op)
 #define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, visible_length_key))
 
 #define REAL_SIZE_TP(tp) PyInt_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, real_length_key))
-#define REAL_SIZE(op) REAL_SIZE_TP((op)->ob_type)
+#define REAL_SIZE(op) REAL_SIZE_TP(Py_Type(op))
 
 #define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
-#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP((op)->ob_type)
+#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_Type(op))
 
 
 PyObject *
@@ -32,7 +32,7 @@
 	PyStructSequence *obj;
        
 	obj = PyObject_New(PyStructSequence, type);
-	obj->ob_size = VISIBLE_SIZE_TP(type);
+	Py_Size(obj) = VISIBLE_SIZE_TP(type);
 
 	return (PyObject*) obj;
 }
@@ -90,6 +90,54 @@
 }
 
 static PyObject *
+structseq_subscript(PyStructSequence *self, PyObject *item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+
+		if (i < 0)
+			i += VISIBLE_SIZE(self);
+
+		if (i < 0 || i >= VISIBLE_SIZE(self)) {
+			PyErr_SetString(PyExc_IndexError,
+				"tuple index out of range");
+			return NULL;
+		}
+		Py_INCREF(self->ob_item[i]);
+		return self->ob_item[i];
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelen, cur, i;
+		PyObject *result;
+		
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 VISIBLE_SIZE(self), &start, &stop,
+					 &step, &slicelen) < 0) {
+			return NULL;
+		}
+		if (slicelen <= 0)
+			return PyTuple_New(0);
+		result = PyTuple_New(slicelen);
+		if (result == NULL)
+			return NULL;
+		for (cur = start, i = 0; i < slicelen;
+		     cur += step, i++) {
+			PyObject *v = self->ob_item[cur];
+			Py_INCREF(v);
+			PyTuple_SET_ITEM(result, i, v);
+		}
+		return result;
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"structseq index must be integer");
+		return NULL;
+	}
+}
+
+static PyObject *
 structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
 	PyObject *arg = NULL;
@@ -274,12 +322,12 @@
 	}
 	
 	for (; i < n_fields; i++) {
-		char *n = self->ob_type->tp_members[i-n_unnamed_fields].name;
+		char *n = Py_Type(self)->tp_members[i-n_unnamed_fields].name;
 		PyDict_SetItemString(dict, n,
 				     self->ob_item[i]);
 	}
 
-	result = Py_BuildValue("(O(OO))", self->ob_type, tup, dict);
+	result = Py_BuildValue("(O(OO))", Py_Type(self), tup, dict);
 
 	Py_DECREF(tup);
 	Py_DECREF(dict);
@@ -298,6 +346,11 @@
 	(objobjproc)structseq_contains,	        /* sq_contains */
 };
 
+static PyMappingMethods structseq_as_mapping = {
+	(lenfunc)structseq_length,
+	(binaryfunc)structseq_subscript,
+};
+
 static PyMethodDef structseq_methods[] = {
 	{"__reduce__", (PyCFunction)structseq_reduce, 
 	 METH_NOARGS, NULL},
@@ -305,8 +358,7 @@
 };
 
 static PyTypeObject _struct_sequence_template = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	NULL,	                     		/* tp_name */
         0,		                        /* tp_basicsize */
 	0,	                      		/* tp_itemsize */
@@ -318,7 +370,7 @@
 	(reprfunc)structseq_repr,             	/* tp_repr */
 	0,					/* tp_as_number */
 	&structseq_as_sequence,			/* tp_as_sequence */
-	0,					/* tp_as_mapping */
+	&structseq_as_mapping,			/* tp_as_mapping */
 	structseq_hash,				/* tp_hash */
 	0,              			/* tp_call */
 	0,					/* tp_str */

Modified: python/branches/bcannon-objcap/Objects/tupleobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/tupleobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/tupleobject.c	Thu Sep  6 21:35:45 2007
@@ -49,8 +49,8 @@
 #endif
 		/* Inline PyObject_InitVar */
 #ifdef Py_TRACE_REFS
-		op->ob_size = size;
-		op->ob_type = &PyTuple_Type;
+		Py_Size(op) = size;
+		Py_Type(op) = &PyTuple_Type;
 #endif
 		_Py_NewReference((PyObject *)op);
 	}
@@ -90,7 +90,7 @@
 		return -1;
 	}
 	else
-		return ((PyTupleObject *)op)->ob_size;
+		return Py_Size(op);
 }
 
 PyObject *
@@ -100,7 +100,7 @@
 		PyErr_BadInternalCall();
 		return NULL;
 	}
-	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
+	if (i < 0 || i >= Py_Size(op)) {
 		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
 		return NULL;
 	}
@@ -117,7 +117,7 @@
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
+	if (i < 0 || i >= Py_Size(op)) {
 		Py_XDECREF(newitem);
 		PyErr_SetString(PyExc_IndexError,
 				"tuple assignment index out of range");
@@ -160,7 +160,7 @@
 tupledealloc(register PyTupleObject *op)
 {
 	register Py_ssize_t i;
-	register Py_ssize_t len =  op->ob_size;
+	register Py_ssize_t len =  Py_Size(op);
 	PyObject_GC_UnTrack(op);
 	Py_TRASHCAN_SAFE_BEGIN(op)
 	if (len > 0) {
@@ -170,7 +170,7 @@
 #if MAXSAVESIZE > 0
 		if (len < MAXSAVESIZE &&
 		    num_free_tuples[len] < MAXSAVEDTUPLES &&
-		    op->ob_type == &PyTuple_Type)
+		    Py_Type(op) == &PyTuple_Type)
 		{
 			op->ob_item[0] = (PyObject *) free_tuples[len];
 			num_free_tuples[len]++;
@@ -179,7 +179,7 @@
 		}
 #endif
 	}
-	op->ob_type->tp_free((PyObject *)op);
+	Py_Type(op)->tp_free((PyObject *)op);
 done:
 	Py_TRASHCAN_SAFE_END(op)
 }
@@ -189,13 +189,13 @@
 {
 	Py_ssize_t i;
 	fprintf(fp, "(");
-	for (i = 0; i < op->ob_size; i++) {
+	for (i = 0; i < Py_Size(op); i++) {
 		if (i > 0)
 			fprintf(fp, ", ");
 		if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
 			return -1;
 	}
-	if (op->ob_size == 1)
+	if (Py_Size(op) == 1)
 		fprintf(fp, ",");
 	fprintf(fp, ")");
 	return 0;
@@ -208,7 +208,7 @@
 	PyObject *s, *temp;
 	PyObject *pieces, *result = NULL;
 
-	n = v->ob_size;
+	n = Py_Size(v);
 	if (n == 0)
 		return PyString_FromString("()");
 
@@ -268,7 +268,7 @@
 tuplehash(PyTupleObject *v)
 {
 	register long x, y;
-	register Py_ssize_t len = v->ob_size;
+	register Py_ssize_t len = Py_Size(v);
 	register PyObject **p;
 	long mult = 1000003L;
 	x = 0x345678L;
@@ -290,7 +290,7 @@
 static Py_ssize_t
 tuplelength(PyTupleObject *a)
 {
-	return a->ob_size;
+	return Py_Size(a);
 }
 
 static int
@@ -299,7 +299,7 @@
 	Py_ssize_t i;
 	int cmp;
 
-	for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
+	for (i = 0, cmp = 0 ; cmp == 0 && i < Py_Size(a); ++i)
 		cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
 						   Py_EQ);
 	return cmp;
@@ -308,7 +308,7 @@
 static PyObject *
 tupleitem(register PyTupleObject *a, register Py_ssize_t i)
 {
-	if (i < 0 || i >= a->ob_size) {
+	if (i < 0 || i >= Py_Size(a)) {
 		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
 		return NULL;
 	}
@@ -326,11 +326,11 @@
 	Py_ssize_t len;
 	if (ilow < 0)
 		ilow = 0;
-	if (ihigh > a->ob_size)
-		ihigh = a->ob_size;
+	if (ihigh > Py_Size(a))
+		ihigh = Py_Size(a);
 	if (ihigh < ilow)
 		ihigh = ilow;
-	if (ilow == 0 && ihigh == a->ob_size && PyTuple_CheckExact(a)) {
+	if (ilow == 0 && ihigh == Py_Size(a) && PyTuple_CheckExact(a)) {
 		Py_INCREF(a);
 		return (PyObject *)a;
 	}
@@ -368,11 +368,11 @@
 	if (!PyTuple_Check(bb)) {
 		PyErr_Format(PyExc_TypeError,
        		     "can only concatenate tuple (not \"%.200s\") to tuple",
-			     bb->ob_type->tp_name);
+			     Py_Type(bb)->tp_name);
 		return NULL;
 	}
 #define b ((PyTupleObject *)bb)
-	size = a->ob_size + b->ob_size;
+	size = Py_Size(a) + Py_Size(b);
 	if (size < 0)
 		return PyErr_NoMemory();
 	np = (PyTupleObject *) PyTuple_New(size);
@@ -381,14 +381,14 @@
 	}
 	src = a->ob_item;
 	dest = np->ob_item;
-	for (i = 0; i < a->ob_size; i++) {
+	for (i = 0; i < Py_Size(a); i++) {
 		PyObject *v = src[i];
 		Py_INCREF(v);
 		dest[i] = v;
 	}
 	src = b->ob_item;
-	dest = np->ob_item + a->ob_size;
-	for (i = 0; i < b->ob_size; i++) {
+	dest = np->ob_item + Py_Size(a);
+	for (i = 0; i < Py_Size(b); i++) {
 		PyObject *v = src[i];
 		Py_INCREF(v);
 		dest[i] = v;
@@ -406,18 +406,18 @@
 	PyObject **p, **items;
 	if (n < 0)
 		n = 0;
-	if (a->ob_size == 0 || n == 1) {
+	if (Py_Size(a) == 0 || n == 1) {
 		if (PyTuple_CheckExact(a)) {
 			/* Since tuples are immutable, we can return a shared
 			   copy in this case */
 			Py_INCREF(a);
 			return (PyObject *)a;
 		}
-		if (a->ob_size == 0)
+		if (Py_Size(a) == 0)
 			return PyTuple_New(0);
 	}
-	size = a->ob_size * n;
-	if (size/a->ob_size != n)
+	size = Py_Size(a) * n;
+	if (size/Py_Size(a) != n)
 		return PyErr_NoMemory();
 	np = (PyTupleObject *) PyTuple_New(size);
 	if (np == NULL)
@@ -425,7 +425,7 @@
 	p = np->ob_item;
 	items = a->ob_item;
 	for (i = 0; i < n; i++) {
-		for (j = 0; j < a->ob_size; j++) {
+		for (j = 0; j < Py_Size(a); j++) {
 			*p = items[j];
 			Py_INCREF(*p);
 			p++;
@@ -439,7 +439,7 @@
 {
 	Py_ssize_t i;
 
-	for (i = o->ob_size; --i >= 0; )
+	for (i = Py_Size(o); --i >= 0; )
 		Py_VISIT(o->ob_item[i]);
 	return 0;
 }
@@ -459,8 +459,8 @@
 	vt = (PyTupleObject *)v;
 	wt = (PyTupleObject *)w;
 
-	vlen = vt->ob_size;
-	wlen = wt->ob_size;
+	vlen = Py_Size(vt);
+	wlen = Py_Size(wt);
 
 	/* Note:  the corresponding code for lists has an "early out" test
 	 * here when op is EQ or NE and the lengths differ.  That pays there,
@@ -603,6 +603,12 @@
 		if (slicelength <= 0) {
 			return PyTuple_New(0);
 		}
+		else if (start == 0 && step == 1 &&
+			 slicelength == PyTuple_GET_SIZE(self) &&
+			 PyTuple_CheckExact(self)) {
+			Py_INCREF(self);
+			return (PyObject *)self;
+		}
 		else {
 			result = PyTuple_New(slicelength);
 			if (!result) return NULL;
@@ -622,7 +628,7 @@
 	else {
 		PyErr_Format(PyExc_TypeError, 
 			     "tuple indices must be integers, not %.200s",
-			     item->ob_type->tp_name);
+			     Py_Type(item)->tp_name);
 		return NULL;
 	}
 }
@@ -630,7 +636,7 @@
 static PyObject *
 tuple_getnewargs(PyTupleObject *v)
 {
-	return Py_BuildValue("(N)", tupleslice(v, 0, v->ob_size));
+	return Py_BuildValue("(N)", tupleslice(v, 0, Py_Size(v)));
 	
 }
 
@@ -648,8 +654,7 @@
 static PyObject *tuple_iter(PyObject *seq);
 
 PyTypeObject PyTuple_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"tuple",
 	sizeof(PyTupleObject) - sizeof(PyObject *),
 	sizeof(PyObject *),
@@ -707,14 +712,14 @@
 	Py_ssize_t oldsize;
 
 	v = (PyTupleObject *) *pv;
-	if (v == NULL || v->ob_type != &PyTuple_Type ||
-	    (v->ob_size != 0 && v->ob_refcnt != 1)) {
+	if (v == NULL || Py_Type(v) != &PyTuple_Type ||
+	    (Py_Size(v) != 0 && Py_Refcnt(v) != 1)) {
 		*pv = 0;
 		Py_XDECREF(v);
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	oldsize = v->ob_size;
+	oldsize = Py_Size(v);
 	if (oldsize == newsize)
 		return 0;
 
@@ -838,8 +843,7 @@
 };
 
 PyTypeObject PyTupleIter_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"tupleiterator",			/* tp_name */
 	sizeof(tupleiterobject),		/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/typeobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/typeobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/typeobject.c	Thu Sep  6 21:35:45 2007
@@ -57,7 +57,7 @@
 	if (!PyString_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 			     "can only assign string to %s.__name__, not '%s'",
-			     type->tp_name, value->ob_type->tp_name);
+			     type->tp_name, Py_Type(value)->tp_name);
 		return -1;
 	}
 	if (strlen(PyString_AS_STRING(value))
@@ -203,7 +203,7 @@
 	if (!PyTuple_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 		     "can only assign tuple to %s.__bases__, not %s",
-			     type->tp_name, value->ob_type->tp_name);
+			     type->tp_name, Py_Type(value)->tp_name);
 		return -1;
 	}
 	if (PyTuple_GET_SIZE(value) == 0) {
@@ -218,7 +218,7 @@
 			PyErr_Format(
 				PyExc_TypeError,
 	"%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
-				type->tp_name, ob->ob_type->tp_name);
+				type->tp_name, Py_Type(ob)->tp_name);
 			return -1;
 		}
 		if (PyType_Check(ob)) {
@@ -343,8 +343,8 @@
 		result = Py_None;
 		Py_INCREF(result);
 	}
-	else if (result->ob_type->tp_descr_get) {
-		result = result->ob_type->tp_descr_get(result, NULL,
+	else if (Py_Type(result)->tp_descr_get) {
+		result = Py_Type(result)->tp_descr_get(result, NULL,
 						       (PyObject *)type);
 	}
 	else {
@@ -488,7 +488,7 @@
 	Py_ssize_t i, n;
 	PyMemberDef *mp;
 
-	n = type->ob_size;
+	n = Py_Size(type);
 	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
 	for (i = 0; i < n; i++, mp++) {
 		if (mp->type == T_OBJECT_EX) {
@@ -512,10 +512,10 @@
 
 	/* Find the nearest base with a different tp_traverse,
 	   and traverse slots while we're at it */
-	type = self->ob_type;
+	type = Py_Type(self);
 	base = type;
 	while ((basetraverse = base->tp_traverse) == subtype_traverse) {
-		if (base->ob_size) {
+		if (Py_Size(base)) {
 			int err = traverse_slots(base, self, visit, arg);
 			if (err)
 				return err;
@@ -547,7 +547,7 @@
 	Py_ssize_t i, n;
 	PyMemberDef *mp;
 
-	n = type->ob_size;
+	n = Py_Size(type);
 	mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
 	for (i = 0; i < n; i++, mp++) {
 		if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
@@ -569,10 +569,10 @@
 
 	/* Find the nearest base with a different tp_clear
 	   and clear slots while we're at it */
-	type = self->ob_type;
+	type = Py_Type(self);
 	base = type;
 	while ((baseclear = base->tp_clear) == subtype_clear) {
-		if (base->ob_size)
+		if (Py_Size(base))
 			clear_slots(base, self);
 		base = base->tp_base;
 		assert(base);
@@ -593,7 +593,7 @@
 	destructor basedealloc;
 
 	/* Extract the type; we expect it to be a heap type */
-	type = self->ob_type;
+	type = Py_Type(self);
 	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
 
 	/* Test whether the type has GC exactly once */
@@ -615,7 +615,7 @@
 		/* Find the nearest base with a different tp_dealloc */
 		base = type;
 		while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
-			assert(base->ob_size == 0);
+			assert(Py_Size(base) == 0);
 			base = base->tp_base;
 			assert(base);
 		}
@@ -683,7 +683,7 @@
 	/*  Clear slots up to the nearest base with a different tp_dealloc */
 	base = type;
 	while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
-		if (base->ob_size)
+		if (Py_Size(base))
 			clear_slots(base, self);
 		base = base->tp_base;
 		assert(base);
@@ -877,13 +877,13 @@
 		if (*attrobj == NULL)
 			return NULL;
 	}
-	res = _PyType_Lookup(self->ob_type, *attrobj);
+	res = _PyType_Lookup(Py_Type(self), *attrobj);
 	if (res != NULL) {
 		descrgetfunc f;
-		if ((f = res->ob_type->tp_descr_get) == NULL)
+		if ((f = Py_Type(res)->tp_descr_get) == NULL)
 			Py_INCREF(res);
 		else
-			res = f(res, self, (PyObject *)(self->ob_type));
+			res = f(res, self, (PyObject *)(Py_Type(self)));
 	}
 	return res;
 }
@@ -1301,7 +1301,7 @@
 	PyObject *mro, *result, *tuple;
 	int checkit = 0;
 
-	if (type->ob_type == &PyType_Type) {
+	if (Py_Type(type) == &PyType_Type) {
 		result = mro_implementation(type);
 	}
 	else {
@@ -1336,7 +1336,7 @@
 			else if (!PyType_Check(cls)) {
 				PyErr_Format(PyExc_TypeError,
 			     "mro() returned a non-class ('%.500s')",
-					     cls->ob_type->tp_name);
+					     Py_Type(cls)->tp_name);
 				Py_DECREF(tuple);
 				return -1;
 			}
@@ -1565,7 +1565,7 @@
 	if (value != NULL && !PyDict_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 			     "__dict__ must be set to a dictionary, "
-			     "not a '%.200s'", value->ob_type->tp_name);
+			     "not a '%.200s'", Py_Type(value)->tp_name);
 		return -1;
 	}
 	dict = *dictptr;
@@ -1581,16 +1581,16 @@
 	PyObject **weaklistptr;
 	PyObject *result;
 
-	if (obj->ob_type->tp_weaklistoffset == 0) {
+	if (Py_Type(obj)->tp_weaklistoffset == 0) {
 		PyErr_SetString(PyExc_AttributeError,
 				"This object has no __weakref__");
 		return NULL;
 	}
-	assert(obj->ob_type->tp_weaklistoffset > 0);
-	assert(obj->ob_type->tp_weaklistoffset + sizeof(PyObject *) <=
-	       (size_t)(obj->ob_type->tp_basicsize));
+	assert(Py_Type(obj)->tp_weaklistoffset > 0);
+	assert(Py_Type(obj)->tp_weaklistoffset + sizeof(PyObject *) <=
+	       (size_t)(Py_Type(obj)->tp_basicsize));
 	weaklistptr = (PyObject **)
-		((char *)obj + obj->ob_type->tp_weaklistoffset);
+		((char *)obj + Py_Type(obj)->tp_weaklistoffset);
 	if (*weaklistptr == NULL)
 		result = Py_None;
 	else
@@ -1630,7 +1630,7 @@
 	if (!PyString_Check(s)) {
 		PyErr_Format(PyExc_TypeError,
 			     "__slots__ items must be strings, not '%.200s'",
-			     s->ob_type->tp_name);
+			     Py_Type(s)->tp_name);
 		return 0;
 	}
 	p = (unsigned char *) PyString_AS_STRING(s);
@@ -1740,8 +1740,8 @@
 
 		if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
 			PyObject *x = PyTuple_GET_ITEM(args, 0);
-			Py_INCREF(x->ob_type);
-			return (PyObject *) x->ob_type;
+			Py_INCREF(Py_Type(x));
+			return (PyObject *) Py_Type(x);
 		}
 
 		/* SF bug 475327 -- if that didn't trigger, we need 3
@@ -2176,7 +2176,7 @@
 static PyObject *
 type_getattro(PyTypeObject *type, PyObject *name)
 {
-	PyTypeObject *metatype = type->ob_type;
+	PyTypeObject *metatype = Py_Type(type);
 	PyObject *meta_attribute, *attribute;
 	descrgetfunc meta_get;
 
@@ -2193,7 +2193,7 @@
 	meta_attribute = _PyType_Lookup(metatype, name);
 
 	if (meta_attribute != NULL) {
-		meta_get = meta_attribute->ob_type->tp_descr_get;
+		meta_get = Py_Type(meta_attribute)->tp_descr_get;
 
 		if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
 			/* Data descriptors implement tp_descr_set to intercept
@@ -2211,7 +2211,7 @@
 	attribute = _PyType_Lookup(type, name);
 	if (attribute != NULL) {
 		/* Implement descriptor functionality, if any */
-		descrgetfunc local_get = attribute->ob_type->tp_descr_get;
+		descrgetfunc local_get = Py_Type(attribute)->tp_descr_get;
 
 		Py_XDECREF(meta_attribute);
 
@@ -2289,7 +2289,7 @@
 	PyObject_Free((char *)type->tp_doc);
 	Py_XDECREF(et->ht_name);
 	Py_XDECREF(et->ht_slots);
-	type->ob_type->tp_free((PyObject *)type);
+	Py_Type(type)->tp_free((PyObject *)type);
 }
 
 
@@ -2368,8 +2368,7 @@
 }
 
 PyTypeObject PyType_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"type",					/* tp_name */
 	sizeof(PyHeapTypeObject),		/* tp_basicsize */
 	sizeof(PyMemberDef),			/* tp_itemsize */
@@ -2471,7 +2470,7 @@
 {
 	int err = 0;
 	if (excess_args(args, kwds)) {
-		PyTypeObject *type = self->ob_type;
+		PyTypeObject *type = Py_Type(self);
 		if (type->tp_init != object_init &&
 		    type->tp_new != object_new)
 		{
@@ -2518,7 +2517,7 @@
 static void
 object_dealloc(PyObject *self)
 {
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyObject *
@@ -2527,7 +2526,7 @@
 	PyTypeObject *type;
 	PyObject *mod, *name, *rtn;
 
-	type = self->ob_type;
+	type = Py_Type(self);
 	mod = type_module(type, NULL);
 	if (mod == NULL)
 		PyErr_Clear();
@@ -2556,7 +2555,7 @@
 {
 	unaryfunc f;
 
-	f = self->ob_type->tp_repr;
+	f = Py_Type(self)->tp_repr;
 	if (f == NULL)
 		f = object_repr;
 	return f(self);
@@ -2571,8 +2570,8 @@
 static PyObject *
 object_get_class(PyObject *self, void *closure)
 {
-	Py_INCREF(self->ob_type);
-	return (PyObject *)(self->ob_type);
+	Py_INCREF(Py_Type(self));
+	return (PyObject *)(Py_Type(self));
 }
 
 static int
@@ -2657,7 +2656,7 @@
 static int
 object_set_class(PyObject *self, PyObject *value, void *closure)
 {
-	PyTypeObject *oldto = self->ob_type;
+	PyTypeObject *oldto = Py_Type(self);
 	PyTypeObject *newto;
 
 	if (value == NULL) {
@@ -2668,7 +2667,7 @@
 	if (!PyType_Check(value)) {
 		PyErr_Format(PyExc_TypeError,
 		  "__class__ must be set to new-style class, not '%s' object",
-		  value->ob_type->tp_name);
+		  Py_Type(value)->tp_name);
 		return -1;
 	}
 	newto = (PyTypeObject *)value;
@@ -2681,7 +2680,7 @@
 	}
 	if (compatible_for_assignment(newto, oldto, "__class__")) {
 		Py_INCREF(newto);
-		self->ob_type = newto;
+		Py_Type(self) = newto;
 		Py_DECREF(oldto);
 		return 0;
 	}
@@ -2777,7 +2776,7 @@
 		if (args != NULL && !PyTuple_Check(args)) {
 			PyErr_Format(PyExc_TypeError,
 				"__getnewargs__ should return a tuple, "
-				"not '%.200s'", args->ob_type->tp_name);
+				"not '%.200s'", Py_Type(args)->tp_name);
 			goto end;
 		}
 	}
@@ -2989,8 +2988,7 @@
 
 
 PyTypeObject PyBaseObject_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"object",				/* tp_name */
 	sizeof(PyObject),			/* tp_basicsize */
 	0,					/* tp_itemsize */
@@ -3432,8 +3430,8 @@
 	   NULL when type is &PyBaseObject_Type, and we know its ob_type is
 	   not NULL (it's initialized to &PyType_Type).	 But coverity doesn't
 	   know that. */
-	if (type->ob_type == NULL && base != NULL)
-		type->ob_type = base->ob_type;
+	if (Py_Type(type) == NULL && base != NULL)
+		Py_Type(type) = Py_Type(base);
 
 	/* Initialize tp_bases */
 	bases = type->tp_bases;
@@ -3793,7 +3791,7 @@
 	if (i == -1 && PyErr_Occurred())
 		return -1;
 	if (i < 0) {
-		PySequenceMethods *sq = self->ob_type->tp_as_sequence;
+		PySequenceMethods *sq = Py_Type(self)->tp_as_sequence;
 		if (sq && sq->sq_length) {
 			Py_ssize_t n = (*sq->sq_length)(self);
 			if (n < 0)
@@ -3969,14 +3967,14 @@
 	if (!check_num_args(args, 1))
 		return NULL;
 	other = PyTuple_GET_ITEM(args, 0);
-	if (other->ob_type->tp_compare != func &&
-	    !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+	if (Py_Type(other)->tp_compare != func &&
+	    !PyType_IsSubtype(Py_Type(other), Py_Type(self))) {
 		PyErr_Format(
 			PyExc_TypeError,
 			"%s.__cmp__(x,y) requires y to be a '%s', not a '%s'",
-			self->ob_type->tp_name,
-			self->ob_type->tp_name,
-			other->ob_type->tp_name);
+			Py_Type(self)->tp_name,
+			Py_Type(self)->tp_name,
+			Py_Type(other)->tp_name);
 		return NULL;
 	}
 	res = (*func)(self, other);
@@ -3990,7 +3988,7 @@
 static int
 hackcheck(PyObject *self, setattrofunc func, char *what)
 {
-	PyTypeObject *type = self->ob_type;
+	PyTypeObject *type = Py_Type(self);
 	while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
 		type = type->tp_base;
 	/* If type is NULL now, this is a really weird type.
@@ -4190,7 +4188,7 @@
 		PyErr_Format(PyExc_TypeError,
 			     "%s.__new__(X): X is not a type object (%s)",
 			     type->tp_name,
-			     arg0->ob_type->tp_name);
+			     Py_Type(arg0)->tp_name);
 		return NULL;
 	}
 	subtype = (PyTypeObject *)arg0;
@@ -4281,14 +4279,14 @@
 	PyObject *a, *b;
 	int ok;
 
-	b = PyObject_GetAttrString((PyObject *)(right->ob_type), name);
+	b = PyObject_GetAttrString((PyObject *)(Py_Type(right)), name);
 	if (b == NULL) {
 		PyErr_Clear();
 		/* If right doesn't have it, it's not overloaded */
 		return 0;
 	}
 
-	a = PyObject_GetAttrString((PyObject *)(left->ob_type), name);
+	a = PyObject_GetAttrString((PyObject *)(Py_Type(left)), name);
 	if (a == NULL) {
 		PyErr_Clear();
 		Py_DECREF(b);
@@ -4313,14 +4311,14 @@
 FUNCNAME(PyObject *self, PyObject *other) \
 { \
 	static PyObject *cache_str, *rcache_str; \
-	int do_other = self->ob_type != other->ob_type && \
-	    other->ob_type->tp_as_number != NULL && \
-	    other->ob_type->tp_as_number->SLOTNAME == TESTFUNC; \
-	if (self->ob_type->tp_as_number != NULL && \
-	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
+	int do_other = Py_Type(self) != Py_Type(other) && \
+	    Py_Type(other)->tp_as_number != NULL && \
+	    Py_Type(other)->tp_as_number->SLOTNAME == TESTFUNC; \
+	if (Py_Type(self)->tp_as_number != NULL && \
+	    Py_Type(self)->tp_as_number->SLOTNAME == TESTFUNC) { \
 		PyObject *r; \
 		if (do_other && \
-		    PyType_IsSubtype(other->ob_type, self->ob_type) && \
+		    PyType_IsSubtype(Py_Type(other), Py_Type(self)) && \
 		    method_is_overloaded(self, other, ROPSTR)) { \
 			r = call_maybe( \
 				other, ROPSTR, &rcache_str, "(O)", self); \
@@ -4332,7 +4330,7 @@
 		r = call_maybe( \
 			self, OPSTR, &cache_str, "(O)", other); \
 		if (r != Py_NotImplemented || \
-		    other->ob_type == self->ob_type) \
+		    Py_Type(other) == Py_Type(self)) \
 			return r; \
 		Py_DECREF(r); \
 	} \
@@ -4390,12 +4388,12 @@
 		if (getitem_str == NULL)
 			return NULL;
 	}
-	func = _PyType_Lookup(self->ob_type, getitem_str);
+	func = _PyType_Lookup(Py_Type(self), getitem_str);
 	if (func != NULL) {
-		if ((f = func->ob_type->tp_descr_get) == NULL)
+		if ((f = Py_Type(func)->tp_descr_get) == NULL)
 			Py_INCREF(func);
 		else {
-			func = f(func, self, (PyObject *)(self->ob_type));
+			func = f(func, self, (PyObject *)(Py_Type(self)));
 			if (func == NULL) {
 				return NULL;
 			}
@@ -4534,8 +4532,8 @@
 	/* Three-arg power doesn't use __rpow__.  But ternary_op
 	   can call this when the second argument's type uses
 	   slot_nb_power, so check before calling self.__pow__. */
-	if (self->ob_type->tp_as_number != NULL &&
-	    self->ob_type->tp_as_number->nb_power == slot_nb_power) {
+	if (Py_Type(self)->tp_as_number != NULL &&
+	    Py_Type(self)->tp_as_number->nb_power == slot_nb_power) {
 		return call_method(self, "__pow__", &pow_str,
 				   "(OO)", other, modulus);
 	}
@@ -4725,12 +4723,12 @@
 {
 	int c;
 
-	if (self->ob_type->tp_compare == _PyObject_SlotCompare) {
+	if (Py_Type(self)->tp_compare == _PyObject_SlotCompare) {
 		c = half_compare(self, other);
 		if (c <= 1)
 			return c;
 	}
-	if (other->ob_type->tp_compare == _PyObject_SlotCompare) {
+	if (Py_Type(other)->tp_compare == _PyObject_SlotCompare) {
 		c = half_compare(other, self);
 		if (c < -1)
 			return -2;
@@ -4755,7 +4753,7 @@
 	}
 	PyErr_Clear();
 	return PyString_FromFormat("<%s object at %p>",
-				   self->ob_type->tp_name, self);
+				   Py_Type(self)->tp_name, self);
 }
 
 static PyObject *
@@ -4864,7 +4862,7 @@
 static PyObject *
 slot_tp_getattr_hook(PyObject *self, PyObject *name)
 {
-	PyTypeObject *tp = self->ob_type;
+	PyTypeObject *tp = Py_Type(self);
 	PyObject *getattr, *getattribute, *res;
 	static PyObject *getattribute_str = NULL;
 	static PyObject *getattr_str = NULL;
@@ -4888,7 +4886,7 @@
 	}
 	getattribute = _PyType_Lookup(tp, getattribute_str);
 	if (getattribute == NULL ||
-	    (getattribute->ob_type == &PyWrapperDescr_Type &&
+	    (Py_Type(getattribute) == &PyWrapperDescr_Type &&
 	     ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
 	     (void *)PyObject_GenericGetAttr))
 		res = PyObject_GenericGetAttr(self, name);
@@ -4957,13 +4955,13 @@
 {
 	PyObject *res;
 
-	if (self->ob_type->tp_richcompare == slot_tp_richcompare) {
+	if (Py_Type(self)->tp_richcompare == slot_tp_richcompare) {
 		res = half_richcompare(self, other, op);
 		if (res != Py_NotImplemented)
 			return res;
 		Py_DECREF(res);
 	}
-	if (other->ob_type->tp_richcompare == slot_tp_richcompare) {
+	if (Py_Type(other)->tp_richcompare == slot_tp_richcompare) {
 		res = half_richcompare(other, self, _Py_SwappedOp[op]);
 		if (res != Py_NotImplemented) {
 			return res;
@@ -4996,7 +4994,7 @@
 	if (func == NULL) {
 		PyErr_Format(PyExc_TypeError,
 			     "'%.200s' object is not iterable",
-			     self->ob_type->tp_name);
+			     Py_Type(self)->tp_name);
 		return NULL;
 	}
 	Py_DECREF(func);
@@ -5013,7 +5011,7 @@
 static PyObject *
 slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
 {
-	PyTypeObject *tp = self->ob_type;
+	PyTypeObject *tp = Py_Type(self);
 	PyObject *get;
 	static PyObject *get_str = NULL;
 
@@ -5071,7 +5069,7 @@
 	if (res != Py_None) {
 		PyErr_Format(PyExc_TypeError,
 			     "__init__() should return None, not '%.200s'",
-			     res->ob_type->tp_name);
+			     Py_Type(res)->tp_name);
 		Py_DECREF(res);
 		return -1;
 	}
@@ -5156,7 +5154,7 @@
 		_Py_NewReference(self);
 		self->ob_refcnt = refcnt;
 	}
-	assert(!PyType_IS_GC(self->ob_type) ||
+	assert(!PyType_IS_GC(Py_Type(self)) ||
 	       _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
 	/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
 	 * we need to undo that. */
@@ -5168,8 +5166,8 @@
 	 * undone.
 	 */
 #ifdef COUNT_ALLOCS
-	--self->ob_type->tp_frees;
-	--self->ob_type->tp_allocs;
+	--Py_Type(self)->tp_frees;
+	--Py_Type(self)->tp_allocs;
 #endif
 }
 
@@ -5531,7 +5529,7 @@
 		descr = _PyType_Lookup(type, p->name_strobj);
 		if (descr == NULL)
 			continue;
-		if (descr->ob_type == &PyWrapperDescr_Type) {
+		if (Py_Type(descr) == &PyWrapperDescr_Type) {
 			void **tptr = resolve_slotdups(type, p->name_strobj);
 			if (tptr == NULL || tptr == ptr)
 				generic = p->function;
@@ -5546,7 +5544,7 @@
 					use_generic = 1;
 			}
 		}
-		else if (descr->ob_type == &PyCFunction_Type &&
+		else if (Py_Type(descr) == &PyCFunction_Type &&
 			 PyCFunction_GET_FUNCTION(descr) ==
 			 (PyCFunction)tp_new_wrapper &&
 			 strcmp(p->name, "__new__") == 0)
@@ -5817,7 +5815,7 @@
 	Py_XDECREF(su->obj);
 	Py_XDECREF(su->type);
 	Py_XDECREF(su->obj_type);
-	self->ob_type->tp_free(self);
+	Py_Type(self)->tp_free(self);
 }
 
 static PyObject *
@@ -5882,7 +5880,7 @@
 			res = PyDict_GetItem(dict, name);
 			if (res != NULL) {
 				Py_INCREF(res);
-				f = res->ob_type->tp_descr_get;
+				f = Py_Type(res)->tp_descr_get;
 				if (f != NULL) {
 					tmp = f(res,
 						/* Only pass 'obj' param if
@@ -5918,7 +5916,7 @@
 	     the normal case; the return value is obj.__class__.
 
 	   But... when obj is an instance, we want to allow for the case where
-	   obj->ob_type is not a subclass of type, but obj.__class__ is!
+	   Py_Type(obj) is not a subclass of type, but obj.__class__ is!
 	   This will allow using super() with a proxy for obj.
 	*/
 
@@ -5929,9 +5927,9 @@
 	}
 
 	/* Normal case */
-	if (PyType_IsSubtype(obj->ob_type, type)) {
-		Py_INCREF(obj->ob_type);
-		return obj->ob_type;
+	if (PyType_IsSubtype(Py_Type(obj), type)) {
+		Py_INCREF(Py_Type(obj));
+		return Py_Type(obj);
 	}
 	else {
 		/* Try the slow way */
@@ -5948,7 +5946,7 @@
 
 		if (class_attr != NULL &&
 		    PyType_Check(class_attr) &&
-		    (PyTypeObject *)class_attr != obj->ob_type)
+		    (PyTypeObject *)class_attr != Py_Type(obj))
 		{
 			int ok = PyType_IsSubtype(
 				(PyTypeObject *)class_attr, type);
@@ -5979,10 +5977,10 @@
 		Py_INCREF(self);
 		return self;
 	}
-	if (su->ob_type != &PySuper_Type)
+	if (Py_Type(su) != &PySuper_Type)
 		/* If su is an instance of a (strict) subclass of super,
 		   call its type */
-		return PyObject_CallFunctionObjArgs((PyObject *)su->ob_type,
+		return PyObject_CallFunctionObjArgs((PyObject *)Py_Type(su),
 						    su->type, obj, NULL);
 	else {
 		/* Inline the common case */
@@ -6051,8 +6049,7 @@
 }
 
 PyTypeObject PySuper_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"super",				/* tp_name */
 	sizeof(superobject),			/* tp_basicsize */
 	0,					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/unicodeobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/unicodeobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/unicodeobject.c	Thu Sep  6 21:35:45 2007
@@ -312,7 +312,7 @@
     else {
 	PyMem_DEL(unicode->str);
 	Py_XDECREF(unicode->defenc);
-	unicode->ob_type->tp_free((PyObject *)unicode);
+	Py_Type(unicode)->tp_free((PyObject *)unicode);
     }
 }
 
@@ -326,7 +326,7 @@
 	return -1;
     }
     v = (PyUnicodeObject *)*unicode;
-    if (v == NULL || !PyUnicode_Check(v) || v->ob_refcnt != 1 || length < 0) {
+    if (v == NULL || !PyUnicode_Check(v) || Py_Refcnt(v) != 1 || length < 0) {
 	PyErr_BadInternalCall();
 	return -1;
     }
@@ -554,7 +554,7 @@
 	PyErr_Format(PyExc_TypeError,
 			 "coercing to Unicode: need string or buffer, "
 			 "%.80s found",
-		     obj->ob_type->tp_name);
+		     Py_Type(obj)->tp_name);
 	goto onError;
     }
 
@@ -604,7 +604,7 @@
     if (!PyUnicode_Check(unicode)) {
         PyErr_Format(PyExc_TypeError,
                      "decoder did not return an unicode object (type=%.400s)",
-                     unicode->ob_type->tp_name);
+                     Py_Type(unicode)->tp_name);
         Py_DECREF(unicode);
         goto onError;
     }
@@ -714,7 +714,7 @@
     if (!PyString_Check(v)) {
         PyErr_Format(PyExc_TypeError,
                      "encoder did not return a string object (type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         goto onError;
     }
@@ -795,7 +795,8 @@
 static
 int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler,
                  const char *encoding, const char *reason,
-                 const char *input, Py_ssize_t insize, Py_ssize_t *startinpos, Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
+                 const char *input, Py_ssize_t insize, Py_ssize_t *startinpos,
+                 Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
                  PyObject **output, Py_ssize_t *outpos, Py_UNICODE **outptr)
 {
     static char *argparse = "O!n;decoding error handler must return (unicode, int) tuple";
@@ -1027,6 +1028,7 @@
             }
         }
         else if (SPECIAL(ch,0,0)) {
+            startinpos = s-starts;
             errmsg = "unexpected special character";
             s++;
 	        goto utf7Error;
@@ -1504,6 +1506,272 @@
 				NULL);
 }
 
+/* --- UTF-32 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF32(const char *s,
+		      Py_ssize_t size,
+		      const char *errors,
+		      int *byteorder)
+{
+    return PyUnicode_DecodeUTF32Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF32Stateful(const char *s,
+			      Py_ssize_t size,
+			      const char *errors,
+			      int *byteorder,
+			      Py_ssize_t *consumed)
+{
+    const char *starts = s;
+    Py_ssize_t startinpos;
+    Py_ssize_t endinpos;
+    Py_ssize_t outpos;
+    PyUnicodeObject *unicode;
+    Py_UNICODE *p;
+#ifndef Py_UNICODE_WIDE
+    int i, pairs;
+#else
+    const int pairs = 0;
+#endif
+    const unsigned char *q, *e;
+    int bo = 0;       /* assume native ordering by default */
+    const char *errmsg = "";
+    /* Offsets from q for retrieving bytes in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int iorder[] = {0, 1, 2, 3};
+#else
+    int iorder[] = {3, 2, 1, 0};
+#endif
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+    /* On narrow builds we split characters outside the BMP into two
+       codepoints => count how much extra space we need. */
+#ifndef Py_UNICODE_WIDE
+    for (i = pairs = 0; i < size/4; i++)
+	if (((Py_UCS4 *)s)[i] >= 0x10000)
+	    pairs++;
+#endif
+
+    /* This might be one to much, because of a BOM */
+    unicode = _PyUnicode_New((size+3)/4+pairs);
+    if (!unicode)
+        return NULL;
+    if (size == 0)
+        return (PyObject *)unicode;
+
+    /* Unpack UTF-32 encoded data */
+    p = unicode->str;
+    q = (unsigned char *)s;
+    e = q + size;
+
+    if (byteorder)
+        bo = *byteorder;
+
+    /* Check for BOM marks (U+FEFF) in the input and adjust current
+       byte order setting accordingly. In native mode, the leading BOM
+       mark is skipped, in all other modes, it is copied to the output
+       stream as-is (giving a ZWNBSP character). */
+    if (bo == 0) {
+        if (size >= 4) {
+            const Py_UCS4 bom = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+                                (q[iorder[1]] << 8) | q[iorder[0]];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+	    if (bom == 0x0000FEFF) {
+		q += 4;
+		bo = -1;
+	    }
+	    else if (bom == 0xFFFE0000) {
+		q += 4;
+		bo = 1;
+	    }
+#else
+	    if (bom == 0x0000FEFF) {
+		q += 4;
+		bo = 1;
+	    }
+	    else if (bom == 0xFFFE0000) {
+		q += 4;
+		bo = -1;
+	    }
+#endif
+	}
+    }
+
+    if (bo == -1) {
+        /* force LE */
+        iorder[0] = 0;
+        iorder[1] = 1;
+        iorder[2] = 2;
+        iorder[3] = 3;
+    }
+    else if (bo == 1) {
+        /* force BE */
+        iorder[0] = 3;
+        iorder[1] = 2;
+        iorder[2] = 1;
+        iorder[3] = 0;
+    }
+
+    while (q < e) {
+	Py_UCS4 ch;
+	/* remaining bytes at the end? (size should be divisible by 4) */
+	if (e-q<4) {
+	    if (consumed)
+		break;
+	    errmsg = "truncated data";
+	    startinpos = ((const char *)q)-starts;
+	    endinpos = ((const char *)e)-starts;
+	    goto utf32Error;
+	    /* The remaining input chars are ignored if the callback
+	       chooses to skip the input */
+	}
+	ch = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+	     (q[iorder[1]] << 8) | q[iorder[0]];
+
+	if (ch >= 0x110000)
+	{
+	    errmsg = "codepoint not in range(0x110000)";
+	    startinpos = ((const char *)q)-starts;
+	    endinpos = startinpos+4;
+	    goto utf32Error;
+	}
+#ifndef Py_UNICODE_WIDE
+	if (ch >= 0x10000)
+	{
+	    *p++ = 0xD800 | ((ch-0x10000) >> 10);
+	    *p++ = 0xDC00 | ((ch-0x10000) & 0x3FF);
+	}
+	else
+#endif
+	    *p++ = ch;
+	q += 4;
+	continue;
+    utf32Error:
+	outpos = p-PyUnicode_AS_UNICODE(unicode);
+    if (unicode_decode_call_errorhandler(
+         errors, &errorHandler,
+         "utf32", errmsg,
+         starts, size, &startinpos, &endinpos, &exc, &s,
+         (PyObject **)&unicode, &outpos, &p))
+	    goto onError;
+    }
+
+    if (byteorder)
+        *byteorder = bo;
+
+    if (consumed)
+	*consumed = (const char *)q-starts;
+
+    /* Adjust length */
+    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+        goto onError;
+
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)unicode;
+
+onError:
+    Py_DECREF(unicode);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF32(const Py_UNICODE *s,
+		      Py_ssize_t size,
+		      const char *errors,
+		      int byteorder)
+{
+    PyObject *v;
+    unsigned char *p;
+#ifndef Py_UNICODE_WIDE
+    int i, pairs;
+#else
+    const int pairs = 0;
+#endif
+    /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+    int iorder[] = {0, 1, 2, 3};
+#else
+    int iorder[] = {3, 2, 1, 0};
+#endif
+
+#define STORECHAR(CH)                       \
+    do {                                    \
+        p[iorder[3]] = ((CH) >> 24) & 0xff; \
+        p[iorder[2]] = ((CH) >> 16) & 0xff; \
+        p[iorder[1]] = ((CH) >> 8) & 0xff;  \
+        p[iorder[0]] = (CH) & 0xff;         \
+        p += 4;                             \
+    } while(0)
+
+    /* In narrow builds we can output surrogate pairs as one codepoint,
+       so we need less space. */
+#ifndef Py_UNICODE_WIDE
+    for (i = pairs = 0; i < size-1; i++)
+	if (0xD800 <= s[i] && s[i] <= 0xDBFF &&
+	    0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF)
+	    pairs++;
+#endif
+    v = PyString_FromStringAndSize(NULL,
+		  4 * (size - pairs + (byteorder == 0)));
+    if (v == NULL)
+        return NULL;
+
+    p = (unsigned char *)PyString_AS_STRING(v);
+    if (byteorder == 0)
+	STORECHAR(0xFEFF);
+    if (size == 0)
+        return v;
+
+    if (byteorder == -1) {
+        /* force LE */
+        iorder[0] = 0;
+        iorder[1] = 1;
+        iorder[2] = 2;
+        iorder[3] = 3;
+    }
+    else if (byteorder == 1) {
+        /* force BE */
+        iorder[0] = 3;
+        iorder[1] = 2;
+        iorder[2] = 1;
+        iorder[3] = 0;
+    }
+
+    while (size-- > 0) {
+	Py_UCS4 ch = *s++;
+#ifndef Py_UNICODE_WIDE
+	if (0xD800 <= ch && ch <= 0xDBFF && size > 0) {
+	    Py_UCS4 ch2 = *s;
+	    if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+		ch = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+		s++;
+		size--;
+	    }
+	}
+#endif
+        STORECHAR(ch);
+    }
+    return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF32String(PyObject *unicode)
+{
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(unicode),
+				 PyUnicode_GET_SIZE(unicode),
+				 NULL,
+				 0);
+}
+
 /* --- UTF-16 Codec ------------------------------------------------------- */
 
 PyObject *
@@ -3242,8 +3510,7 @@
 }
 
 static PyTypeObject EncodingMapType = {
-	PyObject_HEAD_INIT(NULL)
-        0,                      /*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
         "EncodingMap",          /*tp_name*/
         sizeof(struct encoding_map),   /*tp_basicsize*/
         0,                      /*tp_itemsize*/
@@ -3502,7 +3769,7 @@
     char *outstart;
     Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
 
-    if (mapping->ob_type == &EncodingMapType) {
+    if (Py_Type(mapping) == &EncodingMapType) {
         int res = encoding_map_lookup(c, mapping);
 	Py_ssize_t requiredsize = *outpos+1;
         if (res == -1)
@@ -3574,7 +3841,7 @@
     /* find all unencodable characters */
     while (collendpos < size) {
         PyObject *rep;
-        if (mapping->ob_type == &EncodingMapType) {
+        if (Py_Type(mapping) == &EncodingMapType) {
 	    int res = encoding_map_lookup(p[collendpos], mapping);
 	    if (res != -1)
 		break;
@@ -4632,7 +4899,7 @@
 	    PyErr_Format(PyExc_TypeError,
 			 "sequence item %zd: expected string or Unicode,"
 			 " %.80s found",
-			 i, item->ob_type->tp_name);
+			 i, Py_Type(item)->tp_name);
 	    goto onError;
 	}
 	item = PyUnicode_FromObject(item);
@@ -5632,7 +5899,7 @@
         PyErr_Format(PyExc_TypeError,
                      "encoder did not return a string/unicode object "
                      "(type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         return NULL;
     }
@@ -5668,7 +5935,7 @@
         PyErr_Format(PyExc_TypeError,
                      "decoder did not return a string/unicode object "
                      "(type=%.400s)",
-                     v->ob_type->tp_name);
+                     Py_Type(v)->tp_name);
         Py_DECREF(v);
         return NULL;
     }
@@ -5761,7 +6028,7 @@
 "S.find(sub [,start [,end]]) -> int\n\
 \n\
 Return the lowest index in S where substring sub is found,\n\
-such that sub is contained within s[start,end].  Optional\n\
+such that sub is contained within s[start:end].  Optional\n\
 arguments start and end are interpreted as in slice notation.\n\
 \n\
 Return -1 on failure.");
@@ -6502,7 +6769,7 @@
 "S.rfind(sub [,start [,end]]) -> int\n\
 \n\
 Return the highest index in S where substring sub is found,\n\
-such that sub is contained within s[start,end].  Optional\n\
+such that sub is contained within s[start:end].  Optional\n\
 arguments start and end are interpreted as in slice notation.\n\
 \n\
 Return -1 on failure.");
@@ -7120,6 +7387,12 @@
 
         if (slicelength <= 0) {
             return PyUnicode_FromUnicode(NULL, 0);
+        } else if (start == 0 && step == 1 && slicelength == self->length &&
+                   PyUnicode_CheckExact(self)) {
+            Py_INCREF(self);
+            return (PyObject *)self;
+        } else if (step == 1) {
+            return PyUnicode_FromUnicode(self->str + start, slicelength);
         } else {
             source_buf = PyUnicode_AS_UNICODE((PyObject*)self);
             result_buf = (Py_UNICODE *)PyMem_MALLOC(slicelength*
@@ -7294,7 +7567,8 @@
        always given), therefore increase the length by one.
 
     */
-    if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) ||
+    if (((type == 'g' || type == 'G') && 
+          buflen <= (size_t)10 + (size_t)prec) ||
 	(type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
 	PyErr_SetString(PyExc_OverflowError,
 			"formatted float is too long (precision too large?)");
@@ -7498,7 +7772,7 @@
 	arglen = -1;
 	argidx = -2;
     }
-    if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) &&
+    if (Py_Type(args)->tp_as_mapping && !PyTuple_Check(args) &&
         !PyObject_TypeCheck(args, &PyBaseString_Type))
 	dict = args;
 
@@ -7962,8 +8236,7 @@
 errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
 
 PyTypeObject PyUnicode_Type = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0, 					/* ob_size */
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "unicode", 				/* tp_name */
     sizeof(PyUnicodeObject), 		/* tp_size */
     0, 					/* tp_itemsize */

Modified: python/branches/bcannon-objcap/Objects/weakrefobject.c
==============================================================================
--- python/branches/bcannon-objcap/Objects/weakrefobject.c	(original)
+++ python/branches/bcannon-objcap/Objects/weakrefobject.c	Thu Sep  6 21:35:45 2007
@@ -105,7 +105,7 @@
 {
     PyObject_GC_UnTrack(self);
     clear_weakref((PyWeakReference *) self);
-    self->ob_type->tp_free(self);
+    Py_Type(self)->tp_free(self);
 }
 
 
@@ -172,7 +172,7 @@
 		      name ? "<weakref at %p; to '%.50s' at %p (%s)>"
 		           : "<weakref at %p; to '%.50s' at %p>",
 		      self,
-		      PyWeakref_GET_OBJECT(self)->ob_type->tp_name,
+		      Py_Type(PyWeakref_GET_OBJECT(self))->tp_name,
 		      PyWeakref_GET_OBJECT(self),
 		      name);
 	Py_XDECREF(nameobj);
@@ -274,10 +274,10 @@
         PyWeakReference *ref, *proxy;
         PyWeakReference **list;
 
-        if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+        if (!PyType_SUPPORTS_WEAKREFS(Py_Type(ob))) {
             PyErr_Format(PyExc_TypeError,
                          "cannot create weak reference to '%s' object",
-                         ob->ob_type->tp_name);
+                         Py_Type(ob)->tp_name);
             return NULL;
         }
         if (callback == Py_None)
@@ -332,8 +332,7 @@
 
 PyTypeObject
 _PyWeakref_RefType = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "weakref",
     sizeof(PyWeakReference),
     0,
@@ -447,7 +446,7 @@
     char buf[160];
     PyOS_snprintf(buf, sizeof(buf),
 		  "<weakproxy at %p to %.100s at %p>", proxy,
-		  PyWeakref_GET_OBJECT(proxy)->ob_type->tp_name,
+		  Py_Type(PyWeakref_GET_OBJECT(proxy))->tp_name,
 		  PyWeakref_GET_OBJECT(proxy));
     return PyString_FromString(buf);
 }
@@ -646,8 +645,7 @@
 
 PyTypeObject
 _PyWeakref_ProxyType = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "weakproxy",
     sizeof(PyWeakReference),
     0,
@@ -681,8 +679,7 @@
 
 PyTypeObject
 _PyWeakref_CallableProxyType = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "weakcallableproxy",
     sizeof(PyWeakReference),
     0,
@@ -722,10 +719,10 @@
     PyWeakReference **list;
     PyWeakReference *ref, *proxy;
 
-    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+    if (!PyType_SUPPORTS_WEAKREFS(Py_Type(ob))) {
         PyErr_Format(PyExc_TypeError,
 		     "cannot create weak reference to '%s' object",
-                     ob->ob_type->tp_name);
+                     Py_Type(ob)->tp_name);
         return NULL;
     }
     list = GET_WEAKREFS_LISTPTR(ob);
@@ -781,10 +778,10 @@
     PyWeakReference **list;
     PyWeakReference *ref, *proxy;
 
-    if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {
+    if (!PyType_SUPPORTS_WEAKREFS(Py_Type(ob))) {
         PyErr_Format(PyExc_TypeError,
 		     "cannot create weak reference to '%s' object",
-                     ob->ob_type->tp_name);
+                     Py_Type(ob)->tp_name);
         return NULL;
     }
     list = GET_WEAKREFS_LISTPTR(ob);
@@ -807,9 +804,9 @@
             PyWeakReference *prev;
 
             if (PyCallable_Check(ob))
-                result->ob_type = &_PyWeakref_CallableProxyType;
+                Py_Type(result) = &_PyWeakref_CallableProxyType;
             else
-                result->ob_type = &_PyWeakref_ProxyType;
+                Py_Type(result) = &_PyWeakref_ProxyType;
             get_basic_refs(*list, &ref, &proxy);
             if (callback == NULL) {
                 if (proxy != NULL) {
@@ -874,7 +871,7 @@
     PyWeakReference **list;
 
     if (object == NULL
-        || !PyType_SUPPORTS_WEAKREFS(object->ob_type)
+        || !PyType_SUPPORTS_WEAKREFS(Py_Type(object))
         || object->ob_refcnt != 0) {
         PyErr_BadInternalCall();
         return;

Modified: python/branches/bcannon-objcap/PC/_msi.c
==============================================================================
--- python/branches/bcannon-objcap/PC/_msi.c	(original)
+++ python/branches/bcannon-objcap/PC/_msi.c	Thu Sep  6 21:35:45 2007
@@ -417,8 +417,7 @@
 };
 
 static PyTypeObject record_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_msi.Record",		/*tp_name*/
 	sizeof(msiobj),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -584,8 +583,7 @@
 };
 
 static PyTypeObject summary_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_msi.SummaryInformation",		/*tp_name*/
 	sizeof(msiobj),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -733,8 +731,7 @@
 };
 
 static PyTypeObject msiview_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_msi.View",		/*tp_name*/
 	sizeof(msiobj),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/
@@ -851,8 +848,7 @@
 };
 
 static PyTypeObject msidb_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,			/*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"_msi.Database",		/*tp_name*/
 	sizeof(msiobj),	/*tp_basicsize*/
 	0,			/*tp_itemsize*/

Modified: python/branches/bcannon-objcap/PC/_winreg.c
==============================================================================
--- python/branches/bcannon-objcap/PC/_winreg.c	(original)
+++ python/branches/bcannon-objcap/PC/_winreg.c	Thu Sep  6 21:35:45 2007
@@ -460,8 +460,7 @@
 /* The type itself */
 PyTypeObject PyHKEY_Type =
 {
-	PyObject_HEAD_INIT(0) /* fill in type at module init */
-	0,
+	PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */
 	"PyHKEY",
 	sizeof(PyHKEYObject),
 	0,

Modified: python/branches/bcannon-objcap/PC/pyconfig.h
==============================================================================
--- python/branches/bcannon-objcap/PC/pyconfig.h	(original)
+++ python/branches/bcannon-objcap/PC/pyconfig.h	Thu Sep  6 21:35:45 2007
@@ -32,6 +32,11 @@
 #define MS_WINCE
 #endif
 
+/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */
+#ifdef USE_DL_EXPORT
+#	define Py_BUILD_CORE
+#endif /* USE_DL_EXPORT */
+
 /* Visual Studio 2005 introduces deprecation warnings for
    "insecure" and POSIX functions. The insecure functions should
    be replaced by *_s versions (according to Microsoft); the
@@ -140,7 +145,7 @@
 #if defined(_M_IA64)
 #define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)")
 #define MS_WINI64
-#elif defined(_M_X64)
+#elif defined(_M_X64) || defined(_M_AMD64)
 #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)")
 #define MS_WINX64
 #else
@@ -151,12 +156,26 @@
 /* set the version macros for the windows headers */
 #ifdef MS_WINX64
 /* 64 bit only runs on XP or greater */
-#define _WIN32_WINNT 0x0501
-#define WINVER 0x0501
+#define Py_WINVER 0x0501
 #else
 /* NT 4.0 or greater required otherwise */
-#define _WIN32_WINNT 0x0400
-#define WINVER 0x0400
+#define Py_WINVER 0x0400
+#endif
+
+/* We only set these values when building Python - we don't want to force
+   these values on extensions, as that will affect the prototypes and
+   structures exposed in the Windows headers. Even when building Python, we
+   allow a single source file to override this - they may need access to
+   structures etc so it can optionally use new Windows features if it
+   determines at runtime they are available.
+*/
+#ifdef Py_BUILD_CORE
+#ifndef WINVER
+#define WINVER Py_WINVER
+#endif
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT Py_WINVER
+#endif
 #endif
 
 /* _W64 is not defined for VC6 or eVC4 */
@@ -287,11 +306,6 @@
 #	define MS_COREDLL	/* deprecated old symbol */
 #endif /* !MS_NO_COREDLL && ... */
 
-/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */
-#ifdef USE_DL_EXPORT
-#	define Py_BUILD_CORE
-#endif /* USE_DL_EXPORT */
-
 /*  All windows compilers that use this header support __declspec */
 #define HAVE_DECLSPEC_DLL
 

Modified: python/branches/bcannon-objcap/PCbuild8/build.bat
==============================================================================
--- python/branches/bcannon-objcap/PCbuild8/build.bat	(original)
+++ python/branches/bcannon-objcap/PCbuild8/build.bat	Thu Sep  6 21:35:45 2007
@@ -14,4 +14,15 @@
 
 set cmd=devenv pcbuild.sln %build% "%conf%|%platf%"
 echo %cmd%
-%cmd%
\ No newline at end of file
+%cmd%
+
+rem Copy whatever was built to the canonical 'PCBuild' directory.
+rem This helps extensions which use distutils etc.
+rem (Don't check if the build was successful - we expect a few failures
+rem due to missing libs)
+echo Copying built files to ..\PCBuild
+if not exist %platf%%conf%\. (echo %platf%%conf% does not exist - nothing copied & goto xit)
+if not exist ..\PCBuild\. (echo ..\PCBuild does not exist - nothing copied & goto xit)
+xcopy /q/y %platf%%conf%\* ..\PCBuild\.
+
+:xit

Modified: python/branches/bcannon-objcap/PCbuild8/readme.txt
==============================================================================
--- python/branches/bcannon-objcap/PCbuild8/readme.txt	(original)
+++ python/branches/bcannon-objcap/PCbuild8/readme.txt	Thu Sep  6 21:35:45 2007
@@ -90,6 +90,13 @@
     large tables of Unicode data
 winsound
     play sounds (typically .wav files) under Windows
+    
+Note: Check the dependencies of subprojects when building a subproject.  You 
+need to manually build each of the dependencies, in order, first.  A good 
+example of this is the pythoncore subproject.  It is dependent on both the 
+make_versioninfo and the make_buildinfo subprojects.  You can check the build 
+order by right clicking on the project name, in the solution explorer, and 
+selecting the project build order item.
 
 The following subprojects will generally NOT build out of the box.  They
 wrap code Python doesn't control, and you'll need to download the base

Modified: python/branches/bcannon-objcap/Parser/parsetok.c
==============================================================================
--- python/branches/bcannon-objcap/Parser/parsetok.c	(original)
+++ python/branches/bcannon-objcap/Parser/parsetok.c	Thu Sep  6 21:35:45 2007
@@ -218,16 +218,24 @@
 			err_ret->error = E_EOF;
 		err_ret->lineno = tok->lineno;
 		if (tok->buf != NULL) {
+			char *text = NULL;
 			size_t len;
 			assert(tok->cur - tok->buf < INT_MAX);
 			err_ret->offset = (int)(tok->cur - tok->buf);
 			len = tok->inp - tok->buf;
-			err_ret->text = (char *) PyObject_MALLOC(len + 1);
-			if (err_ret->text != NULL) {
-				if (len > 0)
-					strncpy(err_ret->text, tok->buf, len);
-				err_ret->text[len] = '\0';
+#ifdef Py_USING_UNICODE
+			text = PyTokenizer_RestoreEncoding(tok, len, &err_ret->offset);
+
+#endif
+			if (text == NULL) {
+				text = (char *) PyObject_MALLOC(len + 1);
+				if (text != NULL) {
+					if (len > 0)
+						strncpy(text, tok->buf, len);
+					text[len] = '\0';
+				}
 			}
+			err_ret->text = text;
 		}
 	} else if (tok->encoding != NULL) {
 		node* r = PyNode_New(encoding_decl);

Modified: python/branches/bcannon-objcap/Parser/tokenizer.c
==============================================================================
--- python/branches/bcannon-objcap/Parser/tokenizer.c	(original)
+++ python/branches/bcannon-objcap/Parser/tokenizer.c	Thu Sep  6 21:35:45 2007
@@ -1522,6 +1522,68 @@
 	return result;
 }
 
+/* This function is only called from parsetok. However, it cannot live
+   there, as it must be empty for PGEN, and we can check for PGEN only
+   in this file. */
+
+#ifdef PGEN
+char*
+PyTokenizer_RestoreEncoding(struct tok_state* tok, int len, int* offset)
+{
+	return NULL;
+}
+#else
+static PyObject *
+dec_utf8(const char *enc, const char *text, size_t len) {
+	PyObject *ret = NULL;	
+	PyObject *unicode_text = PyUnicode_DecodeUTF8(text, len, "replace");
+	if (unicode_text) {
+		ret = PyUnicode_AsEncodedString(unicode_text, enc, "replace");
+		Py_DECREF(unicode_text);
+	}
+	if (!ret) {
+		PyErr_Print();
+	}
+	return ret;
+}
+
+char *
+PyTokenizer_RestoreEncoding(struct tok_state* tok, int len, int *offset)
+{
+	char *text = NULL;
+	if (tok->encoding) {
+		/* convert source to original encondig */
+		PyObject *lineobj = dec_utf8(tok->encoding, tok->buf, len);
+		if (lineobj != NULL) {
+			int linelen = PyString_Size(lineobj);
+			const char *line = PyString_AsString(lineobj);
+			text = PyObject_MALLOC(linelen + 1);
+			if (text != NULL && line != NULL) {
+				if (linelen)
+					strncpy(text, line, linelen);
+				text[linelen] = '\0';
+			}
+			Py_DECREF(lineobj);
+					
+			/* adjust error offset */
+			if (*offset > 1) {
+				PyObject *offsetobj = dec_utf8(tok->encoding, 
+							       tok->buf, *offset-1);
+				if (offsetobj) {
+					*offset = PyString_Size(offsetobj) + 1;
+					Py_DECREF(offsetobj);
+				}
+			}
+			
+		}
+	}
+	return text;
+
+}
+#endif
+
+			   
+
 #ifdef Py_DEBUG
 
 void

Modified: python/branches/bcannon-objcap/Parser/tokenizer.h
==============================================================================
--- python/branches/bcannon-objcap/Parser/tokenizer.h	(original)
+++ python/branches/bcannon-objcap/Parser/tokenizer.h	Thu Sep  6 21:35:45 2007
@@ -58,6 +58,8 @@
 extern struct tok_state *PyTokenizer_FromFile(FILE *, char *, char *);
 extern void PyTokenizer_Free(struct tok_state *);
 extern int PyTokenizer_Get(struct tok_state *, char **, char **);
+extern char * PyTokenizer_RestoreEncoding(struct tok_state* tok, 
+					  int len, int *offset);
 
 #ifdef __cplusplus
 }

Modified: python/branches/bcannon-objcap/Python/ast.c
==============================================================================
--- python/branches/bcannon-objcap/Python/ast.c	(original)
+++ python/branches/bcannon-objcap/Python/ast.c	Thu Sep  6 21:35:45 2007
@@ -1243,9 +1243,26 @@
                     c->c_arena);
     case STRING: {
         PyObject *str = parsestrplus(c, n);
-        if (!str)
+        if (!str) {
+            if (PyErr_ExceptionMatches(PyExc_UnicodeError)){
+                PyObject *type, *value, *tback, *errstr;
+                PyErr_Fetch(&type, &value, &tback);
+                errstr = ((PyUnicodeErrorObject *)value)->reason;
+                if (errstr) {
+                    char *s = "";
+                    char buf[128];
+                    s = PyString_AsString(errstr);
+                    PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s);
+                    ast_error(n, buf);
+                } else {
+                    ast_error(n, "(unicode error) unknown error");
+                }
+                Py_DECREF(type);
+                Py_DECREF(value);
+                Py_XDECREF(tback);
+            }
             return NULL;
-
+        }
         PyArena_AddPyObject(c->c_arena, str);
         return Str(str, LINENO(n), n->n_col_offset, c->c_arena);
     }
@@ -3126,6 +3143,7 @@
 #endif
 }
 
+#ifdef Py_USING_UNICODE
 static PyObject *
 decode_unicode(const char *s, size_t len, int rawmode, const char *encoding)
 {
@@ -3187,6 +3205,7 @@
         Py_XDECREF(u);
         return v;
 }
+#endif
 
 /* s is a Python string literal, including the bracketing quote characters,
  * and r &/or u prefixes (if any), and embedded escape sequences (if any).

Modified: python/branches/bcannon-objcap/Python/ceval.c
==============================================================================
--- python/branches/bcannon-objcap/Python/ceval.c	(original)
+++ python/branches/bcannon-objcap/Python/ceval.c	Thu Sep  6 21:35:45 2007
@@ -3655,7 +3655,7 @@
 	}
 	if (argdefs != NULL) {
 		d = &PyTuple_GET_ITEM(argdefs, 0);
-		nd = ((PyTupleObject *)argdefs)->ob_size;
+		nd = Py_Size(argdefs);
 	}
 	return PyEval_EvalCodeEx(co, globals,
 				 (PyObject *)NULL, (*pp_stack)-n, na,

Modified: python/branches/bcannon-objcap/Python/compile.c
==============================================================================
--- python/branches/bcannon-objcap/Python/compile.c	(original)
+++ python/branches/bcannon-objcap/Python/compile.c	Thu Sep  6 21:35:45 2007
@@ -907,7 +907,20 @@
 	Py_ssize_t arg;
 
 	/* necessary to make sure types aren't coerced (e.g., int and long) */
-	t = PyTuple_Pack(2, o, o->ob_type);
+        /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
+        if (PyFloat_Check(o)) {
+            double d = PyFloat_AS_DOUBLE(o);
+            unsigned char* p = (unsigned char*) &d;
+            /* all we need is to make the tuple different in either the 0.0
+             * or -0.0 case from all others, just to avoid the "coercion".
+             */
+            if (*p==0 && p[sizeof(double)-1]==0)
+                t = PyTuple_Pack(3, o, o->ob_type, Py_None);
+            else
+	        t = PyTuple_Pack(2, o, o->ob_type);
+        } else {
+	    t = PyTuple_Pack(2, o, o->ob_type);
+        }
 	if (t == NULL)
 	    return -1;
 

Modified: python/branches/bcannon-objcap/Python/import.c
==============================================================================
--- python/branches/bcannon-objcap/Python/import.c	(original)
+++ python/branches/bcannon-objcap/Python/import.c	Thu Sep  6 21:35:45 2007
@@ -119,15 +119,19 @@
 	/* prepare _PyImport_Filetab: copy entries from
 	   _PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
 	 */
+#ifdef HAVE_DYNAMIC_LOADING
 	for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
 		++countD;
+#endif
 	for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
 		++countS;
 	filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
 	if (filetab == NULL)
 		Py_FatalError("Can't initialize import file table.");
+#ifdef HAVE_DYNAMIC_LOADING
 	memcpy(filetab, _PyImport_DynLoadFiletab,
 	       countD * sizeof(struct filedescr));
+#endif
 	memcpy(filetab + countD, _PyImport_StandardFiletab,
 	       countS * sizeof(struct filedescr));
 	filetab[countD + countS].suffix = NULL;
@@ -1373,7 +1377,7 @@
 		saved_namelen = namelen;
 #endif /* PYOS_OS2 */
 		for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
-#if defined(PYOS_OS2)
+#if defined(PYOS_OS2) && defined(HAVE_DYNAMIC_LOADING)
 			/* OS/2 limits DLLs to 8 character names (w/o
 			   extension)
 			 * so if the name is longer than that and its a
@@ -3039,8 +3043,7 @@
 
 
 static PyTypeObject NullImporterType = {
-	PyObject_HEAD_INIT(NULL)
-	0,                         /*ob_size*/
+	PyVarObject_HEAD_INIT(NULL, 0)
 	"imp.NullImporter",        /*tp_name*/
 	sizeof(NullImporter),      /*tp_basicsize*/
 	0,                         /*tp_itemsize*/

Modified: python/branches/bcannon-objcap/Python/structmember.c
==============================================================================
--- python/branches/bcannon-objcap/Python/structmember.c	(original)
+++ python/branches/bcannon-objcap/Python/structmember.c	Thu Sep  6 21:35:45 2007
@@ -156,6 +156,12 @@
 	return -1;
 }
 
+#define WARN(msg)					\
+    do {						\
+	if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0)	\
+		return -1;				\
+    } while (0)
+
 int
 PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
 {
@@ -178,60 +184,54 @@
 	addr += l->offset;
 	switch (l->type) {
 	case T_BYTE:{
-		long long_val;
-		long_val = PyInt_AsLong(v);
+		long long_val = PyInt_AsLong(v);
 		if ((long_val == -1) && PyErr_Occurred())
 			return -1;
+		*(char*)addr = (char)long_val;
 		/* XXX: For compatibility, only warn about truncations
 		   for now. */
 		if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
-		*(char*)addr = (char)long_val;
+			WARN("Truncation of value to char");
 		break;
 		}
 	case T_UBYTE:{
-		long long_val;
-		long_val = PyInt_AsLong(v);
+		long long_val = PyInt_AsLong(v);
 		if ((long_val == -1) && PyErr_Occurred())
 			return -1;
-		if ((long_val > UCHAR_MAX) || (long_val < 0))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned char");
 		*(unsigned char*)addr = (unsigned char)long_val;
+		if ((long_val > UCHAR_MAX) || (long_val < 0))
+			WARN("Truncation of value to unsigned char");
 		break;
 		}
 	case T_SHORT:{
-		long long_val;
-		long_val = PyInt_AsLong(v);
+		long long_val = PyInt_AsLong(v);
 		if ((long_val == -1) && PyErr_Occurred())
 			return -1;
-		if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
 		*(short*)addr = (short)long_val;
+		if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
+			WARN("Truncation of value to short");
 		break;
 		}
 	case T_USHORT:{
-		long long_val;
-		long_val = PyInt_AsLong(v);
+		long long_val = PyInt_AsLong(v);
 		if ((long_val == -1) && PyErr_Occurred())
 			return -1;
-		if ((long_val > USHRT_MAX) || (long_val < 0))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned short");
 		*(unsigned short*)addr = (unsigned short)long_val;
+		if ((long_val > USHRT_MAX) || (long_val < 0))
+			WARN("Truncation of value to unsigned short");
 		break;
 		}
   	case T_INT:{
-		long long_val;
-		long_val = PyInt_AsLong(v);
+		long long_val = PyInt_AsLong(v);
 		if ((long_val == -1) && PyErr_Occurred())
 			return -1;
-		if ((long_val > INT_MAX) || (long_val < INT_MIN))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
 		*(int *)addr = (int)long_val;
+		if ((long_val > INT_MAX) || (long_val < INT_MIN))
+			WARN("Truncation of value to int");
 		break;
 		}
 	case T_UINT:{
-		unsigned long ulong_val;
-		ulong_val = PyLong_AsUnsignedLong(v);
+		unsigned long ulong_val = PyLong_AsUnsignedLong(v);
 		if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
 			/* XXX: For compatibility, accept negative int values
 			   as well. */
@@ -239,11 +239,12 @@
 			ulong_val = PyLong_AsLong(v);
 			if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
 				return -1;
-			PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
-		}
+			*(unsigned int *)addr = (unsigned int)ulong_val;
+			WARN("Writing negative value into unsigned field");
+		} else
+			*(unsigned int *)addr = (unsigned int)ulong_val;
 		if (ulong_val > UINT_MAX)
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
-		*(unsigned int *)addr = (unsigned int)ulong_val;
+			WARN("Truncation of value to unsigned int");
 		break;
 		}
 	case T_LONG:{
@@ -260,9 +261,10 @@
 			   as well. */
 			PyErr_Clear();
 			*(unsigned long*)addr = PyLong_AsLong(v);
-			if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
+			if ((*(unsigned long*)addr == (unsigned int)-1)
+			    && PyErr_Occurred())
 				return -1;
-			PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
+			WARN("Writing negative value into unsigned field");
 		}
 		break;
 		}
@@ -274,8 +276,7 @@
 		break;
 		}
 	case T_FLOAT:{
-		double double_val;
-		double_val = PyFloat_AsDouble(v);
+		double double_val = PyFloat_AsDouble(v);
 		if ((double_val == -1) && PyErr_Occurred())
 			return -1;
 		*(float*)addr = (float)double_val;

Modified: python/branches/bcannon-objcap/Python/symtable.c
==============================================================================
--- python/branches/bcannon-objcap/Python/symtable.c	(original)
+++ python/branches/bcannon-objcap/Python/symtable.c	Thu Sep  6 21:35:45 2007
@@ -117,8 +117,7 @@
 };
 
 PyTypeObject PySTEntry_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"symtable entry",
 	sizeof(PySTEntryObject),
 	0,

Modified: python/branches/bcannon-objcap/Python/traceback.c
==============================================================================
--- python/branches/bcannon-objcap/Python/traceback.c	(original)
+++ python/branches/bcannon-objcap/Python/traceback.c	Thu Sep  6 21:35:45 2007
@@ -52,8 +52,7 @@
 }
 
 PyTypeObject PyTraceBack_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"traceback",
 	sizeof(PyTracebackObject),
 	0,

Modified: python/branches/bcannon-objcap/Tools/msi/msi.py
==============================================================================
--- python/branches/bcannon-objcap/Tools/msi/msi.py	(original)
+++ python/branches/bcannon-objcap/Tools/msi/msi.py	Thu Sep  6 21:35:45 2007
@@ -103,7 +103,8 @@
 msvcr71_uuid = "{8666C8DD-D0B4-4B42-928E-A69E32FA5D4D}"
 pythondll_uuid = {
     "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}",
-    "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}"
+    "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}",
+    "26":"{34ebecac-f046-4e1c-b0e3-9bac3cdaacfa}",
     } [major+minor]
 
 # Build the mingw import library, libpythonXY.a
@@ -166,9 +167,11 @@
     testprefix = ''
 
 if msilib.Win64:
-    SystemFolderName = "[SystemFolder64]"
+    SystemFolderName = "[System64Folder]"
+    registry_component = 4|256
 else:
     SystemFolderName = "[SystemFolder]"
+    registry_component = 4
 
 msilib.reset()
 
@@ -191,7 +194,7 @@
                   schema, ProductName="Python "+full_current_version,
                   ProductCode=product_code,
                   ProductVersion=current_version,
-                  Manufacturer=u"Martin v. L\xf6wis")
+                  Manufacturer=u"Python Software Foundation")
     # The default sequencing of the RemoveExistingProducts action causes
     # removal of files that got just installed. Place it after
     # InstallInitialize, so we first uninstall everything, but still roll
@@ -1061,15 +1064,15 @@
     tcldata = []
     if have_tcl:
         tcldata = [
-            ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4, None,
+            ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
              "py.IDLE")]
     add_data(db, "Component",
              # msidbComponentAttributesRegistryKeyPath = 4
-             [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", 4, None,
+             [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
                "InstallPath"),
-              ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", 4, None,
+              ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
                "Documentation"),
-              ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", 4,
+              ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", registry_component,
                None, None)] + tcldata)
     # See "FeatureComponents Table".
     # The association between TclTk and pythonw.exe is necessary to make ICE59

Modified: python/branches/bcannon-objcap/Tools/msi/msilib.py
==============================================================================
--- python/branches/bcannon-objcap/Tools/msi/msilib.py	(original)
+++ python/branches/bcannon-objcap/Tools/msi/msilib.py	Thu Sep  6 21:35:45 2007
@@ -390,8 +390,8 @@
             cabarc = "cabarc.exe"
         cmd = r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name)
         p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)[0]
-        for line in (p.stdout, p.stdin):
+                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        for line in p.stdout:
             if line.startswith("  -- adding "):
                 sys.stdout.write(".")
             else:

Modified: python/branches/bcannon-objcap/Tools/scripts/setup.py
==============================================================================
--- python/branches/bcannon-objcap/Tools/scripts/setup.py	(original)
+++ python/branches/bcannon-objcap/Tools/scripts/setup.py	Thu Sep  6 21:35:45 2007
@@ -11,6 +11,7 @@
         'ftpmirror.py',
         'h2py.py',
         'lfcr.py',
+        '../i18n/pygettext.py',
         'logmerge.py',
         '../../Lib/tabnanny.py',
         '../../Lib/timeit.py',

Modified: python/branches/bcannon-objcap/configure
==============================================================================
--- python/branches/bcannon-objcap/configure	(original)
+++ python/branches/bcannon-objcap/configure	Thu Sep  6 21:35:45 2007
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 54283 .
+# From configure.in Revision: 57904 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.61 for python 2.6.
 #
@@ -1838,6 +1838,14 @@
 _ACEOF
 
 
+# OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is
+# also defined. This can be overridden by defining _BSD_SOURCE
+
+cat >>confdefs.h <<\_ACEOF
+#define _BSD_SOURCE 1
+_ACEOF
+
+
 # The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
 # u_int on Irix 5.3. Defining _BSD_TYPES brings it back.
 
@@ -12025,6 +12033,14 @@
 			cur_target=10.3
 		fi
 		CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}}
+
+		# Make sure that MACOSX_DEPLOYMENT_TARGET is set in the
+		# environment with a value that is the same as what we'll use
+		# in the Makefile to ensure that we'll get the same compiler
+		# environment during configure and build time.
+		MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET"
+		export MACOSX_DEPLOYMENT_TARGET
+
 		EXPORT_MACOSX_DEPLOYMENT_TARGET=''
 		if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2
 		then
@@ -21683,6 +21699,77 @@
 fi
 
 
+# also in 4.0
+{ echo "$as_me:$LINENO: checking for rl_completion_display_matches_hook in -lreadline" >&5
+echo $ECHO_N "checking for rl_completion_display_matches_hook in -lreadline... $ECHO_C" >&6; }
+if test "${ac_cv_lib_readline_rl_completion_display_matches_hook+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rl_completion_display_matches_hook ();
+int
+main ()
+{
+return rl_completion_display_matches_hook ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_readline_rl_completion_display_matches_hook=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_readline_rl_completion_display_matches_hook=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_readline_rl_completion_display_matches_hook" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_rl_completion_display_matches_hook" >&6; }
+if test $ac_cv_lib_readline_rl_completion_display_matches_hook = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1
+_ACEOF
+
+fi
+
+
 # check for readline 4.2
 { echo "$as_me:$LINENO: checking for rl_completion_matches in -lreadline" >&5
 echo $ECHO_N "checking for rl_completion_matches in -lreadline... $ECHO_C" >&6; }
@@ -24195,4 +24282,21 @@
 $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
 			-s Modules Modules/Setup.config \
 			Modules/Setup.local Modules/Setup
+
+case $ac_sys_system in
+BeOS)
+        { echo "$as_me:$LINENO: WARNING:
+
+  Support for BeOS is deprecated as of Python 2.6.
+  See PEP 11 for the gory details.
+  " >&5
+echo "$as_me: WARNING:
+
+  Support for BeOS is deprecated as of Python 2.6.
+  See PEP 11 for the gory details.
+  " >&2;}
+  ;;
+*) ;;
+esac
+
 mv config.c Modules

Modified: python/branches/bcannon-objcap/configure.in
==============================================================================
--- python/branches/bcannon-objcap/configure.in	(original)
+++ python/branches/bcannon-objcap/configure.in	Thu Sep  6 21:35:45 2007
@@ -4,7 +4,7 @@
 m4_define(PYTHON_VERSION, 2.6)
 
 AC_REVISION($Revision$)
-AC_PREREQ(2.59)
+AC_PREREQ(2.61)
 AC_INIT(python, PYTHON_VERSION, http://www.python.org/python-bugs)
 AC_CONFIG_SRCDIR([Include/object.h])
 AC_CONFIG_HEADER(pyconfig.h)
@@ -50,6 +50,10 @@
 # them.
 AC_DEFINE(__BSD_VISIBLE, 1, [Define on FreeBSD to activate all library features])
 
+# OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is
+# also defined. This can be overridden by defining _BSD_SOURCE
+AC_DEFINE(_BSD_SOURCE, 1, [Define on OpenBSD to activate all library features])
+
 # The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
 # u_int on Irix 5.3. Defining _BSD_TYPES brings it back.
 AC_DEFINE(_BSD_TYPES, 1, [Define on Irix to enable u_int])
@@ -1505,6 +1509,14 @@
 			cur_target=10.3
 		fi
 		CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}}
+
+		# Make sure that MACOSX_DEPLOYMENT_TARGET is set in the 
+		# environment with a value that is the same as what we'll use
+		# in the Makefile to ensure that we'll get the same compiler
+		# environment during configure and build time.
+		MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET"
+		export MACOSX_DEPLOYMENT_TARGET
+
 		EXPORT_MACOSX_DEPLOYMENT_TARGET=''
 		if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2
 		then
@@ -3125,6 +3137,11 @@
 	AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1,
         [Define if you have readline 4.0]), , )
 
+# also in 4.0
+AC_CHECK_LIB(readline, rl_completion_display_matches_hook,
+	AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1,
+        [Define if you have readline 4.0]), , )
+
 # check for readline 4.2
 AC_CHECK_LIB(readline, rl_completion_matches,
 	AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
@@ -3477,4 +3494,16 @@
 $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
 			-s Modules Modules/Setup.config \
 			Modules/Setup.local Modules/Setup
+
+case $ac_sys_system in
+BeOS)
+        AC_MSG_WARN([
+
+  Support for BeOS is deprecated as of Python 2.6.
+  See PEP 11 for the gory details.
+  ])
+  ;;
+*) ;;
+esac
+
 mv config.c Modules

Modified: python/branches/bcannon-objcap/pyconfig.h.in
==============================================================================
--- python/branches/bcannon-objcap/pyconfig.h.in	(original)
+++ python/branches/bcannon-objcap/pyconfig.h.in	Thu Sep  6 21:35:45 2007
@@ -103,6 +103,10 @@
 /* Define if you have the 'resize_term' function. */
 #undef HAVE_CURSES_RESIZE_TERM
 
+/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
+   */
+#undef HAVE_DECL_TZNAME
+
 /* Define to 1 if you have the device macros. */
 #undef HAVE_DEVICE_MACROS
 
@@ -428,6 +432,9 @@
 /* Define if you have readline 2.2 */
 #undef HAVE_RL_COMPLETION_APPEND_CHARACTER
 
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
+
 /* Define if you have readline 4.2 */
 #undef HAVE_RL_COMPLETION_MATCHES
 
@@ -802,22 +809,22 @@
 /* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
 #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
 
-/* The size of a `double', as computed by sizeof. */
+/* The size of `double', as computed by sizeof. */
 #undef SIZEOF_DOUBLE
 
-/* The size of a `float', as computed by sizeof. */
+/* The size of `float', as computed by sizeof. */
 #undef SIZEOF_FLOAT
 
-/* The size of a `fpos_t', as computed by sizeof. */
+/* The size of `fpos_t', as computed by sizeof. */
 #undef SIZEOF_FPOS_T
 
-/* The size of a `int', as computed by sizeof. */
+/* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
-/* The size of a `long', as computed by sizeof. */
+/* The size of `long', as computed by sizeof. */
 #undef SIZEOF_LONG
 
-/* The size of a `long long', as computed by sizeof. */
+/* The size of `long long', as computed by sizeof. */
 #undef SIZEOF_LONG_LONG
 
 /* The number of bytes in an off_t. */
@@ -826,25 +833,25 @@
 /* The number of bytes in a pthread_t. */
 #undef SIZEOF_PTHREAD_T
 
-/* The size of a `short', as computed by sizeof. */
+/* The size of `short', as computed by sizeof. */
 #undef SIZEOF_SHORT
 
-/* The size of a `size_t', as computed by sizeof. */
+/* The size of `size_t', as computed by sizeof. */
 #undef SIZEOF_SIZE_T
 
 /* The number of bytes in a time_t. */
 #undef SIZEOF_TIME_T
 
-/* The size of a `uintptr_t', as computed by sizeof. */
+/* The size of `uintptr_t', as computed by sizeof. */
 #undef SIZEOF_UINTPTR_T
 
-/* The size of a `void *', as computed by sizeof. */
+/* The size of `void *', as computed by sizeof. */
 #undef SIZEOF_VOID_P
 
-/* The size of a `wchar_t', as computed by sizeof. */
+/* The size of `wchar_t', as computed by sizeof. */
 #undef SIZEOF_WCHAR_T
 
-/* The size of a `_Bool', as computed by sizeof. */
+/* The size of `_Bool', as computed by sizeof. */
 #undef SIZEOF__BOOL
 
 /* Define to 1 if you have the ANSI C header files. */
@@ -924,6 +931,9 @@
 # undef _ALL_SOURCE
 #endif
 
+/* Define on OpenBSD to activate all library features */
+#undef _BSD_SOURCE
+
 /* Define on Irix to enable u_int */
 #undef _BSD_TYPES
 
@@ -980,7 +990,7 @@
 /* Define to `int' if <sys/types.h> does not define. */
 #undef mode_t
 
-/* Define to `long' if <sys/types.h> does not define. */
+/* Define to `long int' if <sys/types.h> does not define. */
 #undef off_t
 
 /* Define to `int' if <sys/types.h> does not define. */
@@ -989,7 +999,7 @@
 /* Define to empty if the keyword does not work. */
 #undef signed
 
-/* Define to `unsigned' if <sys/types.h> does not define. */
+/* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 
 /* Define to `int' if <sys/socket.h> does not define. */

Modified: python/branches/bcannon-objcap/setup.py
==============================================================================
--- python/branches/bcannon-objcap/setup.py	(original)
+++ python/branches/bcannon-objcap/setup.py	Thu Sep  6 21:35:45 2007
@@ -194,18 +194,21 @@
             for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
                 print "%-*s   %-*s   %-*s" % (longest, e, longest, f,
                                               longest, g)
-            print
 
         if missing:
             print
             print "Failed to find the necessary bits to build these modules:"
             print_three_column(missing)
+            print ("To find the necessary bits, look in setup.py in"
+                   " detect_modules() for the module's name.")
+            print
 
         if self.failed:
             failed = self.failed[:]
             print
             print "Failed to build these modules:"
             print_three_column(failed)
+            print
 
     def build_extension(self, ext):
 
@@ -299,7 +302,8 @@
                 # strip out double-dashes first so that we don't end up with
                 # substituting "--Long" to "-Long" and thus lead to "ong" being
                 # used for a library directory.
-                env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], '', env_val)
+                env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1],
+                                 ' ', env_val)
                 parser = optparse.OptionParser()
                 # Make sure that allowing args interspersed with options is
                 # allowed
@@ -631,7 +635,8 @@
                                    include_dirs = ssl_incs,
                                    library_dirs = ssl_libs,
                                    libraries = ['ssl', 'crypto']) )
-            missing.extend(['_sha', '_md5'])
+            # these aren't strictly missing since they are unneeded.
+            #missing.extend(['_sha', '_md5'])
         else:
             # The _sha module implements the SHA1 hash algorithm.
             exts.append( Extension('_sha', ['shamodule.c']) )
@@ -648,6 +653,7 @@
             exts.append( Extension('_sha256', ['sha256module.c']) )
             exts.append( Extension('_sha512', ['sha512module.c']) )
         else:
+            # these aren't strictly missing since they are unneeded.
             missing.extend(['_sha256', '_sha512'])
 
         # Modules that provide persistent dictionary-like semantics.  You will
@@ -657,14 +663,14 @@
         # implementation independent wrapper for these; dumbdbm.py provides
         # similar functionality (but slower of course) implemented in Python.
 
-        # Sleepycat Berkeley DB interface.  http://www.sleepycat.com
+        # Sleepycat^WOracle Berkeley DB interface.  http://www.sleepycat.com
         #
-        # This requires the Sleepycat DB code. The supported versions
+        # This requires the Sleepycat^WOracle DB code. The supported versions
         # are set below.  Visit http://www.sleepycat.com/ to download
         # a release.  Most open source OSes come with one or more
         # versions of BerkeleyDB already installed.
 
-        max_db_ver = (4, 5)
+        max_db_ver = (4, 6)
         min_db_ver = (3, 3)
         db_setup_debug = False   # verbose debug prints from this script?
 
@@ -682,7 +688,7 @@
             '/sw/include/db3',
         ]
         # 4.x minor number specific paths
-        for x in (0,1,2,3,4,5):
+        for x in (0,1,2,3,4,5,6):
             db_inc_paths.append('/usr/include/db4%d' % x)
             db_inc_paths.append('/usr/include/db4.%d' % x)
             db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
@@ -707,7 +713,7 @@
         for dn in inc_dirs:
             std_variants.append(os.path.join(dn, 'db3'))
             std_variants.append(os.path.join(dn, 'db4'))
-            for x in (0,1,2,3,4):
+            for x in (0,1,2,3,4,5,6):
                 std_variants.append(os.path.join(dn, "db4%d"%x))
                 std_variants.append(os.path.join(dn, "db4.%d"%x))
             for x in (2,3):
@@ -903,8 +909,13 @@
         # accidentally building this module with a later version of the
         # underlying db library.  May BSD-ish Unixes incorporate db 1.85
         # symbols into libc and place the include file in /usr/include.
+        #
+        # If the better bsddb library can be built (db_incs is defined)
+        # we do not build this one.  Otherwise this build will pick up
+        # the more recent berkeleydb's db.h file first in the include path
+        # when attempting to compile and it will fail.
         f = "/usr/include/db.h"
-        if os.path.exists(f):
+        if os.path.exists(f) and not db_incs:
             data = open(f).read()
             m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
             if m is not None:


More information about the Python-checkins mailing list